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");
// 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 <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/94697be8a3f0dfcd95dfb13ffbd39b5973f5c65d/contracts/metatx/ERC2771Forwarder.sol#L360-L367>
// increase the lowest gas limit
lowest_gas_limit = mid_gas_limit;
}