fix: improve nonce too low error (#10711)

This commit is contained in:
Panagiotis Ganelis
2024-09-05 16:09:33 +03:00
committed by GitHub
parent 834e99cd2a
commit 8bbd403285
4 changed files with 32 additions and 12 deletions

View File

@ -12,8 +12,13 @@ pub enum InvalidTransactionError {
/// The nonce is lower than the account's nonce, or there is a nonce gap present. /// The nonce is lower than the account's nonce, or there is a nonce gap present.
/// ///
/// This is a consensus error. /// This is a consensus error.
#[display("transaction nonce is not consistent")] #[display("transaction nonce is not consistent: next nonce {state}, tx nonce {tx}")]
NonceNotConsistent, NonceNotConsistent {
/// The nonce of the transaction.
tx: u64,
/// The current state of the nonce in the local chain.
state: u64,
},
/// The transaction is before Spurious Dragon and has a chain ID. /// The transaction is before Spurious Dragon and has a chain ID.
#[display("transactions before Spurious Dragon should not have a chain ID")] #[display("transactions before Spurious Dragon should not have a chain ID")]
OldLegacyChainId, OldLegacyChainId,

View File

@ -15,7 +15,7 @@ use reth_transaction_pool::error::{
Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolErrorKind, Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolErrorKind,
PoolTransactionError, PoolTransactionError,
}; };
use revm::primitives::{EVMError, ExecutionResult, HaltReason, OutOfGasError}; use revm::primitives::{EVMError, ExecutionResult, HaltReason, InvalidTransaction, OutOfGasError};
use revm_inspectors::tracing::MuxError; use revm_inspectors::tracing::MuxError;
use tracing::error; use tracing::error;
@ -236,7 +236,12 @@ where
{ {
fn from(err: EVMError<T>) -> Self { fn from(err: EVMError<T>) -> Self {
match err { match err {
EVMError::Transaction(err) => RpcInvalidTransactionError::from(err).into(), EVMError::Transaction(invalid_tx) => match invalid_tx {
InvalidTransaction::NonceTooLow { tx, state } => {
Self::InvalidTransaction(RpcInvalidTransactionError::NonceTooLow { tx, state })
}
_ => RpcInvalidTransactionError::from(invalid_tx).into(),
},
EVMError::Header(InvalidHeader::PrevrandaoNotSet) => Self::PrevrandaoNotSet, EVMError::Header(InvalidHeader::PrevrandaoNotSet) => Self::PrevrandaoNotSet,
EVMError::Header(InvalidHeader::ExcessBlobGasNotSet) => Self::ExcessBlobGasNotSet, EVMError::Header(InvalidHeader::ExcessBlobGasNotSet) => Self::ExcessBlobGasNotSet,
EVMError::Database(err) => err.into(), EVMError::Database(err) => err.into(),
@ -263,8 +268,13 @@ where
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum RpcInvalidTransactionError { pub enum RpcInvalidTransactionError {
/// returned if the nonce of a transaction is lower than the one present in the local chain. /// returned if the nonce of a transaction is lower than the one present in the local chain.
#[error("nonce too low")] #[error("nonce too low: next nonce {state}, tx nonce {tx}")]
NonceTooLow, NonceTooLow {
/// The nonce of the transaction.
tx: u64,
/// The current state of the nonce in the local chain.
state: u64,
},
/// returned if the nonce of a transaction is higher than the next one expected based on the /// returned if the nonce of a transaction is higher than the next one expected based on the
/// local chain. /// local chain.
#[error("nonce too high")] #[error("nonce too high")]
@ -456,7 +466,7 @@ impl From<revm::primitives::InvalidTransaction> for RpcInvalidTransactionError {
InvalidTransaction::NonceOverflowInTransaction => Self::NonceMaxValue, InvalidTransaction::NonceOverflowInTransaction => Self::NonceMaxValue,
InvalidTransaction::CreateInitCodeSizeLimit => Self::MaxInitCodeSizeExceeded, InvalidTransaction::CreateInitCodeSizeLimit => Self::MaxInitCodeSizeExceeded,
InvalidTransaction::NonceTooHigh { .. } => Self::NonceTooHigh, InvalidTransaction::NonceTooHigh { .. } => Self::NonceTooHigh,
InvalidTransaction::NonceTooLow { .. } => Self::NonceTooLow, InvalidTransaction::NonceTooLow { tx, state } => Self::NonceTooLow { tx, state },
InvalidTransaction::AccessListNotSupported => Self::AccessListNotSupported, InvalidTransaction::AccessListNotSupported => Self::AccessListNotSupported,
InvalidTransaction::MaxFeePerBlobGasNotSupported => Self::MaxFeePerBlobGasNotSupported, InvalidTransaction::MaxFeePerBlobGasNotSupported => Self::MaxFeePerBlobGasNotSupported,
InvalidTransaction::BlobVersionedHashesNotSupported => { InvalidTransaction::BlobVersionedHashesNotSupported => {
@ -494,7 +504,9 @@ impl From<reth_primitives::InvalidTransactionError> for RpcInvalidTransactionErr
// txpool (e.g. `eth_sendRawTransaction`) to their corresponding RPC // txpool (e.g. `eth_sendRawTransaction`) to their corresponding RPC
match err { match err {
InvalidTransactionError::InsufficientFunds { .. } => Self::InsufficientFunds, InvalidTransactionError::InsufficientFunds { .. } => Self::InsufficientFunds,
InvalidTransactionError::NonceNotConsistent => Self::NonceTooLow, InvalidTransactionError::NonceNotConsistent { tx, state } => {
Self::NonceTooLow { tx, state }
}
InvalidTransactionError::OldLegacyChainId => { InvalidTransactionError::OldLegacyChainId => {
// Note: this should be unreachable since Spurious Dragon now enabled // Note: this should be unreachable since Spurious Dragon now enabled
Self::OldLegacyChainId Self::OldLegacyChainId

View File

@ -225,7 +225,7 @@ impl InvalidPoolTransactionError {
// intentionally caused by the sender // intentionally caused by the sender
match err { match err {
InvalidTransactionError::InsufficientFunds { .. } | InvalidTransactionError::InsufficientFunds { .. } |
InvalidTransactionError::NonceNotConsistent => { InvalidTransactionError::NonceNotConsistent { .. } => {
// transaction could just have arrived late/early // transaction could just have arrived late/early
false false
} }
@ -294,7 +294,7 @@ impl InvalidPoolTransactionError {
/// Returns `true` if an import failed due to nonce gap. /// Returns `true` if an import failed due to nonce gap.
pub const fn is_nonce_gap(&self) -> bool { pub const fn is_nonce_gap(&self) -> bool {
matches!(self, Self::Consensus(InvalidTransactionError::NonceNotConsistent)) || matches!(self, Self::Consensus(InvalidTransactionError::NonceNotConsistent { .. })) ||
matches!(self, Self::Eip4844(Eip4844PoolTransactionError::Eip4844NonceGap)) matches!(self, Self::Eip4844(Eip4844PoolTransactionError::Eip4844NonceGap))
} }
} }

View File

@ -359,11 +359,14 @@ where
} }
} }
let tx_nonce = transaction.nonce();
// Checks for nonce // Checks for nonce
if transaction.nonce() < account.nonce { if tx_nonce < account.nonce {
return TransactionValidationOutcome::Invalid( return TransactionValidationOutcome::Invalid(
transaction, transaction,
InvalidTransactionError::NonceNotConsistent.into(), InvalidTransactionError::NonceNotConsistent { tx: tx_nonce, state: account.nonce }
.into(),
) )
} }