chainntnfs: signal reorg notification before required confirmations
In this commit, we send the reorg notification even when the transaction has not yet reached the required confirmations, in case the caller is interested in knowing about it. Signed-off-by: Nishant Bansal <nishant.bansal.282003@gmail.com>
This commit is contained in:
2 files changed
+64
No files matched your search
@@ -2011,6 +2011,20 @@ func (n *TxNotifier) dispatchConfReorg(ntfn *ConfNtfn,
|
||||
if !ntfn.dispatched {
|
||||
confHeight := heightDisconnected + ntfn.NumConfirmations - 1
|
||||
ntfnSet, exists := n.ntfnsByConfirmHeight[confHeight]
|
||||
|
||||
// We also signal the reorg to the notifier in case the
|
||||
// subscriber is also interested in the reorgs before the
|
||||
// transaction received its required confirmation.
|
||||
//
|
||||
// Because as soon as a new block is connected which has the
|
||||
// transaction included again we preemptively read the buffered
|
||||
// channel.
|
||||
select {
|
||||
case ntfn.Event.NegativeConf <- int32(n.reorgDepth):
|
||||
case <-n.quit:
|
||||
return ErrTxNotifierExiting
|
||||
}
|
||||
|
||||
if exists {
|
||||
delete(ntfnSet, ntfn)
|
||||
}
|
||||
|
||||
@@ -1548,6 +1548,56 @@ func TestTxNotifierConfReorg(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestTxNotifierReorgPartialConfirmation ensures that a tx with intermediate
|
||||
// confirmations handles a reorg correctly and emits the appropriate reorg ntfn.
|
||||
func TestTxNotifierReorgPartialConfirmation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const txNumConfs uint32 = 2
|
||||
hintCache := newMockHintCache()
|
||||
n := chainntnfs.NewTxNotifier(
|
||||
7, chainntnfs.ReorgSafetyLimit, hintCache, hintCache,
|
||||
)
|
||||
|
||||
// Tx will be confirmed in block 9 and requires 2 confs.
|
||||
tx := wire.MsgTx{Version: 1}
|
||||
tx.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||
txHash := tx.TxHash()
|
||||
ntfn, err := n.RegisterConf(&txHash, testRawScript, txNumConfs, 1)
|
||||
require.NoError(t, err, "unable to register ntfn")
|
||||
|
||||
err = n.UpdateConfDetails(ntfn.HistoricalDispatch.ConfRequest, nil)
|
||||
require.NoError(t, err, "unable to deliver conf details")
|
||||
|
||||
// Mine 1 block to satisfy the requirement for a partially confirmed tx.
|
||||
block := btcutil.NewBlock(&wire.MsgBlock{
|
||||
Transactions: []*wire.MsgTx{&tx},
|
||||
})
|
||||
err = n.ConnectTip(block, 8)
|
||||
require.NoError(t, err, "failed to connect block")
|
||||
err = n.NotifyHeight(8)
|
||||
require.NoError(t, err, "unable to dispatch notifications")
|
||||
|
||||
// Now that the transaction is partially confirmed, reorg out those
|
||||
// blocks.
|
||||
err = n.DisconnectTip(8)
|
||||
require.NoError(t, err, "unable to disconnect block")
|
||||
|
||||
// After the intermediate confirmation is reorged out, the tx should not
|
||||
// trigger a confirmation ntfn, but should trigger a reorg ntfn.
|
||||
select {
|
||||
case <-ntfn.Event.Confirmed:
|
||||
t.Fatal("unexpected confirmation after reorg")
|
||||
default:
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ntfn.Event.NegativeConf:
|
||||
default:
|
||||
t.Fatal("expected to receive reorg notification")
|
||||
}
|
||||
}
|
||||
|
||||
// TestTxNotifierSpendReorg ensures that clients are notified of a reorg when
|
||||
// the spending transaction of an outpoint for which they registered a spend
|
||||
// notification for has been reorged out of the chain.
|
||||
|
||||
Reference in new issue
Block a user