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

Migrate primitive_types::U256 to ruint::Uint<256, 4> #239

Merged
merged 20 commits into from
Oct 29, 2022
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
429 changes: 259 additions & 170 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ default-members = ["crates/revm"]

[profile.release]
# debug = true
lto = true
codegen-units = 1

[profile.ethtests]
inherits = "test"
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ run tests with command: `cargo run --release -- statetest tests/GeneralStateTest

`GeneralStateTests` contains all tests related to EVM.

## Running benchmarks

```shell
cargo run --package revm-test --release --bin snailtracer
```

```shell
cargo flamegraph --root --freq 4000 --min-width 0.001 --package revm-test --bin snailtracer
```
shekhirin marked this conversation as resolved.
Show resolved Hide resolved

# Used by

* Foundry project (as their main EVM): https://github.com/foundry-rs/foundry
Expand All @@ -46,5 +56,3 @@ run tests with command: `cargo run --release -- statetest tests/GeneralStateTest
There is public telegram group: https://t.me/+Ig4WDWOzikA3MzA0

Or if you want to hire me or contact me directly, here is my email: dragan0rakita@gmail.com and telegram: https://t.me/draganrakita


2 changes: 1 addition & 1 deletion bins/revm-test/src/bin/snailtracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn simple_example() {
let mut times = times[5..].to_vec();
times.sort();
for (i, time) in times.iter().rev().enumerate() {
println!("{}: {:?}", i, time);
println!("{i}: {time:?}");
}
}

Expand Down
1 change: 1 addition & 0 deletions bins/revme/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ plain_hasher = "0.2"
primitive-types = { version = "0.11", features = ["rlp", "serde"] }
revm = { path = "../../crates/revm", version = "2.1", default-features = false, features = ["web3db","std","secp256k1"] }
rlp = { version = "0.5", default-features = false }
ruint = { version = "1.6.0", features = ["rlp", "serde"] }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
Expand Down
3 changes: 2 additions & 1 deletion bins/revme/src/cli_env.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::str::FromStr;

use bytes::Bytes;
use primitive_types::{H160, U256};
use primitive_types::H160;
use revm::{Env, TransactTo};
use ruint::aliases::U256;
use structopt::StructOpt;

#[derive(StructOpt, Clone, Debug)]
Expand Down
2 changes: 1 addition & 1 deletion bins/revme/src/statetest/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct Cmd {
impl Cmd {
pub fn run(&self) -> Result<(), TestError> {
for path in &self.path {
println!("Start running tests on: {:?}", path);
println!("Start running tests on: {path:?}");
let test_files = find_all_json_tests(path);
run(test_files)?
}
Expand Down
11 changes: 4 additions & 7 deletions bins/revme/src/statetest/merkle_trie.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use bytes::Bytes;
use hash_db::Hasher;
use plain_hasher::PlainHasher;
use primitive_types::{H160, H256, U256};
use primitive_types::{H160, H256};
use revm::{db::DbAccount, Log};
use rlp::RlpStream;
use ruint::aliases::U256;
use sha3::{Digest, Keccak256};
use triehash::sec_trie_root;

Expand Down Expand Up @@ -44,12 +45,8 @@ pub fn trie_account_rlp(acc: &DbAccount) -> Bytes {
sec_trie_root::<KeccakHasher, _, _, _>(
acc.storage
.iter()
.filter(|(_k, &v)| v != U256::zero())
.map(|(k, v)| {
let mut temp: [u8; 32] = [0; 32];
k.to_big_endian(&mut temp);
(H256::from(temp), rlp::encode(v))
}),
.filter(|(_k, &v)| v != U256::ZERO)
.map(|(k, v)| (H256::from(k.to_be_bytes()), rlp::encode(v))),
)
});
stream.append(&acc.info.code_hash.as_bytes());
Expand Down
10 changes: 3 additions & 7 deletions bins/revme/src/statetest/models/deserializer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::str::FromStr;

use bytes::Bytes;
use primitive_types::{H160, U256};
use primitive_types::H160;
use ruint::aliases::U256;
use serde::{
de::{self, Error},
Deserialize,
Expand All @@ -27,12 +28,7 @@ where
D: de::Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;

let output = if let Some(stripped) = string.strip_prefix("0x") {
U256::from_str_radix(stripped, 16).unwrap()
} else {
U256::from_dec_str(&string).unwrap()
};
let output = string.parse().unwrap();

Ok(output)
}
Expand Down
7 changes: 4 additions & 3 deletions bins/revme/src/statetest/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bytes::Bytes;
use primitive_types::{H160, H256, U256};
use primitive_types::{H160, H256};
use ruint::aliases::U256;
use std::collections::{BTreeMap, HashMap};
mod deserializer;
mod spec;
Expand All @@ -17,7 +18,7 @@ pub struct TestSuit(pub BTreeMap<String, TestUnit>);
pub struct TestUnit {
pub env: Env,
pub pre: HashMap<H160, AccountInfo>,
pub post: HashMap<SpecName, Vec<Test>>,
pub post: BTreeMap<SpecName, Vec<Test>>,
pub transaction: TransactionParts,
}

Expand Down Expand Up @@ -112,7 +113,7 @@ mod tests {
}

let out: Test = serde_json::from_str(json)?;
println!("out:{:?}", out);
println!("out:{out:?}");
Ok(())
}
}
25 changes: 11 additions & 14 deletions bins/revme/src/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ use std::{
use sha3::{Digest, Keccak256};

use indicatif::ProgressBar;
use primitive_types::{H160, H256, U256};
use primitive_types::{H160, H256};
use revm::{db::AccountState, Bytecode, CreateScheme, Env, ExecutionResult, SpecId, TransactTo};
use ruint::aliases::U256;
use std::sync::atomic::Ordering;
use walkdir::{DirEntry, WalkDir};

Expand Down Expand Up @@ -141,7 +142,7 @@ pub fn execute_test_suit(path: &Path, elapsed: &Arc<Mutex<Duration>>) -> Result<
}
let mut env = Env::default();
// cfg env. SpecId is set down the road
env.cfg.chain_id = 1i32.into(); // for mainnet
env.cfg.chain_id = U256::from(1); // for mainnet

