chainntnfs: Send negative confirmation notifications.

This commit is contained in:
Jim Posen 2017-11-13 17:32:11 -08:00 committed by Olaoluwa Osuntokun
parent c5320f2731
commit 2639b58e4b
2 changed files with 33 additions and 0 deletions

@ -57,6 +57,11 @@ type TxConfNotifier struct {
// The coinbase maturity period is a reasonable value to use.
reorgSafetyLimit uint32
// reorgDepth is the depth of a chain organization that this system is being
// informed of. This is incremented as long as a sequence of blocks are
// disconnected without being interrupted by a new block.
reorgDepth uint32
// confNotifications is an index of notification requests by transaction
// hash.
confNotifications map[chainhash.Hash][]*ConfNtfn
@ -142,6 +147,7 @@ func (tcn *TxConfNotifier) ConnectTip(blockHash *chainhash.Hash,
tcn.currentHeight, blockHeight)
}
tcn.currentHeight++
tcn.reorgDepth = 0
// Record any newly confirmed transactions in ntfnsByConfirmHeight so that
// notifications get dispatched when the tx gets sufficient confirmations.
@ -204,9 +210,26 @@ func (tcn *TxConfNotifier) DisconnectTip(blockHeight uint32) error {
tcn.currentHeight, blockHeight)
}
tcn.currentHeight--
tcn.reorgDepth++
for _, txHash := range tcn.confTxsByInitialHeight[blockHeight] {
for _, ntfn := range tcn.confNotifications[*txHash] {
// If notification has been dispatched with sufficient
// confirmations, notify of the reversal.
if ntfn.dispatched {
select {
case <-ntfn.Event.Confirmed:
// Drain confirmation notification instead of sending
// negative conf if the receiver has not processed it yet.
// This ensures sends to the Confirmed channel are always
// non-blocking.
default:
ntfn.Event.NegativeConf <- int32(tcn.reorgDepth)
}
ntfn.dispatched = false
continue
}
confHeight := blockHeight + ntfn.NumConfirmations - 1
ntfnSet, exists := tcn.ntfnsByConfirmHeight[confHeight]
if !exists {

@ -276,6 +276,16 @@ func TestTxConfChainReorg(t *testing.T) {
t.Fatalf("Failed to connect block: %v", err)
}
select {
case reorgDepth := <-ntfn2.Event.NegativeConf:
if reorgDepth != 1 {
t.Fatalf("Incorrect value for negative conf notification: "+
"expected %d, got %d", 1, reorgDepth)
}
default:
t.Fatalf("Expected negative conf notification for tx1")
}
select {
case txConf := <-ntfn1.Event.Confirmed:
t.Fatalf("Received unexpected confirmation for tx1: %v", txConf)