mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-04 09:48:19 +01:00
chainntnfs: Test that neutrino rescan plays nice with txConfNotifier.
This commit is contained in:
parent
abf3685d2d
commit
c5320f2731
1 changed files with 76 additions and 73 deletions
|
@ -509,36 +509,54 @@ func testTxConfirmedBeforeNtfnRegistration(miner *rpctest.Harness,
|
||||||
// spending from a coinbase output here, so we use the dedicated
|
// spending from a coinbase output here, so we use the dedicated
|
||||||
// function.
|
// function.
|
||||||
|
|
||||||
txid, err := getTestTxId(miner)
|
txid3, err := getTestTxId(miner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create test tx: %v", err)
|
t.Fatalf("unable to create test tx: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now generate one block. The notifier must check older blocks when
|
// Generate another block containing tx 3, but we won't register conf
|
||||||
// the confirmation event is registered below to ensure that the TXID
|
// notifications for this tx until much later. The notifier must check
|
||||||
// hasn't already been included in the chain, otherwise the
|
// 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.
|
// notification will never be sent.
|
||||||
blockHash, err := miner.Node.Generate(1)
|
_, err = miner.Node.Generate(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to generate block: %v", err)
|
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()
|
_, currentHeight, err := miner.Node.GetBestBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to get current height: %v", err)
|
t.Fatalf("unable to get current height: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we have a txid, register a confirmation notification with
|
// Now generate another block containing txs 1 & 2.
|
||||||
// the chainntfn source.
|
blockHash, err := miner.Node.Generate(1)
|
||||||
numConfs := uint32(1)
|
if err != nil {
|
||||||
confIntent, err := notifier.RegisterConfirmationsNtfn(txid, numConfs,
|
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))
|
uint32(currentHeight))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case confInfo := <-confIntent.Confirmed:
|
case confInfo := <-ntfn1.Confirmed:
|
||||||
// Finally, we'll verify that the tx index returned is the exact same
|
// Finally, we'll verify that the tx index returned is the exact same
|
||||||
// as the tx index of the transaction within the block itself.
|
// as the tx index of the transaction within the block itself.
|
||||||
msgBlock, err := miner.Node.GetBlock(blockHash[0])
|
msgBlock, err := miner.Node.GetBlock(blockHash[0])
|
||||||
|
@ -550,14 +568,14 @@ func testTxConfirmedBeforeNtfnRegistration(miner *rpctest.Harness,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to index into block: %v", err)
|
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",
|
t.Fatalf("mismatched tx indexes: expected %v, got %v",
|
||||||
txid, specifiedTxHash)
|
txid1, specifiedTxHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll also ensure that the block height has been set
|
// We'll also ensure that the block height has been set
|
||||||
// properly.
|
// properly.
|
||||||
if confInfo.BlockHeight != uint32(currentHeight) {
|
if confInfo.BlockHeight != uint32(currentHeight+1) {
|
||||||
t.Fatalf("incorrect block height: expected %v, got %v",
|
t.Fatalf("incorrect block height: expected %v, got %v",
|
||||||
confInfo.BlockHeight, currentHeight)
|
confInfo.BlockHeight, currentHeight)
|
||||||
}
|
}
|
||||||
|
@ -566,76 +584,61 @@ func testTxConfirmedBeforeNtfnRegistration(miner *rpctest.Harness,
|
||||||
t.Fatalf("confirmation notification never received")
|
t.Fatalf("confirmation notification never received")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, we want to test fully dispatching the notification for a
|
// Register a confirmation notification for tx2, requiring 3 confirmations.
|
||||||
// transaction that has been *partially* confirmed. So we'll create
|
// This transaction is only partially confirmed, so the notification should
|
||||||
// another test txid.
|
// not fire yet.
|
||||||
txid, err = getTestTxId(miner)
|
ntfn2, err := notifier.RegisterConfirmationsNtfn(txid2, 3,
|
||||||
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,
|
|
||||||
uint32(currentHeight))
|
uint32(currentHeight))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We shouldn't receive a notification at this point, as the
|
// Fully confirm tx3.
|
||||||
// transaction hasn't yet been fully confirmed.
|
_, err = miner.Node.Generate(2)
|
||||||
select {
|
if err != nil {
|
||||||
case <-confIntent.Confirmed:
|
t.Fatalf("unable to generate block: %v", err)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-confIntent.Confirmed:
|
case <-ntfn2.Confirmed:
|
||||||
t.Fatalf("received confirmation notification but shouldn't " +
|
case <-time.After(10 * time.Second):
|
||||||
"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):
|
|
||||||
t.Fatalf("confirmation notification never received")
|
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
|
// Test the case of a notification consumer having forget or being delayed in
|
||||||
|
|
Loading…
Add table
Reference in a new issue