// block env
env.block.number = unit.env.current_number;
Expand Down Expand Up @@ -178,11 +179,7 @@ pub fn execute_test_suit(path: &Path, elapsed: &Arc<Mutex<Duration>>) -> Result<

for (id, test) in tests.into_iter().enumerate() {
let gas_limit = *unit.transaction.gas_limit.get(test.indexes.gas).unwrap();
let gas_limit = if gas_limit > U256::from(u64::MAX) {
u64::MAX
} else {
gas_limit.as_u64()
};
let gas_limit = u64::try_from(gas_limit).unwrap_or(u64::MAX);
env.tx.gas_limit = gas_limit;
env.tx.data = unit
.transaction
Expand All @@ -204,7 +201,7 @@ pub fn execute_test_suit(path: &Path, elapsed: &Arc<Mutex<Duration>>) -> Result<
item.address,
item.storage_keys
.iter()
.map(|f| U256::from_big_endian(f.as_ref()))
.map(|f| U256::from_be_bytes(f.0))
.collect::<Vec<_>>(),
)
})
Expand Down Expand Up @@ -253,20 +250,20 @@ pub fn execute_test_suit(path: &Path, elapsed: &Arc<Mutex<Duration>>) -> Result<
let logs_root = log_rlp_hash(logs);
if test.hash != state_root || test.logs != logs_root {
println!(
"ROOTS mismath:\nstate_root:{:?}:{:?}\nlogs_root:{:?}:{:?}",
test.hash, state_root, test.logs, logs_root
"ROOTS mismath:\nstate_root:{:?}:{state_root:?}\nlogs_root:{:?}:{logs_root:?}",
test.hash, test.logs
);
let mut database_cloned = database.clone();
evm.database(&mut database_cloned);
evm.inspect_commit(CustomPrintTracer::new());
let db = evm.db().unwrap();
println!("{:?} UNIT_TEST:{}\n", path, name);
println!("{path:?} UNIT_TEST:{name}\n");
println!(
"fail reson: {:?} {:?} UNIT_TEST:{}\n gas:{:?} ({:?} refunded)",
exit_reason, path, name, gas_used, gas_refunded,
);
println!("\nApplied state:{:?}\n", db);
println!("\nStateroot: {:?}\n", state_root);
println!("\nApplied state:{db:?}\n");
println!("\nStateroot: {state_root:?}\n");
return Err(TestError::RootMissmatch {
spec_id: env.cfg.spec_id,
id,
Expand Down Expand Up @@ -311,7 +308,7 @@ pub fn run(test_files: Vec<PathBuf>) -> Result<(), TestError> {
//println!("Test:{:?}\n",test_path);
if let Err(err) = execute_test_suit(&test_path, &elapsed) {
endjob.store(true, Ordering::SeqCst);
println!("Test[{}] named:\n{:?} failed: {}\n", index, test_path, err);
println!("Test[{index}] named:\n{test_path:?} failed: {err}\n");
return Err(err);
}

Expand Down
5 changes: 3 additions & 2 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ bytes = { version = "1.1", default-features = false }
futures = { version = "0.3.24", optional = true }
hashbrown = { version = "0.12" }
hex = { version = "0.4", optional = true }
num_enum = { version = "0.5", default-features = false }#used for SpecId from u8 cast
num_enum = { version = "0.5", default-features = false } # used for SpecId from u8 cast
parking_lot = { version = "0.12", optional = true }
primitive-types = { version = "0.11", default-features = false, features = ["rlp"] }
revm_precompiles = { path = "../revm_precompiles", version = "1.1.1", default-features = false }
rlp = { version = "0.5", default-features = false }#used for create2 address calculation
rlp = { version = "0.5", default-features = false } # used for create2 address calculation
ruint = { version = "1.6.0", features = ["rlp"] }
serde = { version = "1.0", features = ["derive","rc"], optional = true }
sha3 = { version = "0.10", default-features = false }
tokio = { version = "1.21", features = ["rt-multi-thread", "macros"], optional = true }
Expand Down
3 changes: 2 additions & 1 deletion crates/revm/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ pub use in_memory_db::{AccountState, BenchmarkDB, CacheDB, DbAccount, EmptyDB, I

use crate::{interpreter::bytecode::Bytecode, Account};
use hashbrown::HashMap as Map;
use primitive_types::{H160, H256, U256};
use primitive_types::{H160, H256};
use ruint::aliases::U256;

use crate::AccountInfo;
use auto_impl::auto_impl;
Expand Down
26 changes: 14 additions & 12 deletions crates/revm/src/db/in_memory_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::{Account, AccountInfo, Log};
use alloc::vec::Vec;
use core::convert::Infallible;
use hashbrown::{hash_map::Entry, HashMap as Map};
use primitive_types::{H160, H256, U256};
use primitive_types::{H160, H256};
use ruint::aliases::U256;
use sha3::{Digest, Keccak256};

pub type InMemoryDB = CacheDB<EmptyDB>;
Expand Down Expand Up @@ -84,7 +85,7 @@ pub enum AccountState {
/// EVM touched this account. For newer hardfork this means it can be clearead/removed from state.
Touched,
/// EVM cleared storage of this account, mostly by selfdestruct, we dont ask database for storage slots
/// and asume they are U256::zero()
/// and asume they are U256::ZERO
StorageCleared,
/// EVM didnt interacted with this account
#[default]
Expand Down Expand Up @@ -240,7 +241,7 @@ impl<ExtDB: DatabaseRef> Database for CacheDB<ExtDB> {
acc_entry.account_state,
AccountState::StorageCleared | AccountState::NotExisting
) {
Ok(U256::zero())
Ok(U256::ZERO)
} else {
let slot = self.db.storage(address, index)?;
entry.insert(slot);
Expand All @@ -258,7 +259,7 @@ impl<ExtDB: DatabaseRef> Database for CacheDB<ExtDB> {
account.storage.insert(index, value);
(account, value)
} else {
(info.into(), U256::zero())
(info.into(), U256::ZERO)
};
acc_entry.insert(account);
Ok(value)
Expand Down Expand Up @@ -296,7 +297,7 @@ impl<ExtDB: DatabaseRef> DatabaseRef for CacheDB<ExtDB> {
acc_entry.account_state,
AccountState::StorageCleared | AccountState::NotExisting
) {
Ok(U256::zero())
Ok(U256::ZERO)
} else {
self.db.storage(address, index)
}
Expand Down Expand Up @@ -342,9 +343,9 @@ impl DatabaseRef for EmptyDB {

// History related
fn block_hash(&self, number: U256) -> Result<H256, Self::Error> {
let mut buffer: [u8; 4 * 8] = [0; 4 * 8];
number.to_big_endian(&mut buffer);
Ok(H256::from_slice(&Keccak256::digest(buffer)))
Ok(H256::from_slice(&Keccak256::digest(
number.to_be_bytes::<{ U256::BYTES }>(),
)))
}
}

Expand Down Expand Up @@ -395,6 +396,7 @@ impl Database for BenchmarkDB {
#[cfg(test)]
mod tests {
use primitive_types::H160;
use ruint::aliases::U256;

use crate::{AccountInfo, Database};

Expand All @@ -413,7 +415,7 @@ mod tests {
},
);

let (key, value) = (123u64.into(), 456u64.into());
let (key, value) = (U256::from(123), U256::from(456));
let mut new_state = CacheDB::new(init_state);
let _ = new_state.insert_account_storage(account, key, value);

Expand All @@ -434,15 +436,15 @@ mod tests {
},
);

let (key0, value0) = (123u64.into(), 456u64.into());
let (key1, value1) = (789u64.into(), 999u64.into());
let (key0, value0) = (U256::from(123), U256::from(456));
let (key1, value1) = (U256::from(789), U256::from(999));
let _ = init_state.insert_account_storage(account, key0, value0);

let mut new_state = CacheDB::new(init_state);
let _ = new_state.replace_account_storage(account, [(key1, value1)].into());

assert_eq!(new_state.basic(account).unwrap().unwrap().nonce, nonce);
assert_eq!(new_state.storage(account, key0), Ok(0.into()));
assert_eq!(new_state.storage(account, key0), Ok(U256::ZERO));
assert_eq!(new_state.storage(account, key1), Ok(value1));
}
}
Loading