From 0f8f092ddd13fdf76b17931b68149153fb97a5bc Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Wed, 5 Mar 2025 11:43:39 +0800 Subject: [PATCH] itest: document a flake from `TxNotifier` --- itest/flakes.go | 24 ++++++++++ itest/lnd_multi-hop_force_close_test.go | 64 ++----------------------- 2 files changed, 28 insertions(+), 60 deletions(-) diff --git a/itest/flakes.go b/itest/flakes.go index e502fcd91..8b3c39638 100644 --- a/itest/flakes.go +++ b/itest/flakes.go @@ -46,3 +46,27 @@ func flakeFundExtraUTXO(ht *lntest.HarnessTest, node *node.HarnessNode) { // - https://github.com/lightningnetwork/lnd/issues/8786 ht.FundCoins(btcutil.SatoshiPerBitcoin, node) } + +// flakeTxNotifierNeutrino documents a flake found when running force close +// tests using neutrino backend, which is a race between two notifications - one +// for the spending notification, the other for the block which contains the +// spending tx. +// +// TODO(yy): remove it once the issue is resolved. +func flakeTxNotifierNeutrino(ht *lntest.HarnessTest) { + // Mine an empty block the for neutrino backend. We need this step to + // trigger Bob's chain watcher to detect the force close tx. Deep down, + // this happens because the notification system for neutrino is very + // different from others. Specifically, when a block contains the force + // close tx is notified, these two calls, + // - RegisterBlockEpochNtfn, will notify the block first. + // - RegisterSpendNtfn, will wait for the neutrino notifier to sync to + // the block, then perform a GetUtxo, which, by the time the spend + // details are sent, the blockbeat is considered processed in Bob's + // chain watcher. + // + // TODO(yy): refactor txNotifier to fix the above issue. + if ht.IsNeutrinoBackend() { + ht.MineEmptyBlocks(1) + } +} diff --git a/itest/lnd_multi-hop_force_close_test.go b/itest/lnd_multi-hop_force_close_test.go index abce20de2..7d8d7ea1d 100644 --- a/itest/lnd_multi-hop_force_close_test.go +++ b/itest/lnd_multi-hop_force_close_test.go @@ -846,21 +846,7 @@ func runMultiHopReceiverPreimageClaim(ht *lntest.HarnessTest, ht.AssertNumPendingSweeps(bob, 2) } - // Mine an empty block the for neutrino backend. We need this step to - // trigger Bob's chain watcher to detect the force close tx. Deep down, - // this happens because the notification system for neutrino is very - // different from others. Specifically, when a block contains the force - // close tx is notified, these two calls, - // - RegisterBlockEpochNtfn, will notify the block first. - // - RegisterSpendNtfn, will wait for the neutrino notifier to sync to - // the block, then perform a GetUtxo, which, by the time the spend - // details are sent, the blockbeat is considered processed in Bob's - // chain watcher. - // - // TODO(yy): refactor txNotifier to fix the above issue. - if ht.IsNeutrinoBackend() { - ht.MineEmptyBlocks(1) - } + flakeTxNotifierNeutrino(ht) if params.CommitmentType == leasedType { // We expect to see 1 txns in the mempool, @@ -1775,21 +1761,7 @@ func runLocalClaimIncomingHTLC(ht *lntest.HarnessTest, // - the anchor output from channel Bob=>Carol. ht.AssertNumPendingSweeps(bob, 3) - // Mine an empty block the for neutrino backend. We need this step to - // trigger Bob's chain watcher to detect the force close tx. Deep down, - // this happens because the notification system for neutrino is very - // different from others. Specifically, when a block contains the force - // close tx is notified, these two calls, - // - RegisterBlockEpochNtfn, will notify the block first. - // - RegisterSpendNtfn, will wait for the neutrino notifier to sync to - // the block, then perform a GetUtxo, which, by the time the spend - // details are sent, the blockbeat is considered processed in Bob's - // chain watcher. - // - // TODO(yy): refactor txNotifier to fix the above issue. - if ht.IsNeutrinoBackend() { - ht.MineEmptyBlocks(1) - } + flakeTxNotifierNeutrino(ht) // Assert txns can be found in the mempool. // @@ -2428,21 +2400,7 @@ func runLocalPreimageClaim(ht *lntest.HarnessTest, // - the commit output sweep from the channel with Carol, no timelock. ht.AssertNumPendingSweeps(bob, 3) - // Mine an empty block the for neutrino backend. We need this step to - // trigger Bob's chain watcher to detect the force close tx. Deep down, - // this happens because the notification system for neutrino is very - // different from others. Specifically, when a block contains the force - // close tx is notified, these two calls, - // - RegisterBlockEpochNtfn, will notify the block first. - // - RegisterSpendNtfn, will wait for the neutrino notifier to sync to - // the block, then perform a GetUtxo, which, by the time the spend - // details are sent, the blockbeat is considered processed in Bob's - // chain watcher. - // - // TODO(yy): refactor txNotifier to fix the above issue. - if ht.IsNeutrinoBackend() { - ht.MineEmptyBlocks(1) - } + flakeTxNotifierNeutrino(ht) // We mine one block to confirm, // - Carol's sweeping tx of the incoming HTLC. @@ -2456,21 +2414,7 @@ func runLocalPreimageClaim(ht *lntest.HarnessTest, // - the htlc sweeping tx. ht.AssertNumPendingSweeps(bob, 3) - // Mine an empty block the for neutrino backend. We need this step to - // trigger Bob's chain watcher to detect the force close tx. Deep down, - // this happens because the notification system for neutrino is very - // different from others. Specifically, when a block contains the force - // close tx is notified, these two calls, - // - RegisterBlockEpochNtfn, will notify the block first. - // - RegisterSpendNtfn, will wait for the neutrino notifier to sync to - // the block, then perform a GetUtxo, which, by the time the spend - // details are sent, the blockbeat is considered processed in Bob's - // chain watcher. - // - // TODO(yy): refactor txNotifier to fix the above issue. - if ht.IsNeutrinoBackend() { - ht.MineEmptyBlocks(1) - } + flakeTxNotifierNeutrino(ht) flakePreimageSettlement(ht)