Skip to content
Merged
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
8 changes: 7 additions & 1 deletion chainntnfs/bitcoindnotify/bitcoind.go
Original file line number Diff line number Diff line change
Expand Up @@ -665,8 +665,14 @@ func (b *BitcoindNotifier) handleBlockConnected(block chainntnfs.BlockEpoch) err
// satisfy any client requests based upon the new block.
b.bestBlock = block

err = b.txNotifier.NotifyHeight(uint32(block.Height))
if err != nil {
return fmt.Errorf("unable to notify height: %w", err)
}

b.notifyBlockEpochs(block.Height, block.Hash, block.BlockHeader)
return b.txNotifier.NotifyHeight(uint32(block.Height))

return nil
}

// notifyBlockEpochs notifies all registered block epoch clients of the newly
Expand Down
7 changes: 6 additions & 1 deletion chainntnfs/btcdnotify/btcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,11 +725,16 @@ func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error {
// satisfy any client requests based upon the new block.
b.bestBlock = epoch

err = b.txNotifier.NotifyHeight(uint32(epoch.Height))
if err != nil {
return fmt.Errorf("unable to notify height: %w", err)
}

b.notifyBlockEpochs(
epoch.Height, epoch.Hash, epoch.BlockHeader,
)

return b.txNotifier.NotifyHeight(uint32(epoch.Height))
return nil
}

// notifyBlockEpochs notifies all registered block epoch clients of the newly
Expand Down
3 changes: 3 additions & 0 deletions chainntnfs/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ type ConfirmationEvent struct {
// channels.
func NewConfirmationEvent(numConfs uint32, cancel func()) *ConfirmationEvent {
return &ConfirmationEvent{
// We cannot rely on the subscriber to immediately read from
// the channel so we need to create a larger buffer to avoid
// blocking the notifier.
Confirmed: make(chan *TxConfirmation, 1),
Updates: make(chan uint32, numConfs),
NegativeConf: make(chan int32, 1),
Expand Down
8 changes: 7 additions & 1 deletion chainntnfs/neutrinonotify/neutrino.go
Original file line number Diff line number Diff line change
Expand Up @@ -689,10 +689,16 @@ func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
n.bestBlock.Height = int32(newBlock.height)
n.bestBlock.BlockHeader = newBlock.header

err = n.txNotifier.NotifyHeight(newBlock.height)
if err != nil {
return fmt.Errorf("unable to notify height: %w", err)
}

n.notifyBlockEpochs(
int32(newBlock.height), &newBlock.hash, newBlock.header,
)
return n.txNotifier.NotifyHeight(newBlock.height)

return nil
}

// getFilteredBlock is a utility to retrieve the full filtered block from a block epoch.
Expand Down
105 changes: 75 additions & 30 deletions chainntnfs/txnotifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,20 +244,25 @@ type ConfNtfn struct {
// notification is to be sent.
NumConfirmations uint32

// Event contains references to the channels that the notifications are to
// be sent over.
// Event contains references to the channels that the notifications are
// to be sent over.
Event *ConfirmationEvent

// HeightHint is the minimum height in the chain that we expect to find
// this txid.
HeightHint uint32

// dispatched is false if the confirmed notification has not been sent yet.
// dispatched is false if the confirmed notification has not been sent
// yet.
dispatched bool

// includeBlock is true if the dispatched notification should also have
// the block included with it.
includeBlock bool

// numConfsLeft is the number of confirmations left to be sent to the
// subscriber.
numConfsLeft uint32
}

// HistoricalConfDispatch parametrizes a manual rescan for a particular
Expand Down Expand Up @@ -589,6 +594,7 @@ func (n *TxNotifier) newConfNtfn(txid *chainhash.Hash,
}),
HeightHint: heightHint,
includeBlock: opts.includeBlock,
numConfsLeft: numConfs,
}, nil
}

Expand Down Expand Up @@ -664,8 +670,8 @@ func (n *TxNotifier) RegisterConf(txid *chainhash.Hash, pkScript []byte,
// already been found, we'll attempt to deliver them immediately
// to this client.
Log.Debugf("Attempting to dispatch confirmation for %v on "+
"registration since rescan has finished",
ntfn.ConfRequest)
"registration since rescan has finished, conf_id=%v",
ntfn.ConfRequest, ntfn.ConfID)

// The default notification we assigned above includes the
// block along with the rest of the details. However not all
Expand All @@ -679,9 +685,13 @@ func (n *TxNotifier) RegisterConf(txid *chainhash.Hash, pkScript []byte,
confDetails = &confDetailsCopy
}

