core: bugfix state change race condition in txpool (#3412)
The transaction pool keeps track of the current nonce in its local pendingState. When a new block comes in the pendingState is reset. During the reset it fetches multiple times the current state through the use of the currentState callback. When a second block comes in during the reset its possible that the state changes during the reset. If that block holds transactions that are currently in the pool the local pendingState that is used to determine nonces can get out of sync.
This commit is contained in:
@ -93,7 +93,7 @@ type testTxPool struct {
|
||||
|
||||
// AddBatch appends a batch of transactions to the pool, and notifies any
|
||||
// listeners if the addition channel is non nil
|
||||
func (p *testTxPool) AddBatch(txs []*types.Transaction) {
|
||||
func (p *testTxPool) AddBatch(txs []*types.Transaction) error {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
@ -101,10 +101,12 @@ func (p *testTxPool) AddBatch(txs []*types.Transaction) {
|
||||
if p.added != nil {
|
||||
p.added <- txs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Pending returns all the transactions known to the pool
|
||||
func (p *testTxPool) Pending() map[common.Address]types.Transactions {
|
||||
func (p *testTxPool) Pending() (map[common.Address]types.Transactions, error) {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
@ -116,7 +118,7 @@ func (p *testTxPool) Pending() map[common.Address]types.Transactions {
|
||||
for _, batch := range batches {
|
||||
sort.Sort(types.TxByNonce(batch))
|
||||
}
|
||||
return batches
|
||||
return batches, nil
|
||||
}
|
||||
|
||||
// newTestTransaction create a new dummy transaction.
|
||||
|
Reference in New Issue
Block a user