From 4dfcd4e6cb794aa3686238e1048ebae565f06b70 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 31 Oct 2023 22:10:17 +0100 Subject: [PATCH] fix: treat invalid opcode as out-of-gas in estimate loop (#5256) --- crates/rpc/rpc/src/eth/api/call.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/rpc/rpc/src/eth/api/call.rs b/crates/rpc/rpc/src/eth/api/call.rs index f0a761d67..94fcbed21 100644 --- a/crates/rpc/rpc/src/eth/api/call.rs +++ b/crates/rpc/rpc/src/eth/api/call.rs @@ -235,7 +235,7 @@ where 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()); // Exceptional case: init used too much gas, we need to increase the gas limit and try @@ -255,6 +255,8 @@ where // succeeded } 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()) } ExecutionResult::Revert { output, .. } => { @@ -317,7 +319,11 @@ where } ExecutionResult::Halt { 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 + // increase the lowest gas limit lowest_gas_limit = mid_gas_limit; }