From d934e50f9d456006c12f7cefc67e629a8bcc7cf2 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:36:37 +0100 Subject: [PATCH 1/7] chore: abstract away hashbrown --- Cargo.lock | 3 --- Cargo.toml | 10 ++-------- crates/anvil/src/eth/backend/cheats.rs | 3 +-- crates/anvil/src/eth/backend/db.rs | 4 ++-- crates/anvil/src/eth/backend/mem/state.rs | 13 ++++++------- crates/config/Cargo.toml | 2 +- crates/evm/core/Cargo.toml | 1 + crates/evm/core/src/backend/snapshot.rs | 8 ++++---- crates/evm/evm/Cargo.toml | 8 +++----- crates/evm/evm/src/lib.rs | 8 +++++++- crates/evm/fuzz/Cargo.toml | 1 - crates/evm/fuzz/src/strategies/calldata.rs | 3 +-- crates/evm/fuzz/src/strategies/state.rs | 3 +-- crates/evm/traces/Cargo.toml | 1 - crates/evm/traces/src/identifier/signatures.rs | 7 +++++-- crates/forge/bin/cmd/remappings.rs | 9 ++++----- crates/forge/src/gas_report.rs | 6 ++++-- crates/verify/src/etherscan/mod.rs | 3 ++- 18 files changed, 44 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dea2c7c4d0ab..24aa79340e4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3391,7 +3391,6 @@ dependencies = [ "foundry-evm-coverage", "foundry-evm-fuzz", "foundry-evm-traces", - "hashbrown 0.14.3", "itertools 0.12.1", "parking_lot", "proptest", @@ -3469,7 +3468,6 @@ dependencies = [ "foundry-evm-core", "foundry-evm-coverage", "foundry-evm-traces", - "hashbrown 0.14.3", "itertools 0.12.1", "parking_lot", "proptest", @@ -3496,7 +3494,6 @@ dependencies = [ "foundry-config", "foundry-evm-core", "futures", - "hashbrown 0.14.3", "itertools 0.12.1", "once_cell", "revm-inspectors", diff --git a/Cargo.toml b/Cargo.toml index 860175871679..fb09fa0132b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -142,8 +142,8 @@ foundry-compilers = { version = "0.3.13", default-features = false } ## revm # no default features to avoid c-kzg -revm = { version = "7.1", default-features = false } -revm-primitives = { version = "3", default-features = false } +revm = { version = "7.1", default-features = false, features = ["std"] } +revm-primitives = { version = "3", default-features = false, features = ["std"] } revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "ba0b6ab", features = [ "serde", ] } @@ -211,9 +211,3 @@ axum = "0.6" hyper = "0.14" tower = "0.4" tower-http = "0.4" - -# [patch.crates-io] -# revm = { path = "../../danipopes/revm/crates/revm" } -# revm-interpreter = { path = "../../danipopes/revm/crates/interpreter" } -# revm-primitives = { path = "../../danipopes/revm/crates/primitives" } -# revm-precompile = { path = "../../danipopes/revm/crates/precompile" } diff --git a/crates/anvil/src/eth/backend/cheats.rs b/crates/anvil/src/eth/backend/cheats.rs index 949ea10e7a33..0dc3189b07eb 100644 --- a/crates/anvil/src/eth/backend/cheats.rs +++ b/crates/anvil/src/eth/backend/cheats.rs @@ -2,9 +2,8 @@ use alloy_primitives::{Address, Signature}; use anvil_core::eth::transaction::impersonated_signature; -use foundry_evm::hashbrown::HashSet; use parking_lot::RwLock; -use std::sync::Arc; +use std::{collections::HashSet, sync::Arc}; /// Manages user modifications that may affect the node's behavior /// diff --git a/crates/anvil/src/eth/backend/db.rs b/crates/anvil/src/eth/backend/db.rs index 2630d19a7663..31e60ddbe4f5 100644 --- a/crates/anvil/src/eth/backend/db.rs +++ b/crates/anvil/src/eth/backend/db.rs @@ -8,10 +8,9 @@ use foundry_common::errors::FsPathError; use foundry_evm::{ backend::{DatabaseError, DatabaseResult, MemDb, RevertSnapshotAction, StateSnapshot}, fork::BlockchainDb, - hashbrown::HashMap, revm::{ db::{CacheDB, DatabaseRef, DbAccount}, - primitives::{BlockEnv, Bytecode, KECCAK_EMPTY}, + primitives::{BlockEnv, Bytecode, HashMap, KECCAK_EMPTY}, Database, DatabaseCommit, }, }; @@ -225,6 +224,7 @@ impl> MaybeHashDatabase for CacheDB { fn maybe_as_hash_db(&self) -> Option<(AsHashDB, B256)> { Some(trie_hash_db(&self.accounts)) } + fn clear_into_snapshot(&mut self) -> StateSnapshot { let db_accounts = std::mem::take(&mut self.accounts); let mut accounts = HashMap::new(); diff --git a/crates/anvil/src/eth/backend/mem/state.rs b/crates/anvil/src/eth/backend/mem/state.rs index af936578d04a..29a774f182ee 100644 --- a/crates/anvil/src/eth/backend/mem/state.rs +++ b/crates/anvil/src/eth/backend/mem/state.rs @@ -7,17 +7,16 @@ use alloy_rpc_types::state::StateOverride; use anvil_core::eth::trie::RefSecTrieDBMut; use foundry_evm::{ backend::DatabaseError, - hashbrown::HashMap as Map, revm::{ db::{CacheDB, DatabaseRef, DbAccount}, - primitives::{AccountInfo, Bytecode}, + primitives::{AccountInfo, Bytecode, HashMap}, }, }; use memory_db::HashKey; use trie_db::TrieMut; /// Returns storage trie of an account as `HashDB` -pub fn storage_trie_db(storage: &Map) -> (AsHashDB, B256) { +pub fn storage_trie_db(storage: &HashMap) -> (AsHashDB, B256) { // Populate DB with full trie from entries. let (db, root) = { let mut db = , _>>::default(); @@ -38,7 +37,7 @@ pub fn storage_trie_db(storage: &Map) -> (AsHashDB, B256) { } /// Returns the account data as `HashDB` -pub fn trie_hash_db(accounts: &Map) -> (AsHashDB, B256) { +pub fn trie_hash_db(accounts: &HashMap) -> (AsHashDB, B256) { let accounts = trie_accounts(accounts); // Populate DB with full trie from entries. @@ -58,7 +57,7 @@ pub fn trie_hash_db(accounts: &Map) -> (AsHashDB, B256) { } /// Returns all RLP-encoded Accounts -pub fn trie_accounts(accounts: &Map) -> Vec<(Address, Bytes)> { +pub fn trie_accounts(accounts: &HashMap) -> Vec<(Address, Bytes)> { accounts .iter() .map(|(address, account)| { @@ -68,12 +67,12 @@ pub fn trie_accounts(accounts: &Map) -> Vec<(Address, Bytes) .collect() } -pub fn state_merkle_trie_root(accounts: &Map) -> B256 { +pub fn state_merkle_trie_root(accounts: &HashMap) -> B256 { trie_hash_db(accounts).1 } /// Returns the RLP for this account. -pub fn trie_account_rlp(info: &AccountInfo, storage: &Map) -> Bytes { +pub fn trie_account_rlp(info: &AccountInfo, storage: &HashMap) -> Bytes { let mut out: Vec = Vec::new(); let list: [&dyn Encodable; 4] = [&info.nonce, &info.balance, &storage_trie_db(storage).1, &info.code_hash]; diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index b3f4c514a766..8dd9f0cb168f 100644 --- a/crates/config/Cargo.toml +++ b/crates/config/Cargo.toml @@ -16,7 +16,7 @@ foundry-compilers = { workspace = true, features = ["svm-solc"] } alloy-chains = { workspace = true, features = ["serde"] } alloy-primitives = { workspace = true, features = ["serde"] } -revm-primitives = { workspace = true, default-features = false, features = ["std"] } +revm-primitives.workspace = true dirs-next = "2" dunce = "1" diff --git a/crates/evm/core/Cargo.toml b/crates/evm/core/Cargo.toml index 7e4ea3c218d2..a55ecdd0c2d9 100644 --- a/crates/evm/core/Cargo.toml +++ b/crates/evm/core/Cargo.toml @@ -39,6 +39,7 @@ revm-inspectors.workspace = true arrayvec.workspace = true auto_impl = "1" +arrayvec.workspace = true derive_more.workspace = true eyre = "0.6" futures = "0.3" diff --git a/crates/evm/core/src/backend/snapshot.rs b/crates/evm/core/src/backend/snapshot.rs index 53ce6f7ddb35..4c0c665f299e 100644 --- a/crates/evm/core/src/backend/snapshot.rs +++ b/crates/evm/core/src/backend/snapshot.rs @@ -1,6 +1,6 @@ use alloy_primitives::{Address, B256, U256}; use revm::{ - primitives::{AccountInfo, Env, HashMap as Map}, + primitives::{AccountInfo, Env, HashMap}, JournaledState, }; use serde::{Deserialize, Serialize}; @@ -8,9 +8,9 @@ use serde::{Deserialize, Serialize}; /// A minimal abstraction of a state at a certain point in time #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct StateSnapshot { - pub accounts: Map, - pub storage: Map>, - pub block_hashes: Map, + pub accounts: HashMap, + pub storage: HashMap>, + pub block_hashes: HashMap, } /// Represents a snapshot taken during evm execution diff --git a/crates/evm/evm/Cargo.toml b/crates/evm/evm/Cargo.toml index a1857b303d3a..9336ffff740e 100644 --- a/crates/evm/evm/Cargo.toml +++ b/crates/evm/evm/Cargo.toml @@ -24,7 +24,6 @@ alloy-dyn-abi = { workspace = true, features = ["arbitrary", "eip712"] } alloy-json-abi.workspace = true alloy-primitives = { workspace = true, features = ["serde", "getrandom", "arbitrary", "rlp"] } alloy-sol-types.workspace = true -hashbrown = { version = "0.14", features = ["serde"] } revm = { workspace = true, default-features = false, features = [ "std", "serde", @@ -36,14 +35,13 @@ revm = { workspace = true, default-features = false, features = [ ] } revm-inspectors.workspace = true -itertools.workspace = true - arrayvec.workspace = true eyre = "0.6" hex.workspace = true +itertools.workspace = true parking_lot = "0.12" proptest = "1" +rand.workspace = true +rayon = "1" thiserror = "1" tracing = "0.1" -rayon = "1" -rand.workspace = true diff --git a/crates/evm/evm/src/lib.rs b/crates/evm/evm/src/lib.rs index 7c69c1823831..aa5386b3e047 100644 --- a/crates/evm/evm/src/lib.rs +++ b/crates/evm/evm/src/lib.rs @@ -17,4 +17,10 @@ pub use foundry_evm_traces as traces; // TODO: We should probably remove these, but it's a pretty big breaking change. #[doc(hidden)] -pub use {hashbrown, revm}; +pub use revm; + +#[doc(hidden)] +#[deprecated = "use `{hash_map, hash_set, HashMap, HashSet}` in `std::collections` or `revm::primitives` instead"] +pub mod hashbrown { + pub use revm::primitives::{hash_map, hash_set, HashMap, HashSet}; +} diff --git a/crates/evm/fuzz/Cargo.toml b/crates/evm/fuzz/Cargo.toml index 47b578728514..7ec4a381b107 100644 --- a/crates/evm/fuzz/Cargo.toml +++ b/crates/evm/fuzz/Cargo.toml @@ -33,7 +33,6 @@ revm = { workspace = true, default-features = false, features = [ arbitrary = "1.3.1" eyre = "0.6" -hashbrown = { version = "0.14", features = ["serde"] } itertools.workspace = true parking_lot = "0.12" proptest = "1" diff --git a/crates/evm/fuzz/src/strategies/calldata.rs b/crates/evm/fuzz/src/strategies/calldata.rs index cb56f3330b0d..124c705a6832 100644 --- a/crates/evm/fuzz/src/strategies/calldata.rs +++ b/crates/evm/fuzz/src/strategies/calldata.rs @@ -3,9 +3,8 @@ use alloy_dyn_abi::JsonAbiExt; use alloy_json_abi::Function; use alloy_primitives::{Address, Bytes}; use foundry_config::FuzzDictionaryConfig; -use hashbrown::HashSet; use proptest::prelude::{BoxedStrategy, Strategy}; -use std::{fmt, sync::Arc}; +use std::{collections::HashSet, fmt, sync::Arc}; /// Clonable wrapper around [CalldataFuzzDictionary]. #[derive(Debug, Clone)] diff --git a/crates/evm/fuzz/src/strategies/state.rs b/crates/evm/fuzz/src/strategies/state.rs index cf2f6ec6e8a3..d7e7ab6da019 100644 --- a/crates/evm/fuzz/src/strategies/state.rs +++ b/crates/evm/fuzz/src/strategies/state.rs @@ -6,7 +6,6 @@ use alloy_primitives::{Address, Bytes, Log, B256, U256}; use foundry_common::contracts::{ContractsByAddress, ContractsByArtifact}; use foundry_config::FuzzDictionaryConfig; use foundry_evm_core::utils::StateChangeset; -use hashbrown::HashSet; use parking_lot::RwLock; use proptest::prelude::{BoxedStrategy, Strategy}; use revm::{ @@ -14,7 +13,7 @@ use revm::{ interpreter::opcode::{self, spec_opcode_gas}, primitives::SpecId, }; -use std::{fmt, str::FromStr, sync::Arc}; +use std::{collections::HashSet, fmt, str::FromStr, sync::Arc}; /// A set of arbitrary 32 byte data from the VM used to generate values for the strategy. /// diff --git a/crates/evm/traces/Cargo.toml b/crates/evm/traces/Cargo.toml index 94dd36b63d28..be3cecb36383 100644 --- a/crates/evm/traces/Cargo.toml +++ b/crates/evm/traces/Cargo.toml @@ -25,7 +25,6 @@ revm-inspectors.workspace = true eyre = "0.6" futures = "0.3" -hashbrown = "0.14" hex.workspace = true itertools.workspace = true once_cell = "1" diff --git a/crates/evm/traces/src/identifier/signatures.rs b/crates/evm/traces/src/identifier/signatures.rs index b1f3124cdf1b..976e9ea6979c 100644 --- a/crates/evm/traces/src/identifier/signatures.rs +++ b/crates/evm/traces/src/identifier/signatures.rs @@ -4,9 +4,12 @@ use foundry_common::{ fs, selectors::{SelectorType, SignEthClient}, }; -use hashbrown::HashSet; use serde::{Deserialize, Serialize}; -use std::{collections::BTreeMap, path::PathBuf, sync::Arc}; +use std::{ + collections::{BTreeMap, HashSet}, + path::PathBuf, + sync::Arc, +}; use tokio::sync::RwLock; pub type SingleSignaturesIdentifier = Arc>; diff --git a/crates/forge/bin/cmd/remappings.rs b/crates/forge/bin/cmd/remappings.rs index 6728f0ae1aff..b33f3442cf9b 100644 --- a/crates/forge/bin/cmd/remappings.rs +++ b/crates/forge/bin/cmd/remappings.rs @@ -2,8 +2,7 @@ use clap::{Parser, ValueHint}; use eyre::Result; use foundry_cli::utils::LoadConfig; use foundry_config::impl_figment_convert_basic; -use foundry_evm::hashbrown::HashMap; -use std::path::PathBuf; +use std::{collections::BTreeMap, path::PathBuf}; /// CLI arguments for `forge remappings`. #[derive(Clone, Debug, Parser)] @@ -25,7 +24,7 @@ impl RemappingArgs { let config = self.try_load_config_emit_warnings()?; if self.pretty { - let mut groups = HashMap::<_, Vec<_>>::with_capacity(config.remappings.len()); + let mut groups = BTreeMap::<_, Vec<_>>::new(); for remapping in config.remappings { groups.entry(remapping.context.clone()).or_default().push(remapping); } @@ -36,14 +35,14 @@ impl RemappingArgs { println!("Global:"); } - for mut remapping in remappings.into_iter() { + for mut remapping in remappings { remapping.context = None; // avoid writing context twice println!("- {remapping}"); } println!(); } } else { - for remapping in config.remappings.into_iter() { + for remapping in config.remappings { println!("{remapping}"); } } diff --git a/crates/forge/src/gas_report.rs b/crates/forge/src/gas_report.rs index de36b871cb1e..2bdd6d4daec6 100644 --- a/crates/forge/src/gas_report.rs +++ b/crates/forge/src/gas_report.rs @@ -2,14 +2,16 @@ use crate::{ constants::{CHEATCODE_ADDRESS, HARDHAT_CONSOLE_ADDRESS}, - hashbrown::HashSet, traces::{CallTraceArena, CallTraceDecoder, CallTraceNode, DecodedCallData}, }; use comfy_table::{presets::ASCII_MARKDOWN, *}; use foundry_common::{calc, TestFunctionExt}; use foundry_evm::traces::CallKind; use serde::{Deserialize, Serialize}; -use std::{collections::BTreeMap, fmt::Display}; +use std::{ + collections::{BTreeMap, HashSet}, + fmt::Display, +}; /// Represents the gas report for a set of contracts. #[derive(Clone, Debug, Default, Serialize, Deserialize)] diff --git a/crates/verify/src/etherscan/mod.rs b/crates/verify/src/etherscan/mod.rs index 42986a160b7c..7e79321efa4c 100644 --- a/crates/verify/src/etherscan/mod.rs +++ b/crates/verify/src/etherscan/mod.rs @@ -18,12 +18,13 @@ use foundry_compilers::{ Artifact, Project, Solc, }; use foundry_config::{Chain, Config, SolcReq}; -use foundry_evm::{constants::DEFAULT_CREATE2_DEPLOYER, hashbrown::HashSet}; +use foundry_evm::constants::DEFAULT_CREATE2_DEPLOYER; use futures::FutureExt; use once_cell::sync::Lazy; use regex::Regex; use semver::{BuildMetadata, Version}; use std::{ + collections::HashSet, fmt::Debug, path::{Path, PathBuf}, }; From aecb49bb1a856486903a0b598515bad9d13cb02a Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:47:23 +0100 Subject: [PATCH 2/7] deps --- Cargo.lock | 2 -- Cargo.toml | 1 - crates/evm/core/Cargo.toml | 1 - crates/evm/evm/Cargo.toml | 1 - 4 files changed, 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24aa79340e4f..221776a741c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3380,7 +3380,6 @@ dependencies = [ "alloy-json-abi", "alloy-primitives", "alloy-sol-types", - "arrayvec", "const-hex", "eyre", "foundry-cheatcodes", @@ -3413,7 +3412,6 @@ dependencies = [ "alloy-providers", "alloy-rpc-types", "alloy-sol-types", - "arrayvec", "auto_impl", "const-hex", "derive_more", diff --git a/Cargo.toml b/Cargo.toml index fb09fa0132b6..8e2070727268 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -185,7 +185,6 @@ alloy-rlp = "0.3.3" solang-parser = "=0.3.3" ## misc -arrayvec = "0.7" base64 = "0.22" chrono = { version = "0.4", default-features = false, features = ["clock", "std"] } color-eyre = "0.6" diff --git a/crates/evm/core/Cargo.toml b/crates/evm/core/Cargo.toml index a55ecdd0c2d9..7e4ea3c218d2 100644 --- a/crates/evm/core/Cargo.toml +++ b/crates/evm/core/Cargo.toml @@ -39,7 +39,6 @@ revm-inspectors.workspace = true arrayvec.workspace = true auto_impl = "1" -arrayvec.workspace = true derive_more.workspace = true eyre = "0.6" futures = "0.3" diff --git a/crates/evm/evm/Cargo.toml b/crates/evm/evm/Cargo.toml index 9336ffff740e..7517ab081c5e 100644 --- a/crates/evm/evm/Cargo.toml +++ b/crates/evm/evm/Cargo.toml @@ -35,7 +35,6 @@ revm = { workspace = true, default-features = false, features = [ ] } revm-inspectors.workspace = true -arrayvec.workspace = true eyre = "0.6" hex.workspace = true itertools.workspace = true From c9fe028b5516d6a114a50c26a58c8460a4f43087 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 18 Mar 2024 18:09:10 +0100 Subject: [PATCH 3/7] fix --- Cargo.lock | 2 ++ Cargo.toml | 1 + crates/evm/evm/Cargo.toml | 1 + 3 files changed, 4 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 221776a741c8..24aa79340e4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3380,6 +3380,7 @@ dependencies = [ "alloy-json-abi", "alloy-primitives", "alloy-sol-types", + "arrayvec", "const-hex", "eyre", "foundry-cheatcodes", @@ -3412,6 +3413,7 @@ dependencies = [ "alloy-providers", "alloy-rpc-types", "alloy-sol-types", + "arrayvec", "auto_impl", "const-hex", "derive_more", diff --git a/Cargo.toml b/Cargo.toml index 8e2070727268..fb09fa0132b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -185,6 +185,7 @@ alloy-rlp = "0.3.3" solang-parser = "=0.3.3" ## misc +arrayvec = "0.7" base64 = "0.22" chrono = { version = "0.4", default-features = false, features = ["clock", "std"] } color-eyre = "0.6" diff --git a/crates/evm/evm/Cargo.toml b/crates/evm/evm/Cargo.toml index 7517ab081c5e..9336ffff740e 100644 --- a/crates/evm/evm/Cargo.toml +++ b/crates/evm/evm/Cargo.toml @@ -35,6 +35,7 @@ revm = { workspace = true, default-features = false, features = [ ] } revm-inspectors.workspace = true +arrayvec.workspace = true eyre = "0.6" hex.workspace = true itertools.workspace = true From e0b11112d3c1591995e031e9eec08e9725df2481 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 18 Mar 2024 18:35:48 +0100 Subject: [PATCH 4/7] log --- crates/forge/tests/it/fuzz.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/forge/tests/it/fuzz.rs b/crates/forge/tests/it/fuzz.rs index 47bc7745dff2..50ce05d4a8c8 100644 --- a/crates/forge/tests/it/fuzz.rs +++ b/crates/forge/tests/it/fuzz.rs @@ -136,13 +136,13 @@ async fn test_persist_fuzz_failure() { }; // run several times and compare counterexamples calldata - for _ in 0..10 { + for i in 0..10 { let new_calldata = match get_failure_result!() { Some(CounterExample::Single(counterexample)) => counterexample.calldata, _ => Bytes::new(), }; // calldata should be the same with the initial one - assert_eq!(initial_calldata, new_calldata); + assert_eq!(initial_calldata, new_calldata, "run {i}"); } // write new failure in different file From d96fb69f6d344125b80a63605f53d225d66dbc27 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:19:35 +0100 Subject: [PATCH 5/7] fix: use indexset --- Cargo.lock | 2 ++ Cargo.toml | 1 + crates/evm/fuzz/Cargo.toml | 2 ++ crates/evm/fuzz/src/strategies/state.rs | 19 ++++++++++++------- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24aa79340e4f..d9078233b368 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3468,11 +3468,13 @@ dependencies = [ "foundry-evm-core", "foundry-evm-coverage", "foundry-evm-traces", + "indexmap", "itertools 0.12.1", "parking_lot", "proptest", "rand 0.8.5", "revm", + "rustc-hash", "serde", "thiserror", "tracing", diff --git a/Cargo.toml b/Cargo.toml index fb09fa0132b6..bc478da6a81c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -206,6 +206,7 @@ toml = "0.8" tracing = "0.1" tracing-subscriber = "0.3" vergen = { version = "8", default-features = false } +indexmap = "2.2" axum = "0.6" hyper = "0.14" diff --git a/crates/evm/fuzz/Cargo.toml b/crates/evm/fuzz/Cargo.toml index 7ec4a381b107..0c6380556293 100644 --- a/crates/evm/fuzz/Cargo.toml +++ b/crates/evm/fuzz/Cargo.toml @@ -40,3 +40,5 @@ rand.workspace = true serde = "1" thiserror = "1" tracing = "0.1" +rustc-hash.workspace = true +indexmap.workspace = true diff --git a/crates/evm/fuzz/src/strategies/state.rs b/crates/evm/fuzz/src/strategies/state.rs index d7e7ab6da019..e33391cfe32b 100644 --- a/crates/evm/fuzz/src/strategies/state.rs +++ b/crates/evm/fuzz/src/strategies/state.rs @@ -13,7 +13,12 @@ use revm::{ interpreter::opcode::{self, spec_opcode_gas}, primitives::SpecId, }; -use std::{collections::HashSet, fmt, str::FromStr, sync::Arc}; +use std::{fmt, str::FromStr, sync::Arc}; + +// We're using `IndexSet` to have a stable element order when restoring persisted state, as well as +// for performance when iterating over the sets. +type FxIndexSet = + indexmap::set::IndexSet>; /// A set of arbitrary 32 byte data from the VM used to generate values for the strategy. /// @@ -23,9 +28,9 @@ pub type EvmFuzzState = Arc>; #[derive(Default)] pub struct FuzzDictionary { /// Collected state values. - state_values: HashSet<[u8; 32]>, + state_values: FxIndexSet<[u8; 32]>, /// Addresses that already had their PUSH bytes collected. - addresses: HashSet
, + addresses: FxIndexSet
, } impl fmt::Debug for FuzzDictionary { @@ -39,22 +44,22 @@ impl fmt::Debug for FuzzDictionary { impl FuzzDictionary { #[inline] - pub fn values(&self) -> &HashSet<[u8; 32]> { + pub fn values(&self) -> &FxIndexSet<[u8; 32]> { &self.state_values } #[inline] - pub fn values_mut(&mut self) -> &mut HashSet<[u8; 32]> { + pub fn values_mut(&mut self) -> &mut FxIndexSet<[u8; 32]> { &mut self.state_values } #[inline] - pub fn addresses(&mut self) -> &HashSet
{ + pub fn addresses(&self) -> &FxIndexSet
{ &self.addresses } #[inline] - pub fn addresses_mut(&mut self) -> &mut HashSet
{ + pub fn addresses_mut(&mut self) -> &mut FxIndexSet
{ &mut self.addresses } } From 1c55c202060b91350798cf517dd244f3885e3834 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:31:48 +0100 Subject: [PATCH 6/7] test --- crates/forge/tests/it/invariant.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/forge/tests/it/invariant.rs b/crates/forge/tests/it/invariant.rs index 99b9ad962783..5fb0f44d4b73 100644 --- a/crates/forge/tests/it/invariant.rs +++ b/crates/forge/tests/it/invariant.rs @@ -235,7 +235,7 @@ async fn test_invariant_shrink() { CounterExample::Single(_) => panic!("CounterExample should be a sequence."), // `fuzz_seed` at 119 makes this sequence shrinkable from 4 to 2. CounterExample::Sequence(sequence) => { - assert_eq!(sequence.len(), 2); + assert!(sequence.len() <= 3); // call order should always be preserved let create_fren_sequence = sequence[0].clone(); From 8ef4e143ac87c771d06fab80bb3dbf64e39944b9 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:39:33 +0100 Subject: [PATCH 7/7] test --- crates/forge/tests/it/invariant.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/crates/forge/tests/it/invariant.rs b/crates/forge/tests/it/invariant.rs index 5fb0f44d4b73..9339a54c3067 100644 --- a/crates/forge/tests/it/invariant.rs +++ b/crates/forge/tests/it/invariant.rs @@ -237,20 +237,22 @@ async fn test_invariant_shrink() { CounterExample::Sequence(sequence) => { assert!(sequence.len() <= 3); - // call order should always be preserved - let create_fren_sequence = sequence[0].clone(); - assert_eq!( - create_fren_sequence.contract_name.unwrap(), - "fuzz/invariant/common/InvariantInnerContract.t.sol:Jesus" - ); - assert_eq!(create_fren_sequence.signature.unwrap(), "create_fren()"); + if sequence.len() == 2 { + // call order should always be preserved + let create_fren_sequence = sequence[0].clone(); + assert_eq!( + create_fren_sequence.contract_name.unwrap(), + "fuzz/invariant/common/InvariantInnerContract.t.sol:Jesus" + ); + assert_eq!(create_fren_sequence.signature.unwrap(), "create_fren()"); - let betray_sequence = sequence[1].clone(); - assert_eq!( - betray_sequence.contract_name.unwrap(), - "fuzz/invariant/common/InvariantInnerContract.t.sol:Judas" - ); - assert_eq!(betray_sequence.signature.unwrap(), "betray()"); + let betray_sequence = sequence[1].clone(); + assert_eq!( + betray_sequence.contract_name.unwrap(), + "fuzz/invariant/common/InvariantInnerContract.t.sol:Judas" + ); + assert_eq!(betray_sequence.signature.unwrap(), "betray()"); + } } }; }