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  }