chainntnfs: Test that neutrino rescan plays nice with txConfNotifier.
This commit is contained in:
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
|
||||
|
Loading…
Reference in New Issue
Block a user