diff --git a/Cargo.lock b/Cargo.lock index 8d63e75dabec..968181a65683 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -69,6 +69,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "alloy-rlp" version = "0.3.2" @@ -547,9 +553,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -625,6 +631,9 @@ name = "bitflags" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +dependencies = [ + "serde", +] [[package]] name = "bitvec" @@ -940,9 +949,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.23" +version = "4.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03aef18ddf7d879c15ce20f04826ef8418101c7e528014c3eeea13321047dca3" +checksum = "fb690e81c7840c0d7aade59f242ea3b41b9bc27bcd5997890e7702ae4b32e487" dependencies = [ "clap_builder", "clap_derive", @@ -951,9 +960,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.23" +version = "4.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ce6fffb678c9b80a70b6b6de0aad31df727623a70fd9a842c30cd573e2fa98" +checksum = "5ed2e96bc16d8d740f6f48d663eddf4b8a0983e79210fd55479b7bcd0a69860e" dependencies = [ "anstream", "anstyle", @@ -1697,9 +1706,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -2812,9 +2821,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "git2" @@ -3166,6 +3175,11 @@ name = "hashbrown" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "ahash 0.8.3", + "allocator-api2", + "serde", +] [[package]] name = "hashers" @@ -4207,9 +4221,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -4316,9 +4330,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" dependencies = [ "memchr", ] @@ -4429,9 +4443,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "3.9.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126d3e6f3926bfb0fb24495b4f4da50626f547e54956594748e3d8882a0320b4" +checksum = "2a54938017eacd63036332b4ae5c8a49fc8c0c1d6d629893057e4f13609edd06" dependencies = [ "num-traits", ] @@ -5338,6 +5352,8 @@ name = "revm" version = "3.3.0" dependencies = [ "auto_impl", + "once_cell", + "rayon", "revm-interpreter", "revm-precompile", "serde", @@ -5377,12 +5393,13 @@ name = "revm-primitives" version = "1.1.2" dependencies = [ "auto_impl", + "bitflags 2.4.0", "bitvec 1.0.1", "bytes", "derive_more", "enumn", "fixed-hash", - "hashbrown 0.13.2", + "hashbrown 0.14.0", "hex", "hex-literal", "primitive-types", @@ -5390,6 +5407,7 @@ dependencies = [ "ruint", "serde", "sha3", + "to-binary", ] [[package]] @@ -5941,9 +5959,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.171" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" dependencies = [ "serde_derive", ] @@ -5961,9 +5979,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" dependencies = [ "proc-macro2", "quote", @@ -6181,9 +6199,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" @@ -6550,9 +6568,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a79d09ac6b08c1ab3906a2f7cc2e81a0e27c7ae89c63812df75e52bef0751e07" +checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07" dependencies = [ "deranged", "itoa", @@ -6571,9 +6589,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c65469ed6b3a4809d987a41eb1dc918e9bc1d92211cbad7ae82931846f7451" +checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9" dependencies = [ "time-core", ] @@ -6612,6 +6630,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "to-binary" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424552bc848fd1afbcd81f0e8a54b7401b90fd81bb418655ad6dc6d0823bbe3" +dependencies = [ + "hex", +] + [[package]] name = "tokio" version = "1.32.0" diff --git a/crates/anvil/src/config.rs b/crates/anvil/src/config.rs index f262cfb0c559..653847839a27 100644 --- a/crates/anvil/src/config.rs +++ b/crates/anvil/src/config.rs @@ -781,18 +781,19 @@ impl NodeConfig { /// *Note*: only memory based backend for now pub(crate) async fn setup(&mut self) -> mem::Backend { // configure the revm environment + + let mut cfg = CfgEnv::default(); + cfg.spec_id = self.get_hardfork().into(); + cfg.chain_id = rU256::from(self.get_chain_id()); + cfg.limit_contract_code_size = self.code_size_limit; + // EIP-3607 rejects transactions from senders with deployed code. + // If EIP-3607 is enabled it can cause issues during fuzz/invariant tests if the + // caller is a contract. So we disable the check by default. + cfg.disable_eip3607 = true; + cfg.disable_block_gas_limit = self.disable_block_gas_limit; + let mut env = revm::primitives::Env { - cfg: CfgEnv { - spec_id: self.get_hardfork().into(), - chain_id: rU256::from(self.get_chain_id()), - limit_contract_code_size: self.code_size_limit, - // EIP-3607 rejects transactions from senders with deployed code. - // If EIP-3607 is enabled it can cause issues during fuzz/invariant tests if the - // caller is a contract. So we disable the check by default. - disable_eip3607: true, - disable_block_gas_limit: self.disable_block_gas_limit, - ..Default::default() - }, + cfg, block: BlockEnv { gas_limit: self.gas_limit.into(), basefee: self.get_base_fee().into(), diff --git a/crates/anvil/src/eth/backend/mem/inspector.rs b/crates/anvil/src/eth/backend/mem/inspector.rs index ca409b734a1f..9ca7686c618b 100644 --- a/crates/anvil/src/eth/backend/mem/inspector.rs +++ b/crates/anvil/src/eth/backend/mem/inspector.rs @@ -53,23 +53,17 @@ impl revm::Inspector for Inspector { &mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>, - is_static: bool, ) -> InstructionResult { call_inspectors!([&mut self.tracer], |inspector| { - inspector.initialize_interp(interp, data, is_static); + inspector.initialize_interp(interp, data); }); InstructionResult::Continue } #[inline] - fn step( - &mut self, - interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, - is_static: bool, - ) -> InstructionResult { + fn step(&mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>) -> InstructionResult { call_inspectors!([&mut self.tracer], |inspector| { - inspector.step(interp, data, is_static); + inspector.step(interp, data); }); InstructionResult::Continue } @@ -92,11 +86,10 @@ impl revm::Inspector for Inspector { &mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>, - is_static: bool, eval: InstructionResult, ) -> InstructionResult { call_inspectors!([&mut self.tracer], |inspector| { - inspector.step_end(interp, data, is_static, eval); + inspector.step_end(interp, data, eval); }); eval } @@ -106,10 +99,9 @@ impl revm::Inspector for Inspector { &mut self, data: &mut EVMData<'_, DB>, call: &mut CallInputs, - is_static: bool, ) -> (InstructionResult, Gas, Bytes) { call_inspectors!([&mut self.tracer, Some(&mut self.log_collector)], |inspector| { - inspector.call(data, call, is_static); + inspector.call(data, call); }); (InstructionResult::Continue, Gas::new(call.gas_limit), Bytes::new()) @@ -123,10 +115,9 @@ impl revm::Inspector for Inspector { remaining_gas: Gas, ret: InstructionResult, out: Bytes, - is_static: bool, ) -> (InstructionResult, Gas, Bytes) { call_inspectors!([&mut self.tracer], |inspector| { - inspector.call_end(data, inputs, remaining_gas, ret, out.clone(), is_static); + inspector.call_end(data, inputs, remaining_gas, ret, out.clone()); }); (ret, remaining_gas, out) } diff --git a/crates/anvil/src/eth/error.rs b/crates/anvil/src/eth/error.rs index 888f185d5647..8289fd289b37 100644 --- a/crates/anvil/src/eth/error.rs +++ b/crates/anvil/src/eth/error.rs @@ -181,6 +181,9 @@ pub enum InvalidTransactionError { /// Thrown when a legacy tx was signed for a different chain #[error("Incompatible EIP-155 transaction, signed for another chain")] IncompatibleEIP155, + /// Thrown when an access list is used before the berlin hard fork. + #[error("Access lists are not supported before the Berlin hardfork")] + AccessListNotSupported, } impl From for InvalidTransactionError { @@ -203,7 +206,7 @@ impl From for InvalidTransactionError { }) } InvalidTransaction::RejectCallerWithCode => InvalidTransactionError::SenderNoEOA, - InvalidTransaction::LackOfFundForGasLimit { .. } => { + InvalidTransaction::LackOfFundForMaxFee { .. } => { InvalidTransactionError::InsufficientFunds } InvalidTransaction::OverflowPaymentInTransaction => { @@ -217,6 +220,9 @@ impl From for InvalidTransactionError { } InvalidTransaction::NonceTooHigh { .. } => InvalidTransactionError::NonceTooHigh, InvalidTransaction::NonceTooLow { .. } => InvalidTransactionError::NonceTooLow, + InvalidTransaction::AccessListNotSupported => { + InvalidTransactionError::AccessListNotSupported + } } } } diff --git a/crates/anvil/src/genesis.rs b/crates/anvil/src/genesis.rs index 3ab285a1018a..71b64feebd68 100644 --- a/crates/anvil/src/genesis.rs +++ b/crates/anvil/src/genesis.rs @@ -146,7 +146,7 @@ impl From for AccountInfo { AccountInfo { balance: balance.into(), nonce: nonce.unwrap_or_default(), - code_hash: code.as_ref().map(|code| code.hash).unwrap_or(KECCAK_EMPTY), + code_hash: code.as_ref().map(|code| code.hash_slow()).unwrap_or(KECCAK_EMPTY), code, } } diff --git a/crates/evm/src/executor/backend/mod.rs b/crates/evm/src/executor/backend/mod.rs index d286cb8a84b7..3e468f223513 100644 --- a/crates/evm/src/executor/backend/mod.rs +++ b/crates/evm/src/executor/backend/mod.rs @@ -1099,7 +1099,7 @@ impl DatabaseExt for Backend { // prevent issues in the new journalstate, e.g. assumptions that accounts are loaded // if the account is not touched, we reload it, if it's touched we clone it for (addr, acc) in journaled_state.state.iter() { - if acc.is_touched { + if acc.is_touched() { merge_journaled_state_data( b160_to_h160(*addr), journaled_state, diff --git a/crates/evm/src/executor/fork/cache.rs b/crates/evm/src/executor/fork/cache.rs index dbd4cfe747c8..8a5f18dc6edf 100644 --- a/crates/evm/src/executor/fork/cache.rs +++ b/crates/evm/src/executor/fork/cache.rs @@ -1,9 +1,10 @@ //! Cache related abstraction use crate::executor::backend::snapshot::StateSnapshot; -use hashbrown::HashMap as Map; use parking_lot::RwLock; use revm::{ - primitives::{Account, AccountInfo, B160, B256, KECCAK_EMPTY, U256}, + primitives::{ + Account, AccountInfo, AccountStatus, HashMap as Map, B160, B256, KECCAK_EMPTY, U256, + }, DatabaseCommit, }; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; @@ -256,13 +257,17 @@ impl MemDb { let mut storage = self.storage.write(); let mut accounts = self.accounts.write(); for (add, mut acc) in changes { - if acc.is_empty() || acc.is_destroyed { + if acc.is_empty() || acc.is_selfdestructed() { accounts.remove(&add); storage.remove(&add); } else { // insert account - if let Some(code_hash) = - acc.info.code.as_ref().filter(|code| !code.is_empty()).map(|code| code.hash) + if let Some(code_hash) = acc + .info + .code + .as_ref() + .filter(|code| !code.is_empty()) + .map(|code| code.hash_slow()) { acc.info.code_hash = code_hash; } else if acc.info.code_hash.is_zero() { @@ -271,7 +276,7 @@ impl MemDb { accounts.insert(add, acc.info); let acc_storage = storage.entry(add).or_default(); - if acc.storage_cleared { + if acc.status.contains(AccountStatus::Created) { acc_storage.clear(); } for (index, value) in acc.storage { @@ -474,6 +479,7 @@ mod tests { "chain_id": "0x539", "spec_id": "LATEST", "perf_all_precompiles_have_balance": false, + "disable_coinbase_tip": false, "perf_analyse_created_bytecodes": "Analyse", "limit_contract_code_size": 18446744073709551615, "memory_limit": 4294967295 diff --git a/crates/evm/src/executor/fork/init.rs b/crates/evm/src/executor/fork/init.rs index 849b46f51cf0..886129053b1e 100644 --- a/crates/evm/src/executor/fork/init.rs +++ b/crates/evm/src/executor/fork/init.rs @@ -58,17 +58,16 @@ where eyre::bail!("Failed to get block for block number: {}", block_number) }; + let mut cfg = CfgEnv::default(); + cfg.chain_id = u256_to_ru256(override_chain_id.unwrap_or(rpc_chain_id.as_u64()).into()); + cfg.memory_limit = memory_limit; + cfg.limit_contract_code_size = Some(usize::MAX); + // EIP-3607 rejects transactions from senders with deployed code. + // If EIP-3607 is enabled it can cause issues during fuzz/invariant tests if the caller + // is a contract. So we disable the check by default. + cfg.disable_eip3607 = true; let mut env = Env { - cfg: CfgEnv { - chain_id: u256_to_ru256(override_chain_id.unwrap_or(rpc_chain_id.as_u64()).into()), - memory_limit, - limit_contract_code_size: Some(usize::MAX), - // EIP-3607 rejects transactions from senders with deployed code. - // If EIP-3607 is enabled it can cause issues during fuzz/invariant tests if the caller - // is a contract. So we disable the check by default. - disable_eip3607: true, - ..Default::default() - }, + cfg, block: BlockEnv { number: u256_to_ru256(block.number.expect("block number not found").as_u64().into()), timestamp: block.timestamp.into(), diff --git a/crates/evm/src/executor/inspector/access_list.rs b/crates/evm/src/executor/inspector/access_list.rs index 88619de35da0..65e15c300add 100644 --- a/crates/evm/src/executor/inspector/access_list.rs +++ b/crates/evm/src/executor/inspector/access_list.rs @@ -56,7 +56,6 @@ impl Inspector for AccessListTracer { &mut self, interpreter: &mut Interpreter, _data: &mut EVMData<'_, DB>, - _is_static: bool, ) -> InstructionResult { let pc = interpreter.program_counter(); let op = interpreter.contract.bytecode.bytecode()[pc]; diff --git a/crates/evm/src/executor/inspector/cheatcodes/mapping.rs b/crates/evm/src/executor/inspector/cheatcodes/mapping.rs index cf81dc447eb1..0ae5439a938b 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/mapping.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/mapping.rs @@ -91,7 +91,7 @@ pub fn on_evm_step( _data: &mut EVMData<'_, DB>, ) { match interpreter.contract.bytecode.bytecode()[interpreter.program_counter()] { - opcode::SHA3 => { + opcode::KECCAK256 => { if interpreter.stack.peek(1) == Ok(revm::primitives::U256::from(0x40)) { let address = interpreter.contract.address; let offset = interpreter.stack.peek(0).expect("stack size > 1").to::(); diff --git a/crates/evm/src/executor/inspector/cheatcodes/mod.rs b/crates/evm/src/executor/inspector/cheatcodes/mod.rs index 2a0a24b7b06e..e8900054929a 100644 --- a/crates/evm/src/executor/inspector/cheatcodes/mod.rs +++ b/crates/evm/src/executor/inspector/cheatcodes/mod.rs @@ -294,7 +294,6 @@ impl Inspector for Cheatcodes { &mut self, _: &mut Interpreter, data: &mut EVMData<'_, DB>, - _: bool, ) -> InstructionResult { // 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. @@ -312,7 +311,6 @@ impl Inspector for Cheatcodes { &mut self, interpreter: &mut Interpreter, data: &mut EVMData<'_, DB>, - _: bool, ) -> InstructionResult { self.pc = interpreter.program_counter(); @@ -513,7 +511,7 @@ impl Inspector for Cheatcodes { (CALLCODE, 5, 6, true), (STATICCALL, 4, 5, true), (DELEGATECALL, 4, 5, true), - (SHA3, 0, 1, false), + (KECCAK256, 0, 1, false), (LOG0, 0, 1, false), (LOG1, 0, 1, false), (LOG2, 0, 1, false), @@ -568,7 +566,6 @@ impl Inspector for Cheatcodes { &mut self, data: &mut EVMData<'_, DB>, call: &mut CallInputs, - is_static: bool, ) -> (InstructionResult, Gas, bytes::Bytes) { if call.contract == h160_to_b160(CHEATCODE_ADDRESS) { let gas = Gas::new(call.gas_limit); @@ -677,7 +674,7 @@ impl Inspector for Cheatcodes { // because we only need the from, to, value, and data. We can later change this // into 1559, in the cli package, relatively easily once we // know the target chain supports EIP-1559. - if !is_static { + if !call.is_static { if let Err(err) = data .journaled_state .load_account(h160_to_b160(broadcast.new_origin), data.db) @@ -742,7 +739,6 @@ impl Inspector for Cheatcodes { remaining_gas: Gas, status: InstructionResult, retdata: bytes::Bytes, - _: bool, ) -> (InstructionResult, Gas, bytes::Bytes) { if call.contract == h160_to_b160(CHEATCODE_ADDRESS) || call.contract == h160_to_b160(HARDHAT_CONSOLE_ADDRESS) diff --git a/crates/evm/src/executor/inspector/chisel_state.rs b/crates/evm/src/executor/inspector/chisel_state.rs index cb7a2a6c17e7..958e33cb5cd9 100644 --- a/crates/evm/src/executor/inspector/chisel_state.rs +++ b/crates/evm/src/executor/inspector/chisel_state.rs @@ -26,7 +26,6 @@ impl Inspector for ChiselState { &mut self, interp: &mut Interpreter, _: &mut revm::EVMData<'_, DB>, - _: bool, eval: InstructionResult, ) -> InstructionResult { // If we are at the final pc of the REPL contract execution, set the state. diff --git a/crates/evm/src/executor/inspector/coverage.rs b/crates/evm/src/executor/inspector/coverage.rs index b7af6f660901..1a549de04e95 100644 --- a/crates/evm/src/executor/inspector/coverage.rs +++ b/crates/evm/src/executor/inspector/coverage.rs @@ -20,9 +20,8 @@ impl Inspector for CoverageCollector { &mut self, interpreter: &mut Interpreter, _: &mut EVMData<'_, DB>, - _: bool, ) -> InstructionResult { - let hash = b256_to_h256(interpreter.contract.bytecode.hash()); + let hash = b256_to_h256(interpreter.contract.hash); self.maps.entry(hash).or_insert_with(|| { HitMap::new(Bytes::copy_from_slice( interpreter.contract.bytecode.original_bytecode_slice(), @@ -37,9 +36,8 @@ impl Inspector for CoverageCollector { &mut self, interpreter: &mut Interpreter, _: &mut EVMData<'_, DB>, - _: bool, ) -> InstructionResult { - let hash = b256_to_h256(interpreter.contract.bytecode.hash()); + let hash = b256_to_h256(interpreter.contract.hash); self.maps.entry(hash).and_modify(|map| map.hit(interpreter.program_counter())); InstructionResult::Continue diff --git a/crates/evm/src/executor/inspector/debugger.rs b/crates/evm/src/executor/inspector/debugger.rs index e051ad73cf53..a21a0f3247a8 100644 --- a/crates/evm/src/executor/inspector/debugger.rs +++ b/crates/evm/src/executor/inspector/debugger.rs @@ -55,7 +55,6 @@ impl Inspector for Debugger { &mut self, interpreter: &mut Interpreter, data: &mut EVMData<'_, DB>, - _: bool, ) -> InstructionResult { let pc = interpreter.program_counter(); let op = interpreter.contract.bytecode.bytecode()[pc]; @@ -98,7 +97,6 @@ impl Inspector for Debugger { &mut self, data: &mut EVMData<'_, DB>, call: &mut CallInputs, - _: bool, ) -> (InstructionResult, Gas, Bytes) { self.enter( data.journaled_state.depth() as usize, @@ -126,7 +124,6 @@ impl Inspector for Debugger { gas: Gas, status: InstructionResult, retdata: Bytes, - _: bool, ) -> (InstructionResult, Gas, Bytes) { self.exit(); diff --git a/crates/evm/src/executor/inspector/fuzzer.rs b/crates/evm/src/executor/inspector/fuzzer.rs index 17926e887f1d..a7363614a01a 100644 --- a/crates/evm/src/executor/inspector/fuzzer.rs +++ b/crates/evm/src/executor/inspector/fuzzer.rs @@ -25,7 +25,6 @@ impl Inspector for Fuzzer { &mut self, interpreter: &mut Interpreter, _: &mut EVMData<'_, DB>, - _: bool, ) -> InstructionResult { // We only collect `stack` and `memory` data before and after calls. if self.collect { @@ -40,7 +39,6 @@ impl Inspector for Fuzzer { &mut self, data: &mut EVMData<'_, DB>, call: &mut CallInputs, - _: bool, ) -> (InstructionResult, Gas, Bytes) { // We don't want to override the very first call made to the test contract. if self.call_generator.is_some() && data.env.tx.caller != call.context.caller { @@ -62,7 +60,6 @@ impl Inspector for Fuzzer { remaining_gas: Gas, status: InstructionResult, retdata: Bytes, - _: bool, ) -> (InstructionResult, Gas, Bytes) { if let Some(ref mut call_generator) = self.call_generator { call_generator.used = false; diff --git a/crates/evm/src/executor/inspector/logs.rs b/crates/evm/src/executor/inspector/logs.rs index c848e329c9f7..a4124d4695a6 100644 --- a/crates/evm/src/executor/inspector/logs.rs +++ b/crates/evm/src/executor/inspector/logs.rs @@ -57,7 +57,6 @@ impl Inspector for LogCollector { &mut self, _: &mut EVMData<'_, DB>, call: &mut CallInputs, - _: bool, ) -> (InstructionResult, Gas, Bytes) { if call.contract == h160_to_b160(HARDHAT_CONSOLE_ADDRESS) { let (status, reason) = self.hardhat_log(call.input.to_vec()); diff --git a/crates/evm/src/executor/inspector/printer.rs b/crates/evm/src/executor/inspector/printer.rs index 6b694f12f0ee..0f8d9127bf87 100644 --- a/crates/evm/src/executor/inspector/printer.rs +++ b/crates/evm/src/executor/inspector/printer.rs @@ -12,12 +12,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>, - _: bool, - ) -> InstructionResult { + fn step(&mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>) -> InstructionResult { let opcode = interp.current_opcode(); let opcode_str = opcode::OPCODE_JUMPMAP[opcode as usize]; let gas_remaining = interp.gas.remaining(); @@ -43,13 +38,12 @@ impl Inspector for TracePrinter { &mut self, _data: &mut EVMData<'_, DB>, inputs: &mut CallInputs, - is_static: bool, ) -> (InstructionResult, Gas, Bytes) { println!( "SM CALL: {:?},context:{:?}, is_static:{:?}, transfer:{:?}, input_size:{:?}", inputs.contract, inputs.context, - is_static, + inputs.is_static, inputs.transfer, inputs.input.len(), ); diff --git a/crates/evm/src/executor/inspector/stack.rs b/crates/evm/src/executor/inspector/stack.rs index 7c22a4d65d55..d626fc3d4e33 100644 --- a/crates/evm/src/executor/inspector/stack.rs +++ b/crates/evm/src/executor/inspector/stack.rs @@ -326,7 +326,6 @@ impl InspectorStack { remaining_gas: Gas, status: InstructionResult, retdata: Bytes, - is_static: bool, ) -> (InstructionResult, Gas, Bytes) { call_inspectors!( [ @@ -339,14 +338,8 @@ impl InspectorStack { &mut self.printer ], |inspector| { - let (new_status, new_gas, new_retdata) = inspector.call_end( - data, - call, - remaining_gas, - status, - retdata.clone(), - is_static, - ); + let (new_status, new_gas, new_retdata) = + inspector.call_end(data, call, remaining_gas, status, retdata.clone()); // If the inspector returns a different status or a revert with a non-empty message, // we assume it wants to tell us something @@ -367,7 +360,6 @@ impl Inspector for InspectorStack { &mut self, interpreter: &mut Interpreter, data: &mut EVMData<'_, DB>, - is_static: bool, ) -> InstructionResult { call_inspectors!( [ @@ -379,7 +371,7 @@ impl Inspector for InspectorStack { &mut self.printer ], |inspector| { - let status = inspector.initialize_interp(interpreter, data, is_static); + let status = inspector.initialize_interp(interpreter, data); // Allow inspectors to exit early if status != InstructionResult::Continue { @@ -395,7 +387,6 @@ impl Inspector for InspectorStack { &mut self, interpreter: &mut Interpreter, data: &mut EVMData<'_, DB>, - is_static: bool, ) -> InstructionResult { call_inspectors!( [ @@ -408,7 +399,7 @@ impl Inspector for InspectorStack { &mut self.printer ], |inspector| { - let status = inspector.step(interpreter, data, is_static); + let status = inspector.step(interpreter, data); // Allow inspectors to exit early if status != InstructionResult::Continue { @@ -439,7 +430,6 @@ impl Inspector for InspectorStack { &mut self, interpreter: &mut Interpreter, data: &mut EVMData<'_, DB>, - is_static: bool, status: InstructionResult, ) -> InstructionResult { call_inspectors!( @@ -452,7 +442,7 @@ impl Inspector for InspectorStack { &mut self.chisel_state ], |inspector| { - let status = inspector.step_end(interpreter, data, is_static, status); + let status = inspector.step_end(interpreter, data, status); // Allow inspectors to exit early if status != InstructionResult::Continue { @@ -468,7 +458,6 @@ impl Inspector for InspectorStack { &mut self, data: &mut EVMData<'_, DB>, call: &mut CallInputs, - is_static: bool, ) -> (InstructionResult, Gas, Bytes) { call_inspectors!( [ @@ -481,7 +470,7 @@ impl Inspector for InspectorStack { &mut self.printer ], |inspector| { - let (status, gas, retdata) = inspector.call(data, call, is_static); + let (status, gas, retdata) = inspector.call(data, call); // Allow inspectors to exit early if status != InstructionResult::Continue { @@ -500,9 +489,8 @@ impl Inspector for InspectorStack { remaining_gas: Gas, status: InstructionResult, retdata: Bytes, - is_static: bool, ) -> (InstructionResult, Gas, Bytes) { - let res = self.do_call_end(data, call, remaining_gas, status, retdata, is_static); + let res = self.do_call_end(data, call, remaining_gas, status, retdata); if matches!(res.0, return_revert!()) { // Encountered a revert, since cheatcodes may have altered the evm state in such a way diff --git a/crates/evm/src/executor/inspector/tracer.rs b/crates/evm/src/executor/inspector/tracer.rs index 5d5c80ba6b55..c8851edf7ec7 100644 --- a/crates/evm/src/executor/inspector/tracer.rs +++ b/crates/evm/src/executor/inspector/tracer.rs @@ -150,12 +150,7 @@ impl Tracer { impl Inspector for Tracer { #[inline] - fn step( - &mut self, - interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, - _is_static: bool, - ) -> InstructionResult { + fn step(&mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>) -> InstructionResult { if self.record_steps { self.start_step(interp, data); } @@ -167,7 +162,6 @@ impl Inspector for Tracer { &mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>, - _: bool, status: InstructionResult, ) -> InstructionResult { if self.record_steps { @@ -189,7 +183,6 @@ impl Inspector for Tracer { &mut self, data: &mut EVMData<'_, DB>, inputs: &mut CallInputs, - _: bool, ) -> (InstructionResult, Gas, Bytes) { let (from, to) = match inputs.context.scheme { CallScheme::DelegateCall | CallScheme::CallCode => { @@ -218,7 +211,6 @@ impl Inspector for Tracer { gas: Gas, status: InstructionResult, retdata: Bytes, - _: bool, ) -> (InstructionResult, Gas, Bytes) { self.fill_trace( status, diff --git a/crates/evm/src/executor/opts.rs b/crates/evm/src/executor/opts.rs index 944a46206dfe..e572ff81dbf9 100644 --- a/crates/evm/src/executor/opts.rs +++ b/crates/evm/src/executor/opts.rs @@ -93,6 +93,16 @@ impl EvmOpts { /// Returns the `revm::Env` configured with only local settings pub fn local_evm_env(&self) -> revm::primitives::Env { + let mut cfg = CfgEnv::default(); + cfg.chain_id = rU256::from(self.env.chain_id.unwrap_or(foundry_common::DEV_CHAIN_ID)); + cfg.spec_id = SpecId::MERGE; + cfg.limit_contract_code_size = self.env.code_size_limit.or(Some(usize::MAX)); + cfg.memory_limit = self.memory_limit; + // EIP-3607 rejects transactions from senders with deployed code. + // If EIP-3607 is enabled it can cause issues during fuzz/invariant tests if the + // caller is a contract. So we disable the check by default. + cfg.disable_eip3607 = true; + revm::primitives::Env { block: BlockEnv { number: rU256::from(self.env.block_number), @@ -103,17 +113,7 @@ impl EvmOpts { basefee: rU256::from(self.env.block_base_fee_per_gas), gas_limit: self.gas_limit().into(), }, - cfg: CfgEnv { - chain_id: rU256::from(self.env.chain_id.unwrap_or(foundry_common::DEV_CHAIN_ID)), - spec_id: SpecId::MERGE, - limit_contract_code_size: self.env.code_size_limit.or(Some(usize::MAX)), - memory_limit: self.memory_limit, - // EIP-3607 rejects transactions from senders with deployed code. - // If EIP-3607 is enabled it can cause issues during fuzz/invariant tests if the - // caller is a contract. So we disable the check by default. - disable_eip3607: true, - ..Default::default() - }, + cfg, tx: TxEnv { gas_price: rU256::from(self.env.gas_price.unwrap_or_default()), gas_limit: self.gas_limit().as_u64(), diff --git a/crates/evm/src/fuzz/strategies/state.rs b/crates/evm/src/fuzz/strategies/state.rs index 2cad56de2498..ba62a0eb2256 100644 --- a/crates/evm/src/fuzz/strategies/state.rs +++ b/crates/evm/src/fuzz/strategies/state.rs @@ -268,7 +268,7 @@ pub fn collect_created_contracts( for (address, account) in state_changeset { if !setup_contracts.contains_key(&b160_to_h160(*address)) { - if let (true, Some(code)) = (&account.is_touched, &account.info.code) { + if let (true, Some(code)) = (&account.is_touched(), &account.info.code) { if !code.is_empty() { if let Some((artifact, (abi, _))) = project_contracts.find_by_code(code.bytes()) { diff --git a/crates/evm/test-data/storage.json b/crates/evm/test-data/storage.json index 41114b2cc39b..7544ef1be56c 100644 --- a/crates/evm/test-data/storage.json +++ b/crates/evm/test-data/storage.json @@ -1 +1 @@ -{"meta":{"cfg_env":{"chain_id":"0x1","spec_id":"LATEST","perf_all_precompiles_have_balance":false,"memory_limit":4294967295, "perf_analyse_created_bytecodes":"Analyse", "limit_contract_code_size": 24576},"block_env":{"number":"0xdc42b8","coinbase":"0x0000000000000000000000000000000000000000","timestamp":"0x1","difficulty":"0x0","basefee":"0x0","gas_limit":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},"hosts":["mainnet.infura.io"]},"accounts":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"balance":"0x0","code_hash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","code":null,"nonce":0}},"storage":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"0x0":"0x0","0x1":"0x0","0x2":"0x0","0x3":"0x0","0x4":"0x0","0x5":"0x0","0x6":"0x0","0x7":"0x0","0x8":"0x0","0x9":"0x0"}},"block_hashes":{}} \ No newline at end of file +{"meta":{"cfg_env":{"chain_id":"0x1","spec_id":"LATEST","perf_all_precompiles_have_balance":false,"memory_limit":4294967295, "perf_analyse_created_bytecodes":"Analyse", "limit_contract_code_size": 24576, "disable_coinbase_tip": false},"block_env":{"number":"0xdc42b8","coinbase":"0x0000000000000000000000000000000000000000","timestamp":"0x1","difficulty":"0x0","basefee":"0x0","gas_limit":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},"hosts":["mainnet.infura.io"]},"accounts":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"balance":"0x0","code_hash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","code":null,"nonce":0}},"storage":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"0x0":"0x0","0x1":"0x0","0x2":"0x0","0x3":"0x0","0x4":"0x0","0x5":"0x0","0x6":"0x0","0x7":"0x0","0x8":"0x0","0x9":"0x0"}},"block_hashes":{}} \ No newline at end of file diff --git a/crates/forge/bin/cmd/inspect.rs b/crates/forge/bin/cmd/inspect.rs index c4c955f6486f..1359067578b9 100644 --- a/crates/forge/bin/cmd/inspect.rs +++ b/crates/forge/bin/cmd/inspect.rs @@ -275,7 +275,7 @@ macro_rules! impl_value_enum { (enum $name:ident { $($field:ident => $main:literal $(| $alias:literal)*),+ $(,)? }) => { impl $name { /// All the variants of this enum. - pub const ALL: &[Self] = &[$(Self::$field),+]; + pub const ALL: &'static [Self] = &[$(Self::$field),+]; /// Returns the string representation of `self`. #[inline] diff --git a/crates/forge/src/lib.rs b/crates/forge/src/lib.rs index 24bebfd7c138..99af3a7e9841 100644 --- a/crates/forge/src/lib.rs +++ b/crates/forge/src/lib.rs @@ -3,6 +3,7 @@ use foundry_config::{ validate_profiles, Config, FuzzConfig, InlineConfig, InlineConfigError, InlineConfigParser, InvariantConfig, NatSpec, }; + use proptest::test_runner::{RngAlgorithm, TestRng, TestRunner}; use std::path::Path;