From 932f85077e91cfb5a6c11f6ace74678636ea05f8 Mon Sep 17 00:00:00 2001 From: lightsing Date: Mon, 8 Jul 2024 15:30:41 +0800 Subject: [PATCH 1/2] defer bytecode load --- crates/revm/src/context/evm_context.rs | 62 ++++++++++++++------------ 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index d7b1e556fc..560f407fab 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -166,21 +166,6 @@ impl EvmContext { return return_result(InstructionResult::CallTooDeep); } - let (account, _) = self - .inner - .journaled_state - .load_code(inputs.bytecode_address, &mut self.inner.db)?; - - let code_hash = account.info.code_hash(); - let bytecode = account.info.code.clone().unwrap_or_default(); - - // ExtDelegateCall is not allowed to call non-EOF contracts. - if inputs.scheme.is_ext_delegate_call() - && bytecode.bytes_slice().get(..2) != Some(&EOF_MAGIC_BYTES) - { - return return_result(InstructionResult::InvalidExtDelegateCallTarget); - } - // Create subroutine checkpoint let checkpoint = self.journaled_state.checkpoint(); @@ -216,18 +201,39 @@ impl EvmContext { result, inputs.return_memory_offset.clone(), )) - } else if !bytecode.is_empty() { - let contract = - Contract::new_with_context(inputs.input.clone(), bytecode, Some(code_hash), inputs); - // Create interpreter and executes call and push new CallStackFrame. - Ok(FrameOrResult::new_call_frame( - inputs.return_memory_offset.clone(), - checkpoint, - Interpreter::new(contract, gas.limit(), inputs.is_static), - )) } else { - self.journaled_state.checkpoint_commit(); - return_result(InstructionResult::Stop) + let (account, _) = self + .inner + .journaled_state + .load_code(inputs.bytecode_address, &mut self.inner.db)?; + + let code_hash = account.info.code_hash(); + let bytecode = account.info.code.clone().unwrap_or_default(); + + // ExtDelegateCall is not allowed to call non-EOF contracts. + if inputs.scheme.is_ext_delegate_call() + && bytecode.bytes_slice().get(..2) != Some(&EOF_MAGIC_BYTES) + { + return return_result(InstructionResult::InvalidExtDelegateCallTarget); + } + + if !bytecode.is_empty() { + let contract = Contract::new_with_context( + inputs.input.clone(), + bytecode, + Some(code_hash), + inputs, + ); + // Create interpreter and executes call and push new CallStackFrame. + Ok(FrameOrResult::new_call_frame( + inputs.return_memory_offset.clone(), + checkpoint, + Interpreter::new(contract, gas.limit(), inputs.is_static), + )) + } else { + self.journaled_state.checkpoint_commit(); + return_result(InstructionResult::Stop) + } } } } @@ -323,7 +329,7 @@ mod tests { use crate::{ db::{CacheDB, EmptyDB}, primitives::{address, Bytecode}, - Frame, JournalEntry, + Frame, }; use std::boxed::Box; use test_utils::*; @@ -367,7 +373,7 @@ mod tests { result.interpreter_result().result, InstructionResult::OutOfFunds ); - let checkpointed = vec![vec![JournalEntry::AccountWarmed { address: contract }]]; + let checkpointed = vec![vec![]]; assert_eq!(evm_context.journaled_state.journal, checkpointed); assert_eq!(evm_context.journaled_state.depth, 0); } From 58eceade8c945d83899df23458035dfbd6faf509 Mon Sep 17 00:00:00 2001 From: lightsing Date: Tue, 9 Jul 2024 10:05:57 +0800 Subject: [PATCH 2/2] apply review --- crates/revm/src/context/evm_context.rs | 36 ++++++++++++++------------ 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index 560f407fab..543a8ab125 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -166,6 +166,12 @@ impl EvmContext { return return_result(InstructionResult::CallTooDeep); } + // Make account warm and loaded + let _ = self + .inner + .journaled_state + .load_account(inputs.bytecode_address, &mut self.inner.db)?; + // Create subroutine checkpoint let checkpoint = self.journaled_state.checkpoint(); @@ -217,23 +223,19 @@ impl EvmContext { return return_result(InstructionResult::InvalidExtDelegateCallTarget); } - if !bytecode.is_empty() { - let contract = Contract::new_with_context( - inputs.input.clone(), - bytecode, - Some(code_hash), - inputs, - ); - // Create interpreter and executes call and push new CallStackFrame. - Ok(FrameOrResult::new_call_frame( - inputs.return_memory_offset.clone(), - checkpoint, - Interpreter::new(contract, gas.limit(), inputs.is_static), - )) - } else { + if bytecode.is_empty() { self.journaled_state.checkpoint_commit(); - return_result(InstructionResult::Stop) + return return_result(InstructionResult::Stop); } + + let contract = + Contract::new_with_context(inputs.input.clone(), bytecode, Some(code_hash), inputs); + // Create interpreter and executes call and push new CallStackFrame. + Ok(FrameOrResult::new_call_frame( + inputs.return_memory_offset.clone(), + checkpoint, + Interpreter::new(contract, gas.limit(), inputs.is_static), + )) } } } @@ -329,7 +331,7 @@ mod tests { use crate::{ db::{CacheDB, EmptyDB}, primitives::{address, Bytecode}, - Frame, + Frame, JournalEntry, }; use std::boxed::Box; use test_utils::*; @@ -373,7 +375,7 @@ mod tests { result.interpreter_result().result, InstructionResult::OutOfFunds ); - let checkpointed = vec![vec![]]; + let checkpointed = vec![vec![JournalEntry::AccountWarmed { address: contract }]]; assert_eq!(evm_context.journaled_state.journal, checkpointed); assert_eq!(evm_context.journaled_state.depth, 0); }