err := n.dispatchConfDetails(ntfn, confDetails)
if err != nil {
return nil, err
// Deliver the details to the whole conf set where this ntfn
// lives in.
for _, subscriber := range confSet.ntfns {
Comment thread
yyforyongyu marked this conversation as resolved.
err := n.dispatchConfDetails(subscriber, confDetails)
if err != nil {
return nil, err
}
}

return &ConfRegistration{
Expand Down Expand Up @@ -912,10 +922,16 @@ func (n *TxNotifier) dispatchConfDetails(
// If there are no conf details to dispatch or if the notification has
// already been dispatched, then we can skip dispatching to this
// client.
if details == nil || ntfn.dispatched {
Log.Debugf("Skipping dispatch of conf details(%v) for "+
"request %v, dispatched=%v", details, ntfn.ConfRequest,
ntfn.dispatched)
if details == nil {
Log.Debugf("Skipped dispatching nil conf details for request "+
"%v, conf_id=%v", ntfn.ConfRequest, ntfn.ConfID)

return nil
}

if ntfn.dispatched {
Log.Debugf("Skipped dispatched conf details for request %v "+
"conf_id=%v", ntfn.ConfRequest, ntfn.ConfID)

return nil
}
Expand All @@ -925,16 +941,16 @@ func (n *TxNotifier) dispatchConfDetails(
// we'll dispatch a confirmation notification to the caller.
confHeight := details.BlockHeight + ntfn.NumConfirmations - 1
if confHeight <= n.currentHeight {
Log.Debugf("Dispatching %v confirmation notification for %v",
ntfn.NumConfirmations, ntfn.ConfRequest)
Log.Debugf("Dispatching %v confirmation notification for "+
"conf_id=%v, %v", ntfn.NumConfirmations, ntfn.ConfID,
ntfn.ConfRequest)

// We'll send a 0 value to the Updates channel,
// indicating that the transaction/output script has already
// been confirmed.
select {
case ntfn.Event.Updates <- 0:
case <-n.quit:
return ErrTxNotifierExiting
err := n.notifyNumConfsLeft(ntfn, 0)
if err != nil {
return err
}

select {
Expand All @@ -944,8 +960,8 @@ func (n *TxNotifier) dispatchConfDetails(
return ErrTxNotifierExiting
}
} else {
Log.Debugf("Queueing %v confirmation notification for %v at tip ",
ntfn.NumConfirmations, ntfn.ConfRequest)
Log.Debugf("Queueing %v confirmation notification for %v at "+
"tip", ntfn.NumConfirmations, ntfn.ConfRequest)

// Otherwise, we'll keep track of the notification
// request by the height at which we should dispatch the
Expand All @@ -961,10 +977,9 @@ func (n *TxNotifier) dispatchConfDetails(
// confirmations are left for the transaction/output script to
// be confirmed.
numConfsLeft := confHeight - n.currentHeight
select {
case ntfn.Event.Updates <- numConfsLeft:
case <-n.quit:
return ErrTxNotifierExiting
err := n.notifyNumConfsLeft(ntfn, numConfsLeft)
if err != nil {
return err
}
}

Expand Down Expand Up @@ -1729,10 +1744,9 @@ func (n *TxNotifier) NotifyHeight(height uint32) error {
continue
}

select {
case ntfn.Event.Updates <- numConfsLeft:
case <-n.quit:
return ErrTxNotifierExiting
err := n.notifyNumConfsLeft(ntfn, numConfsLeft)
if err != nil {
return err
}
}
}
Expand All @@ -1743,8 +1757,9 @@ func (n *TxNotifier) NotifyHeight(height uint32) error {
for ntfn := range n.ntfnsByConfirmHeight[height] {
confSet := n.confNotifications[ntfn.ConfRequest]

Log.Debugf("Dispatching %v confirmation notification for %v",
ntfn.NumConfirmations, ntfn.ConfRequest)
Log.Debugf("Dispatching %v confirmation notification for "+
"conf_id=%v, %v", ntfn.NumConfirmations, ntfn.ConfID,
ntfn.ConfRequest)

// The default notification we assigned above includes the
// block along with the rest of the details. However not all
Expand Down Expand Up @@ -1833,6 +1848,9 @@ func (n *TxNotifier) DisconnectTip(blockHeight uint32) error {
default:
}

// We also reset the num of confs update.
ntfn.numConfsLeft = ntfn.NumConfirmations

// Then, we'll check if the current
// transaction/output script was included in the
// block currently being disconnected. If it
Expand Down Expand Up @@ -2069,3 +2087,30 @@ func (n *TxNotifier) TearDown() {
}
}
}

// notifyNumConfsLeft sends the number of confirmations left to the
// notification subscriber through the Event.Updates channel.
//
// NOTE: must be used with the TxNotifier's lock held.
func (n *TxNotifier) notifyNumConfsLeft(ntfn *ConfNtfn, num uint32) error {
// If the number left is no less than the recorded value, we can skip
// sending it as it means this same value has already been sent before.
if num >= ntfn.numConfsLeft {
Log.Debugf("Skipped dispatched update (numConfsLeft=%v) for "+
"request %v conf_id=%v", num, ntfn.ConfRequest,
ntfn.ConfID)

return nil
}

// Update the number of confirmations left to the notification.
ntfn.numConfsLeft = num

select {
case ntfn.Event.Updates <- num:
case <-n.quit:
return ErrTxNotifierExiting
}

return nil
}
7 changes: 7 additions & 0 deletions docs/release-notes/release-notes-0.19.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
* [Fixed a bug](https://github.com/lightningnetwork/lnd/pull/9275) where the
peer may block the shutdown process of lnd.

* [Fixed a case](https://github.com/lightningnetwork/lnd/pull/9258) where the
confirmation notification may be missed.

# New Features
## Functional Enhancements
## RPC Additions
Expand Down Expand Up @@ -199,6 +202,10 @@ The underlying functionality between those two options remain the same.
* Oliver Gugger
* Pins
* Viktor Tigerström
<<<<<<< HEAD
* Yong Yu
* Ziggie

=======
* Ziggie
>>>>>>> 5a6264b6a (docs: update release notes)