diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 4b8f577a..ec83b250 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -7,6 +7,7 @@ package mempool import ( "encoding/hex" "reflect" + "runtime" "sync" "testing" "time" @@ -331,6 +332,43 @@ func newPoolHarness(chainParams *chaincfg.Params) (*poolHarness, []spendableOutp return &harness, outputs, nil } +// testContext houses a test-related state that is useful to pass to helper +// functions as a single argument. +type testContext struct { + t *testing.T + harness *poolHarness +} + +// testPoolMembership tests the transaction pool associated with the provided +// test context to determine if the passed transaction matches the provided +// orphan pool and transaction pool status. It also further determines if it +// should be reported as available by the HaveTransaction function based upon +// the two flags and tests that condition as well. +func testPoolMembership(tc *testContext, tx *btcutil.Tx, inOrphanPool, inTxPool bool) { + txHash := tx.Hash() + gotOrphanPool := tc.harness.txPool.IsOrphanInPool(txHash) + if inOrphanPool != gotOrphanPool { + _, file, line, _ := runtime.Caller(1) + tc.t.Fatalf("%s:%d -- IsOrphanInPool: want %v, got %v", file, + line, inOrphanPool, gotOrphanPool) + } + + gotTxPool := tc.harness.txPool.IsTransactionInPool(txHash) + if inTxPool != gotTxPool { + _, file, line, _ := runtime.Caller(1) + tc.t.Fatalf("%s:%d -- IsTransactionInPool: want %v, got %v", + file, line, inTxPool, gotTxPool) + } + + gotHaveTx := tc.harness.txPool.HaveTransaction(txHash) + wantHaveTx := inOrphanPool || inTxPool + if wantHaveTx != gotHaveTx { + _, file, line, _ := runtime.Caller(1) + tc.t.Fatalf("%s:%d -- HaveTransaction: want %v, got %v", file, + line, wantHaveTx, gotHaveTx) + } +} + // TestSimpleOrphanChain ensures that a simple chain of orphans is handled // properly. In particular, it generates a chain of single input, single output // transactions and inserts them while skipping the first linking transaction so @@ -343,6 +381,7 @@ func TestSimpleOrphanChain(t *testing.T) { if err != nil { t.Fatalf("unable to create test pool: %v", err) } + tc := &testContext{t, harness} // Create a chain of transactions rooted with the first spendable output // provided by the harness. @@ -369,20 +408,9 @@ func TestSimpleOrphanChain(t *testing.T) { len(acceptedTxns)) } - // Ensure the transaction is in the orphan pool. - if !harness.txPool.IsOrphanInPool(tx.Hash()) { - t.Fatal("IsOrphanInPool: false for accepted orphan") - } - - // Ensure the transaction is not in the transaction pool. - if harness.txPool.IsTransactionInPool(tx.Hash()) { - t.Fatal("IsTransactionInPool: true for accepted orphan") - } - - // Ensure the transaction is reported as available. - if !harness.txPool.HaveTransaction(tx.Hash()) { - t.Fatal("HaveTransaction: false for accepted orphan") - } + // Ensure the transaction is in the orphan pool, is not in the + // transaction pool, and is reported as available. + testPoolMembership(tc, tx, true, false) } // Add the transaction which completes the orphan chain and ensure they @@ -401,18 +429,9 @@ func TestSimpleOrphanChain(t *testing.T) { len(acceptedTxns), len(chainedTxns)) } for _, tx := range acceptedTxns { - // Ensure none of the transactions are still in the orphan pool. - if harness.txPool.IsOrphanInPool(tx.Hash()) { - t.Fatalf("IsOrphanInPool: true for accepted tx %v", - tx.Hash()) - } - - // Ensure all of the transactions are now in the transaction - // pool. - if !harness.txPool.IsTransactionInPool(tx.Hash()) { - t.Fatalf("IsTransactionInPool: false for accepted tx %v", - tx.Hash()) - } + // Ensure the transaction is no longer in the orphan pool, is + // now in the transaction pool, and is reported as available. + testPoolMembership(tc, tx, false, true) } } @@ -425,6 +444,7 @@ func TestOrphanReject(t *testing.T) { if err != nil { t.Fatalf("unable to create test pool: %v", err) } + tc := &testContext{t, harness} // Create a chain of transactions rooted with the first spendable output // provided by the harness. @@ -464,20 +484,9 @@ func TestOrphanReject(t *testing.T) { len(acceptedTxns)) } - // Ensure the transaction is not in the orphan pool. - if harness.txPool.IsOrphanInPool(tx.Hash()) { - t.Fatal("IsOrphanInPool: true for rejected orphan") - } - - // Ensure the transaction is not in the transaction pool. - if harness.txPool.IsTransactionInPool(tx.Hash()) { - t.Fatal("IsTransactionInPool: true for rejected orphan") - } - - // Ensure the transaction is not reported as available. - if harness.txPool.HaveTransaction(tx.Hash()) { - t.Fatal("HaveTransaction: true for rejected orphan") - } + // Ensure the transaction is not in the orphan pool, not in the + // transaction pool, and not reported as available + testPoolMembership(tc, tx, false, false) } } @@ -490,6 +499,7 @@ func TestOrphanEviction(t *testing.T) { if err != nil { t.Fatalf("unable to create test pool: %v", err) } + tc := &testContext{t, harness} // Create a chain of transactions rooted with the first spendable output // provided by the harness that is long enough to be able to force @@ -517,20 +527,9 @@ func TestOrphanEviction(t *testing.T) { len(acceptedTxns)) } - // Ensure the transaction is in the orphan pool. - if !harness.txPool.IsOrphanInPool(tx.Hash()) { - t.Fatal("IsOrphanInPool: false for accepted orphan") - } - - // Ensure the transaction is not in the transaction pool. - if harness.txPool.IsTransactionInPool(tx.Hash()) { - t.Fatal("IsTransactionInPool: true for accepted orphan") - } - - // Ensure the transaction is reported as available. - if !harness.txPool.HaveTransaction(tx.Hash()) { - t.Fatal("HaveTransaction: false for accepted orphan") - } + // Ensure the transaction is in the orphan pool, is not in the + // transaction pool, and is reported as available. + testPoolMembership(tc, tx, true, false) } // Figure out which transactions were evicted and make sure the number @@ -547,11 +546,9 @@ func TestOrphanEviction(t *testing.T) { len(evictedTxns), expectedEvictions) } - // Ensure none of the evicted transactioned ended up the transaction + // Ensure none of the evicted transactions ended up in the transaction // pool. for _, tx := range evictedTxns { - if harness.txPool.IsTransactionInPool(tx.Hash()) { - t.Fatalf("IsTransactionInPool: true for evicted orphan") - } + testPoolMembership(tc, tx, false, false) } }