From 2f78eb98fbf125c1adf9972ed21b2aa7b4968232 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 16 Oct 2023 10:40:18 +0200 Subject: [PATCH] feat(interpreter): add more helper methods to memory (#794) * feat(interpreter): add more helper methods to memory * chore: reduce usage of `#[inline(always)]` * docs --- bins/revme/src/statetest/merkle_trie.rs | 1 - crates/interpreter/src/instructions/i256.rs | 16 +- crates/interpreter/src/instructions/memory.rs | 11 +- crates/interpreter/src/interpreter.rs | 3 +- .../src/interpreter/shared_memory.rs | 221 ++++++++++++------ crates/interpreter/src/interpreter/stack.rs | 26 +-- crates/precompile/src/kzg_point_evaluation.rs | 6 +- crates/primitives/build.rs | 2 - crates/primitives/src/specification.rs | 4 +- crates/revm/src/evm_impl.rs | 2 +- crates/revm/src/journaled_state.rs | 20 +- 11 files changed, 186 insertions(+), 126 deletions(-) diff --git a/bins/revme/src/statetest/merkle_trie.rs b/bins/revme/src/statetest/merkle_trie.rs index 1a8b3ec2b2..c869938bf0 100644 --- a/bins/revme/src/statetest/merkle_trie.rs +++ b/bins/revme/src/statetest/merkle_trie.rs @@ -33,7 +33,6 @@ struct TrieAccount { } impl TrieAccount { - #[inline(always)] fn new(acc: &PlainAccount) -> Self { Self { nonce: acc.info.nonce, diff --git a/crates/interpreter/src/instructions/i256.rs b/crates/interpreter/src/instructions/i256.rs index 6f217b9911..5a5112bf9e 100644 --- a/crates/interpreter/src/instructions/i256.rs +++ b/crates/interpreter/src/instructions/i256.rs @@ -20,7 +20,7 @@ const MIN_NEGATIVE_VALUE: U256 = U256::from_limbs([ const FLIPH_BITMASK_U64: u64 = 0x7FFFFFFFFFFFFFFF; -#[inline(always)] +#[inline] pub fn i256_sign(val: &U256) -> Sign { if val.bit(U256::BITS - 1) { Sign::Minus @@ -30,7 +30,7 @@ pub fn i256_sign(val: &U256) -> Sign { } } -#[inline(always)] +#[inline] pub fn i256_sign_compl(val: &mut U256) -> Sign { let sign = i256_sign(val); if sign == Sign::Minus { @@ -39,7 +39,7 @@ pub fn i256_sign_compl(val: &mut U256) -> Sign { sign } -#[inline(always)] +#[inline] fn u256_remove_sign(val: &mut U256) { // SAFETY: U256 does not have any padding bytes unsafe { @@ -47,17 +47,17 @@ fn u256_remove_sign(val: &mut U256) { } } -#[inline(always)] +#[inline] pub fn two_compl_mut(op: &mut U256) { *op = two_compl(*op); } -#[inline(always)] +#[inline] pub fn two_compl(op: U256) -> U256 { op.wrapping_neg() } -#[inline(always)] +#[inline] pub fn i256_cmp(first: &U256, second: &U256) -> Ordering { let first_sign = i256_sign(first); let second_sign = i256_sign(second); @@ -69,7 +69,7 @@ pub fn i256_cmp(first: &U256, second: &U256) -> Ordering { } } -#[inline(always)] +#[inline] pub fn i256_div(mut first: U256, mut second: U256) -> U256 { let second_sign = i256_sign_compl(&mut second); if second_sign == Sign::Zero { @@ -98,7 +98,7 @@ pub fn i256_div(mut first: U256, mut second: U256) -> U256 { } } -#[inline(always)] +#[inline] pub fn i256_mod(mut first: U256, mut second: U256) -> U256 { let first_sign = i256_sign_compl(&mut first); if first_sign == Sign::Zero { diff --git a/crates/interpreter/src/instructions/memory.rs b/crates/interpreter/src/instructions/memory.rs index 8fb321855c..faa9924416 100644 --- a/crates/interpreter/src/instructions/memory.rs +++ b/crates/interpreter/src/instructions/memory.rs @@ -10,16 +10,7 @@ pub fn mload(interpreter: &mut Interpreter<'_>, _host: &mut H) { pop!(interpreter, index); let index = as_usize_or_fail!(interpreter, index); shared_memory_resize!(interpreter, index, 32); - push!( - interpreter, - U256::from_be_bytes::<32>( - interpreter - .shared_memory - .slice(index, 32) - .try_into() - .unwrap() - ) - ); + push!(interpreter, interpreter.shared_memory.get_u256(index)); } pub fn mstore(interpreter: &mut Interpreter<'_>, _host: &mut H) { diff --git a/crates/interpreter/src/interpreter.rs b/crates/interpreter/src/interpreter.rs index 2b661c9902..e4ce89f7ad 100644 --- a/crates/interpreter/src/interpreter.rs +++ b/crates/interpreter/src/interpreter.rs @@ -96,7 +96,8 @@ impl<'a> Interpreter<'a> { /// Returns the current program counter. #[inline] pub fn program_counter(&self) -> usize { - // Safety: this is just subtraction of pointers, it is safe to do. + // SAFETY: `instruction_pointer` should be at an offset from the start of the bytecode. + // In practice this is always true unless a caller modifies the `instruction_pointer` field manually. unsafe { self.instruction_pointer .offset_from(self.contract.bytecode.as_ptr()) as usize diff --git a/crates/interpreter/src/interpreter/shared_memory.rs b/crates/interpreter/src/interpreter/shared_memory.rs index 94ba4221e7..411040b6b4 100644 --- a/crates/interpreter/src/interpreter/shared_memory.rs +++ b/crates/interpreter/src/interpreter/shared_memory.rs @@ -1,4 +1,4 @@ -use revm_primitives::U256; +use revm_primitives::{B256, U256}; use crate::alloc::vec::Vec; use core::{ @@ -14,23 +14,52 @@ use core::{ #[derive(Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SharedMemory { - /// Shared buffer + /// The underlying buffer. data: Vec, - /// Memory checkpoints for each depth + /// Memory checkpoints for each depth. + /// Invariant: these are always in bounds of `data`. checkpoints: Vec, - /// How much memory has been used in the current context + /// How much memory has been used in the current context. + /// Invariant: `checkpoints.last() + current_len <= data.len()` current_len: usize, /// Memory limit. See [`crate::CfgEnv`]. #[cfg(feature = "memory_limit")] memory_limit: u64, } +impl fmt::Debug for SharedMemory { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SharedMemory") + .field("current_len", &self.current_len) + .field( + "context_memory", + &crate::primitives::hex::encode(self.context_memory()), + ) + .finish_non_exhaustive() + } +} + +impl Default for SharedMemory { + #[inline] + fn default() -> Self { + Self::new() + } +} + impl SharedMemory { - /// Allocate memory to be shared between calls. - /// Initial capacity is 4KiB which is expanded if needed + /// Creates a new memory instance that can be shared between calls. + /// + /// The default initial capacity is 4KiB. + #[inline] pub fn new() -> Self { + Self::with_capacity(4 * 1024) // from evmone + } + + /// Creates a new memory instance that can be shared between calls with the given `capacity`. + #[inline] + pub fn with_capacity(capacity: usize) -> Self { Self { - data: Vec::with_capacity(4 * 1024), // from evmone + data: Vec::with_capacity(capacity), checkpoints: Vec::with_capacity(32), current_len: 0, #[cfg(feature = "memory_limit")] @@ -38,10 +67,12 @@ impl SharedMemory { } } - /// Allocate memory to be shared between calls, with `memory_limit` - /// as upper bound for allocation size. - /// Initial capacity is 4KiB which is expanded if needed + /// Creates a new memory instance that can be shared between calls, + /// with `memory_limit` as upper bound for allocation size. + /// + /// The default initial capacity is 4KiB. #[cfg(feature = "memory_limit")] + #[inline] pub fn new_with_memory_limit(memory_limit: u64) -> Self { Self { memory_limit, @@ -49,14 +80,16 @@ impl SharedMemory { } } - /// Returns true if the `new_size` for the current context memory will - /// make the shared buffer length exceed the `memory_limit` + /// Returns `true` if the `new_size` for the current context memory will + /// make the shared buffer length exceed the `memory_limit`. #[cfg(feature = "memory_limit")] + #[inline] pub fn limit_reached(&self, new_size: usize) -> bool { (self.last_checkpoint() + new_size) as u64 > self.memory_limit } - /// Prepares the shared memory for a new context + /// Prepares the shared memory for a new context. + #[inline] pub fn new_context_memory(&mut self) { let base_offset = self.last_checkpoint(); let new_checkpoint = base_offset + self.current_len; @@ -65,7 +98,8 @@ impl SharedMemory { self.current_len = 0; } - /// Prepares the shared memory for returning to the previous context + /// Prepares the shared memory for returning to the previous context. + #[inline] pub fn free_context_memory(&mut self) { if let Some(old_checkpoint) = self.checkpoints.pop() { let last_checkpoint = self.last_checkpoint(); @@ -73,41 +107,39 @@ impl SharedMemory { } } - /// Get the length of the current memory range. - #[inline(always)] + /// Returns the length of the current memory range. + #[inline] pub fn len(&self) -> usize { self.current_len } - /// Returns true if the current memory range is empty. - #[inline(always)] + /// Returns `true` if the current memory range is empty. + #[inline] pub fn is_empty(&self) -> bool { self.current_len == 0 } - /// Resize the memory. assume that we already checked if: - /// - we have enough gas to resize this vector - /// - we made new_size as multiply of 32 - /// - [new_size] is greater than `self.len()` - #[inline(always)] - pub fn resize(&mut self, new_size: usize) { + /// Resizes the memory in-place so that `len` is equal to `new_len`. + #[inline] + pub fn resize(&mut self, new_len: usize) { let last_checkpoint = self.last_checkpoint(); - let range = last_checkpoint + self.current_len..last_checkpoint + new_size; + let range = last_checkpoint + self.current_len..last_checkpoint + new_len; if let Some(available_memory) = self.data.get_mut(range) { available_memory.fill(0); } else { - self.data - .resize(last_checkpoint + usize::max(new_size, 4 * 1024), 0); + self.data.resize(last_checkpoint + new_len, 0); } - self.current_len = new_size; + self.current_len = new_len; } /// Returns a byte slice of the memory region at the given offset. /// + /// # Panics + /// /// Panics on out of bounds. - #[inline(always)] + #[inline] #[cfg_attr(debug_assertions, track_caller)] pub fn slice(&self, offset: usize, size: usize) -> &[u8] { let end = offset + size; @@ -115,7 +147,7 @@ impl SharedMemory { match self .data - .get(last_checkpoint + offset..last_checkpoint + offset + size) + .get(last_checkpoint + offset..last_checkpoint + end) { Some(slice) => slice, None => debug_unreachable!("slice OOB: {offset}..{end}; len: {}", self.len()), @@ -124,8 +156,10 @@ impl SharedMemory { /// Returns a byte slice of the memory region at the given offset. /// + /// # Panics + /// /// Panics on out of bounds. - #[inline(always)] + #[inline] #[cfg_attr(debug_assertions, track_caller)] pub fn slice_mut(&mut self, offset: usize, size: usize) -> &mut [u8] { let len = self.len(); @@ -134,30 +168,71 @@ impl SharedMemory { match self .data - .get_mut(last_checkpoint + offset..last_checkpoint + offset + size) + .get_mut(last_checkpoint + offset..last_checkpoint + end) { Some(slice) => slice, - None => debug_unreachable!("slice OOB: {offset}..{end}; len: {}", len), + None => debug_unreachable!("slice OOB: {offset}..{end}; len: {len}"), } } + /// Returns the byte at the given offset. + /// + /// # Panics + /// + /// Panics on out of bounds. + #[inline] + pub fn get_byte(&self, offset: usize) -> u8 { + self.slice(offset, 1)[0] + } + + /// Returns a 32-byte slice of the memory region at the given offset. + /// + /// # Panics + /// + /// Panics on out of bounds. + #[inline] + pub fn get_word(&self, offset: usize) -> B256 { + self.slice(offset, 32).try_into().unwrap() + } + + /// Returns a U256 of the memory region at the given offset. + /// + /// # Panics + /// + /// Panics on out of bounds. + #[inline] + pub fn get_u256(&self, offset: usize) -> U256 { + self.get_word(offset).into() + } + /// Sets the `byte` at the given `index`. /// - /// Panics when `index` is out of bounds. - #[inline(always)] + /// # Panics + /// + /// Panics on out of bounds. + #[inline] #[cfg_attr(debug_assertions, track_caller)] - pub fn set_byte(&mut self, index: usize, byte: u8) { - let last_checkpoint = self.last_checkpoint(); - match self.data.get_mut(last_checkpoint + index) { - Some(b) => *b = byte, - None => debug_unreachable!("set_byte OOB: {index}; len: {}", self.len()), - } + pub fn set_byte(&mut self, offset: usize, byte: u8) { + self.set(offset, &[byte]); } - /// Sets the given `value` to the memory region at the given `offset`. + /// Sets the given 32-byte `value` to the memory region at the given `offset`. + /// + /// # Panics /// /// Panics on out of bounds. - #[inline(always)] + #[inline] + #[cfg_attr(debug_assertions, track_caller)] + pub fn set_word(&mut self, offset: usize, value: &B256) { + self.set(offset, &value[..]); + } + + /// Sets the given U256 `value` to the memory region at the given `offset`. + /// + /// # Panics + /// + /// Panics on out of bounds. + #[inline] #[cfg_attr(debug_assertions, track_caller)] pub fn set_u256(&mut self, offset: usize, value: U256) { self.set(offset, &value.to_be_bytes::<32>()); @@ -165,8 +240,10 @@ impl SharedMemory { /// Set memory region at given `offset`. /// + /// # Panics + /// /// Panics on out of bounds. - #[inline(always)] + #[inline] #[cfg_attr(debug_assertions, track_caller)] pub fn set(&mut self, offset: usize, value: &[u8]) { if !value.is_empty() { @@ -177,8 +254,10 @@ impl SharedMemory { /// Set memory from data. Our memory offset+len is expected to be correct but we /// are doing bound checks on data/data_offeset/len and zeroing parts that is not copied. /// + /// # Panics + /// /// Panics on out of bounds. - #[inline(always)] + #[inline] #[cfg_attr(debug_assertions, track_caller)] pub fn set_data(&mut self, memory_offset: usize, data_offset: usize, len: usize, data: &[u8]) { if data_offset >= data.len() { @@ -201,53 +280,45 @@ impl SharedMemory { /// Copies elements from one part of the memory to another part of itself. /// + /// # Panics + /// /// Panics on out of bounds. - #[inline(always)] + #[inline] #[cfg_attr(debug_assertions, track_caller)] pub fn copy(&mut self, dst: usize, src: usize, len: usize) { self.context_memory_mut().copy_within(src..src + len, dst); } - /// Get a reference to the memory of the current context - #[inline(always)] + /// Returns a reference to the memory of the current context. + #[inline] fn context_memory(&self) -> &[u8] { let last_checkpoint = self.last_checkpoint(); let current_len = self.current_len; - // Safety: it is a valid pointer to a slice of `self.data` - &self.data[last_checkpoint..last_checkpoint + current_len] + debug_assert!(last_checkpoint + current_len <= self.data.len()); + // SAFETY: `last_checkpoint` and `current_len` are always in bounds of `self.data` + unsafe { + self.data + .get_unchecked(last_checkpoint..last_checkpoint + current_len) + } } - /// Get a mutable reference to the memory of the current context - #[inline(always)] + /// Returns a mutable reference to the memory of the current context. + #[inline] fn context_memory_mut(&mut self) -> &mut [u8] { let last_checkpoint = self.last_checkpoint(); let current_len = self.current_len; - // Safety: it is a valid pointer to a slice of `self.data` - &mut self.data[last_checkpoint..last_checkpoint + current_len] + debug_assert!(last_checkpoint + current_len <= self.data.len()); + // SAFETY: `last_checkpoint` and `current_len` are always in bounds of `self.data` + unsafe { + self.data + .get_unchecked_mut(last_checkpoint..last_checkpoint + current_len) + } } - /// Get the last memory checkpoint - #[inline(always)] + /// Returns the last memory checkpoint. This is always in bounds of the memory. + #[inline] fn last_checkpoint(&self) -> usize { - self.checkpoints.last().cloned().unwrap_or_default() - } -} - -impl fmt::Debug for SharedMemory { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SharedMemory") - .field("current_len", &self.current_len) - .field( - "context_memory", - &crate::primitives::hex::encode(self.context_memory()), - ) - .finish_non_exhaustive() - } -} - -impl Default for SharedMemory { - fn default() -> Self { - Self::new() + self.checkpoints.last().copied().unwrap_or(0) } } diff --git a/crates/interpreter/src/interpreter/stack.rs b/crates/interpreter/src/interpreter/stack.rs index 8848181f00..dc8c782843 100644 --- a/crates/interpreter/src/interpreter/stack.rs +++ b/crates/interpreter/src/interpreter/stack.rs @@ -75,7 +75,7 @@ impl Stack { /// # Safety /// /// The caller is responsible for checking the length of the stack. - #[inline(always)] + #[inline] pub unsafe fn pop_unsafe(&mut self) -> U256 { self.data.pop().unwrap_unchecked() } @@ -85,7 +85,7 @@ impl Stack { /// # Safety /// /// The caller is responsible for checking the length of the stack. - #[inline(always)] + #[inline] pub unsafe fn top_unsafe(&mut self) -> &mut U256 { let len = self.data.len(); self.data.get_unchecked_mut(len - 1) @@ -96,7 +96,7 @@ impl Stack { /// # Safety /// /// The caller is responsible for checking the length of the stack. - #[inline(always)] + #[inline] pub unsafe fn pop_top_unsafe(&mut self) -> (U256, &mut U256) { let pop = self.pop_unsafe(); let top = self.top_unsafe(); @@ -108,7 +108,7 @@ impl Stack { /// # Safety /// /// The caller is responsible for checking the length of the stack. - #[inline(always)] + #[inline] pub unsafe fn pop2_unsafe(&mut self) -> (U256, U256) { let pop1 = self.pop_unsafe(); let pop2 = self.pop_unsafe(); @@ -120,7 +120,7 @@ impl Stack { /// # Safety /// /// The caller is responsible for checking the length of the stack. - #[inline(always)] + #[inline] pub unsafe fn pop2_top_unsafe(&mut self) -> (U256, U256, &mut U256) { let pop1 = self.pop_unsafe(); let pop2 = self.pop_unsafe(); @@ -134,7 +134,7 @@ impl Stack { /// # Safety /// /// The caller is responsible for checking the length of the stack. - #[inline(always)] + #[inline] pub unsafe fn pop3_unsafe(&mut self) -> (U256, U256, U256) { let pop1 = self.pop_unsafe(); let pop2 = self.pop_unsafe(); @@ -148,7 +148,7 @@ impl Stack { /// # Safety /// /// The caller is responsible for checking the length of the stack. - #[inline(always)] + #[inline] pub unsafe fn pop4_unsafe(&mut self) -> (U256, U256, U256, U256) { let pop1 = self.pop_unsafe(); let pop2 = self.pop_unsafe(); @@ -160,7 +160,7 @@ impl Stack { /// Push a new value into the stack. If it will exceed the stack limit, /// returns `StackOverflow` error and leaves the stack unchanged. - #[inline(always)] + #[inline] pub fn push_b256(&mut self, value: B256) -> Result<(), InstructionResult> { self.push(value.into()) } @@ -169,7 +169,7 @@ impl Stack { /// /// If it will exceed the stack limit, returns `StackOverflow` error and leaves the stack /// unchanged. - #[inline(always)] + #[inline] pub fn push(&mut self, value: U256) -> Result<(), InstructionResult> { // allows the compiler to optimize out the `Vec::push` capacity check assume!(self.data.capacity() == STACK_LIMIT); @@ -183,7 +183,7 @@ impl Stack { /// Peek a value at given index for the stack, where the top of /// the stack is at index `0`. If the index is too large, /// `StackError::Underflow` is returned. - #[inline(always)] + #[inline] pub fn peek(&self, no_from_top: usize) -> Result { if self.data.len() > no_from_top { Ok(self.data[self.data.len() - no_from_top - 1]) @@ -193,7 +193,7 @@ impl Stack { } /// Duplicates the `N`th value from the top of the stack. - #[inline(always)] + #[inline] pub fn dup(&mut self) -> Result<(), InstructionResult> { let len = self.data.len(); if len < N { @@ -211,7 +211,7 @@ impl Stack { } /// Swaps the topmost value with the `N`th value from the top. - #[inline(always)] + #[inline] pub fn swap(&mut self) -> Result<(), InstructionResult> { let len = self.data.len(); if len <= N { @@ -226,7 +226,7 @@ impl Stack { /// /// If it will exceed the stack limit, returns `StackOverflow` error and leaves the stack /// unchanged. - #[inline(always)] + #[inline] pub fn push_slice(&mut self, slice: &[u8]) -> Result<(), InstructionResult> { let new_len = self.data.len() + 1; if new_len > STACK_LIMIT { diff --git a/crates/precompile/src/kzg_point_evaluation.rs b/crates/precompile/src/kzg_point_evaluation.rs index 579f2333b5..a6674cefde 100644 --- a/crates/precompile/src/kzg_point_evaluation.rs +++ b/crates/precompile/src/kzg_point_evaluation.rs @@ -80,20 +80,20 @@ fn verify_kzg_proof( } } -#[inline(always)] +#[inline] #[track_caller] fn as_array(bytes: &[u8]) -> &[u8; N] { bytes.try_into().expect("slice with incorrect length") } -#[inline(always)] +#[inline] #[track_caller] fn as_bytes32(bytes: &[u8]) -> &Bytes32 { // SAFETY: `#[repr(C)] Bytes32([u8; 32])` unsafe { &*as_array::<32>(bytes).as_ptr().cast() } } -#[inline(always)] +#[inline] #[track_caller] fn as_bytes48(bytes: &[u8]) -> &Bytes48 { // SAFETY: `#[repr(C)] Bytes48([u8; 48])` diff --git a/crates/primitives/build.rs b/crates/primitives/build.rs index 161e3523be..074d73a627 100644 --- a/crates/primitives/build.rs +++ b/crates/primitives/build.rs @@ -94,7 +94,6 @@ pub const G2_POINTS: &G2Points = {{ } /// [`Vec::into_flattened`]. -#[inline] fn into_flattened(vec: Vec<[T; N]>) -> Vec { let (ptr, len, cap) = into_raw_parts(vec); let (new_len, new_cap) = if core::mem::size_of::() == 0 { @@ -122,7 +121,6 @@ fn into_flattened(vec: Vec<[T; N]>) -> Vec { } /// [`Vec::into_raw_parts`] -#[inline(always)] fn into_raw_parts(vec: Vec) -> (*mut T, usize, usize) { let mut me = core::mem::ManuallyDrop::new(vec); (me.as_mut_ptr(), me.len(), me.capacity()) diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 61c2d7f6d7..5c5b6e1a14 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -40,7 +40,7 @@ impl SpecId { Self::n(spec_id) } - #[inline(always)] + #[inline] pub const fn enabled(our: SpecId, other: SpecId) -> bool { #[cfg(feature = "optimism")] { @@ -94,7 +94,7 @@ pub trait Spec: Sized { const SPEC_ID: SpecId; /// Returns `true` if the given specification ID is enabled in this spec. - #[inline(always)] + #[inline] fn enabled(spec_id: SpecId) -> bool { #[cfg(feature = "optimism")] { diff --git a/crates/revm/src/evm_impl.rs b/crates/revm/src/evm_impl.rs index 4a3dd68379..486ecbfe17 100644 --- a/crates/revm/src/evm_impl.rs +++ b/crates/revm/src/evm_impl.rs @@ -830,7 +830,7 @@ impl<'a, GSPEC: Spec + 'static, DB: Database> EVMImpl<'a, GSPEC, DB> { Err(e) => return e, }; - let ret = if is_precompile(inputs.contract, self.data.precompiles.len()) { + let ret = if is_precompile(&inputs.contract, self.data.precompiles.len()) { self.call_precompile(inputs, prepared_call.gas) } else if !prepared_call.contract.bytecode.is_empty() { // Create interpreter and execute subcall diff --git a/crates/revm/src/journaled_state.rs b/crates/revm/src/journaled_state.rs index c55369ca2b..10d6db8226 100644 --- a/crates/revm/src/journaled_state.rs +++ b/crates/revm/src/journaled_state.rs @@ -252,7 +252,7 @@ impl JournaledState { Ok(checkpoint) } - #[inline(always)] + #[inline] pub fn check_account_collision( address: Address, account: &Account, @@ -268,7 +268,7 @@ impl JournaledState { } // Check collision. New account address is precompile. - if is_precompile(address, num_of_precompiles) { + if is_precompile(&address, num_of_precompiles) { return true; } @@ -540,7 +540,7 @@ impl JournaledState { .push(JournalEntry::AccountLoaded { address }); // precompiles are warm loaded so we need to take that into account - let is_cold = !is_precompile(address, self.num_of_precompiles); + let is_cold = !is_precompile(&address, self.num_of_precompiles); (vac.insert(account), is_cold) } @@ -783,8 +783,8 @@ pub struct JournalCheckpoint { /// Check if address is precompile by having assumption /// that precompiles are in range of 1 to N. -#[inline(always)] -pub fn is_precompile(address: Address, num_of_precompiles: usize) -> bool { +#[inline] +pub fn is_precompile(address: &Address, num_of_precompiles: usize) -> bool { if !address[..18].iter().all(|i| *i == 0) { return false; } @@ -800,7 +800,7 @@ mod test { fn test_is_precompile() { assert!( !is_precompile( - Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + &Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 3 ), "Zero is not precompile" @@ -808,7 +808,7 @@ mod test { assert!( !is_precompile( - Address::new([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9]), + &Address::new([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9]), 3 ), "0x100..0 is not precompile" @@ -816,7 +816,7 @@ mod test { assert!( !is_precompile( - Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]), + &Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]), 3 ), "0x000..4 is not precompile" @@ -824,7 +824,7 @@ mod test { assert!( is_precompile( - Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), + &Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 3 ), "0x00..01 is precompile" @@ -832,7 +832,7 @@ mod test { assert!( is_precompile( - Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]), + &Address::new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]), 3 ), "0x000..3 is precompile"