diff --git a/Cargo.lock b/Cargo.lock index b54f8c102fe9b..cfda789a12c5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -602,6 +602,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8ab6b55fe97976e46f91ddbed8d147d966475dc29b2032757ba47e02376fbc3" +[[package]] +name = "aurora-engine-modexp" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfacad86e9e138fca0670949eb8ed4ffdf73a55bded8887efe0863cd1a3a6f70" +dependencies = [ + "hex", + "num", +] + [[package]] name = "auto_impl" version = "1.1.0" @@ -906,9 +916,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "0.1.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac926d808fb72fe09ebf471a091d6d72918876ccf0b4989766093d2d0d24a0ef" +checksum = "32700dc7904064bb64e857d38a1766607372928e2466ee5f02a869829b3297d7" dependencies = [ "bindgen", "blst", @@ -5729,8 +5739,7 @@ dependencies = [ [[package]] name = "revm" version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f4ca8ae0345104523b4af1a8a7ea97cfa1865cdb7a7c25d23c1a18d9b48598" +source = "git+https://github.com/bluealloy/revm?rev=1609e07c68048909ad1682c98cf2b9baa76310b5#1609e07c68048909ad1682c98cf2b9baa76310b5" dependencies = [ "auto_impl", "revm-interpreter", @@ -5742,8 +5751,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f959cafdf64a7f89b014fa73dc2325001cf654b3d9400260b212d19a2ebe3da0" +source = "git+https://github.com/bluealloy/revm?rev=1609e07c68048909ad1682c98cf2b9baa76310b5#1609e07c68048909ad1682c98cf2b9baa76310b5" dependencies = [ "revm-primitives", "serde", @@ -5752,12 +5760,11 @@ dependencies = [ [[package]] name = "revm-precompile" version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d360a88223d85709d2e95d4609eb1e19c649c47e28954bfabae5e92bb37e83e" +source = "git+https://github.com/bluealloy/revm?rev=1609e07c68048909ad1682c98cf2b9baa76310b5#1609e07c68048909ad1682c98cf2b9baa76310b5" dependencies = [ + "aurora-engine-modexp", "c-kzg", "k256", - "num", "once_cell", "revm-primitives", "ripemd", @@ -5769,8 +5776,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51187b852d9e458816a2e19c81f1dd6c924077e1a8fccd16e4f044f865f299d7" +source = "git+https://github.com/bluealloy/revm?rev=1609e07c68048909ad1682c98cf2b9baa76310b5#1609e07c68048909ad1682c98cf2b9baa76310b5" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -6269,18 +6275,18 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +checksum = "2acea373acb8c21ecb5a23741452acd2593ed44ee3d343e72baaa143bc89d0d5" dependencies = [ "secp256k1-sys", ] [[package]] name = "secp256k1-sys" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +checksum = "09e67c467c38fd24bd5499dc9a18183b31575c12ee549197e3e20d57aa4fe3b7" dependencies = [ "cc", ] diff --git a/Cargo.toml b/Cargo.toml index 058e2771dcfa0..697c973d4372f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -211,3 +211,6 @@ alloy-dyn-abi = { git = "https://github.com/alloy-rs/core/" } alloy-primitives = { git = "https://github.com/alloy-rs/core/" } alloy-json-abi = { git = "https://github.com/alloy-rs/core/" } alloy-sol-types = { git = "https://github.com/alloy-rs/core/" } + +revm = { git = "https://github.com/bluealloy/revm", rev = "1609e07c68048909ad1682c98cf2b9baa76310b5" } +revm-primitives = { git = "https://github.com/bluealloy/revm", rev = "1609e07c68048909ad1682c98cf2b9baa76310b5" } \ No newline at end of file diff --git a/crates/anvil/src/eth/backend/db.rs b/crates/anvil/src/eth/backend/db.rs index d848d9dea43db..781fb5c0bdde1 100644 --- a/crates/anvil/src/eth/backend/db.rs +++ b/crates/anvil/src/eth/backend/db.rs @@ -136,7 +136,7 @@ pub trait Db: /// Deserialize and add all chain data to the backend storage fn load_state(&mut self, state: SerializableState) -> DatabaseResult { for (addr, account) in state.accounts.into_iter() { - let old_account_nonce = DatabaseRef::basic(self, addr.to_alloy()) + let old_account_nonce = DatabaseRef::basic_ref(self, addr.to_alloy()) .ok() .and_then(|acc| acc.map(|acc| acc.nonce)) .unwrap_or_default(); @@ -288,20 +288,20 @@ impl StateDb { impl DatabaseRef for StateDb { type Error = DatabaseError; - fn basic(&self, address: B160) -> DatabaseResult> { - self.0.basic(address) + fn basic_ref(&self, address: B160) -> DatabaseResult> { + self.0.basic_ref(address) } - fn code_by_hash(&self, code_hash: B256) -> DatabaseResult { - self.0.code_by_hash(code_hash) + fn code_by_hash_ref(&self, code_hash: B256) -> DatabaseResult { + self.0.code_by_hash_ref(code_hash) } - fn storage(&self, address: B160, index: rU256) -> DatabaseResult { - self.0.storage(address, index) + fn storage_ref(&self, address: B160, index: rU256) -> DatabaseResult { + self.0.storage_ref(address, index) } - fn block_hash(&self, number: rU256) -> DatabaseResult { - self.0.block_hash(number) + fn block_hash_ref(&self, number: rU256) -> DatabaseResult { + self.0.block_hash_ref(number) } } diff --git a/crates/anvil/src/eth/backend/genesis.rs b/crates/anvil/src/eth/backend/genesis.rs index 157f7b104e350..5178b001300c4 100644 --- a/crates/anvil/src/eth/backend/genesis.rs +++ b/crates/anvil/src/eth/backend/genesis.rs @@ -103,21 +103,21 @@ pub(crate) struct AtGenesisStateDb<'a> { impl<'a> DatabaseRef for AtGenesisStateDb<'a> { type Error = DatabaseError; - fn basic(&self, address: aAddress) -> DatabaseResult> { + fn basic_ref(&self, address: aAddress) -> DatabaseResult> { if let Some(acc) = self.accounts.get(&(address.to_ethers())).cloned() { return Ok(Some(acc)) } - self.db.basic(address) + self.db.basic_ref(address) } - fn code_by_hash(&self, code_hash: B256) -> DatabaseResult { + fn code_by_hash_ref(&self, code_hash: B256) -> DatabaseResult { if let Some((_, acc)) = self.accounts.iter().find(|(_, acc)| acc.code_hash == code_hash) { return Ok(acc.code.clone().unwrap_or_default()) } - self.db.code_by_hash(code_hash) + self.db.code_by_hash_ref(code_hash) } - fn storage(&self, address: aAddress, index: U256) -> DatabaseResult { + fn storage_ref(&self, address: aAddress, index: U256) -> DatabaseResult { if let Some(acc) = self .genesis .as_ref() @@ -130,11 +130,11 @@ impl<'a> DatabaseRef for AtGenesisStateDb<'a> { .unwrap_or_default(); return Ok(value.into_uint().to_alloy()) } - self.db.storage(address, index) + self.db.storage_ref(address, index) } - fn block_hash(&self, number: U256) -> DatabaseResult { - self.db.block_hash(number) + fn block_hash_ref(&self, number: U256) -> DatabaseResult { + self.db.block_hash_ref(number) } } diff --git a/crates/anvil/src/eth/backend/mem/in_memory_db.rs b/crates/anvil/src/eth/backend/mem/in_memory_db.rs index 1610bfc125a1d..159e8aca2366e 100644 --- a/crates/anvil/src/eth/backend/mem/in_memory_db.rs +++ b/crates/anvil/src/eth/backend/mem/in_memory_db.rs @@ -42,7 +42,7 @@ impl Db for MemDb { let code = if let Some(code) = v.info.code { code } else { - self.inner.code_by_hash(v.info.code_hash)? + self.inner.code_by_hash_ref(v.info.code_hash)? } .to_checked(); Ok(( @@ -177,13 +177,13 @@ mod tests { load_db.load_state(state).unwrap(); - let loaded_account = load_db.basic(test_addr.to_alloy()).unwrap().unwrap(); + let loaded_account = load_db.basic_ref(test_addr.to_alloy()).unwrap().unwrap(); assert_eq!(loaded_account.balance, rU256::from(123456)); - assert_eq!(load_db.code_by_hash(loaded_account.code_hash).unwrap(), contract_code); + assert_eq!(load_db.code_by_hash_ref(loaded_account.code_hash).unwrap(), contract_code); assert_eq!(loaded_account.nonce, 1234); assert_eq!( - load_db.storage(test_addr.to_alloy(), rU256::from(1234567)).unwrap(), + load_db.storage_ref(test_addr.to_alloy(), rU256::from(1234567)).unwrap(), rU256::from(1) ); } @@ -241,15 +241,21 @@ mod tests { db.load_state(new_state).unwrap(); - let loaded_account = db.basic(test_addr.to_alloy()).unwrap().unwrap(); - let loaded_account2 = db.basic(test_addr2.to_alloy()).unwrap().unwrap(); + let loaded_account = db.basic_ref(test_addr.to_alloy()).unwrap().unwrap(); + let loaded_account2 = db.basic_ref(test_addr2.to_alloy()).unwrap().unwrap(); assert_eq!(loaded_account2.nonce, 1); assert_eq!(loaded_account.balance, rU256::from(100100)); - assert_eq!(db.code_by_hash(loaded_account.code_hash).unwrap(), contract_code); + assert_eq!(db.code_by_hash_ref(loaded_account.code_hash).unwrap(), contract_code); assert_eq!(loaded_account.nonce, 1234); - assert_eq!(db.storage(test_addr.to_alloy(), rU256::from(1234567)).unwrap(), rU256::from(1)); - assert_eq!(db.storage(test_addr.to_alloy(), rU256::from(1234568)).unwrap(), rU256::from(5)); + assert_eq!( + db.storage_ref(test_addr.to_alloy(), rU256::from(1234567)).unwrap(), + rU256::from(1) + ); + assert_eq!( + db.storage_ref(test_addr.to_alloy(), rU256::from(1234568)).unwrap(), + rU256::from(5) + ); } } diff --git a/crates/anvil/src/eth/backend/mem/inspector.rs b/crates/anvil/src/eth/backend/mem/inspector.rs index a4e2d0d94f4db..295558408ba3d 100644 --- a/crates/anvil/src/eth/backend/mem/inspector.rs +++ b/crates/anvil/src/eth/backend/mem/inspector.rs @@ -48,23 +48,17 @@ impl Inspector { impl revm::Inspector for Inspector { #[inline] - fn initialize_interp( - &mut self, - interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn initialize_interp(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { call_inspectors!([&mut self.tracer], |inspector| { inspector.initialize_interp(interp, data); }); - InstructionResult::Continue } #[inline] - fn step(&mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>) -> InstructionResult { + fn step(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { call_inspectors!([&mut self.tracer], |inspector| { inspector.step(interp, data); }); - InstructionResult::Continue } #[inline] @@ -81,16 +75,10 @@ impl revm::Inspector for Inspector { } #[inline] - fn step_end( - &mut self, - interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, - eval: InstructionResult, - ) -> InstructionResult { + fn step_end(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { call_inspectors!([&mut self.tracer], |inspector| { - inspector.step_end(interp, data, eval); + inspector.step_end(interp, data); }); - eval } #[inline] diff --git a/crates/anvil/src/eth/backend/mem/mod.rs b/crates/anvil/src/eth/backend/mem/mod.rs index b6b99f3e16812..fcfaa8f1040ea 100644 --- a/crates/anvil/src/eth/backend/mem/mod.rs +++ b/crates/anvil/src/eth/backend/mem/mod.rs @@ -267,7 +267,7 @@ impl Backend { // accounts concurrently by spawning the job to a new task genesis_accounts_futures.push(tokio::task::spawn(async move { let db = db.read().await; - let info = db.basic(address.to_alloy())?.unwrap_or_default(); + let info = db.basic_ref(address.to_alloy())?.unwrap_or_default(); Ok::<_, DatabaseError>((address, info)) })); } @@ -341,7 +341,7 @@ impl Backend { /// Returns the `AccountInfo` from the database pub async fn get_account(&self, address: Address) -> DatabaseResult { - Ok(self.db.read().await.basic(address.to_alloy())?.unwrap_or_default()) + Ok(self.db.read().await.basic_ref(address.to_alloy())?.unwrap_or_default()) } /// Whether we're forked off some remote client @@ -1148,7 +1148,7 @@ impl Backend { let to = if let Some(to) = request.to { to.to_alloy() } else { - let nonce = state.basic(from)?.unwrap_or_default().nonce; + let nonce = state.basic_ref(from)?.unwrap_or_default().nonce; from.create(nonce) }; @@ -1675,7 +1675,7 @@ impl Backend { ) -> Result { self.with_database_at(block_request, |db, _| { trace!(target: "backend", "get storage for {:?} at {:?}", address, index); - let val = db.storage(address.to_alloy(), index.to_alloy())?; + let val = db.storage_ref(address.to_alloy(), index.to_alloy())?; Ok(u256_to_h256_be(val.to_ethers())) }) .await? @@ -1702,7 +1702,7 @@ impl Backend { D: DatabaseRef, { trace!(target: "backend", "get code for {:?}", address); - let account = state.basic(address.to_alloy())?.unwrap_or_default(); + let account = state.basic_ref(address.to_alloy())?.unwrap_or_default(); if account.code_hash == KECCAK_EMPTY { // if the code hash is `KECCAK_EMPTY`, we check no further return Ok(Default::default()) @@ -1710,7 +1710,7 @@ impl Backend { let code = if let Some(code) = account.code { code } else { - state.code_by_hash(account.code_hash)? + state.code_by_hash_ref(account.code_hash)? }; Ok(code.bytes()[..code.len()].to_vec().into()) } @@ -1736,7 +1736,7 @@ impl Backend { D: DatabaseRef, { trace!(target: "backend", "get balance for {:?}", address); - Ok(state.basic(address.to_alloy())?.unwrap_or_default().balance.to_ethers()) + Ok(state.basic_ref(address.to_alloy())?.unwrap_or_default().balance.to_ethers()) } /// Returns the nonce of the address @@ -1759,7 +1759,7 @@ impl Backend { }; self.with_database_at(final_block_request, |db, _| { trace!(target: "backend", "get nonce for {:?}", address); - Ok(db.basic(address.to_alloy())?.unwrap_or_default().nonce.into()) + Ok(db.basic_ref(address.to_alloy())?.unwrap_or_default().nonce.into()) }) .await? } diff --git a/crates/anvil/src/eth/backend/mem/state.rs b/crates/anvil/src/eth/backend/mem/state.rs index 036dc672651df..9abe81fef3f88 100644 --- a/crates/anvil/src/eth/backend/mem/state.rs +++ b/crates/anvil/src/eth/backend/mem/state.rs @@ -116,7 +116,7 @@ where { let mut cache_db = CacheDB::new(state); for (account, account_overrides) in overrides.iter() { - let mut account_info = cache_db.basic((*account).to_alloy())?.unwrap_or_default(); + let mut account_info = cache_db.basic_ref((*account).to_alloy())?.unwrap_or_default(); if let Some(nonce) = account_overrides.nonce { account_info.nonce = nonce; diff --git a/crates/anvil/src/eth/backend/mem/storage.rs b/crates/anvil/src/eth/backend/mem/storage.rs index 236b76f5f043b..10f7ded45eda6 100644 --- a/crates/anvil/src/eth/backend/mem/storage.rs +++ b/crates/anvil/src/eth/backend/mem/storage.rs @@ -478,7 +478,7 @@ mod tests { let loaded = storage.get(&one).unwrap(); - let acc = loaded.basic(addr.to_alloy()).unwrap().unwrap(); + let acc = loaded.basic_ref(addr.to_alloy()).unwrap().unwrap(); assert_eq!(acc.balance, rU256::from(1337u64)); } @@ -508,7 +508,7 @@ mod tests { let hash = H256::from_uint(&U256::from(idx)); let addr = Address::from(hash); let loaded = storage.get(&hash).unwrap(); - let acc = loaded.basic(addr.to_alloy()).unwrap().unwrap(); + let acc = loaded.basic_ref(addr.to_alloy()).unwrap().unwrap(); let balance = (idx * 2) as u64; assert_eq!(acc.balance, rU256::from(balance)); } diff --git a/crates/anvil/src/eth/util.rs b/crates/anvil/src/eth/util.rs index 5fdf3dc6ae1c4..76816b4b30f4e 100644 --- a/crates/anvil/src/eth/util.rs +++ b/crates/anvil/src/eth/util.rs @@ -1,12 +1,14 @@ -use ethers::{abi::Address, types::H160}; +use ethers::abi::Address; use foundry_evm::revm::{self, precompile::Precompiles, primitives::SpecId}; +use foundry_utils::types::ToEthers; use std::fmt; pub fn get_precompiles_for(spec_id: SpecId) -> Vec
{ Precompiles::new(to_precompile_id(spec_id)) .addresses() .into_iter() - .map(|item| H160::from_slice(item)) + .copied() + .map(|item| item.to_ethers()) .collect() } diff --git a/crates/cheatcodes/src/evm/mapping.rs b/crates/cheatcodes/src/evm/mapping.rs index 8ff789c8e4191..f5acc4966595a 100644 --- a/crates/cheatcodes/src/evm/mapping.rs +++ b/crates/cheatcodes/src/evm/mapping.rs @@ -119,7 +119,7 @@ pub(crate) fn step(mapping_slots: &mut HashMap, interpret if interpreter.stack.peek(1) == Ok(U256::from(0x40)) { let address = interpreter.contract.address; let offset = interpreter.stack.peek(0).expect("stack size > 1").saturating_to(); - let data = interpreter.memory.slice(offset, 0x40); + let data = interpreter.shared_memory.slice(offset, 0x40); let low = B256::from_slice(&data[..0x20]); let high = B256::from_slice(&data[0x20..]); let result = keccak256(data); diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs index ab5368c44f5d7..3ff0d563c32de 100644 --- a/crates/cheatcodes/src/inspector.rs +++ b/crates/cheatcodes/src/inspector.rs @@ -46,7 +46,7 @@ macro_rules! try_or_continue { ($e:expr) => { match $e { Ok(v) => v, - Err(_) => return InstructionResult::Continue, + Err(_) => return, } }; } @@ -281,11 +281,7 @@ impl Cheatcodes { impl Inspector for Cheatcodes { #[inline] - fn initialize_interp( - &mut self, - _: &mut Interpreter, - data: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn initialize_interp(&mut self, _: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { // When the first interpreter is initialized we've circumvented the balance and gas checks, // so we apply our actual block data with the correct fees and all. if let Some(block) = self.block.take() { @@ -294,15 +290,9 @@ impl Inspector for Cheatcodes { if let Some(gas_price) = self.gas_price.take() { data.env.tx.gas_price = gas_price; } - - InstructionResult::Continue } - fn step( - &mut self, - interpreter: &mut Interpreter, - data: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn step(&mut self, interpreter: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { self.pc = interpreter.program_counter(); // reset gas if gas metering is turned off @@ -422,7 +412,8 @@ impl Inspector for Cheatcodes { range.contains(&offset) && range.contains(&(offset + 31)) }) { disallowed_mem_write(offset, 32, interpreter, ranges); - return InstructionResult::Revert + interpreter.instruction_result = InstructionResult::Revert; + return } } opcode::MSTORE8 => { @@ -433,7 +424,8 @@ impl Inspector for Cheatcodes { // unexpectedly mutated. if !ranges.iter().any(|range| range.contains(&offset)) { disallowed_mem_write(offset, 1, interpreter, ranges); - return InstructionResult::Revert + interpreter.instruction_result = InstructionResult::Revert; + return } } @@ -448,11 +440,12 @@ impl Inspector for Cheatcodes { // If the offset being loaded is >= than the memory size, the // memory is being expanded. If none of the allowed ranges contain // [offset, offset + 32), memory has been unexpectedly mutated. - if offset >= interpreter.memory.len() as u64 && !ranges.iter().any(|range| { + if offset >= interpreter.shared_memory.len() as u64 && !ranges.iter().any(|range| { range.contains(&offset) && range.contains(&(offset + 31)) }) { disallowed_mem_write(offset, 32, interpreter, ranges); - return InstructionResult::Revert + interpreter.instruction_result = InstructionResult::Revert; + return } } @@ -475,7 +468,7 @@ impl Inspector for Cheatcodes { range.contains(&(dest_offset + size.saturating_sub(1))) }) && ($writes || [dest_offset, (dest_offset + size).saturating_sub(1)].into_iter().any(|offset| { - offset >= interpreter.memory.len() as u64 + offset >= interpreter.shared_memory.len() as u64 }) ); @@ -483,7 +476,8 @@ impl Inspector for Cheatcodes { // that gives information about the allowed ranges and revert. if fail_cond { disallowed_mem_write(dest_offset, size, interpreter, ranges); - return InstructionResult::Revert + interpreter.instruction_result = InstructionResult::Revert; + return } })* _ => () @@ -519,8 +513,6 @@ impl Inspector for Cheatcodes { if let Some(mapping_slots) = &mut self.mapping_slots { mapping::step(mapping_slots, interpreter); } - - InstructionResult::Continue } fn log(&mut self, _: &mut EVMData<'_, DB>, address: &Address, topics: &[B256], data: &Bytes) { @@ -1030,7 +1022,7 @@ impl Inspector for Cheatcodes { fn disallowed_mem_write( dest_offset: u64, size: u64, - interpreter: &mut Interpreter, + interpreter: &mut Interpreter<'_>, ranges: &[Range], ) { let revert_string = format!( @@ -1045,12 +1037,12 @@ fn disallowed_mem_write( /// Expands memory, stores a revert string, and sets the return range to the revert /// string's location in memory. -fn mstore_revert_string(interpreter: &mut Interpreter, bytes: &[u8]) { - let starting_offset = interpreter.memory.len(); - interpreter.memory.resize(starting_offset + bytes.len()); - interpreter.memory.set_data(starting_offset, 0, bytes.len(), bytes); +fn mstore_revert_string(interpreter: &mut Interpreter<'_>, bytes: &[u8]) { + let starting_offset = interpreter.shared_memory.len(); + interpreter.shared_memory.resize(starting_offset + bytes.len()); + interpreter.shared_memory.set_data(starting_offset, 0, bytes.len(), bytes); interpreter.return_offset = starting_offset; - interpreter.return_len = interpreter.memory.len() - starting_offset + interpreter.return_len = interpreter.shared_memory.len() - starting_offset } fn process_create( diff --git a/crates/chisel/src/dispatcher.rs b/crates/chisel/src/dispatcher.rs index 90e1dd72d29f5..26f13933b049a 100644 --- a/crates/chisel/src/dispatcher.rs +++ b/crates/chisel/src/dispatcher.rs @@ -421,7 +421,7 @@ impl ChiselDispatcher { i + 32 )), Paint::cyan(hex::encode_prefixed( - &mem.data()[i..i + 32] + &mem.context_memory()[i..i + 32] )) ); }); diff --git a/crates/chisel/src/executor.rs b/crates/chisel/src/executor.rs index 9fe2f57615bfb..6b97535ba8e0a 100644 --- a/crates/chisel/src/executor.rs +++ b/crates/chisel/src/executor.rs @@ -223,7 +223,7 @@ impl SessionSource { // the file compiled correctly, thus the last stack item must be the memory offset of // the `bytes memory inspectoor` value let mut offset = stack.data().last().unwrap().to_ethers().as_usize(); - let mem = memory.data(); + let mem = memory.context_memory(); let mem_offset = &mem[offset..offset + 32]; let len = U256::try_from_be_slice(mem_offset).unwrap().to::(); offset += 32; diff --git a/crates/chisel/src/runner.rs b/crates/chisel/src/runner.rs index 14485ab2fb731..86ed659fbd4b9 100644 --- a/crates/chisel/src/runner.rs +++ b/crates/chisel/src/runner.rs @@ -52,7 +52,7 @@ pub struct ChiselResult { /// EVM State at the final instruction of the `run()` function pub state: Option<( revm::interpreter::Stack, - revm::interpreter::Memory, + revm::interpreter::SharedMemory, revm::interpreter::InstructionResult, )>, } diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index cb1d76d9fc03e..378a029118df8 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -1795,7 +1795,7 @@ impl Default for Config { block_difficulty: 0, block_prevrandao: Default::default(), block_gas_limit: None, - memory_limit: 2u64.pow(25), + memory_limit: 1 << 25, // 32MiB = 33554432 bytes eth_rpc_url: None, eth_rpc_jwt: None, etherscan_api_key: None, diff --git a/crates/debugger/src/lib.rs b/crates/debugger/src/lib.rs index d5f31d7f89f45..4a74c302fedae 100644 --- a/crates/debugger/src/lib.rs +++ b/crates/debugger/src/lib.rs @@ -920,7 +920,7 @@ Line::from(Span::styled("[t]: stack labels | [m]: memory decoding | [shift + j/k let stack_space = Block::default() .title(format!("Memory (max expansion: {} bytes)", memory.len())) .borders(Borders::ALL); - let memory = memory.data(); + let memory = memory.context_memory(); let max_i = memory.len() / 32; let min_len = format!("{:x}", max_i * 32).len(); diff --git a/crates/evm/core/src/backend/fuzz.rs b/crates/evm/core/src/backend/fuzz.rs index 77e8bd6f577cf..7fa3de4b25469 100644 --- a/crates/evm/core/src/backend/fuzz.rs +++ b/crates/evm/core/src/backend/fuzz.rs @@ -63,7 +63,7 @@ impl<'a> FuzzBackendWrapper<'a> { // this is a new call to inspect with a new env, so even if we've cloned the backend // already, we reset the initialized state self.is_initialized = false; - match revm::evm_inner::(env, self, &mut inspector).transact() { + match revm::evm_inner::(env, self, Some(&mut inspector)).transact() { Ok(result) => Ok(result), Err(e) => eyre::bail!("fuzz: failed to inspect: {e}"), } @@ -235,20 +235,20 @@ impl<'a> DatabaseExt for FuzzBackendWrapper<'a> { impl<'a> DatabaseRef for FuzzBackendWrapper<'a> { type Error = DatabaseError; - fn basic(&self, address: Address) -> Result, Self::Error> { - DatabaseRef::basic(self.backend.as_ref(), address) + fn basic_ref(&self, address: Address) -> Result, Self::Error> { + DatabaseRef::basic_ref(self.backend.as_ref(), address) } - fn code_by_hash(&self, code_hash: B256) -> Result { - DatabaseRef::code_by_hash(self.backend.as_ref(), code_hash) + fn code_by_hash_ref(&self, code_hash: B256) -> Result { + DatabaseRef::code_by_hash_ref(self.backend.as_ref(), code_hash) } - fn storage(&self, address: Address, index: U256) -> Result { - DatabaseRef::storage(self.backend.as_ref(), address, index) + fn storage_ref(&self, address: Address, index: U256) -> Result { + DatabaseRef::storage_ref(self.backend.as_ref(), address, index) } - fn block_hash(&self, number: U256) -> Result { - DatabaseRef::block_hash(self.backend.as_ref(), number) + fn block_hash_ref(&self, number: U256) -> Result { + DatabaseRef::block_hash_ref(self.backend.as_ref(), number) } } @@ -256,18 +256,18 @@ impl<'a> Database for FuzzBackendWrapper<'a> { type Error = DatabaseError; fn basic(&mut self, address: Address) -> Result, Self::Error> { - DatabaseRef::basic(self, address) + DatabaseRef::basic_ref(self, address) } fn code_by_hash(&mut self, code_hash: B256) -> Result { - DatabaseRef::code_by_hash(self, code_hash) + DatabaseRef::code_by_hash_ref(self, code_hash) } fn storage(&mut self, address: Address, index: U256) -> Result { - DatabaseRef::storage(self, address, index) + DatabaseRef::storage_ref(self, address, index) } fn block_hash(&mut self, number: U256) -> Result { - DatabaseRef::block_hash(self, number) + DatabaseRef::block_hash_ref(self, number) } } diff --git a/crates/evm/core/src/backend/in_memory_db.rs b/crates/evm/core/src/backend/in_memory_db.rs index 6deec78d1e761..6cb2c73eebdee 100644 --- a/crates/evm/core/src/backend/in_memory_db.rs +++ b/crates/evm/core/src/backend/in_memory_db.rs @@ -29,20 +29,20 @@ impl Default for MemDb { impl DatabaseRef for MemDb { type Error = DatabaseError; - fn basic(&self, address: Address) -> Result, Self::Error> { - DatabaseRef::basic(&self.inner, address) + fn basic_ref(&self, address: Address) -> Result, Self::Error> { + DatabaseRef::basic_ref(&self.inner, address) } - fn code_by_hash(&self, code_hash: B256) -> Result { - DatabaseRef::code_by_hash(&self.inner, code_hash) + fn code_by_hash_ref(&self, code_hash: B256) -> Result { + DatabaseRef::code_by_hash_ref(&self.inner, code_hash) } - fn storage(&self, address: Address, index: U256) -> Result { - DatabaseRef::storage(&self.inner, address, index) + fn storage_ref(&self, address: Address, index: U256) -> Result { + DatabaseRef::storage_ref(&self.inner, address, index) } - fn block_hash(&self, number: U256) -> Result { - DatabaseRef::block_hash(&self.inner, number) + fn block_hash_ref(&self, number: U256) -> Result { + DatabaseRef::block_hash_ref(&self.inner, number) } } @@ -93,20 +93,20 @@ pub struct EmptyDBWrapper(EmptyDB); impl DatabaseRef for EmptyDBWrapper { type Error = DatabaseError; - fn basic(&self, _address: Address) -> Result, Self::Error> { + fn basic_ref(&self, _address: Address) -> Result, Self::Error> { // Note: this will always return `Some(AccountInfo)`, for the reason explained above Ok(Some(AccountInfo::default())) } - fn code_by_hash(&self, code_hash: B256) -> Result { - Ok(self.0.code_by_hash(code_hash)?) + fn code_by_hash_ref(&self, code_hash: B256) -> Result { + Ok(self.0.code_by_hash_ref(code_hash)?) } - fn storage(&self, address: Address, index: U256) -> Result { - Ok(self.0.storage(address, index)?) + fn storage_ref(&self, address: Address, index: U256) -> Result { + Ok(self.0.storage_ref(address, index)?) } - fn block_hash(&self, number: U256) -> Result { - Ok(self.0.block_hash(number)?) + fn block_hash_ref(&self, number: U256) -> Result { + Ok(self.0.block_hash_ref(number)?) } } @@ -143,7 +143,7 @@ mod tests { let mut db = CacheDB::new(EmptyDB::default()); let address = Address::random(); - let info = DatabaseRef::basic(&db, address).unwrap(); + let info = DatabaseRef::basic_ref(&db, address).unwrap(); assert!(info.is_none()); let mut info = info.unwrap_or_default(); info.balance = U256::from(500u64); diff --git a/crates/evm/core/src/backend/mod.rs b/crates/evm/core/src/backend/mod.rs index 90849b53c1941..4e756af98268f 100644 --- a/crates/evm/core/src/backend/mod.rs +++ b/crates/evm/core/src/backend/mod.rs @@ -594,7 +594,7 @@ impl Backend { bool private _failed; } */ - let value = self.storage(address, U256::ZERO).unwrap_or_default(); + let value = self.storage_ref(address, U256::ZERO).unwrap_or_default(); value.as_le_bytes()[1] != 0 } @@ -747,11 +747,11 @@ impl Backend { let test_contract = match env.tx.transact_to { TransactTo::Call(to) => to, TransactTo::Create(CreateScheme::Create) => { - revm::primitives::create_address(env.tx.caller, env.tx.nonce.unwrap_or_default()) + env.tx.caller.create(env.tx.nonce.unwrap_or_default()) } TransactTo::Create(CreateScheme::Create2 { salt }) => { let code_hash = B256::from_slice(keccak256(&env.tx.data).as_slice()); - revm::primitives::create2_address(env.tx.caller, code_hash, salt) + env.tx.caller.create2(B256::from(salt), code_hash) } }; self.set_test_contract(test_contract); @@ -768,7 +768,7 @@ impl Backend { { self.initialize(env); - match revm::evm_inner::(env, self, &mut inspector).transact() { + match revm::evm_inner::(env, self, Some(&mut inspector)).transact() { Ok(res) => Ok(res), Err(e) => eyre::bail!("backend: failed while inspecting: {e}"), } @@ -1355,70 +1355,35 @@ impl DatabaseExt for Backend { impl DatabaseRef for Backend { type Error = DatabaseError; - fn basic(&self, address: Address) -> Result, Self::Error> { + fn basic_ref(&self, address: Address) -> Result, Self::Error> { if let Some(db) = self.active_fork_db() { - db.basic(address) - } else { - Ok(self.mem_db.basic(address)?) - } - } - - fn code_by_hash(&self, code_hash: B256) -> Result { - if let Some(db) = self.active_fork_db() { - db.code_by_hash(code_hash) - } else { - Ok(self.mem_db.code_by_hash(code_hash)?) - } - } - - fn storage(&self, address: Address, index: U256) -> Result { - if let Some(db) = self.active_fork_db() { - DatabaseRef::storage(db, address, index) - } else { - Ok(DatabaseRef::storage(&self.mem_db, address, index)?) - } - } - - fn block_hash(&self, number: U256) -> Result { - if let Some(db) = self.active_fork_db() { - db.block_hash(number) - } else { - Ok(self.mem_db.block_hash(number)?) - } - } -} - -impl<'a> DatabaseRef for &'a mut Backend { - type Error = DatabaseError; - fn basic(&self, address: Address) -> Result, Self::Error> { - if let Some(db) = self.active_fork_db() { - DatabaseRef::basic(db, address) + db.basic_ref(address) } else { - Ok(DatabaseRef::basic(&self.mem_db, address)?) + Ok(self.mem_db.basic_ref(address)?) } } - fn code_by_hash(&self, code_hash: B256) -> Result { + fn code_by_hash_ref(&self, code_hash: B256) -> Result { if let Some(db) = self.active_fork_db() { - DatabaseRef::code_by_hash(db, code_hash) + db.code_by_hash_ref(code_hash) } else { - Ok(DatabaseRef::code_by_hash(&self.mem_db, code_hash)?) + Ok(self.mem_db.code_by_hash_ref(code_hash)?) } } - fn storage(&self, address: Address, index: U256) -> Result { + fn storage_ref(&self, address: Address, index: U256) -> Result { if let Some(db) = self.active_fork_db() { - DatabaseRef::storage(db, address, index) + DatabaseRef::storage_ref(db, address, index) } else { - Ok(DatabaseRef::storage(&self.mem_db, address, index)?) + Ok(DatabaseRef::storage_ref(&self.mem_db, address, index)?) } } - fn block_hash(&self, number: U256) -> Result { + fn block_hash_ref(&self, number: U256) -> Result { if let Some(db) = self.active_fork_db() { - DatabaseRef::block_hash(db, number) + db.block_hash_ref(number) } else { - Ok(DatabaseRef::block_hash(&self.mem_db, number)?) + Ok(self.mem_db.block_hash_ref(number)?) } } } @@ -1489,7 +1454,7 @@ pub struct Fork { impl Fork { /// Returns true if the account is a contract pub fn is_contract(&self, acc: Address) -> bool { - if let Ok(Some(acc)) = self.db.basic(acc) { + if let Ok(Some(acc)) = self.db.basic_ref(acc) { if acc.code_hash != KECCAK_EMPTY { return true } @@ -1735,8 +1700,8 @@ impl BackendInner { } } JournaledState::new( - self.precompiles().len(), precompiles_spec_id_to_primitives_spec_id(self.precompile_id), + self.precompiles().addresses().into_iter().copied().collect(), ) } } diff --git a/crates/evm/core/src/debug.rs b/crates/evm/core/src/debug.rs index f0d6b2c19d85d..76bc7f3a55888 100644 --- a/crates/evm/core/src/debug.rs +++ b/crates/evm/core/src/debug.rs @@ -1,6 +1,6 @@ use crate::utils::CallKind; use alloy_primitives::{Address, U256}; -use revm::interpreter::{Memory, OpCode}; +use revm::interpreter::{OpCode, SharedMemory}; use serde::{Deserialize, Serialize}; use std::fmt::Display; @@ -114,7 +114,7 @@ pub struct DebugStep { /// Stack *prior* to running the associated opcode pub stack: Vec, /// Memory *prior* to running the associated opcode - pub memory: Memory, + pub memory: SharedMemory, /// Opcode to be executed pub instruction: Instruction, /// Optional bytes that are being pushed onto the stack @@ -132,7 +132,7 @@ impl Default for DebugStep { fn default() -> Self { Self { stack: vec![], - memory: Memory::new(), + memory: Default::default(), instruction: Instruction::OpCode(revm::interpreter::opcode::INVALID), push_bytes: None, pc: 0, diff --git a/crates/evm/core/src/fork/backend.rs b/crates/evm/core/src/fork/backend.rs index 37ac0b937b0a8..ba9329c36761c 100644 --- a/crates/evm/core/src/fork/backend.rs +++ b/crates/evm/core/src/fork/backend.rs @@ -642,7 +642,7 @@ impl SharedBackend { impl DatabaseRef for SharedBackend { type Error = DatabaseError; - fn basic(&self, address: Address) -> Result, Self::Error> { + fn basic_ref(&self, address: Address) -> Result, Self::Error> { trace!(target: "sharedbackend", %address, "request basic"); self.do_get_basic(address).map_err(|err| { error!(target: "sharedbackend", %err, %address, "Failed to send/recv `basic`"); @@ -653,11 +653,11 @@ impl DatabaseRef for SharedBackend { }) } - fn code_by_hash(&self, hash: B256) -> Result { + fn code_by_hash_ref(&self, hash: B256) -> Result { Err(DatabaseError::MissingCode(hash)) } - fn storage(&self, address: Address, index: U256) -> Result { + fn storage_ref(&self, address: Address, index: U256) -> Result { trace!(target: "sharedbackend", "request storage {:?} at {:?}", address, index); match self.do_get_storage(address, index).map_err(|err| { error!(target: "sharedbackend", %err, %address, %index, "Failed to send/recv `storage`"); @@ -671,7 +671,7 @@ impl DatabaseRef for SharedBackend { } } - fn block_hash(&self, number: U256) -> Result { + fn block_hash_ref(&self, number: U256) -> Result { if number > U256::from(u64::MAX) { return Ok(KECCAK_EMPTY) } @@ -720,8 +720,8 @@ mod tests { let address: Address = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap(); let idx = U256::from(0u64); - let value = backend.storage(address, idx).unwrap(); - let account = backend.basic(address).unwrap().unwrap(); + let value = backend.storage_ref(address, idx).unwrap(); + let account = backend.basic_ref(address).unwrap().unwrap(); let mem_acc = db.accounts().read().get(&address).unwrap().clone(); assert_eq!(account.balance, mem_acc.balance); @@ -731,7 +731,7 @@ mod tests { assert_eq!(slots.get(&idx).copied().unwrap(), value); let num = U256::from(10u64); - let hash = backend.block_hash(num).unwrap(); + let hash = backend.block_hash_ref(num).unwrap(); let mem_hash = *db.block_hashes().read().get(&num).unwrap(); assert_eq!(hash, mem_hash); @@ -739,7 +739,7 @@ mod tests { let handle = std::thread::spawn(move || { for i in 1..max_slots { let idx = U256::from(i); - let _ = backend.storage(address, idx); + let _ = backend.storage_ref(address, idx); } }); handle.join().unwrap(); @@ -779,13 +779,13 @@ mod tests { let address: Address = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap(); let idx = U256::from(0u64); - let _value = backend.storage(address, idx); - let _account = backend.basic(address); + let _value = backend.storage_ref(address, idx); + let _account = backend.basic_ref(address); // fill some slots let num_slots = 10u64; for idx in 1..num_slots { - let _ = backend.storage(address, U256::from(idx)); + let _ = backend.storage_ref(address, U256::from(idx)); } drop(backend); diff --git a/crates/evm/core/src/fork/database.rs b/crates/evm/core/src/fork/database.rs index 7d548440be75e..3eaeb6465bfb0 100644 --- a/crates/evm/core/src/fork/database.rs +++ b/crates/evm/core/src/fork/database.rs @@ -172,20 +172,20 @@ impl Database for ForkedDatabase { impl DatabaseRef for ForkedDatabase { type Error = DatabaseError; - fn basic(&self, address: Address) -> Result, Self::Error> { - self.cache_db.basic(address) + fn basic_ref(&self, address: Address) -> Result, Self::Error> { + self.cache_db.basic_ref(address) } - fn code_by_hash(&self, code_hash: B256) -> Result { - self.cache_db.code_by_hash(code_hash) + fn code_by_hash_ref(&self, code_hash: B256) -> Result { + self.cache_db.code_by_hash_ref(code_hash) } - fn storage(&self, address: Address, index: U256) -> Result { - DatabaseRef::storage(&self.cache_db, address, index) + fn storage_ref(&self, address: Address, index: U256) -> Result { + DatabaseRef::storage_ref(&self.cache_db, address, index) } - fn block_hash(&self, number: U256) -> Result { - self.cache_db.block_hash(number) + fn block_hash_ref(&self, number: U256) -> Result { + self.cache_db.block_hash_ref(number) } } @@ -218,43 +218,43 @@ impl ForkDbSnapshot { impl DatabaseRef for ForkDbSnapshot { type Error = DatabaseError; - fn basic(&self, address: Address) -> Result, Self::Error> { + fn basic_ref(&self, address: Address) -> Result, Self::Error> { match self.local.accounts.get(&address) { Some(account) => Ok(Some(account.info.clone())), None => { let mut acc = self.snapshot.accounts.get(&address).cloned(); if acc.is_none() { - acc = self.local.basic(address)?; + acc = self.local.basic_ref(address)?; } Ok(acc) } } } - fn code_by_hash(&self, code_hash: B256) -> Result { - self.local.code_by_hash(code_hash) + fn code_by_hash_ref(&self, code_hash: B256) -> Result { + self.local.code_by_hash_ref(code_hash) } - fn storage(&self, address: Address, index: U256) -> Result { + fn storage_ref(&self, address: Address, index: U256) -> Result { match self.local.accounts.get(&address) { Some(account) => match account.storage.get(&index) { Some(entry) => Ok(*entry), None => match self.get_storage(address, index) { - None => DatabaseRef::storage(&self.local, address, index), + None => DatabaseRef::storage_ref(&self.local, address, index), Some(storage) => Ok(storage), }, }, None => match self.get_storage(address, index) { - None => DatabaseRef::storage(&self.local, address, index), + None => DatabaseRef::storage_ref(&self.local, address, index), Some(storage) => Ok(storage), }, } } - fn block_hash(&self, number: U256) -> Result { + fn block_hash_ref(&self, number: U256) -> Result { match self.snapshot.block_hashes.get(&number).copied() { - None => self.local.block_hash(number), + None => self.local.block_hash_ref(number), Some(block_hash) => Ok(block_hash), } } diff --git a/crates/evm/coverage/src/inspector.rs b/crates/evm/coverage/src/inspector.rs index 3ee7ec98cce9b..8a57a2349d877 100644 --- a/crates/evm/coverage/src/inspector.rs +++ b/crates/evm/coverage/src/inspector.rs @@ -1,9 +1,6 @@ use crate::{HitMap, HitMaps}; use alloy_primitives::Bytes; -use revm::{ - interpreter::{InstructionResult, Interpreter}, - Database, EVMData, Inspector, -}; +use revm::{interpreter::Interpreter, Database, EVMData, Inspector}; #[derive(Clone, Default, Debug)] pub struct CoverageCollector { @@ -13,30 +10,18 @@ pub struct CoverageCollector { impl Inspector for CoverageCollector { #[inline] - fn initialize_interp( - &mut self, - interpreter: &mut Interpreter, - _: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn initialize_interp(&mut self, interpreter: &mut Interpreter<'_>, _: &mut EVMData<'_, DB>) { let hash = interpreter.contract.hash; self.maps.entry(hash).or_insert_with(|| { HitMap::new(Bytes::copy_from_slice( interpreter.contract.bytecode.original_bytecode_slice(), )) }); - - InstructionResult::Continue } #[inline] - fn step( - &mut self, - interpreter: &mut Interpreter, - _: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn step(&mut self, interpreter: &mut Interpreter<'_>, _: &mut EVMData<'_, DB>) { let hash = interpreter.contract.hash; self.maps.entry(hash).and_modify(|map| map.hit(interpreter.program_counter())); - - InstructionResult::Continue } } diff --git a/crates/evm/evm/src/executors/mod.rs b/crates/evm/evm/src/executors/mod.rs index fdfe0da701da7..4cbdcdb3d813b 100644 --- a/crates/evm/evm/src/executors/mod.rs +++ b/crates/evm/evm/src/executors/mod.rs @@ -28,7 +28,7 @@ use foundry_evm_coverage::HitMaps; use foundry_evm_traces::CallTraceArena; use revm::{ db::{DatabaseCommit, DatabaseRef}, - interpreter::{return_ok, CreateScheme, InstructionResult, Memory, Stack}, + interpreter::{return_ok, CreateScheme, InstructionResult, SharedMemory, Stack}, primitives::{ BlockEnv, Bytecode, Env, ExecutionResult, Output, ResultAndState, SpecId, TransactTo, TxEnv, }, @@ -94,7 +94,7 @@ impl Executor { trace!("deploying local create2 deployer"); let create2_deployer_account = self .backend - .basic(DEFAULT_CREATE2_DEPLOYER)? + .basic_ref(DEFAULT_CREATE2_DEPLOYER)? .ok_or_else(|| DatabaseError::MissingAccount(DEFAULT_CREATE2_DEPLOYER))?; // if the deployer is not currently deployed, deploy the default one @@ -117,7 +117,7 @@ impl Executor { /// Set the balance of an account. pub fn set_balance(&mut self, address: Address, amount: U256) -> DatabaseResult<&mut Self> { trace!(?address, ?amount, "setting account balance"); - let mut account = self.backend.basic(address)?.unwrap_or_default(); + let mut account = self.backend.basic_ref(address)?.unwrap_or_default(); account.balance = amount; self.backend.insert_account_info(address, account); @@ -126,12 +126,12 @@ impl Executor { /// Gets the balance of an account pub fn get_balance(&self, address: Address) -> DatabaseResult { - Ok(self.backend.basic(address)?.map(|acc| acc.balance).unwrap_or_default()) + Ok(self.backend.basic_ref(address)?.map(|acc| acc.balance).unwrap_or_default()) } /// Set the nonce of an account. pub fn set_nonce(&mut self, address: Address, nonce: u64) -> DatabaseResult<&mut Self> { - let mut account = self.backend.basic(address)?.unwrap_or_default(); + let mut account = self.backend.basic_ref(address)?.unwrap_or_default(); account.nonce = nonce; self.backend.insert_account_info(address, account); @@ -483,7 +483,7 @@ impl Executor { // we only clone the test contract and cheatcode accounts, that's all we need to evaluate // success for addr in [address, CHEATCODE_ADDRESS] { - let acc = self.backend.basic(addr)?.unwrap_or_default(); + let acc = self.backend.basic_ref(addr)?.unwrap_or_default(); backend.insert_account_info(addr, acc); } @@ -682,7 +682,7 @@ pub struct RawCallResult { /// The raw output of the execution pub out: Option, /// The chisel state - pub chisel_state: Option<(Stack, Memory, InstructionResult)>, + pub chisel_state: Option<(Stack, SharedMemory, InstructionResult)>, } impl Default for RawCallResult { diff --git a/crates/evm/evm/src/inspectors/access_list.rs b/crates/evm/evm/src/inspectors/access_list.rs index 8d193fb05589d..56ad89729973d 100644 --- a/crates/evm/evm/src/inspectors/access_list.rs +++ b/crates/evm/evm/src/inspectors/access_list.rs @@ -3,7 +3,7 @@ use ethers_core::types::transaction::eip2930::{AccessList, AccessListItem}; use foundry_utils::types::{ToAlloy, ToEthers}; use hashbrown::{HashMap, HashSet}; use revm::{ - interpreter::{opcode, InstructionResult, Interpreter}, + interpreter::{opcode, Interpreter}, Database, EVMData, Inspector, }; @@ -51,11 +51,7 @@ impl AccessListTracer { impl Inspector for AccessListTracer { #[inline] - fn step( - &mut self, - interpreter: &mut Interpreter, - _data: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn step(&mut self, interpreter: &mut Interpreter<'_>, _data: &mut EVMData<'_, DB>) { match interpreter.current_opcode() { opcode::SLOAD | opcode::SSTORE => { if let Ok(slot) = interpreter.stack().peek(0) { @@ -85,6 +81,5 @@ impl Inspector for AccessListTracer { } _ => (), } - InstructionResult::Continue } } diff --git a/crates/evm/evm/src/inspectors/chisel_state.rs b/crates/evm/evm/src/inspectors/chisel_state.rs index 614cafeeb9679..6a32950b80fca 100644 --- a/crates/evm/evm/src/inspectors/chisel_state.rs +++ b/crates/evm/evm/src/inspectors/chisel_state.rs @@ -1,5 +1,5 @@ use revm::{ - interpreter::{InstructionResult, Interpreter, Memory, Stack}, + interpreter::{InstructionResult, Interpreter, SharedMemory, Stack}, Database, Inspector, }; @@ -9,7 +9,7 @@ pub struct ChiselState { /// The PC of the final instruction pub final_pc: usize, /// The final state of the REPL contract call - pub state: Option<(Stack, Memory, InstructionResult)>, + pub state: Option<(Stack, SharedMemory, InstructionResult)>, } impl ChiselState { @@ -22,18 +22,15 @@ impl ChiselState { impl Inspector for ChiselState { #[inline] - fn step_end( - &mut self, - interp: &mut Interpreter, - _: &mut revm::EVMData<'_, DB>, - eval: InstructionResult, - ) -> InstructionResult { + fn step_end(&mut self, interp: &mut Interpreter<'_>, _: &mut revm::EVMData<'_, DB>) { // If we are at the final pc of the REPL contract execution, set the state. // Subtraction can't overflow because `pc` is always at least 1 in `step_end`. if self.final_pc == interp.program_counter() - 1 { - self.state = Some((interp.stack().clone(), interp.memory.clone(), eval)) + self.state = Some(( + interp.stack().clone(), + interp.shared_memory.clone(), + interp.instruction_result, + )) } - // Pass on [revm::Return] from arguments - eval } } diff --git a/crates/evm/evm/src/inspectors/debugger.rs b/crates/evm/evm/src/inspectors/debugger.rs index be06fc7225592..27782ca474b03 100644 --- a/crates/evm/evm/src/inspectors/debugger.rs +++ b/crates/evm/evm/src/inspectors/debugger.rs @@ -45,11 +45,7 @@ impl Debugger { impl Inspector for Debugger { #[inline] - fn step( - &mut self, - interpreter: &mut Interpreter, - data: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn step(&mut self, interpreter: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { let pc = interpreter.program_counter(); let op = interpreter.current_opcode(); @@ -77,13 +73,11 @@ impl Inspector for Debugger { self.arena.arena[self.head].steps.push(DebugStep { pc, stack: interpreter.stack().data().clone(), - memory: interpreter.memory.clone(), + memory: interpreter.shared_memory.clone(), instruction: Instruction::OpCode(op), push_bytes, total_gas_used, }); - - InstructionResult::Continue } #[inline] diff --git a/crates/evm/evm/src/inspectors/printer.rs b/crates/evm/evm/src/inspectors/printer.rs index 016e1c2e16309..02a47fda178aa 100644 --- a/crates/evm/evm/src/inspectors/printer.rs +++ b/crates/evm/evm/src/inspectors/printer.rs @@ -11,7 +11,7 @@ pub struct TracePrinter; impl Inspector for TracePrinter { // get opcode by calling `interp.contract.opcode(interp.program_counter())`. // all other information can be obtained from interp. - fn step(&mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>) -> InstructionResult { + fn step(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { let opcode = interp.current_opcode(); let opcode_str = opcode::OPCODE_JUMPMAP[opcode as usize]; let gas_remaining = interp.gas.remaining(); @@ -26,11 +26,9 @@ impl Inspector for TracePrinter { interp.gas.refunded(), interp.gas.refunded(), interp.stack.data(), - interp.memory.data().len(), - hex::encode(interp.memory.data()), + interp.shared_memory.len(), + hex::encode(interp.shared_memory.context_memory()), ); - - InstructionResult::Continue } fn call( diff --git a/crates/evm/evm/src/inspectors/stack.rs b/crates/evm/evm/src/inspectors/stack.rs index 0bc25df44cb37..34795bca2de29 100644 --- a/crates/evm/evm/src/inspectors/stack.rs +++ b/crates/evm/evm/src/inspectors/stack.rs @@ -10,7 +10,8 @@ use foundry_evm_coverage::HitMaps; use foundry_evm_traces::CallTraceArena; use revm::{ interpreter::{ - return_revert, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, Memory, Stack, + return_revert, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, SharedMemory, + Stack, }, primitives::{BlockEnv, Env}, EVMData, Inspector, @@ -191,7 +192,7 @@ pub struct InspectorData { pub coverage: Option, pub cheatcodes: Option, pub script_wallets: Vec, - pub chisel_state: Option<(Stack, Memory, InstructionResult)>, + pub chisel_state: Option<(Stack, SharedMemory, InstructionResult)>, } /// An inspector that calls multiple inspectors in sequence. @@ -354,11 +355,8 @@ impl InspectorStack { } impl Inspector for InspectorStack { - fn initialize_interp( - &mut self, - interpreter: &mut Interpreter, - data: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn initialize_interp(&mut self, interpreter: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + let res = interpreter.instruction_result; call_inspectors!( [ &mut self.debugger, @@ -369,23 +367,19 @@ impl Inspector for InspectorStack { &mut self.printer ], |inspector| { - let status = inspector.initialize_interp(interpreter, data); + inspector.initialize_interp(interpreter, data); // Allow inspectors to exit early - if status != InstructionResult::Continue { - return status + if interpreter.instruction_result != res { + #[allow(clippy::needless_return)] + return } } ); - - InstructionResult::Continue } - fn step( - &mut self, - interpreter: &mut Interpreter, - data: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn step(&mut self, interpreter: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + let res = interpreter.instruction_result; call_inspectors!( [ &mut self.fuzzer, @@ -397,16 +391,15 @@ impl Inspector for InspectorStack { &mut self.printer ], |inspector| { - let status = inspector.step(interpreter, data); + inspector.step(interpreter, data); // Allow inspectors to exit early - if status != InstructionResult::Continue { - return status + if interpreter.instruction_result != res { + #[allow(clippy::needless_return)] + return } } ); - - InstructionResult::Continue } fn log( @@ -424,12 +417,8 @@ impl Inspector for InspectorStack { ); } - fn step_end( - &mut self, - interpreter: &mut Interpreter, - data: &mut EVMData<'_, DB>, - status: InstructionResult, - ) -> InstructionResult { + fn step_end(&mut self, interpreter: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { + let res = interpreter.instruction_result; call_inspectors!( [ &mut self.debugger, @@ -440,16 +429,15 @@ impl Inspector for InspectorStack { &mut self.chisel_state ], |inspector| { - let status = inspector.step_end(interpreter, data, status); + inspector.step_end(interpreter, data); // Allow inspectors to exit early - if status != InstructionResult::Continue { - return status + if interpreter.instruction_result != res { + #[allow(clippy::needless_return)] + return } } ); - - InstructionResult::Continue } fn call( @@ -471,6 +459,7 @@ impl Inspector for InspectorStack { let (status, gas, retdata) = inspector.call(data, call); // Allow inspectors to exit early + #[allow(clippy::needless_return)] if status != InstructionResult::Continue { return (status, gas, retdata) } diff --git a/crates/evm/fuzz/src/inspector.rs b/crates/evm/fuzz/src/inspector.rs index fe1b76c58a250..21517805ce3f1 100644 --- a/crates/evm/fuzz/src/inspector.rs +++ b/crates/evm/fuzz/src/inspector.rs @@ -20,17 +20,12 @@ pub struct Fuzzer { impl Inspector for Fuzzer { #[inline] - fn step( - &mut self, - interpreter: &mut Interpreter, - _: &mut EVMData<'_, DB>, - ) -> InstructionResult { + fn step(&mut self, interpreter: &mut Interpreter<'_>, _: &mut EVMData<'_, DB>) { // We only collect `stack` and `memory` data before and after calls. if self.collect { self.collect_data(interpreter); self.collect = false; } - InstructionResult::Continue } #[inline] @@ -74,7 +69,7 @@ impl Inspector for Fuzzer { impl Fuzzer { /// Collects `stack` and `memory` values into the fuzz dictionary. - fn collect_data(&mut self, interpreter: &Interpreter) { + fn collect_data(&mut self, interpreter: &Interpreter<'_>) { let mut state = self.fuzz_state.write(); for slot in interpreter.stack().data() { @@ -82,9 +77,9 @@ impl Fuzzer { } // TODO: disabled for now since it's flooding the dictionary - // for index in 0..interpreter.memory.len() / 32 { + // for index in 0..interpreter.shared_memory.len() / 32 { // let mut slot = [0u8; 32]; - // slot.clone_from_slice(interpreter.memory.get_slice(index * 32, 32)); + // slot.clone_from_slice(interpreter.shared_memory.get_slice(index * 32, 32)); // state.insert(slot); // } diff --git a/crates/evm/traces/src/inspector.rs b/crates/evm/traces/src/inspector.rs index 80b34f0f14d31..03f500edda762 100644 --- a/crates/evm/traces/src/inspector.rs +++ b/crates/evm/traces/src/inspector.rs @@ -74,7 +74,7 @@ impl Tracer { } } - fn start_step(&mut self, interp: &Interpreter, data: &EVMData<'_, DB>) { + fn start_step(&mut self, interp: &Interpreter<'_>, data: &EVMData<'_, DB>) { let trace_idx = *self.trace_stack.last().expect("can't start step without starting a trace first"); let node = &mut self.traces.arena[trace_idx]; @@ -87,7 +87,7 @@ impl Tracer { op: OpCode(interp.current_opcode()), contract: interp.contract.address, stack: interp.stack.clone(), - memory: interp.memory.clone(), + memory: interp.shared_memory.clone(), gas: interp.gas.remaining(), gas_refund_counter: interp.gas.refunded() as u64, gas_cost: 0, @@ -96,12 +96,7 @@ impl Tracer { }); } - fn fill_step( - &mut self, - interp: &Interpreter, - data: &EVMData<'_, DB>, - status: InstructionResult, - ) { + fn fill_step(&mut self, interp: &Interpreter<'_>, data: &EVMData<'_, DB>) { let (trace_idx, step_idx) = self.step_stack.pop().expect("can't fill step without starting a step first"); let step = &mut self.traces.arena[trace_idx].trace.steps[step_idx]; @@ -128,32 +123,25 @@ impl Tracer { step.gas_cost = step.gas - interp.gas.remaining(); // Error codes only - if status as u8 > InstructionResult::OutOfGas as u8 { - step.error = Some(format!("{status:?}")); + if interp.instruction_result.is_error() { + step.error = Some(format!("{:?}", interp.instruction_result)); } } } impl Inspector for Tracer { #[inline] - fn step(&mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>) -> InstructionResult { + fn step(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { if self.record_steps { self.start_step(interp, data); } - InstructionResult::Continue } #[inline] - fn step_end( - &mut self, - interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, - status: InstructionResult, - ) -> InstructionResult { + fn step_end(&mut self, interp: &mut Interpreter<'_>, data: &mut EVMData<'_, DB>) { if self.record_steps { - self.fill_step(interp, data, status); + self.fill_step(interp, data); } - status } #[inline] diff --git a/crates/evm/traces/src/lib.rs b/crates/evm/traces/src/lib.rs index 63a08cb8aa191..98b05188d8ffd 100644 --- a/crates/evm/traces/src/lib.rs +++ b/crates/evm/traces/src/lib.rs @@ -14,7 +14,7 @@ use foundry_evm_core::{constants::CHEATCODE_ADDRESS, debug::Instruction, utils:: use foundry_utils::types::ToEthers; use hashbrown::HashMap; use itertools::Itertools; -use revm::interpreter::{opcode, CallContext, InstructionResult, Memory, Stack}; +use revm::interpreter::{opcode, CallContext, InstructionResult, SharedMemory, Stack}; use serde::{Deserialize, Serialize}; use std::{ collections::{BTreeMap, HashSet}, @@ -392,7 +392,7 @@ pub struct CallTraceStep { /// Stack before step execution pub stack: Stack, /// Memory before step execution - pub memory: Memory, + pub memory: SharedMemory, /// Remaining gas before step execution pub gas: u64, /// Gas refund counter before step execution @@ -414,7 +414,7 @@ impl From<&CallTraceStep> for StructLog { error: step.error.clone(), gas: step.gas, gas_cost: step.gas_cost, - memory: Some(convert_memory(step.memory.data())), + memory: Some(convert_memory(step.memory.context_memory())), op: step.op.to_string(), pc: step.pc as u64, refund_counter: if step.gas_refund_counter > 0 { diff --git a/crates/forge/tests/cli/ext_integration.rs b/crates/forge/tests/cli/ext_integration.rs index 55c128b07f500..8a6c0be8c93d0 100644 --- a/crates/forge/tests/cli/ext_integration.rs +++ b/crates/forge/tests/cli/ext_integration.rs @@ -16,7 +16,11 @@ forgetest_external!( // `run: pnpm --version` is ok, `Command::new("pnpm")` isn't. Good job Windows. #[cfg_attr(windows, ignore = "Windows cannot find installed programs")] snekmate, - "pcaversaccio/snekmate" + "pcaversaccio/snekmate", + // 64MiB memory limit: + // - https://github.com/foundry-rs/foundry/pull/6281 + // - https://github.com/bluealloy/revm/issues/865 + &["--memory-limit", &(1u64 << 26).to_string()] ); // Forking tests diff --git a/deny.toml b/deny.toml index 021da25edd9ec..25b3e6a971a68 100644 --- a/deny.toml +++ b/deny.toml @@ -69,6 +69,7 @@ exceptions = [ { allow = ["CC0-1.0"], name = "notify" }, { allow = ["CC0-1.0"], name = "constant_time_eq" }, { allow = ["CC0-1.0"], name = "dunce" }, + { allow = ["CC0-1.0"], name = "aurora-engine-modexp" }, { allow = ["GPL-3.0"], name = "fastrlp" }, { allow = ["GPL-3.0"], name = "fastrlp-derive" },