diff --git a/crates/handler/src/execution.rs b/crates/handler/src/execution.rs index aecda06d20..e79f9d4b4c 100644 --- a/crates/handler/src/execution.rs +++ b/crates/handler/src/execution.rs @@ -17,14 +17,13 @@ pub fn create_init_frame( match tx.kind() { TxKind::Call(target_address) => { - let (bytecode, bytecode_hash) = bytecode.unwrap_or_default(); + let known_bytecode = bytecode.map(|(code, hash)| (hash, code)); FrameInput::Call(Box::new(CallInputs { input: CallInput::Bytes(input), gas_limit, target_address, bytecode_address: target_address, - bytecode, - bytecode_hash, + known_bytecode, caller: tx.caller(), value: CallValue::Transfer(tx.value()), scheme: CallScheme::Call, diff --git a/crates/handler/src/frame.rs b/crates/handler/src/frame.rs index df97956023..ed71b69038 100644 --- a/crates/handler/src/frame.rs +++ b/crates/handler/src/frame.rs @@ -201,8 +201,20 @@ impl EthFrame { }))); } - let bytecode = inputs.bytecode.clone(); - let bytecode_hash = inputs.bytecode_hash; + // Get bytecode and hash - either from known_bytecode or load from account + let (bytecode, bytecode_hash) = if let Some((hash, code)) = inputs.known_bytecode.clone() { + // Use provided bytecode and hash + (code, hash) + } else { + // Load account and get its bytecode + let account = ctx + .journal_mut() + .load_account_code(inputs.bytecode_address)?; + ( + account.info.code.clone().unwrap_or_default(), + account.info.code_hash, + ) + }; // Returns success if bytecode is empty. if bytecode.is_empty() { diff --git a/crates/interpreter/src/instructions/contract.rs b/crates/interpreter/src/instructions/contract.rs index e3137ff04b..22a36f6629 100644 --- a/crates/interpreter/src/instructions/contract.rs +++ b/crates/interpreter/src/instructions/contract.rs @@ -144,8 +144,7 @@ pub fn call( target_address: to, caller: context.interpreter.input.target_address(), bytecode_address: to, - bytecode, - bytecode_hash, + known_bytecode: Some((bytecode_hash, bytecode)), value: CallValue::Transfer(value), scheme: CallScheme::Call, is_static: context.interpreter.runtime_flag.is_static(), @@ -188,8 +187,7 @@ pub fn call_code( target_address: context.interpreter.input.target_address(), caller: context.interpreter.input.target_address(), bytecode_address: to, - bytecode, - bytecode_hash, + known_bytecode: Some((bytecode_hash, bytecode)), value: CallValue::Transfer(value), scheme: CallScheme::CallCode, is_static: context.interpreter.runtime_flag.is_static(), @@ -232,8 +230,7 @@ pub fn delegate_call( target_address: context.interpreter.input.target_address(), caller: context.interpreter.input.caller_address(), bytecode_address: to, - bytecode, - bytecode_hash, + known_bytecode: Some((bytecode_hash, bytecode)), value: CallValue::Apparent(context.interpreter.input.call_value()), scheme: CallScheme::DelegateCall, is_static: context.interpreter.runtime_flag.is_static(), @@ -276,8 +273,7 @@ pub fn static_call( target_address: to, caller: context.interpreter.input.target_address(), bytecode_address: to, - bytecode, - bytecode_hash, + known_bytecode: Some((bytecode_hash, bytecode)), value: CallValue::Transfer(U256::ZERO), scheme: CallScheme::StaticCall, is_static: true, diff --git a/crates/interpreter/src/interpreter_action/call_inputs.rs b/crates/interpreter/src/interpreter_action/call_inputs.rs index 581bc15c95..e7224607cf 100644 --- a/crates/interpreter/src/interpreter_action/call_inputs.rs +++ b/crates/interpreter/src/interpreter_action/call_inputs.rs @@ -79,10 +79,10 @@ pub struct CallInputs { /// /// Previously `context.code_address`. pub bytecode_address: Address, - /// Bytecode that is going to be executed. - pub bytecode: Bytecode, - /// Bytecode hash, - pub bytecode_hash: B256, + /// Known bytecode and its hash. + /// If None, bytecode will be loaded from the account at `bytecode_address`. + /// If Some((hash, bytecode)), the provided bytecode and hash will be used. + pub known_bytecode: Option<(B256, Bytecode)>, /// Target address, this account storage is going to be modified. /// /// Previously `context.address`.