19
19
// Transaction Pool Errors
20
20
ErrInvalidSender = errors .New ("Invalid sender" )
21
21
ErrNonce = errors .New ("Nonce too low" )
22
+ ErrCheap = errors .New ("Gas price too low for acceptance" )
22
23
ErrBalance = errors .New ("Insufficient balance" )
23
24
ErrNonExistentAccount = errors .New ("Account does not exist or account balance too low" )
24
25
ErrInsufficientFunds = errors .New ("Insufficient funds for gas * price + value" )
27
28
ErrNegativeValue = errors .New ("Negative value" )
28
29
)
29
30
31
+ const (
32
+ maxQueued = 200 // max limit of queued txs per address
33
+ )
34
+
30
35
type stateFn func () * state.StateDB
31
36
32
37
// TxPool contains all currently known transactions. Transactions
@@ -41,6 +46,7 @@ type TxPool struct {
41
46
currentState stateFn // The state function which will allow us to do some pre checkes
42
47
pendingState * state.ManagedState
43
48
gasLimit func () * big.Int // The current gas limit function callback
49
+ minGasPrice * big.Int
44
50
eventMux * event.TypeMux
45
51
events event.Subscription
46
52
@@ -57,8 +63,9 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func(
57
63
eventMux : eventMux ,
58
64
currentState : currentStateFn ,
59
65
gasLimit : gasLimitFn ,
66
+ minGasPrice : new (big.Int ),
60
67
pendingState : state .ManageState (currentStateFn ()),
61
- events : eventMux .Subscribe (ChainEvent {}),
68
+ events : eventMux .Subscribe (ChainEvent {}, GasPriceChanged {} ),
62
69
}
63
70
go pool .eventLoop ()
64
71
@@ -69,10 +76,15 @@ func (pool *TxPool) eventLoop() {
69
76
// Track chain events. When a chain events occurs (new chain canon block)
70
77
// we need to know the new state. The new state will help us determine
71
78
// the nonces in the managed state
72
- for _ = range pool .events .Chan () {
79
+ for ev : = range pool .events .Chan () {
73
80
pool .mu .Lock ()
74
81
75
- pool .resetState ()
82
+ switch ev := ev .(type ) {
83
+ case ChainEvent :
84
+ pool .resetState ()
85
+ case GasPriceChanged :
86
+ pool .minGasPrice = ev .Price
87
+ }
76
88
77
89
pool .mu .Unlock ()
78
90
}
@@ -124,6 +136,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
124
136
err error
125
137
)
126
138
139
+ // Drop transactions under our own minimal accepted gas price
140
+ if pool .minGasPrice .Cmp (tx .GasPrice ()) > 0 {
141
+ return ErrCheap
142
+ }
143
+
127
144
// Validate the transaction sender and it's sig. Throw
128
145
// if the from fields is invalid.
129
146
if from , err = tx .From (); err != nil {
@@ -335,7 +352,16 @@ func (pool *TxPool) checkQueue() {
335
352
// Find the next consecutive nonce range starting at the
336
353
// current account nonce.
337
354
sort .Sort (addq )
338
- for _ , e := range addq {
355
+ for i , e := range addq {
356
+ // start deleting the transactions from the queue if they exceed the limit
357
+ if i > maxQueued {
358
+ if glog .V (logger .Debug ) {
359
+ glog .Infof ("Queued tx limit exceeded for %s. Tx %s removed\n " , common .PP (address [:]), common .PP (e .hash [:]))
360
+ }
361
+ delete (pool .queue [address ], e .hash )
362
+ continue
363
+ }
364
+
339
365
if e .AccountNonce > guessedNonce {
340
366
break
341
367
}
0 commit comments