_mining_test.go raw
1 package mining
2
3 import (
4 "container/heap"
5 "math/rand"
6 "testing"
7
8 "github.com/p9c/p9/pkg/util"
9 )
10
11 // TestTxFeePrioHeap ensures the priority queue for transaction fees and priorities works as expected.
12 func TestTxFeePrioHeap( t *testing.T) {
13 // Create some fake priority items that exercise the expected sort edge conditions.
14 testItems := []*txPrioItem{
15 {feePerKB: 5678, priority: 3},
16 {feePerKB: 5678, priority: 1},
17 {feePerKB: 5678, priority: 1}, // Duplicate fee and prio
18 {feePerKB: 5678, priority: 5},
19 {feePerKB: 5678, priority: 2},
20 {feePerKB: 1234, priority: 3},
21 {feePerKB: 1234, priority: 1},
22 {feePerKB: 1234, priority: 5},
23 {feePerKB: 1234, priority: 5}, // Duplicate fee and prio
24 {feePerKB: 1234, priority: 2},
25 {feePerKB: 10000, priority: 0}, // Higher fee, smaller prio
26 {feePerKB: 0, priority: 10000}, // Higher prio, lower fee
27 }
28 // Add random data in addition to the edge conditions already manually specified.
29 randSeed := rand.Int63()
30 defer func() {
31 if t.Failed() {
32 t.Logf("Random numbers using seed: %v", randSeed)
33 }
34 }()
35 prng := rand.New(rand.NewSource(randSeed))
36 for i := 0; i < 1000; i++ {
37 testItems = append(testItems, &txPrioItem{
38 feePerKB: int64(prng.Float64() * util.SatoshiPerBitcoin),
39 priority: prng.Float64() * 100,
40 })
41 }
42 // Test sorting by fee per KB then priority.
43 var highest *txPrioItem
44 priorityQueue := newTxPriorityQueue(len(testItems), true)
45 for i := 0; i < len(testItems); i++ {
46 prioItem := testItems[i]
47 if highest == nil {
48 highest = prioItem
49 }
50 if prioItem.feePerKB >= highest.feePerKB &&
51 prioItem.priority > highest.priority {
52 highest = prioItem
53 }
54 heap.Push(priorityQueue, prioItem)
55 }
56 for i := 0; i < len(testItems); i++ {
57 prioItem := heap.Pop(priorityQueue).(*txPrioItem)
58 if prioItem.feePerKB >= highest.feePerKB &&
59 prioItem.priority > highest.priority {
60 t.Fatalf("fee sort: item (fee per KB: %v, "+
61 "priority: %v) higher than than prev "+
62 "(fee per KB: %v, priority %v)",
63 prioItem.feePerKB, prioItem.priority,
64 highest.feePerKB, highest.priority)
65 }
66 highest = prioItem
67 }
68 // Test sorting by priority then fee per KB.
69 highest = nil
70 priorityQueue = newTxPriorityQueue(len(testItems), false)
71 for i := 0; i < len(testItems); i++ {
72 prioItem := testItems[i]
73 if highest == nil {
74 highest = prioItem
75 }
76 if prioItem.priority >= highest.priority &&
77 prioItem.feePerKB > highest.feePerKB {
78 highest = prioItem
79 }
80 heap.Push(priorityQueue, prioItem)
81 }
82 for i := 0; i < len(testItems); i++ {
83 prioItem := heap.Pop(priorityQueue).(*txPrioItem)
84 if prioItem.priority >= highest.priority &&
85 prioItem.feePerKB > highest.feePerKB {
86 t.Fatalf("priority sort: item (fee per KB: %v, "+
87 "priority: %v) higher than than prev "+
88 "(fee per KB: %v, priority %v)",
89 prioItem.feePerKB, prioItem.priority,
90 highest.feePerKB, highest.priority)
91 }
92 highest = prioItem
93 }
94 }
95