diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index 566eff7a58..0e3253d3c1 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -254,14 +254,14 @@ fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps { } } -fn fn_gen_error_state_associated_ops(error: &ExecError) -> FnGenAssociatedOps { +fn fn_gen_error_state_associated_ops(error: &ExecError) -> Option { match error { - ExecError::InvalidJump => ErrorInvalidJump::gen_associated_ops, - ExecError::OutOfGas(OogError::Call) => OOGCall::gen_associated_ops, + ExecError::InvalidJump => Some(ErrorInvalidJump::gen_associated_ops), + ExecError::OutOfGas(OogError::Call) => Some(OOGCall::gen_associated_ops), // more future errors place here _ => { - warn!("Using dummy gen_associated_ops for error state {:?}", error); - Dummy::gen_associated_ops + warn!("TODO: error state {:?} not implemented", error); + None } } } @@ -303,21 +303,23 @@ pub fn gen_associated_ops( exec_step.error = Some(exec_error.clone()); // TODO: after more error state handled, refactor all error handling in // fn_gen_error_state_associated_ops method - if exec_step.oog_or_stack_error() && !geth_step.op.is_call_or_create() { - state.gen_restore_context_ops(&mut exec_step, geth_steps)?; + // For exceptions that have been implemented + if let Some(fn_gen_error_ops) = fn_gen_error_state_associated_ops(&exec_error) { + return fn_gen_error_ops(state, geth_steps); } else { + // For exceptions that already enter next call context, but fail immediately + // (e.g. Depth, InsufficientBalance), we still need to parse the call. if geth_step.op.is_call_or_create() && !exec_step.oog_or_stack_error() { let call = state.parse_call(geth_step)?; - // Switch to callee's call context state.push_call(call); + // For exceptions that fail to enter next call context, we need + // to restore call context of current caller } else { - let fn_gen_error_associated_ops = fn_gen_error_state_associated_ops(&exec_error); - return fn_gen_error_associated_ops(state, geth_steps); + state.gen_restore_context_ops(&mut exec_step, geth_steps)?; } + state.handle_return(geth_step)?; + return Ok(vec![exec_step]); } - - state.handle_return(geth_step)?; - return Ok(vec![exec_step]); } // if no errors, continue as normal fn_gen_associated_ops(state, geth_steps)