core, miner: drop transactions from the same sender when error occurs (#27038)

This PR unifies the error handling in miner. 

Whenever an error occur while applying a transaction, the transaction should be regarded as invalid and all following transactions from the same sender not executable because of the nonce restriction. The only exception is the `nonceTooLow` error which is handled separately.
pull/27069/head^2
rjl493456442 2 years ago committed by GitHub
parent 230df98e4d
commit b946b7a13b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      core/state_transition.go
  2. 21
      miner/worker.go

@ -136,7 +136,7 @@ type Message struct {
Data []byte Data []byte
AccessList types.AccessList AccessList types.AccessList
// When SkipAccountCheckss is true, the message nonce is not checked against the // When SkipAccountChecks is true, the message nonce is not checked against the
// account nonce in state. It also disables checking that the sender is an EOA. // account nonce in state. It also disables checking that the sender is an EOA.
// This field will be set to true for operations like RPC eth_call. // This field will be set to true for operations like RPC eth_call.
SkipAccountChecks bool SkipAccountChecks bool

@ -918,37 +918,22 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
logs, err := w.commitTransaction(env, tx) logs, err := w.commitTransaction(env, tx)
switch { switch {
case errors.Is(err, core.ErrGasLimitReached):
// Pop the current out-of-gas transaction without shifting in the next from the account
log.Trace("Gas limit exceeded for current block", "sender", from)
txs.Pop()
case errors.Is(err, core.ErrNonceTooLow): case errors.Is(err, core.ErrNonceTooLow):
// New head notification data race between the transaction pool and miner, shift // New head notification data race between the transaction pool and miner, shift
log.Trace("Skipping transaction with low nonce", "sender", from, "nonce", tx.Nonce()) log.Trace("Skipping transaction with low nonce", "sender", from, "nonce", tx.Nonce())
txs.Shift() txs.Shift()
case errors.Is(err, core.ErrNonceTooHigh):
// Reorg notification data race between the transaction pool and miner, skip account =
log.Trace("Skipping account with hight nonce", "sender", from, "nonce", tx.Nonce())
txs.Pop()
case errors.Is(err, nil): case errors.Is(err, nil):
// Everything ok, collect the logs and shift in the next transaction from the same account // Everything ok, collect the logs and shift in the next transaction from the same account
coalescedLogs = append(coalescedLogs, logs...) coalescedLogs = append(coalescedLogs, logs...)
env.tcount++ env.tcount++
txs.Shift() txs.Shift()
case errors.Is(err, types.ErrTxTypeNotSupported):
// Pop the unsupported transaction without shifting in the next from the account
log.Trace("Skipping unsupported transaction type", "sender", from, "type", tx.Type())
txs.Pop()
default: default:
// Strange error, discard the transaction and get the next in line (note, the // Transaction is regarded as invalid, drop all consecutive transactions from
// nonce-too-high clause will prevent us from executing in vain). // the same sender because of `nonce-too-high` clause.
log.Debug("Transaction failed, account skipped", "hash", tx.Hash(), "err", err) log.Debug("Transaction failed, account skipped", "hash", tx.Hash(), "err", err)
txs.Shift() txs.Pop()
} }
} }
if !w.isRunning() && len(coalescedLogs) > 0 { if !w.isRunning() && len(coalescedLogs) > 0 {

Loading…
Cancel
Save