This repository has been archived by the owner on Dec 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 535
/
Copy pathqueue_priced.go
123 lines (98 loc) · 2.52 KB
/
queue_priced.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
package txpool
import (
"container/heap"
"math/big"
"github.com/0xPolygon/polygon-edge/types"
)
type pricedQueue struct {
queue *maxPriceQueue
}
// newPricesQueue creates the priced queue with initial transactions and base fee
func newPricesQueue(baseFee uint64, initialTxs []*types.Transaction) *pricedQueue {
q := &pricedQueue{
queue: &maxPriceQueue{
baseFee: new(big.Int).SetUint64(baseFee),
txs: initialTxs,
},
}
heap.Init(q.queue)
return q
}
// Pushes the given transactions onto the queue.
func (q *pricedQueue) push(tx *types.Transaction) {
heap.Push(q.queue, tx)
}
// Pop removes the first transaction from the queue
// or nil if the queue is empty.
func (q *pricedQueue) pop() *types.Transaction {
if q.length() == 0 {
return nil
}
transaction, ok := heap.Pop(q.queue).(*types.Transaction)
if !ok {
return nil
}
return transaction
}
// length returns the number of transactions in the queue.
func (q *pricedQueue) length() int {
return q.queue.Len()
}
// transactions sorted by gas price (descending)
type maxPriceQueue struct {
baseFee *big.Int
txs []*types.Transaction
}
/* Queue methods required by the heap interface */
func (q *maxPriceQueue) Peek() *types.Transaction {
if q.Len() == 0 {
return nil
}
return q.txs[0]
}
func (q *maxPriceQueue) Len() int {
return len(q.txs)
}
func (q *maxPriceQueue) Swap(i, j int) {
q.txs[i], q.txs[j] = q.txs[j], q.txs[i]
}
func (q *maxPriceQueue) Push(x interface{}) {
transaction, ok := x.(*types.Transaction)
if !ok {
return
}
q.txs = append(q.txs, transaction)
}
func (q *maxPriceQueue) Pop() interface{} {
old := q.txs
n := len(old)
x := old[n-1]
q.txs = old[0 : n-1]
return x
}
// @see https://github.com/etclabscore/core-geth/blob/4e2b0e37f89515a4e7b6bafaa40910a296cb38c0/core/txpool/list.go#L458
// for details why is something implemented like it is
func (q *maxPriceQueue) Less(i, j int) bool {
switch cmp(q.txs[i], q.txs[j], q.baseFee) {
case -1:
return false
case 1:
return true
default:
return q.txs[i].Nonce < q.txs[j].Nonce
}
}
func cmp(a, b *types.Transaction, baseFee *big.Int) int {
if baseFee.BitLen() > 0 {
// Compare effective tips if baseFee is specified
if c := a.EffectiveGasTip(baseFee).Cmp(b.EffectiveGasTip(baseFee)); c != 0 {
return c
}
}
// Compare fee caps if baseFee is not specified or effective tips are equal
if c := a.GetGasFeeCap().Cmp(b.GetGasFeeCap()); c != 0 {
return c
}
// Compare tips if effective tips and fee caps are equal
return a.GetGasTipCap().Cmp(b.GetGasTipCap())
}