chainntnfs: Test that neutrino rescan plays nice with txConfNotifier.

This commit is contained in:
Jim Posen 2017-11-13 17:19:43 -08:00 committed by Olaoluwa Osuntokun
parent abf3685d2d
commit c5320f2731

@ -509,36 +509,54 @@ func testTxConfirmedBeforeNtfnRegistration(miner *rpctest.Harness,
// spending from a coinbase output here, so we use the dedicated
// function.
txid, err := getTestTxId(miner)
txid3, err := getTestTxId(miner)
if err != nil {
t.Fatalf("unable to create test tx: %v", err)
}
// Now generate one block. The notifier must check older blocks when
// the confirmation event is registered below to ensure that the TXID
// hasn't already been included in the chain, otherwise the
// Generate another block containing tx 3, but we won't register conf
// notifications for this tx until much later. The notifier must check
// older blocks when the confirmation event is registered below to ensure
// that the TXID hasn't already been included in the chain, otherwise the
// notification will never be sent.
blockHash, err := miner.Node.Generate(1)
_, err = miner.Node.Generate(1)
if err != nil {
t.Fatalf("unable to generate block: %v", err)
}
txid1, err := getTestTxId(miner)
if err != nil {
t.Fatalf("unable to create test tx: %v", err)
}
txid2, err := getTestTxId(miner)
if err != nil {
t.Fatalf("unable to create test tx: %v", err)
}
_, currentHeight, err := miner.Node.GetBestBlock()
if err != nil {
t.Fatalf("unable to get current height: %v", err)
}
// Now that we have a txid, register a confirmation notification with
// the chainntfn source.
numConfs := uint32(1)
confIntent, err := notifier.RegisterConfirmationsNtfn(txid, numConfs,
// Now generate another block containing txs 1 & 2.
blockHash, err := miner.Node.Generate(1)
if err != nil {
t.Fatalf("unable to generate block: %v", err)
}
// Register a confirmation notification with the chainntfn source for tx2,
// which is included in the last block. The height hint is the height before
// the block is included. This notification should fire immediately since
// only 1 confirmation is required.
ntfn1, err := notifier.RegisterConfirmationsNtfn(txid1, 1,
uint32(currentHeight))
if err != nil {
t.Fatalf("unable to register ntfn: %v", err)
}
select {
case confInfo := <-confIntent.Confirmed:
case confInfo := <-ntfn1.Confirmed:
// Finally, we'll verify that the tx index returned is the exact same
// as the tx index of the transaction within the block itself.
msgBlock, err := miner.Node.GetBlock(blockHash[0])
@ -550,14 +568,14 @@ func testTxConfirmedBeforeNtfnRegistration(miner *rpctest.Harness,
if err != nil {
t.Fatalf("unable to index into block: %v", err)
}
if !specifiedTxHash.IsEqual(txid) {
if !specifiedTxHash.IsEqual(txid1) {
t.Fatalf("mismatched tx indexes: expected %v, got %v",
txid, specifiedTxHash)
txid1, specifiedTxHash)
}
// We'll also ensure that the block height has been set
// properly.
if confInfo.BlockHeight != uint32(currentHeight) {
if confInfo.BlockHeight != uint32(currentHeight+1) {
t.Fatalf("incorrect block height: expected %v, got %v",
confInfo.BlockHeight, currentHeight)
}
@ -566,76 +584,61 @@ func testTxConfirmedBeforeNtfnRegistration(miner *rpctest.Harness,
t.Fatalf("confirmation notification never received")
}
// Next, we want to test fully dispatching the notification for a
// transaction that has been *partially* confirmed. So we'll create
// another test txid.
txid, err = getTestTxId(miner)
if err != nil {
t.Fatalf("unable to create test tx: %v", err)
}
_, currentHeight, err = miner.Node.GetBestBlock()
if err != nil {
t.Fatalf("unable to get current height: %v", err)
}
// We'll request 6 confirmations for the above generated txid, but we
// will generate the confirmations in chunks.
numConfs = 6
time.Sleep(time.Second * 2)
// First, generate 2 confirmations.
if _, err := miner.Node.Generate(2); err != nil {
t.Fatalf("unable to generate blocks: %v", err)
}
time.Sleep(time.Second * 2)
// Next, register for the notification *after* the transition has
// already been partially confirmed.
confIntent, err = notifier.RegisterConfirmationsNtfn(txid, numConfs,
// Register a confirmation notification for tx2, requiring 3 confirmations.
// This transaction is only partially confirmed, so the notification should
// not fire yet.
ntfn2, err := notifier.RegisterConfirmationsNtfn(txid2, 3,
uint32(currentHeight))
if err != nil {
t.Fatalf("unable to register ntfn: %v", err)
}
// We shouldn't receive a notification at this point, as the
// transaction hasn't yet been fully confirmed.
select {
case <-confIntent.Confirmed:
t.Fatalf("received confirmation notification but shouldn't " +
"have")
default:
// Expected case
}
// With the notification registered, generate another 3 blocks, this
// shouldn't yet dispatch the notification.
if _, err := miner.Node.Generate(3); err != nil {
t.Fatalf("unable to generate blocks: %v", err)
// Fully confirm tx3.
_, err = miner.Node.Generate(2)
if err != nil {
t.Fatalf("unable to generate block: %v", err)
}
select {
case <-confIntent.Confirmed:
t.Fatalf("received confirmation notification but shouldn't " +
"have")
default:
// Expected case
}
// Finally, we'll mine the final block which should dispatch the
// notification.
if _, err := miner.Node.Generate(1); err != nil {
t.Fatalf("unable to generate blocks: %v", err)
}
select {
case <-confIntent.Confirmed:
break
case <-time.After(30 * time.Second):
case <-ntfn2.Confirmed:
case <-time.After(10 * time.Second):
t.Fatalf("confirmation notification never received")
}
select {
case <-ntfn1.Confirmed:
t.Fatalf("received multiple confirmations for tx")
case <-time.After(1 * time.Second):
}
// Finally register a confirmation notification for tx3, requiring 1
// confirmation. Ensure that conf notifications do not refire on txs
// 1 or 2.
ntfn3, err := notifier.RegisterConfirmationsNtfn(txid3, 1,
uint32(currentHeight-1))
if err != nil {
t.Fatalf("unable to register ntfn: %v", err)
}
select {
case <-ntfn3.Confirmed:
case <-time.After(10 * time.Second):
t.Fatalf("confirmation notification never received")
}
time.Sleep(1 * time.Second)
select {
case <-ntfn1.Confirmed:
t.Fatalf("received multiple confirmations for tx")
default:
}
select {
case <-ntfn2.Confirmed:
t.Fatalf("received multiple confirmations for tx")
default:
}
}
// Test the case of a notification consumer having forget or being delayed in