Improve revm halt out of gas error handling (#1725)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
GianfrancoBazzani
2023-03-15 11:49:58 +01:00
committed by GitHub
parent 15d79cedad
commit 43e3621115
2 changed files with 29 additions and 4 deletions

View File

@ -168,7 +168,9 @@ where
}
ExecutionResult::Halt { reason, .. } => {
return match reason {
Halt::OutOfGas(_) => Err(InvalidTransactionError::OutOfGas(gas_limit).into()),
Halt::OutOfGas(err) => {
Err(InvalidTransactionError::out_of_gas(err, gas_limit).into())
}
Halt::NonceOverflow => Err(InvalidTransactionError::NonceMaxValue.into()),
err => Err(InvalidTransactionError::EvmHalt(err).into()),
}
@ -184,7 +186,8 @@ where
ExecutionResult::Success { .. } => {
// transaction succeeded by manually increasing the gas limit to
// highest, which means the caller lacks funds to pay for the tx
Err(InvalidTransactionError::OutOfGas(U256::from(req_gas_limit)).into())
Err(InvalidTransactionError::BasicOutOfGas(U256::from(req_gas_limit))
.into())
}
ExecutionResult::Revert { .. } => {
// reverted again after bumping the limit

View File

@ -5,7 +5,7 @@ use jsonrpsee::{core::Error as RpcError, types::error::INVALID_PARAMS_CODE};
use reth_primitives::{constants::SELECTOR_LEN, Address, U128, U256};
use reth_rpc_types::{error::EthRpcErrorCode, BlockError};
use reth_transaction_pool::error::{InvalidPoolTransactionError, PoolError};
use revm::primitives::{EVMError, Halt};
use revm::primitives::{EVMError, Halt, OutOfGasError};
/// Result alias
pub type EthResult<T> = Result<T, EthApiError>;
@ -158,7 +158,16 @@ pub enum InvalidTransactionError {
SenderNoEOA,
/// Thrown during estimate if caller has insufficient funds to cover the tx.
#[error("Out of gas: gas required exceeds allowance: {0:?}")]
OutOfGas(U256),
BasicOutOfGas(U256),
/// As BasicOutOfGas but thrown when gas exhausts during memory expansion.
#[error("Out of gas: gas exhausts during memory expansion: {0:?}")]
MemoryOutOfGas(U256),
/// As BasicOutOfGas but thrown when gas exhausts during precompiled contract execution.
#[error("Out of gas: gas exhausts during precompiled contract execution: {0:?}")]
PrecompileOutOfGas(U256),
/// revm's Type cast error, U256 casts down to a u64 with overflow
#[error("Out of gas: revm's Type cast error, U256 casts down to a u64 with overflow {0:?}")]
InvalidOperandOutOfGas(U256),
/// Thrown if executing a transaction failed during estimate/call
#[error("{0}")]
Revert(RevertError),
@ -181,6 +190,19 @@ impl InvalidTransactionError {
_ => EthRpcErrorCode::TransactionRejected.code(),
}
}
/// Converts the out of gas error
pub(crate) fn out_of_gas(reason: OutOfGasError, gas_limit: U256) -> Self {
match reason {
OutOfGasError::BasicOutOfGas => InvalidTransactionError::BasicOutOfGas(gas_limit),
OutOfGasError::Memory => InvalidTransactionError::MemoryOutOfGas(gas_limit),
OutOfGasError::Precompile => InvalidTransactionError::PrecompileOutOfGas(gas_limit),
OutOfGasError::InvalidOperand => {
InvalidTransactionError::InvalidOperandOutOfGas(gas_limit)
}
OutOfGasError::MemoryLimit => InvalidTransactionError::MemoryOutOfGas(gas_limit),
}
}
}
impl From<InvalidTransactionError> for RpcError {