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