sweeper: relax anchor sweeping when there's no deadline pressure (#7965)

* sweep: use longer variable name for clarity in `addToState`

* sweeper: add more docs and debug logs

* sweep: prioritize smaller inputs when adding wallet UTXOs

This commit sorts wallet UTXOs by their values when using them for
sweeping inputs. This way we'd avoid locking large UTXOs when sweeping
inputs and also provide an opportunity to aggregate wallet UTXOs.

* contractcourt+itest: relax anchor sweeping for CPFP purpose

This commit changes from always sweeping anchor for a local force close
to only do so when there is an actual time pressure. After this change,
a forced anchor sweeping will only be attempted when the deadline is
less than 144 blocks.

* docs: update release notes

* itest: update test `testMultiHopHtlcLocalChainClaim` to skip CPFP

Since we now only perform CPFP when both the fee rate is higher and the
deadline is less than 144, we need to update the test to reflect that
Bob will not CPFP the force close tx for the channle Alice->Bob.

* itest: fix `testMultiHopRemoteForceCloseOnChainHtlcTimeout`

* itest: update related tests to reflect anchor sweeping

This commit updates all related tests to reflect the latest anchor
sweeping behavior. Previously, anchor sweeping is always attempted as
CPFP when a force close is broadcast, while now it only happens when the
deadline is less than 144. For non-CPFP purpose sweeping, it will happen
after one block is mined after the force close transaction is confirmed
as the anchor will be resent to the sweeper with a floor fee rate, hence
making it economical to sweep.
This commit is contained in:
Yong authored and GitHub committed 2023-10-12 17:18:59 +02:00
1 parent ca9cdacd5f
commit 939375f1a5
9 files changed
+248 -99

No files matched your search

+13 -11
View File
@@ -521,18 +521,20 @@ func testAnchorThirdPartySpend(ht *lntest.HarnessTest) {
require.Equal(ht, testMemo,
pendingChannelsResp.WaitingCloseChannels[0].Channel.Memo)
// At this point, the channel is waiting close, and we have both the
// commitment transaction and anchor sweep in the mempool.
const expectedTxns = 2
sweepTxns := ht.Miner.GetNumTxsFromMempool(expectedTxns)
// At this point, the channel is waiting close so we have the
// commitment transaction in the mempool. Alice's anchor, however,
// because there's no deadline pressure, it won't be swept.
aliceCloseTx := waitingClose.Commitments.LocalTxid
_, aliceAnchor := ht.FindCommitAndAnchor(sweepTxns, aliceCloseTx)
// We'll now mine _only_ the commitment force close transaction, as we
// want the anchor sweep to stay unconfirmed.
ht.MineBlocksAndAssertNumTxes(1, 1)
forceCloseTxID, _ := chainhash.NewHashFromStr(aliceCloseTx)
commitTxn := ht.Miner.GetRawTransaction(forceCloseTxID)
ht.Miner.MineBlockWithTxes([]*btcutil.Tx{commitTxn})
// Mine one block to trigger Alice's sweeper to reconsider the anchor
// sweeping. Because we are now sweeping at the fee rate floor, the
// sweeper will consider this input has positive yield thus attempts
// the sweeping.
ht.MineEmptyBlocks(1)
sweepTxns := ht.Miner.GetNumTxsFromMempool(1)
_, aliceAnchor := ht.FindCommitAndAnchor(sweepTxns, aliceCloseTx)
// Assert that the channel is now in PendingForceClose.
//
@@ -573,7 +575,7 @@ func testAnchorThirdPartySpend(ht *lntest.HarnessTest) {
// call, we'll generate a series of _empty_ blocks here.
aliceRestart := ht.SuspendNode(alice)
const anchorCsv = 16
ht.MineEmptyBlocks(anchorCsv)
ht.MineEmptyBlocks(anchorCsv - 1)
// Before we sweep the anchor, we'll restart Alice.
require.NoErrorf(ht, aliceRestart(), "unable to restart alice")