fix: treat invalid opcode as out-of-gas in estimate loop (#5256)

This commit is contained in:
Matthias Seitz
2023-10-31 22:10:17 +01:00
committed by GitHub
parent 9bac558ef4
commit 4dfcd4e6cb

View File

@ -235,7 +235,7 @@ where
trace!(target: "rpc::eth::estimate", ?env, "Starting gas estimation"); trace!(target: "rpc::eth::estimate", ?env, "Starting gas estimation");
// execute the call without writing to db // transact with the highest __possible__ gas limit
let ethres = transact(&mut db, env.clone()); let ethres = transact(&mut db, env.clone());
// Exceptional case: init used too much gas, we need to increase the gas limit and try // Exceptional case: init used too much gas, we need to increase the gas limit and try
@ -255,6 +255,8 @@ where
// succeeded // succeeded
} }
ExecutionResult::Halt { reason, gas_used } => { ExecutionResult::Halt { reason, gas_used } => {
// here we don't check for invalid opcode because already executed with highest gas
// limit
return Err(RpcInvalidTransactionError::halt(reason, gas_used).into()) return Err(RpcInvalidTransactionError::halt(reason, gas_used).into())
} }
ExecutionResult::Revert { output, .. } => { ExecutionResult::Revert { output, .. } => {
@ -317,7 +319,11 @@ where
} }
ExecutionResult::Halt { reason, .. } => { ExecutionResult::Halt { reason, .. } => {
match reason { match reason {
Halt::OutOfGas(_) => { Halt::OutOfGas(_) | Halt::InvalidFEOpcode => {
// either out of gas or invalid opcode can be thrown dynamically if
// gasLeft is too low, so we treat this as `out of gas`, we know this
// call succeeds with a higher gaslimit. common usage of invalid opcode in openzeppelin <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/94697be8a3f0dfcd95dfb13ffbd39b5973f5c65d/contracts/metatx/ERC2771Forwarder.sol#L360-L367>
// increase the lowest gas limit // increase the lowest gas limit
lowest_gas_limit = mid_gas_limit; lowest_gas_limit = mid_gas_limit;
} }