Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Remove state sorting, no_std ci,remove rayon #717

Merged
merged 2 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ jobs:

- name: Install toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: riscv32imac-unknown-none-elf

- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true

- 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
Expand Down
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -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"]
Expand Down
18 changes: 6 additions & 12 deletions crates/revm/src/db.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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};
2 changes: 1 addition & 1 deletion crates/revm/src/db/states/bundle_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<HashMap<_, _>>();
Expand Down
27 changes: 11 additions & 16 deletions crates/revm/src/db/states/bundle_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ use super::{
reverts::{AccountInfoRevert, Reverts},
AccountRevert, AccountStatus, BundleAccount, PlainStateReverts, RevertToSlot, TransitionState,
};
use rayon::slice::ParallelSliceMut;
use alloc::{
collections::{BTreeMap, BTreeSet},
vec::Vec,
};
use core::ops::RangeInclusive;
use revm_interpreter::primitives::{
hash_map::{self, Entry},
AccountInfo, Bytecode, HashMap, StorageSlot, B160, B256, KECCAK_EMPTY, U256,
AccountInfo, Bytecode, HashMap, HashSet, StorageSlot, B160, B256, KECCAK_EMPTY, U256,
};
use std::collections::{BTreeMap, BTreeSet, HashSet};
use std::ops::RangeInclusive;

/// This builder is used to help to facilitate the initialization of `BundleState` struct
#[derive(Debug)]
Expand Down Expand Up @@ -438,8 +440,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);
Expand Down Expand Up @@ -477,7 +479,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,
Expand All @@ -486,18 +487,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::<Vec<_>>();
contracts.par_sort_unstable_by(|a, b| a.0.cmp(&b.0));

StateChangeset {
accounts,
storage,
Expand All @@ -506,12 +501,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())
}

Expand Down
2 changes: 2 additions & 0 deletions crates/revm/src/db/states/cache.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use super::{
plain_account::PlainStorage, transition_account::TransitionAccount, CacheAccount, PlainAccount,
};
use alloc::vec::Vec;
use revm_interpreter::primitives::{AccountInfo, Bytecode, HashMap, State as EVMState, B160, B256};

/// Cache state contains both modified and original values.
///
/// Cache state is main state that revm uses to access state.
Expand Down
23 changes: 13 additions & 10 deletions crates/revm/src/db/states/changes.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
use super::RevertToSlot;
use alloc::vec::Vec;
use revm_interpreter::primitives::{AccountInfo, Bytecode, B160, 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<(B160, Option<AccountInfo>)>,
/// Vector of storage presorted by address
/// First bool is indicator if storage needs to be dropped.
/// Vector of **not** sorted storage.
pub storage: Vec<PlainStorageChangeset>,
/// Vector of contracts presorted by bytecode hash
/// Vector of contracts by bytecode hash. **not** sorted.
pub contracts: Vec<(B256, Bytecode)>,
}

Expand All @@ -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<Vec<(B160, Option<AccountInfo>)>>,
/// Vector of storage presorted by address
/// Vector of storage with its address.
pub storage: Vec<Vec<PlainStorageRevert>>,
}

Expand Down
8 changes: 2 additions & 6 deletions crates/revm/src/db/states/reverts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use super::{
changes::PlainStorageRevert, AccountStatus, BundleAccount, PlainStateReverts,
StorageWithOriginalValues,
};
use alloc::vec::Vec;
use core::ops::{Deref, DerefMut};
use rayon::slice::ParallelSliceMut;
use revm_interpreter::primitives::{AccountInfo, HashMap, B160, U256};

/// Contains reverts of multiple account in multiple transitions (Transitions as a block).
Expand Down Expand Up @@ -58,17 +58,13 @@ impl Reverts {
AccountInfoRevert::DoNothing => (),
}
if revert_account.wipe_storage || !revert_account.storage.is_empty() {
let mut account_storage =
revert_account.storage.into_iter().collect::<Vec<_>>();
account_storage.par_sort_unstable_by(|a, b| a.0.cmp(&b.0));
storage.push(PlainStorageRevert {
address,
wiped: revert_account.wipe_storage,
storage_revert: account_storage,
storage_revert: revert_account.storage.into_iter().collect::<Vec<_>>(),
});
}
}
accounts.par_sort_unstable_by(|a, b| a.0.cmp(&b.0));
state_reverts.accounts.push(accounts);
state_reverts.storage.push(storage);
}
Expand Down
12 changes: 8 additions & 4 deletions crates/revm/src/db/states/state.rs
Original file line number Diff line number Diff line change
@@ -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, B160, B256, BLOCK_HASH_HISTORY, U256,
Expand Down Expand Up @@ -200,7 +204,7 @@ impl<DB: Database> State<DB> {
///
/// 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())
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/revm/src/db/states/transition_state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::TransitionAccount;
use alloc::vec::Vec;
use revm_interpreter::primitives::{hash_map::Entry, HashMap, B160};

#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down