Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/release-notes/release-notes-0.21.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@

## Performance Improvements

* [Zero-conf channels that are already confirmed no longer trigger historical
chain rescans](https://github.com/lightningnetwork/lnd/pull/10459) from the
broadcast height on restart. This significantly reduces bandwidth usage for
mobile and neutrino clients.

## Deprecations

### ⚠️ **Warning:** The deprecated fee rate option `--sat_per_byte` will be removed in release version **0.22**
Expand Down
63 changes: 47 additions & 16 deletions funding/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3812,46 +3812,65 @@
if numConfs < 6 {
numConfs = 6
}

txid := completeChan.FundingOutpoint.Hash
log.Debugf("Will announce channel %v after ChannelPoint"+
"(%v) has gotten %d confirmations",
shortChanID.ToUint64(), completeChan.FundingOutpoint,
numConfs)
log.Debugf("Will announce channel %v after "+
"ChannelPoint(%v) has gotten %d confirmations",
shortChanID.ToUint64(),
completeChan.FundingOutpoint, numConfs)

fundingScript, err := MakeFundingScript(completeChan)
if err != nil {
return fmt.Errorf("unable to create funding script "+
"for ChannelPoint(%v): %v",
return fmt.Errorf("unable to create funding "+
"script for ChannelPoint(%v): %v",
completeChan.FundingOutpoint, err)
}

// Register with the ChainNotifier for a notification once the
// funding transaction reaches at least 6 confirmations.
// For zero-conf channels that are already confirmed, use
// the confirmed block height as the height hint instead
// of the broadcast height. This significantly reduces the
// rescan range on restart, which is especially important
// for mobile devices using the neutrino backend where
// historical rescans consume significant bandwidth.
heightHint := completeChan.BroadcastHeight()
if completeChan.IsZeroConf() && completeChan.ZeroConfConfirmed() {

Check failure on line 3836 in funding/manager.go

View workflow job for this annotation

GitHub Actions / Lint code

the line is 82 characters long, which exceeds the maximum of 80 characters. (ll)
confirmedScid := completeChan.ZeroConfRealScid()
heightHint = confirmedScid.BlockHeight

log.Debugf("Using confirmed height %d as hint for "+
"zero-conf ChannelPoint(%v)",
heightHint, completeChan.FundingOutpoint)
}

// Register with the ChainNotifier for a notification
// once the funding transaction reaches at least 6
// confirmations.
confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
&txid, fundingScript, numConfs,
completeChan.BroadcastHeight(),
heightHint,
)
if err != nil {
return fmt.Errorf("unable to register for "+
"confirmation of ChannelPoint(%v): %v",
completeChan.FundingOutpoint, err)
}

// Wait until 6 confirmations has been reached or the wallet
// signals a shutdown.
// Wait until 6 confirmations has been reached or the
// wallet signals a shutdown.
select {
case _, ok := <-confNtfn.Confirmed:
if !ok {
return fmt.Errorf("ChainNotifier shutting "+
"down, cannot complete funding flow "+
"for ChannelPoint(%v)",
return fmt.Errorf("ChainNotifier "+
"shutting down, cannot "+
"complete funding flow for "+
"ChannelPoint(%v)",
completeChan.FundingOutpoint)
}
// Fallthrough.

case <-f.quit:
return fmt.Errorf("%v, stopping funding flow for "+
"ChannelPoint(%v)",
return fmt.Errorf("%v, stopping funding flow "+
"for ChannelPoint(%v)",
ErrFundingManagerShuttingDown,
completeChan.FundingOutpoint)
}
Expand Down Expand Up @@ -3920,6 +3939,18 @@
// a zero-conf channel. This will wait for the real confirmation, add the
// confirmed SCID to the router graph, and then announce after six confs.
func (f *Manager) waitForZeroConfChannel(c *channeldb.OpenChannel) error {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While the logic to skip the rescan for already confirmed zero-conf channels is sound, this bug fix would benefit from an accompanying regression test. A test case could be added to simulate a restart where a zero-conf channel is already confirmed, and then assert that no historical rescan is triggered. This would help prevent future regressions and ensure the long-term stability of this optimization.

// If the zero-conf channel is already confirmed, we can skip the
// historical chain rescan. This is important for mobile devices where
// rescanning from the broadcast height can consume significant
// bandwidth, especially with the neutrino backend.
if c.ZeroConfConfirmed() {
log.Debugf("Zero-conf ChannelPoint(%v) already confirmed "+
"with SCID %v, skipping chain rescan",
c.FundingOutpoint, c.ZeroConfRealScid())

return nil
}

// First we'll check whether the channel is confirmed on-chain. If it
// is already confirmed, the chainntnfs subsystem will return with the
// confirmed tx. Otherwise, we'll wait here until confirmation occurs.
Expand Down
Loading