Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mempool: Add test for max orphan entry eviction. #769

Merged
merged 2 commits into from
Jul 27, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions mempool/mempool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,3 +531,78 @@ func TestOrphanReject(t *testing.T) {
}
}
}

// TestOrphanEviction ensures that exceeding the maximum number of orphans
// evicts entries to make room for the new ones.
func TestOrphanEviction(t *testing.T) {
t.Parallel()

harness, outputs, err := newPoolHarness(&chaincfg.MainNetParams)
if err != nil {
t.Fatalf("unable to create test pool: %v", err)
}

// Create a chain of transactions rooted with the first spendable output
// provided by the harness that is long enough to be able to force
// several orphan evictions.
maxOrphans := uint32(harness.txPool.cfg.Policy.MaxOrphanTxs)
chainedTxns, err := harness.CreateTxChain(outputs[0], maxOrphans+5)
if err != nil {
t.Fatalf("unable to create transaction chain: %v", err)
}

// Add enough orphans to exceed the max allowed while ensuring they are
// all accepted. This will cause an eviction.
for _, tx := range chainedTxns[1:] {
acceptedTxns, err := harness.txPool.ProcessTransaction(tx, true,
false, true)
if err != nil {
t.Fatalf("ProcessTransaction: failed to accept valid "+
"orphan %v", err)
}

// Ensure no transactions were reported as accepted.
if len(acceptedTxns) != 0 {
t.Fatalf("ProcessTransaction: reported %d accepted "+
"transactions from what should be an orphan",
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")
}
}

// Figure out which transactions were evicted and make sure the number
// evicted matches the expected number.
var evictedTxns []*dcrutil.Tx
for _, tx := range chainedTxns[1:] {
if !harness.txPool.IsOrphanInPool(tx.Hash()) {
evictedTxns = append(evictedTxns, tx)
}
}
expectedEvictions := len(chainedTxns) - 1 - int(maxOrphans)
if len(evictedTxns) != expectedEvictions {
t.Fatalf("unexpected number of evictions -- got %d, want %d",
len(evictedTxns), expectedEvictions)
}

// Ensure none of the evicted transactioned ended up the transaction
// pool.
for _, tx := range evictedTxns {
if harness.txPool.IsTransactionInPool(tx.Hash()) {
t.Fatalf("IsTransactionInPool: true for evicted orphan")
}
}
}