diff --git a/mining_test.go b/mining_test.go index c7069637..e0b5bd72 100644 --- a/mining_test.go +++ b/mining_test.go @@ -15,51 +15,96 @@ import ( // TestTxFeePrioHeap ensures the priority queue for transaction fees and // priorities works as expected. func TestTxFeePrioHeap(t *testing.T) { - // Create priority items with random fees and priorites. - const numItems = 1000 - prioItems := make([]*txPrioItem, numItems) - highestFeePerKB := int64(0) - highestPrio := float64(0) + // Create some fake priority items that exercise the expected sort + // edge conditions. + testItems := []*txPrioItem{ + {feePerKB: 5678, priority: 3}, + {feePerKB: 5678, priority: 1}, + {feePerKB: 5678, priority: 1}, // Duplicate fee and prio + {feePerKB: 5678, priority: 5}, + {feePerKB: 5678, priority: 2}, + {feePerKB: 1234, priority: 3}, + {feePerKB: 1234, priority: 1}, + {feePerKB: 1234, priority: 5}, + {feePerKB: 1234, priority: 5}, // Duplicate fee and prio + {feePerKB: 1234, priority: 2}, + {feePerKB: 10000, priority: 0}, // Higher fee, smaller prio + {feePerKB: 0, priority: 10000}, // Higher prio, lower fee + } + + // Add random data in addition to the edge conditions already manually + // specified. + randSeed := rand.Int63() + defer func() { + if t.Failed() { + t.Logf("Random numbers using seed: %v", randSeed) + } + }() + prng := rand.New(rand.NewSource(randSeed)) for i := 0; i < 1000; i++ { - randPrio := rand.Float64() * 100 - if randPrio > highestPrio { - highestPrio = randPrio - } - randFeePerKB := int64(rand.Float64() * btcutil.SatoshiPerBitcoin) - if randFeePerKB > highestFeePerKB { - highestFeePerKB = randFeePerKB - } - prioItems[i] = &txPrioItem{ - tx: nil, - priority: randPrio, - feePerKB: randFeePerKB, - } + testItems = append(testItems, &txPrioItem{ + feePerKB: int64(prng.Float64() * btcutil.SatoshiPerBitcoin), + priority: prng.Float64() * 100, + }) } - // Test sorting by fee per KB. - priorityQueue := newTxPriorityQueue(numItems, true) - for i := 0; i < numItems; i++ { - heap.Push(priorityQueue, prioItems[i]) - } - for i := 0; i < numItems; i++ { - prioItem := heap.Pop(priorityQueue).(*txPrioItem) - if prioItem.feePerKB > highestFeePerKB { - t.Fatalf("bad pop: %v fee per KB was more than last of %v", - prioItem.feePerKB, highestFeePerKB) + // Test sorting by fee per KB then priority. + var highest *txPrioItem + priorityQueue := newTxPriorityQueue(len(testItems), true) + for i := 0; i < len(testItems); i++ { + prioItem := testItems[i] + if highest == nil { + highest = prioItem } - highestFeePerKB = prioItem.feePerKB + if prioItem.feePerKB >= highest.feePerKB && + prioItem.priority > highest.priority { + + highest = prioItem + } + heap.Push(priorityQueue, prioItem) } - // Test sorting by priority. - priorityQueue = newTxPriorityQueue(numItems, false) - for i := 0; i < numItems; i++ { - heap.Push(priorityQueue, prioItems[i]) - } - for i := 0; i < numItems; i++ { + for i := 0; i < len(testItems); i++ { prioItem := heap.Pop(priorityQueue).(*txPrioItem) - if prioItem.priority > highestPrio { - t.Fatalf("bad pop: %v priority was more than last of %v", - prioItem.priority, highestPrio) + if prioItem.feePerKB >= highest.feePerKB && + prioItem.priority > highest.priority { + + t.Fatalf("fee sort: item (fee per KB: %v, "+ + "priority: %v) higher than than prev "+ + "(fee per KB: %v, priority %v)", + prioItem.feePerKB, prioItem.priority, + highest.feePerKB, highest.priority) } + highest = prioItem + } + + // Test sorting by priority then fee per KB. + highest = nil + priorityQueue = newTxPriorityQueue(len(testItems), false) + for i := 0; i < len(testItems); i++ { + prioItem := testItems[i] + if highest == nil { + highest = prioItem + } + if prioItem.priority >= highest.priority && + prioItem.feePerKB > highest.feePerKB { + + highest = prioItem + } + heap.Push(priorityQueue, prioItem) + } + + for i := 0; i < len(testItems); i++ { + prioItem := heap.Pop(priorityQueue).(*txPrioItem) + if prioItem.priority >= highest.priority && + prioItem.feePerKB > highest.feePerKB { + + t.Fatalf("priority sort: item (fee per KB: %v, "+ + "priority: %v) higher than than prev "+ + "(fee per KB: %v, priority %v)", + prioItem.feePerKB, prioItem.priority, + highest.feePerKB, highest.priority) + } + highest = prioItem } }