From b1506eca95ef1dd7b132286354160e48147f554e Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Thu, 1 Feb 2024 20:47:10 +0100 Subject: [PATCH] itests: add itest for ListSweeps's start_height --- itest/list_on_test.go | 4 ++ itest/lnd_channel_force_close_test.go | 4 +- itest/lnd_onchain_test.go | 97 +++++++++++++++++++++++++++ lntest/harness.go | 4 +- lntest/rpc/wallet_kit.go | 9 ++- 5 files changed, 112 insertions(+), 6 deletions(-) diff --git a/itest/list_on_test.go b/itest/list_on_test.go index 8bf8b0923..631e2a2cb 100644 --- a/itest/list_on_test.go +++ b/itest/list_on_test.go @@ -550,6 +550,10 @@ var allTestCases = []*lntest.TestCase{ Name: "update pending open channels", TestFunc: testUpdateOnPendingOpenChannels, }, + { + Name: "listsweeps", + TestFunc: testListSweeps, + }, { Name: "fail funding flow psbt", TestFunc: testPsbtChanFundingFailFlow, diff --git a/itest/lnd_channel_force_close_test.go b/itest/lnd_channel_force_close_test.go index e640ea583..f4a41f577 100644 --- a/itest/lnd_channel_force_close_test.go +++ b/itest/lnd_channel_force_close_test.go @@ -624,7 +624,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest, // Check that we can find the commitment sweep in our set of known // sweeps, using the simple transaction id ListSweeps output. - ht.AssertSweepFound(alice, sweepingTXID.String(), false) + ht.AssertSweepFound(alice, sweepingTXID.String(), false, 0) // Restart Alice to ensure that she resumes watching the finalized // commitment sweep txid. @@ -952,7 +952,7 @@ func channelForceClosureTest(ht *lntest.HarnessTest, // Check that we can find the htlc sweep in our set of sweeps using // the verbose output of the listsweeps output. - ht.AssertSweepFound(alice, htlcSweepTx.Hash().String(), true) + ht.AssertSweepFound(alice, htlcSweepTx.Hash().String(), true, 0) // The following restart checks to ensure that the nursery store is // storing the txid of the previously broadcast htlc sweep txn, and that diff --git a/itest/lnd_onchain_test.go b/itest/lnd_onchain_test.go index 7029c429f..83d94abe5 100644 --- a/itest/lnd_onchain_test.go +++ b/itest/lnd_onchain_test.go @@ -727,3 +727,100 @@ func genAnchorSweep(ht *lntest.HarnessTest, return btcutil.NewTx(tx) } + +// testListSweeps tests that we are able to: +// - list only those sweeps that are currently in the mempool, +// - list sweeps given a starting block height, +// - list all sweeps. +func testListSweeps(ht *lntest.HarnessTest) { + // Skip this test for neutrino, as it's not aware of mempool + // transactions. + if ht.IsNeutrinoBackend() { + ht.Skipf("skipping ListSweeps test for neutrino backend") + } + + // Create nodes so that we start with no funds on the internal wallet. + alice := ht.NewNode("Alice", nil) + bob := ht.NewNode("Bob", nil) + + const initialWalletAmt = btcutil.SatoshiPerBitcoin + + // Fund Alice with an initial balance. + ht.FundCoins(initialWalletAmt, alice) + + // Connect Alice to Bob. + ht.ConnectNodes(alice, bob) + + // Open a few channels between Alice and Bob. + var chanPoints []*lnrpc.ChannelPoint + for i := 0; i < 3; i++ { + chanPoint := ht.OpenChannel( + alice, bob, lntest.OpenChannelParams{ + Amt: 1e6, + PushAmt: 5e5, + }, + ) + + chanPoints = append(chanPoints, chanPoint) + } + + ht.Shutdown(bob) + + // Close the first channel and sweep the funds. + ht.ForceCloseChannel(alice, chanPoints[0]) + + // Jump a block. + ht.MineBlocks(1) + + // Get the current block height. + bestBlockRes := ht.Alice.RPC.GetBestBlock(nil) + blockHeight := bestBlockRes.BlockHeight + + // Close the second channel and also sweep the funds. + ht.ForceCloseChannel(alice, chanPoints[1]) + + // Now close the third channel but don't sweep the funds just yet. + closeStream, _ := ht.CloseChannelAssertPending( + alice, chanPoints[2], true, + ) + + ht.AssertStreamChannelForceClosed( + alice, chanPoints[2], false, closeStream, + ) + + // Mine enough blocks for the node to sweep its funds from the force + // closed channel. The commit sweep resolver is able to broadcast the + // sweep tx up to one block before the CSV elapses, so wait until + // defaulCSV-1. + ht.MineEmptyBlocks(node.DefaultCSV - 1) + + // Now we can expect that the sweep has been broadcast. + pendingTxHash := ht.Miner.AssertNumTxsInMempool(1) + + // List all unconfirmed sweeps that alice's node had broadcast. + sweepResp := alice.RPC.ListSweeps(false, -1) + txIDs := sweepResp.GetTransactionIds().TransactionIds + + require.Lenf(ht, txIDs, 1, "number of pending sweeps, starting from "+ + "height -1") + require.Equal(ht, pendingTxHash[0].String(), txIDs[0]) + + // Now list sweeps from the closing of the first channel. We should + // only see the sweep from the second channel and the pending one. + sweepResp = alice.RPC.ListSweeps(false, blockHeight) + txIDs = sweepResp.GetTransactionIds().TransactionIds + require.Lenf(ht, txIDs, 2, "number of sweeps, starting from height %d", + blockHeight) + + // Finally list all sweeps from the closing of the second channel. We + // should see all sweeps, including the pending one. + sweepResp = alice.RPC.ListSweeps(false, 0) + txIDs = sweepResp.GetTransactionIds().TransactionIds + require.Lenf(ht, txIDs, 3, "number of sweeps, starting from height 0") + + // Mine the pending sweep and make sure it is no longer returned. + ht.MineBlocks(1) + sweepResp = alice.RPC.ListSweeps(false, -1) + txIDs = sweepResp.GetTransactionIds().TransactionIds + require.Empty(ht, txIDs, "pending sweep should not be returned") +} diff --git a/lntest/harness.go b/lntest/harness.go index 29aba13b9..338b85618 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -1984,10 +1984,10 @@ func (h *HarnessTest) FindCommitAndAnchor(sweepTxns []*wire.MsgTx, // // NOTE: Does not account for node's internal state. func (h *HarnessTest) AssertSweepFound(hn *node.HarnessNode, - sweep string, verbose bool) { + sweep string, verbose bool, startHeight int32) { // List all sweeps that alice's node had broadcast. - sweepResp := hn.RPC.ListSweeps(verbose) + sweepResp := hn.RPC.ListSweeps(verbose, startHeight) var found bool if verbose { diff --git a/lntest/rpc/wallet_kit.go b/lntest/rpc/wallet_kit.go index f28eedf6a..10d3b17ed 100644 --- a/lntest/rpc/wallet_kit.go +++ b/lntest/rpc/wallet_kit.go @@ -158,11 +158,16 @@ func (h *HarnessRPC) VerifyMessageWithAddr( } // ListSweeps makes a ListSweeps RPC call to the node's WalletKit client. -func (h *HarnessRPC) ListSweeps(verbose bool) *walletrpc.ListSweepsResponse { +func (h *HarnessRPC) ListSweeps(verbose bool, + startHeight int32) *walletrpc.ListSweepsResponse { + ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout) defer cancel() - req := &walletrpc.ListSweepsRequest{Verbose: verbose} + req := &walletrpc.ListSweepsRequest{ + Verbose: verbose, + StartHeight: startHeight, + } resp, err := h.WalletKit.ListSweeps(ctxt, req) h.NoError(err, "ListSweeps")