-
Notifications
You must be signed in to change notification settings - Fork 34
/
mining_test.go
148 lines (127 loc) · 4.85 KB
/
mining_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"container/heap"
"math/rand"
"testing"
"github.com/HcashOrg/hcashd/blockchain/stake"
)
// fakePrioritizedTxes prepares some fake prioritized txes for test
func fakePrioritizedTxes() []*txPrioItem {
const numRandTx = 1000
// some items under the edge condition
prioritizedTxes := []*txPrioItem{
{feePerKB: 5678, txType: stake.TxTypeRegular, priority: 3},
{feePerKB: 5678, txType: stake.TxTypeRegular, priority: 1},
{feePerKB: 5678, txType: stake.TxTypeRegular, priority: 1}, // Duplicate fee and prio
{feePerKB: 5678, txType: stake.TxTypeRegular, priority: 5},
{feePerKB: 5678, txType: stake.TxTypeRegular, priority: 2},
{feePerKB: 1234, txType: stake.TxTypeRegular, priority: 3},
{feePerKB: 1234, txType: stake.TxTypeRegular, priority: 1},
{feePerKB: 1234, txType: stake.TxTypeRegular, priority: 5},
{feePerKB: 1234, txType: stake.TxTypeRegular, priority: 5}, // Duplicate fee and prio
{feePerKB: 1234, txType: stake.TxTypeRegular, priority: 2},
{feePerKB: 10000, txType: stake.TxTypeRegular, priority: 0}, // Higher fee, smaller prio
{feePerKB: 0, txType: stake.TxTypeRegular, priority: 10000}, // Higher prio, lower fee
}
for i := 0; i < numRandTx; i++ {
// fake a random tx
randTxType := stake.TxType(rand.Intn(4))
randPriority := rand.Float64() * 100
randFeePerKB := rand.Float64() * 10
prioritizedTxes = append(prioritizedTxes, &txPrioItem{
tx: nil,
txType: randTxType,
feePerKB: randFeePerKB,
priority: randPriority,
})
}
return prioritizedTxes
}
// TestTxPQOnStakePriorityAndFeeAndTxPriority tests the priority
// queue on stake priority, fee per kb and tx priority
func TestTxPQOnStakePriorityAndFeeAndTxPriority(t *testing.T) {
// get fake txes as samples
prioritizedTxes := fakePrioritizedTxes()
pq := newTxPriorityQueue(len(prioritizedTxes), txPQByStakeAndFee)
// build the priority queue tx by tx
for _, tx := range prioritizedTxes {
heap.Push(pq, tx)
}
// ensure the size of queue is correct
if pq.Len() != len(prioritizedTxes) {
t.Errorf("size of priority queue built is %v, want %v\n", pq.Len(), len(prioritizedTxes))
}
// last item popped out
prev := &txPrioItem{
tx: nil,
txType: stake.TxTypeSSGen,
priority: 10000.0, // since highest priority of the fake tx is 10000
feePerKB: 10000.0, // since highest feePerKB of the fake tx is 10000
}
for pq.Len() > 0 {
item := heap.Pop(pq)
if tx, ok := item.(*txPrioItem); ok {
// check correctness of order
// higher stake priority, fee per kb and tx priority comes first
if (compareStakePriority(tx, prev) > 0) ||
((0 == compareStakePriority(tx, prev)) && (tx.feePerKB > prev.feePerKB)) {
t.Errorf("bad pop: %v fee per KB was more than previous of %v "+
"while the txtype was %v but previous was %v",
tx.feePerKB, prev.feePerKB, tx.txType, prev.txType)
}
prev = tx
}
}
}
// TestTxPQOnStakePriorityAndFeeAndTxPriorityConsideringTxType tests the priority
// queue on stake priority, fee per kb
// if both tx are of type regular or revocation, plus the tx priority
func TestTxPQOnStakePriorityAndFeeAndConditionalTxPriority(t *testing.T) {
// get fake txes as samples
prioritizedTxes := fakePrioritizedTxes()
pq := newTxPriorityQueue(len(prioritizedTxes), txPQByStakeAndFeeAndThenPriority)
// build the priority queue tx by tx
for _, tx := range prioritizedTxes {
heap.Push(pq, tx)
}
// ensure the size of queue is correct
if pq.Len() != len(prioritizedTxes) {
t.Errorf("size of priority queue built is %v, want %v\n", pq.Len(), len(prioritizedTxes))
}
// last item popped out
prev := &txPrioItem{
tx: nil,
txType: stake.TxTypeSSGen,
priority: 10000.0, // since highest priority of the fake tx is 10000
feePerKB: 10000.0, // since highest feePerKB of the fake tx is 10000
}
for pq.Len() > 0 {
item := heap.Pop(pq)
if tx, ok := item.(*txPrioItem); ok {
// check correctness of order
// higher stake priority, fee per kb
// if both tx types are either regular or revocation, plus priority
// comes first
stakePriorityDelta := compareStakePriority(tx, prev)
if (txStakePriority(tx.txType) == regOrRevocPriority) &&
(txStakePriority(prev.txType) == regOrRevocPriority) {
// both are of low stake priority
if (stakePriorityDelta > 0) ||
((0 == stakePriorityDelta) && (tx.priority > prev.priority)) {
t.Errorf("bad pop: %v priority was more than previous of %v "+
"while the tx type was %v but previous was %v",
tx.priority, prev.priority, tx.txType, prev.txType)
}
} else {
// neither are of low stake priority
if (stakePriorityDelta > 0) ||
((0 == stakePriorityDelta) && (tx.feePerKB > prev.feePerKB)) {
t.Errorf("bad pop: %v fee per KB was more than previous of %v "+
"while the tx type was %v but previous was %v",
tx.feePerKB, prev.feePerKB, tx.txType, prev.txType)
}
}
prev = tx
}
}
}