From b76597fc28796810b7ded3def9acd4df70699b38 Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 13 Sep 2023 16:47:29 +0200 Subject: [PATCH] feat(state): remove state sorting, no_std ci,remove rayon (#717) * feat: Remove state sorting, no_std ci,remove rayon * nits --- .github/workflows/ci.yml | 5 ++++ Cargo.lock | 1 - crates/revm/Cargo.toml | 5 +--- crates/revm/src/db.rs | 18 ++++-------- crates/revm/src/db/states/bundle_account.rs | 2 +- crates/revm/src/db/states/bundle_state.rs | 28 +++++++------------ crates/revm/src/db/states/cache.rs | 5 ++-- crates/revm/src/db/states/changes.rs | 23 ++++++++------- crates/revm/src/db/states/state.rs | 12 +++++--- crates/revm/src/db/states/transition_state.rs | 3 +- 10 files changed, 48 insertions(+), 54 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12654158ac..b67c05895b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,8 @@ jobs: - name: Install toolchain uses: dtolnay/rust-toolchain@stable + with: + targets: riscv32imac-unknown-none-elf - uses: Swatinem/rust-cache@v2 with: @@ -24,6 +26,9 @@ jobs: - name: cargo test run: cargo test --workspace --all-features + + - name: cargo check no_std + run: cargo check --target riscv32imac-unknown-none-elf --no-default-features lint: name: Lint diff --git a/Cargo.lock b/Cargo.lock index 41857ec822..c73e0a5c19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2272,7 +2272,6 @@ dependencies = [ "futures", "hex", "hex-literal", - "rayon", "revm-interpreter", "revm-precompile", "serde", diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index e217c57010..a853498883 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -29,9 +29,6 @@ ethers-providers = { version = "2.0", optional = true } ethers-core = { version = "2.0", optional = true } futures = { version = "0.3.27", optional = true } -# parallel execution inside state. -rayon = { version = "1.7", optional = true } - [dev-dependencies] hex-literal = "0.4" ethers-contract = { version = "2.0.10", default-features = false } @@ -58,7 +55,7 @@ optional_block_gas_limit = ["revm-interpreter/optional_block_gas_limit"] optional_eip3607 = ["revm-interpreter/optional_eip3607"] optional_gas_refund = ["revm-interpreter/optional_gas_refund"] optional_no_base_fee = ["revm-interpreter/optional_no_base_fee"] -std = ["revm-interpreter/std", "rayon"] +std = ["revm-interpreter/std"] ethersdb = ["std", "tokio", "futures", "ethers-providers", "ethers-core"] serde = ["dep:serde", "dep:serde_json", "revm-interpreter/serde"] arbitrary = ["revm-interpreter/arbitrary"] diff --git a/crates/revm/src/db.rs b/crates/revm/src/db.rs index 26b41fc0f7..72f35cc848 100644 --- a/crates/revm/src/db.rs +++ b/crates/revm/src/db.rs @@ -1,15 +1,14 @@ pub mod emptydb; -pub mod in_memory_db; - #[cfg(feature = "ethersdb")] pub mod ethersdb; -#[cfg(feature = "ethersdb")] -pub use ethersdb::EthersDB; - -#[cfg(feature = "std")] +pub mod in_memory_db; pub mod states; -#[cfg(feature = "std")] +pub use crate::primitives::db::*; +pub use emptydb::{EmptyDB, EmptyDBTyped}; +#[cfg(feature = "ethersdb")] +pub use ethersdb::EthersDB; +pub use in_memory_db::*; pub use states::{ AccountRevert, AccountStatus, BundleAccount, BundleState, CacheState, DBBox, OriginalValuesKnown, PlainAccount, RevertToSlot, State, StateBuilder, StateDBBox, @@ -20,8 +19,3 @@ pub use states::{ compile_error!( "`web3db` feature is deprecated, drop-in replacement can be found with feature `ethersdb`" ); - -pub use crate::primitives::db::*; -pub use in_memory_db::*; - -pub use emptydb::{EmptyDB, EmptyDBTyped}; diff --git a/crates/revm/src/db/states/bundle_account.rs b/crates/revm/src/db/states/bundle_account.rs index b78f214657..d81226a693 100644 --- a/crates/revm/src/db/states/bundle_account.rs +++ b/crates/revm/src/db/states/bundle_account.rs @@ -270,7 +270,7 @@ impl BundleAccount { // and insert it inside revert. let previous_storage = if transition.storage_was_destroyed { - let mut storage = std::mem::take(&mut self.storage) + let mut storage = core::mem::take(&mut self.storage) .into_iter() .map(|t| (t.0, RevertToSlot::Some(t.1.present_value))) .collect::>(); diff --git a/crates/revm/src/db/states/bundle_state.rs b/crates/revm/src/db/states/bundle_state.rs index f93ff9e2d8..f2de37a077 100644 --- a/crates/revm/src/db/states/bundle_state.rs +++ b/crates/revm/src/db/states/bundle_state.rs @@ -3,16 +3,15 @@ use super::{ reverts::{AccountInfoRevert, Reverts}, AccountRevert, AccountStatus, BundleAccount, PlainStateReverts, RevertToSlot, TransitionState, }; -use rayon::slice::ParallelSliceMut; -use revm_interpreter::primitives::{ - hash_map::{self, Entry}, - AccountInfo, Bytecode, HashMap, HashSet, StorageSlot, Address, B256, KECCAK_EMPTY, U256, -}; use alloc::{ collections::{BTreeMap, BTreeSet}, vec::Vec, }; -use std::ops::RangeInclusive; +use core::ops::RangeInclusive; +use revm_interpreter::primitives::{ + hash_map::{self, Entry}, + AccountInfo, Bytecode, HashMap, HashSet, StorageSlot, Address, B256, KECCAK_EMPTY, U256, +}; /// This builder is used to help to facilitate the initialization of `BundleState` struct #[derive(Debug)] @@ -440,8 +439,8 @@ impl BundleState { self.reverts.push(reverts); } - /// Consume the bundle state and return sorted plain state. - pub fn into_plain_state_sorted(self, is_value_known: OriginalValuesKnown) -> StateChangeset { + /// Consume the bundle state and return plain state. + pub fn into_plain_state(self, is_value_known: OriginalValuesKnown) -> StateChangeset { // pessimistically pre-allocate assuming _all_ accounts changed. let state_len = self.state.len(); let mut accounts = Vec::with_capacity(state_len); @@ -479,7 +478,6 @@ impl BundleState { } if !account_storage_changed.is_empty() || was_destroyed { - account_storage_changed.sort_by(|a, b| a.0.cmp(&b.0)); // append storage changes to account. storage.push(PlainStorageChangeset { address, @@ -488,18 +486,12 @@ impl BundleState { }); } } - - accounts.par_sort_unstable_by(|a, b| a.0.cmp(&b.0)); - storage.par_sort_unstable_by(|a, b| a.address.cmp(&b.address)); - - let mut contracts = self + let contracts = self .contracts .into_iter() // remove empty bytecodes .filter(|(b, _)| *b != KECCAK_EMPTY) .collect::>(); - contracts.par_sort_unstable_by(|a, b| a.0.cmp(&b.0)); - StateChangeset { accounts, storage, @@ -508,12 +500,12 @@ impl BundleState { } /// Consume the bundle state and split it into reverts and plain state. - pub fn into_sorted_plain_state_and_reverts( + pub fn into_plain_state_and_reverts( mut self, is_value_known: OriginalValuesKnown, ) -> (StateChangeset, PlainStateReverts) { let reverts = self.take_all_reverts(); - let plain_state = self.into_plain_state_sorted(is_value_known); + let plain_state = self.into_plain_state(is_value_known); (plain_state, reverts.into_plain_state_reverts()) } diff --git a/crates/revm/src/db/states/cache.rs b/crates/revm/src/db/states/cache.rs index 5108b60495..5a42cfd340 100644 --- a/crates/revm/src/db/states/cache.rs +++ b/crates/revm/src/db/states/cache.rs @@ -1,9 +1,8 @@ use super::{ plain_account::PlainStorage, transition_account::TransitionAccount, CacheAccount, PlainAccount, }; -use revm_interpreter::primitives::{ - AccountInfo, Address, Bytecode, HashMap, State as EVMState, B256, -}; +use alloc::vec::Vec; +use revm_interpreter::primitives::{AccountInfo, Bytecode, HashMap, State as EVMState, Address, B256}; /// Cache state contains both modified and original values. /// diff --git a/crates/revm/src/db/states/changes.rs b/crates/revm/src/db/states/changes.rs index b460424527..b537df5a9c 100644 --- a/crates/revm/src/db/states/changes.rs +++ b/crates/revm/src/db/states/changes.rs @@ -1,17 +1,20 @@ use super::RevertToSlot; +use alloc::vec::Vec; use revm_interpreter::primitives::{AccountInfo, Bytecode, Address, B256, U256}; -/// Sorted accounts/storages/contracts for inclusion into database. +/// accounts/storages/contracts for inclusion into database. /// Structure is made so it is easier to apply directly to database /// that mostly have separate tables to store account/storage/contract data. +/// +/// Note: that data is **not** sorted. Some database benefit of faster inclusion +/// and smaller footprint if data is inserted in sorted order. #[derive(Clone, Debug, Default)] pub struct StateChangeset { - /// Vector of account presorted by address, with removed contracts bytecode + /// Vector of **not** sorted accounts information. pub accounts: Vec<(Address, Option)>, - /// Vector of storage presorted by address - /// First bool is indicator if storage needs to be dropped. + /// Vector of **not** sorted storage. pub storage: Vec, - /// Vector of contracts presorted by bytecode hash + /// Vector of contracts by bytecode hash. **not** sorted. pub contracts: Vec<(B256, Bytecode)>, } @@ -37,20 +40,20 @@ pub struct PlainStorageRevert { /// state of this storage from database (And moving it to revert). pub wiped: bool, /// Contains the storage key and old values of that storage. - /// Assume they are sorted by the key. + /// Reverts are **not** sorted. pub storage_revert: Vec<(U256, RevertToSlot)>, } /// Plain state reverts are used to easily store reverts into database. /// -/// Note that accounts are assumed sorted by address. +/// Note that accounts are assumed **not** sorted. #[derive(Clone, Debug, Default)] pub struct PlainStateReverts { - /// Vector of account presorted by address, with removed contracts bytecode + /// Vector of account with removed contracts bytecode /// - /// Note: AccountInfo None means that account needs to be removed. + /// Note: If AccountInfo is None means that account needs to be removed. pub accounts: Vec)>>, - /// Vector of storage presorted by address + /// Vector of storage with its address. pub storage: Vec>, } diff --git a/crates/revm/src/db/states/state.rs b/crates/revm/src/db/states/state.rs index b2a9f64fce..f16a9d3ade 100644 --- a/crates/revm/src/db/states/state.rs +++ b/crates/revm/src/db/states/state.rs @@ -1,9 +1,13 @@ use super::{ bundle_state::BundleRetention, cache::CacheState, plain_account::PlainStorage, BundleState, - CacheAccount, TransitionState, + CacheAccount, StateBuilder, TransitionAccount, TransitionState, +}; +use crate::db::EmptyDB; +use alloc::{ + boxed::Box, + collections::{btree_map, BTreeMap}, + vec::Vec, }; -use crate::{db::EmptyDB, StateBuilder, TransitionAccount}; -use alloc::collections::{btree_map, BTreeMap}; use revm_interpreter::primitives::{ db::{Database, DatabaseCommit}, hash_map, Account, AccountInfo, Bytecode, HashMap, Address, B256, BLOCK_HASH_HISTORY, U256, @@ -200,7 +204,7 @@ impl State { /// /// this will panic. pub fn take_bundle(&mut self) -> BundleState { - std::mem::take(self.bundle_state.as_mut().unwrap()) + core::mem::take(self.bundle_state.as_mut().unwrap()) } } diff --git a/crates/revm/src/db/states/transition_state.rs b/crates/revm/src/db/states/transition_state.rs index 5db6017336..ffcf54ce9a 100644 --- a/crates/revm/src/db/states/transition_state.rs +++ b/crates/revm/src/db/states/transition_state.rs @@ -1,5 +1,6 @@ use super::TransitionAccount; -use revm_interpreter::primitives::{hash_map::Entry, Address, HashMap}; +use alloc::vec::Vec; +use revm_interpreter::primitives::{hash_map::Entry, HashMap, Address}; #[derive(Clone, Debug, Eq, PartialEq)] pub struct TransitionState {