From a806323035f6dbd07e4cb8e238e21015db0b22e8 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Mon, 9 Jun 2025 08:31:18 +0800 Subject: [PATCH 1/3] chainntnfs: patch debug logs and fix `StartHeight` Make sure we patch the `StartHeight` for btcd notifier. --- chainntnfs/bitcoindnotify/bitcoind.go | 8 ++++++-- chainntnfs/btcdnotify/btcd.go | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/chainntnfs/bitcoindnotify/bitcoind.go b/chainntnfs/bitcoindnotify/bitcoind.go index 1dae68995..230443f61 100644 --- a/chainntnfs/bitcoindnotify/bitcoind.go +++ b/chainntnfs/bitcoindnotify/bitcoind.go @@ -833,8 +833,12 @@ func (b *BitcoindNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, return nil, err } - if uint32(blockHeight) > ntfn.HistoricalDispatch.StartHeight { - ntfn.HistoricalDispatch.StartHeight = uint32(blockHeight) + spentHeight := uint32(blockHeight) + chainntnfs.Log.Debugf("Outpoint(%v) has spent at height %v", + outpoint, spentHeight) + + if spentHeight > ntfn.HistoricalDispatch.StartHeight { + ntfn.HistoricalDispatch.StartHeight = spentHeight } } diff --git a/chainntnfs/btcdnotify/btcd.go b/chainntnfs/btcdnotify/btcd.go index 3c7843133..abe9f7d22 100644 --- a/chainntnfs/btcdnotify/btcd.go +++ b/chainntnfs/btcdnotify/btcd.go @@ -933,15 +933,21 @@ func (b *BtcdNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, "block %v: %v", blockHash, err) } - if uint32(blockHeader.Height) > ntfn.HistoricalDispatch.StartHeight { + spentHeight := uint32(blockHeader.Height) + chainntnfs.Log.Debugf("Outpoint(%v) has spent at height %v", + outpoint, spentHeight) + + if spentHeight > ntfn.HistoricalDispatch.StartHeight { startHash, err = b.chainConn.GetBlockHash( - int64(blockHeader.Height), + int64(spentHeight), ) if err != nil { return nil, fmt.Errorf("unable to get block "+ "hash for height %d: %v", blockHeader.Height, err) } + + ntfn.HistoricalDispatch.StartHeight = spentHeight } } From 732cd717bf92179268717987951db6e23a407ae5 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Mon, 9 Jun 2025 08:40:33 +0800 Subject: [PATCH 2/3] chainntnfs: use spent height as height hint if found Previously when deciding whether a UTXO is spent or not, we accept a height hint as the starting block to look for the spending tx in the rescan process. When it's already found spent before the rescan starts, we will update the height hint to be the spent height, only if the latter is greater. This means if the user-specified hint is greater than the actual spending height, this UTXO will never be found as spent. We now fix it by always using the spent height as the hint. --- chainntnfs/bitcoindnotify/bitcoind.go | 6 +++++- chainntnfs/btcdnotify/btcd.go | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/chainntnfs/bitcoindnotify/bitcoind.go b/chainntnfs/bitcoindnotify/bitcoind.go index 230443f61..3cf53978c 100644 --- a/chainntnfs/bitcoindnotify/bitcoind.go +++ b/chainntnfs/bitcoindnotify/bitcoind.go @@ -837,7 +837,11 @@ func (b *BitcoindNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, chainntnfs.Log.Debugf("Outpoint(%v) has spent at height %v", outpoint, spentHeight) - if spentHeight > ntfn.HistoricalDispatch.StartHeight { + // Since the tx has already been spent at spentHeight, the + // heightHint specified by the caller is no longer relevant. We + // now update the starting height to be the spent height to make + // sure we won't miss it in the rescan. + if spentHeight != ntfn.HistoricalDispatch.StartHeight { ntfn.HistoricalDispatch.StartHeight = spentHeight } } diff --git a/chainntnfs/btcdnotify/btcd.go b/chainntnfs/btcdnotify/btcd.go index abe9f7d22..91178044c 100644 --- a/chainntnfs/btcdnotify/btcd.go +++ b/chainntnfs/btcdnotify/btcd.go @@ -937,7 +937,11 @@ func (b *BtcdNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, chainntnfs.Log.Debugf("Outpoint(%v) has spent at height %v", outpoint, spentHeight) - if spentHeight > ntfn.HistoricalDispatch.StartHeight { + // Since the tx has already been spent at spentHeight, the + // heightHint specified by the caller is no longer relevant. We + // now update the starting height to be the spent height to make + // sure we won't miss it in the rescan. + if spentHeight != ntfn.HistoricalDispatch.StartHeight { startHash, err = b.chainConn.GetBlockHash( int64(spentHeight), ) From 1d2217e9a9ffeab680596a3808ecce7db2b1c895 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Mon, 9 Jun 2025 09:16:03 +0800 Subject: [PATCH 3/3] docs: update release notes --- docs/release-notes/release-notes-0.19.2.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/release-notes/release-notes-0.19.2.md b/docs/release-notes/release-notes-0.19.2.md index b2e4d0dbb..11046716a 100644 --- a/docs/release-notes/release-notes-0.19.2.md +++ b/docs/release-notes/release-notes-0.19.2.md @@ -23,6 +23,9 @@ - [Use](https://github.com/lightningnetwork/lnd/pull/9889) `BigSizeT` instead of `uint16` for the htlc index that's used in the revocation log. +- [Fixed](https://github.com/lightningnetwork/lnd/pull/9921) a case where the + spending notification of an output may be missed if wrong height hint is used. + # New Features ## Functional Enhancements