diff --git a/bins/revme/src/cmd/statetest.rs b/bins/revme/src/cmd/statetest.rs index 5747dbf8a4..1284f41ae4 100644 --- a/bins/revme/src/cmd/statetest.rs +++ b/bins/revme/src/cmd/statetest.rs @@ -22,8 +22,13 @@ pub struct Cmd { #[structopt(short = "s", long)] single_thread: bool, /// Output results in JSON format. + /// It will stop second run of evm on failure. #[structopt(long)] json: bool, + /// Output outcome in JSON format. If json is true, this is implied. + /// It will stop second run of evm on failure. + #[structopt(short = "o", long)] + json_outcome: bool, } impl Cmd { @@ -32,11 +37,7 @@ impl Cmd { for path in &self.path { println!("\nRunning tests in {}...", path.display()); let test_files = find_all_json_tests(path); - run( - test_files, - if self.json { true } else { self.single_thread }, - self.json, - )? + run(test_files, self.single_thread, self.json, self.json_outcome)? } Ok(()) } diff --git a/bins/revme/src/cmd/statetest/cmd.rs b/bins/revme/src/cmd/statetest/cmd.rs deleted file mode 100644 index d277e6de47..0000000000 --- a/bins/revme/src/cmd/statetest/cmd.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::path::PathBuf; - -use super::runner::{find_all_json_tests, run, TestError}; -use structopt::StructOpt; - -#[derive(StructOpt, Debug)] -pub struct Cmd { - #[structopt(required = true)] - path: Vec, - #[structopt(short = "s", long)] - single_thread: bool, - #[structopt(long)] - json: bool, -} - -impl Cmd { - pub fn run(&self) -> Result<(), TestError> { - for path in &self.path { - println!("\nRunning tests in {}...", path.display()); - let test_files = find_all_json_tests(path); - run(test_files, self.single_thread, self.json)? - } - Ok(()) - } -} diff --git a/bins/revme/src/cmd/statetest/runner.rs b/bins/revme/src/cmd/statetest/runner.rs index ce0647af80..17cb498571 100644 --- a/bins/revme/src/cmd/statetest/runner.rs +++ b/bins/revme/src/cmd/statetest/runner.rs @@ -113,13 +113,13 @@ fn check_evm_execution( test_name: &str, exec_result: &EVMResultGeneric, evm: &Evm<'_, EXT, &mut State>, - is_json_trace: bool, + print_json_outcome: bool, ) -> Result<(), TestError> { let logs_root = log_rlp_hash(&exec_result.as_ref().map(|r| r.logs()).unwrap_or_default()); let state_root = state_merkle_trie_root(evm.context.evm.db.cache.trie_account()); let print_json_output = |error: Option| { - if is_json_trace { + if print_json_outcome { let json = json!({ "stateRoot": state_root, "logsRoot": logs_root, @@ -215,6 +215,7 @@ pub fn execute_test_suite( path: &Path, elapsed: &Arc>, trace: bool, + print_json_outcome: bool, ) -> Result<(), TestError> { if skip_test(path) { return Ok(()); @@ -252,7 +253,7 @@ pub fn execute_test_suite( env.block.basefee = unit.env.current_base_fee.unwrap_or_default(); env.block.difficulty = unit.env.current_difficulty; // after the Merge prevrandao replaces mix_hash field in block and replaced difficulty opcode in EVM. - env.block.prevrandao = Some(unit.env.current_difficulty.to_be_bytes().into()); + env.block.prevrandao = unit.env.current_random; // EIP-4844 if let (Some(parent_blob_gas_used), Some(parent_excess_blob_gas)) = ( unit.env.parent_blob_gas_used, @@ -361,9 +362,14 @@ pub fn execute_test_suite( .build(); let res = evm.transact_commit(); - let Err(e) = - check_evm_execution(&test, unit.out.as_ref(), &name, &res, &evm, trace) - else { + let Err(e) = check_evm_execution( + &test, + unit.out.as_ref(), + &name, + &res, + &evm, + print_json_outcome, + ) else { continue; }; // reset external context @@ -372,8 +378,14 @@ pub fn execute_test_suite( let res = evm.transact_commit(); // dump state and traces if test failed - let output = - check_evm_execution(&test, unit.out.as_ref(), &name, &res, &evm, trace); + let output = check_evm_execution( + &test, + unit.out.as_ref(), + &name, + &res, + &evm, + print_json_outcome, + ); let Err(e) = output else { continue; }; @@ -428,8 +440,14 @@ pub fn run( test_files: Vec, mut single_thread: bool, trace: bool, + mut print_outcome: bool, ) -> Result<(), TestError> { + // trace implies print_outcome if trace { + print_outcome = true; + } + // print_outcome or trace implies single_thread + if print_outcome { single_thread = true; } let n_files = test_files.len(); @@ -471,7 +489,7 @@ pub fn run( (prev_idx, test_path) }; - if let Err(err) = execute_test_suite(&test_path, &elapsed, trace) { + if let Err(err) = execute_test_suite(&test_path, &elapsed, trace, print_outcome) { endjob.store(true, Ordering::SeqCst); return Err(err); } diff --git a/crates/revm/src/db/emptydb.rs b/crates/revm/src/db/emptydb.rs index 2a8b482623..27d7641c92 100644 --- a/crates/revm/src/db/emptydb.rs +++ b/crates/revm/src/db/emptydb.rs @@ -1,3 +1,4 @@ +use alloc::string::ToString; use core::{convert::Infallible, fmt, marker::PhantomData}; use revm_interpreter::primitives::{ db::{Database, DatabaseRef}, @@ -102,6 +103,37 @@ impl DatabaseRef for EmptyDBTyped { #[inline] fn block_hash_ref(&self, number: U256) -> Result { - Ok(keccak256(number.to_be_bytes::<{ U256::BYTES }>())) + Ok(keccak256(number.to_string().as_bytes())) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::primitives::b256; + + #[test] + fn conform_block_hash_calculation() { + let db = EmptyDB::new(); + assert_eq!( + db.block_hash_ref(U256::from(0)), + Ok(b256!( + "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d" + )) + ); + + assert_eq!( + db.block_hash_ref(U256::from(1)), + Ok(b256!( + "c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6" + )) + ); + + assert_eq!( + db.block_hash_ref(U256::from(100)), + Ok(b256!( + "8c18210df0d9514f2d2e5d8ca7c100978219ee80d3968ad850ab5ead208287b3" + )) + ); } } diff --git a/crates/revm/src/db/states/state.rs b/crates/revm/src/db/states/state.rs index 95b802ee46..ec82cb87ff 100644 --- a/crates/revm/src/db/states/state.rs +++ b/crates/revm/src/db/states/state.rs @@ -315,9 +315,9 @@ mod tests { let test_number = BLOCK_HASH_HISTORY as u64 + 2; - let block1_hash = keccak256(U256::from(1).to_be_bytes::<{ U256::BYTES }>()); - let block2_hash = keccak256(U256::from(2).to_be_bytes::<{ U256::BYTES }>()); - let block_test_hash = keccak256(U256::from(test_number).to_be_bytes::<{ U256::BYTES }>()); + let block1_hash = keccak256(U256::from(1).to_string().as_bytes()); + let block2_hash = keccak256(U256::from(2).to_string().as_bytes()); + let block_test_hash = keccak256(U256::from(test_number).to_string().as_bytes()); assert_eq!( state.block_hashes,