From adca500f8127aa0f5eb770f37889944eb19ab970 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Tue, 16 Jul 2024 01:53:59 +0800 Subject: [PATCH] lntest+itest: fix flakes in `testChannelFundingWithUnstableUtxos` This commit makes sure the sweep requests are received before mining blocks to trigger the actual sweeping in `testChannelFundingWithUnstableUtxos`. In addition, `testFundingExpiryBlocksOnPending` is updated to deal with the old `channel link not found` issue. --- itest/lnd_funding_test.go | 18 ++++++++++-------- itest/lnd_open_channel_test.go | 13 +++++++++++++ lntest/harness_assertion.go | 7 ++++++- lntest/utils.go | 10 ++++++++-- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/itest/lnd_funding_test.go b/itest/lnd_funding_test.go index f8ba4f9fb4a..c6c79a893c7 100644 --- a/itest/lnd_funding_test.go +++ b/itest/lnd_funding_test.go @@ -12,7 +12,6 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/chainreg" - "github.com/lightningnetwork/lnd/fn" "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/labels" @@ -1341,22 +1340,22 @@ func testChannelFundingWithUnstableUtxos(ht *lntest.HarnessTest) { // that by dave force-closing the channel. Which let's carol sweep its // to_remote output which is not encumbered by any relative locktime. ht.CloseChannelAssertPending(dave, chanPoint2, true) + // Mine the force close commitment transaction. ht.MineBlocksAndAssertNumTxes(1, 1) + // Make sure Carol sees her to_remote output from the force close tx. + ht.AssertNumPendingSweeps(carol, 1) + // Mine one block to trigger the sweep transaction. ht.MineEmptyBlocks(1) // We need to wait for carol initiating the sweep of the to_remote // output of chanPoint2. - utxos := ht.AssertNumUTXOsUnconfirmed(carol, 1) + utxo := ht.AssertNumUTXOsUnconfirmed(carol, 1)[0] - // We filter for the unconfirmed utxo and try to open a channel with - // that utxo. - utxoOpt := fn.Find(func(u *lnrpc.Utxo) bool { - return u.Confirmations == 0 - }, utxos) - fundingUtxo := utxoOpt.UnwrapOrFail(ht.T) + // We now try to open channel using the unconfirmed utxo. + fundingUtxo := utxo // Now try to open the channel with this utxo and expect an error. expectedErr := fmt.Errorf("outpoint already spent or "+ @@ -1405,6 +1404,9 @@ func testChannelFundingWithUnstableUtxos(ht *lntest.HarnessTest) { ht.CloseChannelAssertPending(dave, chanPoint3, true) ht.MineBlocksAndAssertNumTxes(1, 1) + // Make sure Carol sees her to_remote output from the force close tx. + ht.AssertNumPendingSweeps(carol, 1) + // Mine one block to trigger the sweep transaction. ht.MineEmptyBlocks(1) diff --git a/itest/lnd_open_channel_test.go b/itest/lnd_open_channel_test.go index a7bac1b4519..52ec622cf7d 100644 --- a/itest/lnd_open_channel_test.go +++ b/itest/lnd_open_channel_test.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" "testing" + "time" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -767,6 +768,18 @@ func testFundingExpiryBlocksOnPending(ht *lntest.HarnessTest) { // channel. ht.MineBlocksAndAssertNumTxes(1, 1) chanPoint := lntest.ChanPointFromPendingUpdate(update) + + // TODO(yy): remove the sleep once the following bug is fixed. + // + // We may get the error `unable to gracefully close channel + // while peer is offline (try force closing it instead): + // channel link not found`. This happens because the channel + // link hasn't been added yet but we now proceed to closing the + // channel. We may need to revisit how the channel open event + // is created and make sure the event is only sent after all + // relevant states have been updated. + time.Sleep(2 * time.Second) + ht.CloseChannel(alice, chanPoint) } diff --git a/lntest/harness_assertion.go b/lntest/harness_assertion.go index 7a863a028e3..4a5d04274e1 100644 --- a/lntest/harness_assertion.go +++ b/lntest/harness_assertion.go @@ -785,8 +785,13 @@ func (h *HarnessTest) AssertNumUTXOsWithConf(hn *node.HarnessNode, return nil } + desc := "has UTXOs:\n" + for _, utxo := range resp.Utxos { + desc += fmt.Sprintf("%v\n", utxo) + } + return errNumNotMatched(hn.Name(), "num of UTXOs", - expectedUtxos, total-old, total, old) + expectedUtxos, total-old, total, old, desc) }, DefaultTimeout) require.NoError(h, err, "timeout waiting for UTXOs") diff --git a/lntest/utils.go b/lntest/utils.go index d230b6b6115..02b59bbe7dd 100644 --- a/lntest/utils.go +++ b/lntest/utils.go @@ -53,10 +53,16 @@ func CopyFile(dest, src string) error { // errNumNotMatched is a helper method to return a nicely formatted error. func errNumNotMatched(name string, subject string, - want, got, total, old int) error { + want, got, total, old int, desc ...any) error { - return fmt.Errorf("%s: assert %s failed: want %d, got: %d, total: "+ + err := fmt.Errorf("%s: assert %s failed: want %d, got: %d, total: "+ "%d, previously had: %d", name, subject, want, got, total, old) + + if len(desc) > 0 { + err = fmt.Errorf("%s, desc: %v", err, desc) + } + + return err } // parseDerivationPath parses a path in the form of m/x'/y'/z'/a/b into a slice