Merge pull request #8946 from ziggie1984/fix-bumpforceclose-behaviour

Fix bumpforceclose behavior for force closes without htlcs.
This commit is contained in:
ProofOfKeags authored and GitHub committed 2024-07-30 14:42:19 -06:00
commit 67c5fa9478
3 files changed
+33 -11

No files matched your search

+16 -6
View File
@@ -40,6 +40,12 @@ const (
// arbitratorBlockBufferSize is the size of the buffer we give to each // arbitratorBlockBufferSize is the size of the buffer we give to each
// channel arbitrator. // channel arbitrator.
arbitratorBlockBufferSize = 20 arbitratorBlockBufferSize = 20
// AnchorOutputValue is the output value for the anchor output of an
// anchor channel.
// See BOLT 03 for more details:
// https://github.com/lightning/bolts/blob/master/03-transactions.md
AnchorOutputValue = btcutil.Amount(330)
) )
// WitnessSubscription represents an intent to be notified once new witnesses // WitnessSubscription represents an intent to be notified once new witnesses
@@ -1313,13 +1319,14 @@ func (c *ChannelArbitrator) sweepAnchors(anchors *lnwallet.AnchorResolutions,
} }
// If we cannot find a deadline, it means there's no HTLCs at // If we cannot find a deadline, it means there's no HTLCs at
// stake, which means we can relax our anchor sweeping as we // stake, which means we can relax our anchor sweeping
// don't have any time sensitive outputs to sweep. // conditions as we don't have any time sensitive outputs to
// sweep. However we need to register the anchor output with the
// sweeper so we are later able to bump the close fee.
if deadline.IsNone() { if deadline.IsNone() {
log.Infof("ChannelArbitrator(%v): no HTLCs at stake, "+ log.Infof("ChannelArbitrator(%v): no HTLCs at stake, "+
"skipped anchor CPFP", c.cfg.ChanPoint) "sweeping anchor with default deadline",
c.cfg.ChanPoint)
return nil
} }
witnessType := input.CommitmentAnchor witnessType := input.CommitmentAnchor
@@ -1357,10 +1364,13 @@ func (c *ChannelArbitrator) sweepAnchors(anchors *lnwallet.AnchorResolutions,
// Calculate the budget based on the value under protection, // Calculate the budget based on the value under protection,
// which is the sum of all HTLCs on this commitment subtracted // which is the sum of all HTLCs on this commitment subtracted
// by their budgets. // by their budgets.
// The anchor output in itself has a small output value of 330
// sats so we also include it in the budget to pay for the
// cpfp transaction.
budget := calculateBudget( budget := calculateBudget(
value, c.cfg.Budget.AnchorCPFPRatio, value, c.cfg.Budget.AnchorCPFPRatio,
c.cfg.Budget.AnchorCPFP, c.cfg.Budget.AnchorCPFP,
) ) + AnchorOutputValue
log.Infof("ChannelArbitrator(%v): offering anchor from %s "+ log.Infof("ChannelArbitrator(%v): offering anchor from %s "+
"commitment %v to sweeper with deadline=%v, budget=%v", "commitment %v to sweeper with deadline=%v, budget=%v",
@@ -39,6 +39,10 @@
* The fee limit for payments [was made * The fee limit for payments [was made
compatible](https://github.com/lightningnetwork/lnd/pull/8941) with inbound compatible](https://github.com/lightningnetwork/lnd/pull/8941) with inbound
fees. fees.
* [Fixed](https://github.com/lightningnetwork/lnd/pull/8946) a case where
bumping an anchor channel closing was not possible when no HTLCs were on the
commitment when the channel was force closed.
# New Features # New Features
## Functional Enhancements ## Functional Enhancements
+13 -5
View File
@@ -73,9 +73,11 @@ func testSweepCPFPAnchorOutgoingTimeout(ht *lntest.HarnessTest) {
htlcBudget := htlcValue.MulF64(contractcourt.DefaultBudgetRatio) htlcBudget := htlcValue.MulF64(contractcourt.DefaultBudgetRatio)
// cpfpBudget is the budget used to sweep the CPFP anchor. // cpfpBudget is the budget used to sweep the CPFP anchor.
// In addition to the htlc amount to protect we also need to include
// the anchor amount itself for the budget.
cpfpBudget := (htlcValue - htlcBudget).MulF64( cpfpBudget := (htlcValue - htlcBudget).MulF64(
contractcourt.DefaultBudgetRatio, contractcourt.DefaultBudgetRatio,
) ) + contractcourt.AnchorOutputValue
// Create a preimage, that will be held by Carol. // Create a preimage, that will be held by Carol.
var preimage lntypes.Preimage var preimage lntypes.Preimage
@@ -488,9 +490,11 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
htlcBudget := htlcValue.MulF64(contractcourt.DefaultBudgetRatio) htlcBudget := htlcValue.MulF64(contractcourt.DefaultBudgetRatio)
// cpfpBudget is the budget used to sweep the CPFP anchor. // cpfpBudget is the budget used to sweep the CPFP anchor.
// In addition to the htlc amount to protect we also need to include
// the anchor amount itself for the budget.
cpfpBudget := (htlcValue - htlcBudget).MulF64( cpfpBudget := (htlcValue - htlcBudget).MulF64(
contractcourt.DefaultBudgetRatio, contractcourt.DefaultBudgetRatio,
) ) + contractcourt.AnchorOutputValue
// Carol should have one incoming HTLC on channel Bob -> Carol. // Carol should have one incoming HTLC on channel Bob -> Carol.
ht.AssertIncomingHTLCActive(carol, bcChanPoint, payHash[:]) ht.AssertIncomingHTLCActive(carol, bcChanPoint, payHash[:])
@@ -1342,9 +1346,13 @@ func testSweepCommitOutputAndAnchor(ht *lntest.HarnessTest) {
// PendingChannels RPC under the waiting close section. // PendingChannels RPC under the waiting close section.
ht.AssertChannelWaitingClose(alice, chanPoint) ht.AssertChannelWaitingClose(alice, chanPoint)
// We should see neither Alice or Bob has any pending sweeps as there // Alice should see 2 anchor sweeps for the local and remote commitment.
// are no time-sensitive HTLCs. // Even without HTLCs at stake the anchors are registered with the
ht.AssertNumPendingSweeps(alice, 0) // sweeper subsytem.
ht.AssertNumPendingSweeps(alice, 2)
// Bob did not force close the channel therefore he should have no
// pending sweeps.
ht.AssertNumPendingSweeps(bob, 0) ht.AssertNumPendingSweeps(bob, 0)
// Mine a block to confirm Alice's force closing tx. Once it's // Mine a block to confirm Alice's force closing tx. Once it's