diff --git a/config_builder.go b/config_builder.go index 3ad6f99d6..56b699ad0 100644 --- a/config_builder.go +++ b/config_builder.go @@ -644,7 +644,7 @@ func proxyBlockEpoch(notifier chainntnfs.ChainNotifier, } // walletReBroadcaster is a simple wrapper around the pushtx.Broadcaster -// interface to adhere to the expanded lnwallet.Rebraodcaster interface. +// interface to adhere to the expanded lnwallet.Rebroadcaster interface. type walletReBroadcaster struct { started atomic.Bool diff --git a/docs/release-notes/release-notes-0.16.1.md b/docs/release-notes/release-notes-0.16.1.md index ceaa1940d..734dcf1af 100644 --- a/docs/release-notes/release-notes-0.16.1.md +++ b/docs/release-notes/release-notes-0.16.1.md @@ -97,12 +97,18 @@ available](https://github.com/lightningnetwork/lnd/pull/7529). funding manager would error out if no persisted initial forwarding policy is found for a channel. +* The internal rebroacaster [will no longer continue to rebroadcast stale + sweeper transactions (have a conflict mined or in the + mempool)](https://github.com/lightningnetwork/lnd/pull/7599). + + # Contributors (Alphabetical Order) * ardevd * Elle Mouton * hieblmi * Oliver Gugger +* Olaoluwa Osuntokun * Pierre Beugnet * Tommy Volk * Yong Yu diff --git a/server.go b/server.go index b9c8867d1..c38ebb69e 100644 --- a/server.go +++ b/server.go @@ -1056,7 +1056,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, FeeEstimator: cc.FeeEstimator, GenSweepScript: newSweepPkScriptGen(cc.Wallet), Signer: cc.Wallet.Cfg.Signer, - Wallet: cc.Wallet, + Wallet: newSweeperWallet(cc.Wallet), NewBatchTimer: func() <-chan time.Time { return time.NewTimer(cfg.Sweeper.BatchWindowDuration).C }, diff --git a/sweep/backend_mock_test.go b/sweep/backend_mock_test.go index 6abce171d..9fd79fa03 100644 --- a/sweep/backend_mock_test.go +++ b/sweep/backend_mock_test.go @@ -159,3 +159,6 @@ func (b *mockBackend) RemoveDescendants(*wire.MsgTx) error { func (b *mockBackend) FetchTx(chainhash.Hash) (*wire.MsgTx, error) { return nil, nil } + +func (b *mockBackend) CancelRebroadcast(tx chainhash.Hash) { +} diff --git a/sweep/interface.go b/sweep/interface.go index d9a1e6094..a9de8bc57 100644 --- a/sweep/interface.go +++ b/sweep/interface.go @@ -35,4 +35,10 @@ type Wallet interface { // hash passed in. If the transaction can't be found then a nil // transaction pointer is returned. FetchTx(chainhash.Hash) (*wire.MsgTx, error) + + // CancelRebroadcast is used to inform the rebroadcaster sub-system + // that it no longer needs to try to rebroadcast a transaction. This is + // used to ensure that invalid transactions (inputs spent) aren't + // retried in the background. + CancelRebroadcast(tx chainhash.Hash) } diff --git a/sweep/sweeper.go b/sweep/sweeper.go index 5957b51ac..4ce48929f 100644 --- a/sweep/sweeper.go +++ b/sweep/sweeper.go @@ -555,6 +555,9 @@ func (s *UtxoSweeper) removeLastSweepDescendants(spendingTx *wire.MsgTx) error { // Transaction wasn't found in the wallet, may have already // been replaced/removed. if sweepTx == nil { + // If it was removed, then we'll play it safe and mark + // it as no longer need to be rebroadcasted. + s.cfg.Wallet.CancelRebroadcast(sweepHash) continue } @@ -579,6 +582,10 @@ func (s *UtxoSweeper) removeLastSweepDescendants(spendingTx *wire.MsgTx) error { if err != nil { log.Warnf("unable to remove descendants: %v", err) } + + // If this transaction was conflicting, then we'll stop + // rebroadcasting it in the background. + s.cfg.Wallet.CancelRebroadcast(sweepHash) } } diff --git a/sweeper_wallet.go b/sweeper_wallet.go new file mode 100644 index 000000000..d347d78dd --- /dev/null +++ b/sweeper_wallet.go @@ -0,0 +1,25 @@ +package lnd + +import ( + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/lightningnetwork/lnd/lnwallet" +) + +// sweeperWallet is a wrapper around the LightningWallet that implements the +// sweeper's Wallet interface. +type sweeperWallet struct { + *lnwallet.LightningWallet +} + +// newSweeperWallet creates a new sweeper wallet from the given +// LightningWallet. +func newSweeperWallet(w *lnwallet.LightningWallet) *sweeperWallet { + return &sweeperWallet{ + LightningWallet: w, + } +} + +// CancelRebroadcast cancels the rebroadcast of the given transaction. +func (s *sweeperWallet) CancelRebroadcast(txid chainhash.Hash) { + s.Cfg.Rebroadcaster.MarkAsConfirmed(txid) +}