7895f01e2e
In this commit, we address a bug where it's possible that we still attempt to manually scan for a transaction to determine whether it's been included in the chain even after successfully checking the txindex and not finding it there. Now, we'll short-circuit this process by exiting early if the txindex lookup was successful but the transaction in question was not found. Otherwise, we'll fall back to the manual scan.
181 lines
5.4 KiB
Go
181 lines
5.4 KiB
Go
// +build debug
|
|
|
|
package btcdnotify
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
"github.com/btcsuite/btcd/integration/rpctest"
|
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
|
)
|
|
|
|
// setUpNotifier is a helper function to start a new notifier backed by a btcd
|
|
// driver.
|
|
func setUpNotifier(t *testing.T, h *rpctest.Harness) *BtcdNotifier {
|
|
rpcCfg := h.RPCConfig()
|
|
notifier, err := New(&rpcCfg)
|
|
if err != nil {
|
|
t.Fatalf("unable to create notifier: %v", err)
|
|
}
|
|
if err := notifier.Start(); err != nil {
|
|
t.Fatalf("unable to start notifier: %v", err)
|
|
}
|
|
|
|
return notifier
|
|
}
|
|
|
|
// TestHistoricalConfDetailsTxIndex ensures that we correctly retrieve
|
|
// historical confirmation details using the backend node's txindex.
|
|
func TestHistoricalConfDetailsTxIndex(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
harness, tearDown := chainntnfs.NewMiner(
|
|
t, []string{"--txindex"}, true, 25,
|
|
)
|
|
defer tearDown()
|
|
|
|
notifier := setUpNotifier(t, harness)
|
|
defer notifier.Stop()
|
|
|
|
// A transaction unknown to the node should not be found within the
|
|
// txindex even if it is enabled, so we should not proceed with any
|
|
// fallback methods.
|
|
var zeroHash chainhash.Hash
|
|
_, txStatus, err := notifier.historicalConfDetails(&zeroHash, 0, 0)
|
|
if err != nil {
|
|
t.Fatalf("unable to retrieve historical conf details: %v", err)
|
|
}
|
|
|
|
switch txStatus {
|
|
case txNotFoundIndex:
|
|
case txNotFoundManually:
|
|
t.Fatal("should not have proceeded with fallback method, but did")
|
|
default:
|
|
t.Fatal("should not have found non-existent transaction, but did")
|
|
}
|
|
|
|
// Now, we'll create a test transaction and attempt to retrieve its
|
|
// confirmation details.
|
|
txid, _, err := chainntnfs.GetTestTxidAndScript(harness)
|
|
if err != nil {
|
|
t.Fatalf("unable to create tx: %v", err)
|
|
}
|
|
if err := chainntnfs.WaitForMempoolTx(harness, txid); err != nil {
|
|
t.Fatalf("unable to find tx in the mempool: %v", err)
|
|
}
|
|
|
|
_, txStatus, err = notifier.historicalConfDetails(txid, 0, 0)
|
|
if err != nil {
|
|
t.Fatalf("unable to retrieve historical conf details: %v", err)
|
|
}
|
|
|
|
// Since it has yet to be included in a block, it should have been found
|
|
// within the mempool.
|
|
switch txStatus {
|
|
case txFoundMempool:
|
|
default:
|
|
t.Fatal("should have found the transaction within the " +
|
|
"mempool, but did not")
|
|
}
|
|
|
|
// We'll now confirm this transaction and re-attempt to retrieve its
|
|
// confirmation details.
|
|
if _, err := harness.Node.Generate(1); err != nil {
|
|
t.Fatalf("unable to generate block: %v", err)
|
|
}
|
|
|
|
_, txStatus, err = notifier.historicalConfDetails(txid, 0, 0)
|
|
if err != nil {
|
|
t.Fatalf("unable to retrieve historical conf details: %v", err)
|
|
}
|
|
|
|
// Since the backend node's txindex is enabled and the transaction has
|
|
// confirmed, we should be able to retrieve it using the txindex.
|
|
switch txStatus {
|
|
case txFoundIndex:
|
|
default:
|
|
t.Fatal("should have found the transaction within the " +
|
|
"txindex, but did not")
|
|
}
|
|
}
|
|
|
|
// TestHistoricalConfDetailsNoTxIndex ensures that we correctly retrieve
|
|
// historical confirmation details using the set of fallback methods when the
|
|
// backend node's txindex is disabled.
|
|
func TestHistoricalConfDetailsNoTxIndex(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
harness, tearDown := chainntnfs.NewMiner(t, nil, true, 25)
|
|
defer tearDown()
|
|
|
|
notifier := setUpNotifier(t, harness)
|
|
defer notifier.Stop()
|
|
|
|
// Since the node has its txindex disabled, we fall back to scanning the
|
|
// chain manually. A transaction unknown to the network should not be
|
|
// found.
|
|
var zeroHash chainhash.Hash
|
|
_, txStatus, err := notifier.historicalConfDetails(&zeroHash, 0, 0)
|
|
if err != nil {
|
|
t.Fatalf("unable to retrieve historical conf details: %v", err)
|
|
}
|
|
|
|
switch txStatus {
|
|
case txNotFoundManually:
|
|
case txNotFoundIndex:
|
|
t.Fatal("should have proceeded with fallback method, but did not")
|
|
default:
|
|
t.Fatal("should not have found non-existent transaction, but did")
|
|
}
|
|
|
|
// Now, we'll create a test transaction and attempt to retrieve its
|
|
// confirmation details. We'll note its broadcast height to use as the
|
|
// height hint when manually scanning the chain.
|
|
_, currentHeight, err := harness.Node.GetBestBlock()
|
|
if err != nil {
|
|
t.Fatalf("unable to retrieve current height: %v", err)
|
|
}
|
|
|
|
txid, _, err := chainntnfs.GetTestTxidAndScript(harness)
|
|
if err != nil {
|
|
t.Fatalf("unable to create tx: %v", err)
|
|
}
|
|
if err := chainntnfs.WaitForMempoolTx(harness, txid); err != nil {
|
|
t.Fatalf("unable to find tx in the mempool: %v", err)
|
|
}
|
|
|
|
_, txStatus, err = notifier.historicalConfDetails(txid, 0, 0)
|
|
if err != nil {
|
|
t.Fatalf("unable to retrieve historical conf details: %v", err)
|
|
}
|
|
|
|
// Since it has yet to be included in a block, it should have been found
|
|
// within the mempool.
|
|
if txStatus != txFoundMempool {
|
|
t.Fatal("should have found the transaction within the " +
|
|
"mempool, but did not")
|
|
}
|
|
|
|
// We'll now confirm this transaction and re-attempt to retrieve its
|
|
// confirmation details.
|
|
if _, err := harness.Node.Generate(1); err != nil {
|
|
t.Fatalf("unable to generate block: %v", err)
|
|
}
|
|
|
|
_, txStatus, err = notifier.historicalConfDetails(
|
|
txid, uint32(currentHeight), uint32(currentHeight)+1,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("unable to retrieve historical conf details: %v", err)
|
|
}
|
|
|
|
// Since the backend node's txindex is disabled and the transaction has
|
|
// confirmed, we should be able to find it by falling back to scanning
|
|
// the chain manually.
|
|
if txStatus != txFoundManually {
|
|
t.Fatal("should have found the transaction by manually " +
|
|
"scanning the chain, but did not")
|
|
}
|
|
}
|