From b55c2c34fea38427bb0f07f7a4a123aedec7e8df Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Wed, 29 Nov 2023 16:17:17 +0100 Subject: [PATCH 01/10] EVM/Eval: merge consecutive writeln --- .../kernel_evm/evm_evaluation/src/runner.rs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index b6c4e1c988d4..479d8ded7641 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -279,19 +279,11 @@ pub fn run_test( _ => { writeln!( host.buffer.borrow_mut(), - "\nSomething unexpected happened for test {}.", - name - ) - .unwrap(); - writeln!( - host.buffer.borrow_mut(), - "Expected exception is the following: {:?}", - test_execution.expect_exception - ) - .unwrap(); - writeln!( - host.buffer.borrow_mut(), - "Furter details on the execution result: {:?}", + "\nSomething unexpected happened for test {}.\n\ + Expected exception is the following: {:?}\n\ + Further details on the execution result: {:?}", + name, + test_execution.expect_exception, exec_result ) .unwrap(); -- GitLab From 3e4d1035de8c4b3bf66c77be451a2fe459eec1dd Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Wed, 29 Nov 2023 16:48:17 +0100 Subject: [PATCH 02/10] EVM/Eval: add macro write_host! --- .../kernel_evm/evm_evaluation/src/helpers.rs | 14 ++++ .../kernel_evm/evm_evaluation/src/runner.rs | 77 +++++-------------- 2 files changed, 35 insertions(+), 56 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/helpers.rs b/etherlink/kernel_evm/evm_evaluation/src/helpers.rs index 750a7ae0785d..bb3d7f66c087 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/helpers.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/helpers.rs @@ -43,3 +43,17 @@ pub fn construct_folder_path( path_buf } + +#[macro_export] +macro_rules! write_host { + ($host: expr, $($args: expr),*) => { + { + extern crate alloc; + writeln!( + $host.buffer.borrow_mut(), + "{}", + { &alloc::format!($($args), *) }, + ).unwrap() + } + }; +} diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index 479d8ded7641..1f23353b1319 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -22,7 +22,7 @@ use crate::evalhost::EvalHost; use crate::fillers::process; use crate::helpers::construct_folder_path; use crate::models::{Env, FillerSource, SpecName, TestSuite}; -use crate::{Opt, ReportValue}; +use crate::{write_host, Opt, ReportValue}; const MAP_CALLER_KEYS: [(H256, H160); 6] = [ ( @@ -95,12 +95,11 @@ pub fn run_test( writeln!(output_file, "Running unit test: {}", name).unwrap(); let full_filler_path = construct_folder_path(&unit._info.source, &opt.eth_tests, &None); - writeln!( - host.buffer.borrow_mut(), + write_host!( + host, "Filler source: {}", &full_filler_path.to_str().unwrap() - ) - .unwrap(); + ); let filler_path = Path::new(&full_filler_path); let reader = std::fs::read(filler_path).unwrap(); let filler_source = if unit._info.source.contains(".json") { @@ -115,45 +114,25 @@ pub fn run_test( None }; - writeln!( - host.buffer.borrow_mut(), - "\n[START] Accounts initialisation" - ) - .unwrap(); + write_host!(host, "\n[START] Accounts initialisation"); for (address, info) in unit.pre.into_iter() { let h160_address: H160 = address.as_fixed_bytes().into(); - writeln!(host.buffer.borrow_mut(), "\nAccount is {}", h160_address).unwrap(); + write_host!(host, "\nAccount is {}", h160_address); let mut account = EthereumAccount::from_address(&address.as_fixed_bytes().into()).unwrap(); if info.nonce != 0 { account.set_nonce(&mut host, info.nonce.into()).unwrap(); - writeln!( - host.buffer.borrow_mut(), - "Nonce is set for {} : {}", - address, - info.nonce - ) - .unwrap(); + write_host!(host, "Nonce is set for {} : {}", address, info.nonce); } account.balance_add(&mut host, info.balance).unwrap(); - writeln!( - host.buffer.borrow_mut(), - "Balance for {} was added : {}", - address, - info.balance - ) - .unwrap(); + write_host!(host, "Balance for {} was added : {}", address, info.balance); account.set_code(&mut host, &info.code).unwrap(); - writeln!(host.buffer.borrow_mut(), "Code was set for {}", address).unwrap(); + write_host!(host, "Code was set for {}", address); for (index, value) in info.storage.iter() { account.set_storage(&mut host, index, value).unwrap(); } } - writeln!( - host.buffer.borrow_mut(), - "\n[END] Accounts initialisation\n" - ) - .unwrap(); + write_host!(host, "\n[END] Accounts initialisation\n"); let mut env = Env::default(); @@ -251,45 +230,32 @@ pub fn run_test( } None => "[INVALID]", }; - writeln!( - host.buffer.borrow_mut(), - "\nOutcome status: {}", - outcome_status - ) - .unwrap(); + write_host!(host, "\nOutcome status: {}", outcome_status); } - Err(e) => writeln!( - host.buffer.borrow_mut(), - "\nA test failed due to {:?}", - e - ) - .unwrap(), + Err(e) => write_host!(host, "\nA test failed due to {:?}", e), } write!(host.buffer.borrow_mut(), "\nFinal check: ").unwrap(); match (&test_execution.expect_exception, &exec_result) { (None, Ok(_)) => { - writeln!(host.buffer.borrow_mut(), "No unexpected exception.") - .unwrap() + write_host!(host, "No unexpected exception.") } (Some(_), Err(_)) => { - writeln!(host.buffer.borrow_mut(), "Exception was expected.") - .unwrap() + write_host!(host, "Exception was expected.") } _ => { - writeln!( - host.buffer.borrow_mut(), + write_host!( + host, "\nSomething unexpected happened for test {}.\n\ Expected exception is the following: {:?}\n\ Further details on the execution result: {:?}", name, test_execution.expect_exception, exec_result - ) - .unwrap(); + ); } } - writeln!(host.buffer.borrow_mut(), "\n=======> OK! <=======\n").unwrap(); + write_host!(host, "\n=======> OK! <=======\n"); } // Check the state after the execution of the result. @@ -302,11 +268,10 @@ pub fn run_test( report_key.clone(), output_file, ), - None => writeln!( - host.buffer.borrow_mut(), + None => write_host!( + host, "No filler file, the outcome of this test is uncertain." - ) - .unwrap(), + ), }; } } -- GitLab From feafcc607af806ef61b29e4ac7532ad03fa550cf Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Wed, 29 Nov 2023 16:28:26 +0100 Subject: [PATCH 03/10] EVM/Eval: extract filler preparation --- .../kernel_evm/evm_evaluation/src/runner.rs | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index 1f23353b1319..e6e9a7e40366 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -21,7 +21,7 @@ use thiserror::Error; use crate::evalhost::EvalHost; use crate::fillers::process; use crate::helpers::construct_folder_path; -use crate::models::{Env, FillerSource, SpecName, TestSuite}; +use crate::models::{Env, FillerSource, SpecName, TestSuite, TestUnit}; use crate::{write_host, Opt, ReportValue}; const MAP_CALLER_KEYS: [(H256, H160); 6] = [ @@ -73,6 +73,33 @@ pub enum TestError { UnknownPrivateKey { private_key: H256 }, } +fn prepare_filler_source( + host: &EvalHost, + unit: &TestUnit, + opt: &Opt, +) -> Result, TestError> { + let full_filler_path = + construct_folder_path(&unit._info.source, &opt.eth_tests, &None); + write_host!( + host, + "Filler source: {}", + &full_filler_path.to_str().unwrap() + ); + let filler_path = Path::new(&full_filler_path); + let reader = std::fs::read(filler_path).unwrap(); + if unit._info.source.contains(".json") { + let filler_source: FillerSource = serde_json::from_reader(&*reader)?; + Ok(Some(filler_source)) + } else if unit._info.source.contains(".yml") { + let filler_source: FillerSource = serde_yaml::from_reader(&*reader)?; + Ok(Some(filler_source)) + } else { + // Test will be ignored, interpretation of results will not + // be possible. + Ok(None) + } +} + pub fn run_test( path: &Path, report_map: &mut HashMap, @@ -93,26 +120,7 @@ pub fn run_test( let mut evm_account_storage = init_account_storage().unwrap(); writeln!(output_file, "Running unit test: {}", name).unwrap(); - let full_filler_path = - construct_folder_path(&unit._info.source, &opt.eth_tests, &None); - write_host!( - host, - "Filler source: {}", - &full_filler_path.to_str().unwrap() - ); - let filler_path = Path::new(&full_filler_path); - let reader = std::fs::read(filler_path).unwrap(); - let filler_source = if unit._info.source.contains(".json") { - let filler_source: FillerSource = serde_json::from_reader(&*reader)?; - Some(filler_source) - } else if unit._info.source.contains(".yml") { - let filler_source: FillerSource = serde_yaml::from_reader(&*reader)?; - Some(filler_source) - } else { - // Test will be ignored, interpretation of results will not - // be possible. - None - }; + let filler_source = prepare_filler_source(&host, &unit, opt)?; write_host!(host, "\n[START] Accounts initialisation"); for (address, info) in unit.pre.into_iter() { -- GitLab From 5126a3f9c20ddae4d3ce44f5a4c669f7e66a6482 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Wed, 29 Nov 2023 16:52:38 +0100 Subject: [PATCH 04/10] EVM/Eval: extract accounts initialization --- .../kernel_evm/evm_evaluation/src/runner.rs | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index e6e9a7e40366..9561cf7e21d7 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -100,6 +100,30 @@ fn prepare_filler_source( } } +fn initialize_accounts(host: &mut EvalHost, unit: &TestUnit) { + write_host!(host, "\n[START] Accounts initialisation"); + + for (address, info) in unit.pre.to_owned().iter() { + let h160_address: H160 = address.as_fixed_bytes().into(); + write_host!(host, "\nAccount is {}", h160_address); + let mut account = + EthereumAccount::from_address(&address.as_fixed_bytes().into()).unwrap(); + if info.nonce != 0 { + account.set_nonce(host, info.nonce.into()).unwrap(); + write_host!(host, "Nonce is set for {} : {}", address, info.nonce); + } + account.balance_add(host, info.balance).unwrap(); + write_host!(host, "Balance for {} was added : {}", address, info.balance); + account.set_code(host, &info.code).unwrap(); + write_host!(host, "Code was set for {}", address); + for (index, value) in info.storage.iter() { + account.set_storage(host, index, value).unwrap(); + } + } + + write_host!(host, "\n[END] Accounts initialisation\n"); +} + pub fn run_test( path: &Path, report_map: &mut HashMap, @@ -122,25 +146,7 @@ pub fn run_test( writeln!(output_file, "Running unit test: {}", name).unwrap(); let filler_source = prepare_filler_source(&host, &unit, opt)?; - write_host!(host, "\n[START] Accounts initialisation"); - for (address, info) in unit.pre.into_iter() { - let h160_address: H160 = address.as_fixed_bytes().into(); - write_host!(host, "\nAccount is {}", h160_address); - let mut account = - EthereumAccount::from_address(&address.as_fixed_bytes().into()).unwrap(); - if info.nonce != 0 { - account.set_nonce(&mut host, info.nonce.into()).unwrap(); - write_host!(host, "Nonce is set for {} : {}", address, info.nonce); - } - account.balance_add(&mut host, info.balance).unwrap(); - write_host!(host, "Balance for {} was added : {}", address, info.balance); - account.set_code(&mut host, &info.code).unwrap(); - write_host!(host, "Code was set for {}", address); - for (index, value) in info.storage.iter() { - account.set_storage(&mut host, index, value).unwrap(); - } - } - write_host!(host, "\n[END] Accounts initialisation\n"); + initialize_accounts(&mut host, &unit); let mut env = Env::default(); -- GitLab From 4163a6edabe12d575c68ebd5dc1d51de20882309 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Thu, 30 Nov 2023 17:11:15 +0100 Subject: [PATCH 05/10] EVM/Eval: extract host initialization --- etherlink/kernel_evm/evm_evaluation/src/runner.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index 9561cf7e21d7..759b5d16a567 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -73,6 +73,12 @@ pub enum TestError { UnknownPrivateKey { private_key: H256 }, } +fn prepare_host() -> EvalHost { + let execution_buffer = Vec::new(); + let buffer = RefCell::new(execution_buffer); + EvalHost::default_with_buffer(buffer) +} + fn prepare_filler_source( host: &EvalHost, unit: &TestUnit, @@ -133,9 +139,7 @@ pub fn run_test( ) -> Result<(), TestError> { let json_reader = std::fs::read(path).unwrap(); let suit: TestSuite = serde_json::from_reader(&*json_reader)?; - let execution_buffer = Vec::new(); - let buffer = RefCell::new(execution_buffer); - let mut host = EvalHost::default_with_buffer(buffer); + let mut host = prepare_host(); let map_caller_keys: HashMap = MAP_CALLER_KEYS.into(); -- GitLab From 22fb72e0750bc5251b9456c5f9873234e5dde682 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Thu, 30 Nov 2023 17:13:36 +0100 Subject: [PATCH 06/10] EVM/Eval: extract testsuite reading --- etherlink/kernel_evm/evm_evaluation/src/runner.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index 759b5d16a567..63681c216226 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -73,6 +73,11 @@ pub enum TestError { UnknownPrivateKey { private_key: H256 }, } +fn read_testsuite(path: &Path) -> Result { + let json_reader = std::fs::read(path).unwrap(); + serde_json::from_reader(&*json_reader).map_err(TestError::from) +} + fn prepare_host() -> EvalHost { let execution_buffer = Vec::new(); let buffer = RefCell::new(execution_buffer); @@ -137,8 +142,7 @@ pub fn run_test( opt: &Opt, output_file: &mut File, ) -> Result<(), TestError> { - let json_reader = std::fs::read(path).unwrap(); - let suit: TestSuite = serde_json::from_reader(&*json_reader)?; + let suit = read_testsuite(path)?; let mut host = prepare_host(); let map_caller_keys: HashMap = MAP_CALLER_KEYS.into(); -- GitLab From fdd7d117bc73db3db61e8002908198dcf85f3527 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Thu, 30 Nov 2023 17:16:18 +0100 Subject: [PATCH 07/10] EVM/Eval: extract env initialization --- .../kernel_evm/evm_evaluation/src/runner.rs | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index 63681c216226..6ed8ed8093be 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -135,6 +135,34 @@ fn initialize_accounts(host: &mut EvalHost, unit: &TestUnit) { write_host!(host, "\n[END] Accounts initialisation\n"); } +fn initialize_env(unit: &TestUnit) -> Result { + let map_caller_keys: HashMap = MAP_CALLER_KEYS.into(); + + let mut env = Env::default(); + + // BlockEnv + env.block.number = unit.env.current_number; + env.block.coinbase = unit.env.current_coinbase; + env.block.timestamp = unit.env.current_timestamp; + env.block.gas_limit = unit.env.current_gas_limit; + env.block.basefee = unit.env.current_base_fee.unwrap_or_default(); + + // TxEnv + env.tx.caller = if let Some(caller) = + map_caller_keys.get(&unit.transaction.secret_key.unwrap()) + { + *caller + } else { + let private_key = unit.transaction.secret_key.unwrap(); + return Err(TestError::UnknownPrivateKey { private_key }); + }; + env.tx.gas_price = unit + .transaction + .gas_price + .unwrap_or_else(|| unit.transaction.max_fee_per_gas.unwrap_or_default()); + Ok(env) +} + pub fn run_test( path: &Path, report_map: &mut HashMap, @@ -145,39 +173,17 @@ pub fn run_test( let suit = read_testsuite(path)?; let mut host = prepare_host(); - let map_caller_keys: HashMap = MAP_CALLER_KEYS.into(); - for (name, unit) in suit.0.into_iter() { + writeln!(output_file, "Running unit test: {}", name).unwrap(); + let precompiles = precompile_set::(); let mut evm_account_storage = init_account_storage().unwrap(); - writeln!(output_file, "Running unit test: {}", name).unwrap(); let filler_source = prepare_filler_source(&host, &unit, opt)?; initialize_accounts(&mut host, &unit); - let mut env = Env::default(); - - // BlockEnv - env.block.number = unit.env.current_number; - env.block.coinbase = unit.env.current_coinbase; - env.block.timestamp = unit.env.current_timestamp; - env.block.gas_limit = unit.env.current_gas_limit; - env.block.basefee = unit.env.current_base_fee.unwrap_or_default(); - - // TxEnv - env.tx.caller = if let Some(caller) = - map_caller_keys.get(&unit.transaction.secret_key.unwrap()) - { - *caller - } else { - let private_key = unit.transaction.secret_key.unwrap(); - return Err(TestError::UnknownPrivateKey { private_key }); - }; - env.tx.gas_price = unit - .transaction - .gas_price - .unwrap_or_else(|| unit.transaction.max_fee_per_gas.unwrap_or_default()); + let mut env = initialize_env(&unit)?; // post and execution for (spec_name, tests) in unit.post { -- GitLab From 289081dd4c5dd808fa8d5debd391be2e51b14c3d Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Thu, 30 Nov 2023 17:17:42 +0100 Subject: [PATCH 08/10] EVM/Eval: extract transaction application --- .../kernel_evm/evm_evaluation/src/runner.rs | 121 ++++++++++-------- 1 file changed, 68 insertions(+), 53 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index 6ed8ed8093be..ff1ec71c43f5 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -3,9 +3,12 @@ // // SPDX-License-Identifier: MIT -use evm_execution::account_storage::{init_account_storage, EthereumAccount}; -use evm_execution::precompiles::precompile_set; -use evm_execution::{run_transaction, Config}; +use evm_execution::account_storage::{ + init_account_storage, EthereumAccount, EthereumAccountStorage, +}; +use evm_execution::handler::ExecutionOutcome; +use evm_execution::precompiles::{precompile_set, PrecompileBTreeMap}; +use evm_execution::{run_transaction, Config, EthereumError}; use tezos_ethereum::block::BlockConstants; @@ -21,7 +24,7 @@ use thiserror::Error; use crate::evalhost::EvalHost; use crate::fillers::process; use crate::helpers::construct_folder_path; -use crate::models::{Env, FillerSource, SpecName, TestSuite, TestUnit}; +use crate::models::{Env, FillerSource, SpecName, Test, TestSuite, TestUnit}; use crate::{write_host, Opt, ReportValue}; const MAP_CALLER_KEYS: [(H256, H160); 6] = [ @@ -163,6 +166,59 @@ fn initialize_env(unit: &TestUnit) -> Result { Ok(env) } +fn execute_transaction( + host: &mut EvalHost, + evm_account_storage: &mut EthereumAccountStorage, + precompiles: &PrecompileBTreeMap, + config: &Config, + unit: &TestUnit, + env: &mut Env, + test: &Test, +) -> Result, EthereumError> { + let gas_limit = *unit.transaction.gas_limit.get(test.indexes.gas).unwrap(); + let gas_limit = u64::try_from(gas_limit).unwrap_or(u64::MAX); + env.tx.gas_limit = gas_limit; + env.tx.data = unit + .transaction + .data + .get(test.indexes.data) + .unwrap() + .clone(); + env.tx.value = *unit.transaction.value.get(test.indexes.value).unwrap(); + env.tx.transact_to = unit.transaction.to; + + let block_constants = BlockConstants { + gas_price: env.tx.gas_price, + number: env.block.number, + coinbase: env.block.coinbase.to_fixed_bytes().into(), + timestamp: env.block.timestamp, + gas_limit: env.block.gas_limit.as_u64(), + base_fee_per_gas: env.block.basefee, + chain_id: U256::from(1337), + }; + let address = env.tx.transact_to.map(|addr| addr.to_fixed_bytes().into()); + let caller = env.tx.caller.to_fixed_bytes().into(); + let call_data = env.tx.data.to_vec(); + let gas_limit = Some(env.tx.gas_limit); + let transaction_value = Some(env.tx.value); + let pay_for_gas = true; // always, for now + + run_transaction( + host, + &block_constants, + evm_account_storage, + precompiles, + config.clone(), + address, + caller, + call_data, + gas_limit, + transaction_value, + pay_for_gas, + u64::MAX, // don't account for ticks during the test + ) +} + pub fn run_test( path: &Path, report_map: &mut HashMap, @@ -186,7 +242,7 @@ pub fn run_test( let mut env = initialize_env(&unit)?; // post and execution - for (spec_name, tests) in unit.post { + for (spec_name, tests) in &unit.post { let config = match spec_name { SpecName::Shanghai => Config::shanghai(), // TODO: enable future configs when parallelization is enabled. @@ -194,56 +250,15 @@ pub fn run_test( _ => continue, }; - for test_execution in tests.into_iter() { - let gas_limit = *unit - .transaction - .gas_limit - .get(test_execution.indexes.gas) - .unwrap(); - let gas_limit = u64::try_from(gas_limit).unwrap_or(u64::MAX); - env.tx.gas_limit = gas_limit; - env.tx.data = unit - .transaction - .data - .get(test_execution.indexes.data) - .unwrap() - .clone(); - env.tx.value = *unit - .transaction - .value - .get(test_execution.indexes.value) - .unwrap(); - env.tx.transact_to = unit.transaction.to; - - let block_constants = BlockConstants { - gas_price: env.tx.gas_price, - number: env.block.number, - coinbase: env.block.coinbase.to_fixed_bytes().into(), - timestamp: env.block.timestamp, - gas_limit: env.block.gas_limit.as_u64(), - base_fee_per_gas: env.block.basefee, - chain_id: U256::from(1337), - }; - let address = env.tx.transact_to.map(|addr| addr.to_fixed_bytes().into()); - let caller = env.tx.caller.to_fixed_bytes().into(); - let call_data = env.tx.data.to_vec(); - let gas_limit = Some(env.tx.gas_limit); - let transaction_value = Some(env.tx.value); - let pay_for_gas = true; // always, for now - - let exec_result = run_transaction( + for test_execution in tests.iter() { + let exec_result = execute_transaction( &mut host, - &block_constants, &mut evm_account_storage, &precompiles, - config.clone(), - address, - caller, - call_data, - gas_limit, - transaction_value, - pay_for_gas, - u64::MAX, // don't account for ticks during the test + &config, + &unit, + &mut env, + test_execution, ); match &exec_result { @@ -291,7 +306,7 @@ pub fn run_test( Some(filler_source) => process( &mut host, filler_source, - &spec_name, + spec_name, report_map, report_key.clone(), output_file, -- GitLab From 668c02a02626548c2118c41469d355e604ff6dfa Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Wed, 29 Nov 2023 17:46:49 +0100 Subject: [PATCH 09/10] EVM/Eval: Extract result checking --- .../kernel_evm/evm_evaluation/src/runner.rs | 85 ++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index ff1ec71c43f5..aa28e6e3dc2f 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -219,6 +219,52 @@ fn execute_transaction( ) } +fn check_results( + host: &EvalHost, + name: &str, + test: &Test, + exec_result: &Result, EthereumError>, +) { + match exec_result { + Ok(execution_outcome_opt) => { + let outcome_status = match execution_outcome_opt { + Some(execution_outcome) => { + if execution_outcome.is_success { + "[SUCCESS]" + } else { + "[FAILURE]" + } + } + None => "[INVALID]", + }; + write_host!(host, "\nOutcome status: {}", outcome_status); + } + Err(e) => write_host!(host, "\nA test failed due to {:?}", e), + } + + write_host!(host, "\nFinal check: "); + match (test.expect_exception.clone(), exec_result) { + (None, Ok(_)) => { + write_host!(host, "No unexpected exception.") + } + (Some(_), Err(_)) => { + write_host!(host, "Exception was expected.") + } + _ => { + write_host!( + host, + "\nSomething unexpected happened for test {}.\n\ + Expected exception is the following: {:?}\n\ + Further details on the execution result: {:?}", + name, + &test.expect_exception, + exec_result + ); + } + } + write_host!(host, "\n=======> OK! <=======\n"); +} + pub fn run_test( path: &Path, report_map: &mut HashMap, @@ -261,44 +307,7 @@ pub fn run_test( test_execution, ); - match &exec_result { - Ok(execution_outcome_opt) => { - let outcome_status = match execution_outcome_opt { - Some(execution_outcome) => { - if execution_outcome.is_success { - "[SUCCESS]" - } else { - "[FAILURE]" - } - } - None => "[INVALID]", - }; - write_host!(host, "\nOutcome status: {}", outcome_status); - } - Err(e) => write_host!(host, "\nA test failed due to {:?}", e), - } - - write!(host.buffer.borrow_mut(), "\nFinal check: ").unwrap(); - match (&test_execution.expect_exception, &exec_result) { - (None, Ok(_)) => { - write_host!(host, "No unexpected exception.") - } - (Some(_), Err(_)) => { - write_host!(host, "Exception was expected.") - } - _ => { - write_host!( - host, - "\nSomething unexpected happened for test {}.\n\ - Expected exception is the following: {:?}\n\ - Further details on the execution result: {:?}", - name, - test_execution.expect_exception, - exec_result - ); - } - } - write_host!(host, "\n=======> OK! <=======\n"); + check_results(&host, &name, test_execution, &exec_result); } // Check the state after the execution of the result. -- GitLab From be72c2dff49f958f199385f0ebb33de3eadeee49 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Thu, 30 Nov 2023 11:11:31 +0100 Subject: [PATCH 10/10] EVM/Eval: use write_host for fillers.rs --- .../kernel_evm/evm_evaluation/src/fillers.rs | 112 ++++-------------- 1 file changed, 25 insertions(+), 87 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/fillers.rs b/etherlink/kernel_evm/evm_evaluation/src/fillers.rs index 0e9ab7a1ef2a..09365e2f7e44 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/fillers.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/fillers.rs @@ -6,7 +6,7 @@ use crate::evalhost::EvalHost; use crate::helpers::{parse_and_get_cmp, purify_network}; use crate::models::spec::SpecId; use crate::models::{AccountInfoFiller, FillerSource, SpecName}; -use crate::ReportValue; +use crate::{write_host, ReportValue}; use evm_execution::account_storage::EthereumAccount; @@ -26,20 +26,10 @@ fn check_should_not_exist( ) { if let Some(_shouldnotexist) = shouldnotexist { if account.balance(host).is_ok() { - writeln!( - host.buffer.borrow_mut(), - "Account {} should not exist.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {} should not exist.", hex_address); *invalid_state = true; } else { - writeln!( - host.buffer.borrow_mut(), - "Account {} rightfully do not exist.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {} rightfully do not exist.", hex_address); } } } @@ -56,24 +46,14 @@ fn check_balance( Ok(current_balance) => { if current_balance != *balance { *invalid_state = true; - writeln!( host.buffer.borrow_mut(), "Account {}: balance don't match current one, {} was expected, but got {}.", hex_address, balance, current_balance).unwrap(); + write_host!( host, "Account {}: balance don't match current one, {} was expected, but got {}.", hex_address, balance, current_balance); } else { - writeln!( - host.buffer.borrow_mut(), - "Account {}: balance matched.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {}: balance matched.", hex_address); } } Err(_) => { *invalid_state = true; - writeln!( - host.buffer.borrow_mut(), - "Account {} should have a balance.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {} should have a balance.", hex_address); } } } @@ -92,24 +72,14 @@ fn check_code( let current_code: Bytes = current_code.into(); if current_code != code { *invalid_state = true; - writeln!( host.buffer.borrow_mut(), "Account {}: code don't match current one, {:?} was expected, but got {:?}.", hex_address, code, current_code).unwrap(); + write_host!( host, "Account {}: code don't match current one, {:?} was expected, but got {:?}.", hex_address, code, current_code); } else { - writeln!( - host.buffer.borrow_mut(), - "Account {}: code matched.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {}: code matched.", hex_address); } } Err(_) => { *invalid_state = true; - writeln!( - host.buffer.borrow_mut(), - "Account {} should have a code.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {} should have a code.", hex_address); } } } @@ -127,24 +97,14 @@ fn check_nonce( Ok(current_nonce) => { if current_nonce != (*nonce).into() { *invalid_state = true; - writeln!( host.buffer.borrow_mut(), "Account {}: nonce don't match current one, {} was expected, but got {}.", hex_address, nonce, current_nonce).unwrap(); + write_host!( host, "Account {}: nonce don't match current one, {} was expected, but got {}.", hex_address, nonce, current_nonce); } else { - writeln!( - host.buffer.borrow_mut(), - "Account {}: nonce matched.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {}: nonce matched.", hex_address); } } Err(_) => { *invalid_state = true; - writeln!( - host.buffer.borrow_mut(), - "Account {} should have a nonce.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {} should have a nonce.", hex_address); } } } @@ -159,12 +119,11 @@ fn check_storage( ) { if let Some(storage) = &storage { if storage.is_empty() { - writeln!( - host.buffer.borrow_mut(), + write_host!( + host, "Account {}: storage matched (both empty).", hex_address - ) - .unwrap(); + ); } for (index, value) in storage.iter() { match account.get_storage(host, index) { @@ -172,25 +131,19 @@ fn check_storage( let storage_value = value; if current_storage_value != *storage_value { *invalid_state = true; - writeln!( host.buffer.borrow_mut(), "Account {}: storage don't match current one for index {}, {} was expected, but got {}.", hex_address, index, storage_value, current_storage_value).unwrap(); + write_host!( host, "Account {}: storage don't match current one for index {}, {} was expected, but got {}.", hex_address, index, storage_value, current_storage_value); } else { - writeln!( - host.buffer.borrow_mut(), + write_host!( + host, "Account {}: storage matched for index {}.", hex_address, index - ) - .unwrap(); + ); } } Err(_) => { *invalid_state = true; - writeln!( - host.buffer.borrow_mut(), - "Account {} should have a storage.", - hex_address - ) - .unwrap(); + write_host!(host, "Account {} should have a storage.", hex_address); } } } @@ -251,9 +204,9 @@ fn check_durable_storage( if invalid_state { // One invalid state will cause the entire test to be a failure. *good_state = false; - writeln!(host.buffer.borrow_mut(), "==> [INVALID STATE]\n").unwrap(); + write_host!(host, "==> [INVALID STATE]\n"); } else { - writeln!(host.buffer.borrow_mut(), "==> [CORRECT STATE]\n").unwrap(); + write_host!(host, "==> [CORRECT STATE]\n"); } } } @@ -269,12 +222,7 @@ pub fn process( let mut good_state = true; for (name, fillers) in filler_source.0.into_iter() { - writeln!( - host.buffer.borrow_mut(), - "Processing checks with filler: {}Filler\n", - name - ) - .unwrap(); + write_host!(host, "Processing checks with filler: {}Filler\n", name); for filler_expectation in fillers.expect { for filler_network in filler_expectation.network { let cmp_spec_id = parse_and_get_cmp(&filler_network); @@ -286,18 +234,8 @@ pub fn process( continue; } - writeln!( - host.buffer.borrow_mut(), - "CONFIG NETWORK ---- {}", - spec_name.to_str() - ) - .unwrap(); - writeln!( - host.buffer.borrow_mut(), - "CHECK NETWORK ---- {}\n", - filler_network - ) - .unwrap(); + write_host!(host, "CONFIG NETWORK ---- {}", spec_name.to_str()); + write_host!(host, "CHECK NETWORK ---- {}\n", filler_network); check_durable_storage(host, &filler_expectation.result, &mut good_state); } -- GitLab