From 259f9005fceca30bb56409d7302f388ec0041f41 Mon Sep 17 00:00:00 2001 From: Amir Pasha Motamed Date: Mon, 14 Oct 2024 22:09:55 +0000 Subject: [PATCH] All state bypass changes --- Cargo.lock | 7 +- crates/ethereum/evm/Cargo.toml | 1 + crates/ethereum/evm/src/execute.rs | 88 ++++- crates/telos/node/Cargo.toml | 1 + crates/telos/node/tests/state_bypass.rs | 383 +++++++++++++++++++++ crates/telos/rpc-engine-api/Cargo.toml | 1 + crates/telos/rpc-engine-api/src/compare.rs | 106 +++++- 7 files changed, 551 insertions(+), 36 deletions(-) create mode 100644 crates/telos/node/tests/state_bypass.rs diff --git a/Cargo.lock b/Cargo.lock index 618b555550acd..836ec793aeb7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5539,7 +5539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -8756,6 +8756,7 @@ dependencies = [ "revm-primitives", "secp256k1", "serde_json", + "sha2 0.10.8", ] [[package]] @@ -9418,6 +9419,7 @@ dependencies = [ "reth-rpc", "reth-stages", "reth-telos-rpc", + "reth-telos-rpc-engine-api 1.0.8", "reth-tracing", "reth-transaction-pool", "serde", @@ -10623,6 +10625,7 @@ dependencies = [ "revm", "revm-primitives", "serde", + "sha2 0.10.8", "tracing", ] @@ -13282,7 +13285,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/crates/ethereum/evm/Cargo.toml b/crates/ethereum/evm/Cargo.toml index 413a3e75411c4..41f32ed58eb15 100644 --- a/crates/ethereum/evm/Cargo.toml +++ b/crates/ethereum/evm/Cargo.toml @@ -32,6 +32,7 @@ alloy-sol-types.workspace = true # telos reth-telos-rpc-engine-api = { workspace = true, optional = true } reth-telos-primitives-traits = { workspace = true, optional = true } +sha2 = "0.10.8" [dev-dependencies] reth-testing-utils.workspace = true diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index d8e6109caa4e4..6f8bf07cff629 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -38,6 +38,8 @@ use reth_telos_rpc_engine_api::compare::compare_state_diffs; use revm_primitives::{Address, Account, AccountInfo, AccountStatus, Bytecode, HashMap, KECCAK_EMPTY}; #[cfg(feature = "telos")] use alloy_primitives::B256; +#[cfg(feature = "telos")] +use sha2::{Sha256, Digest}; /// Provides executors to execute regular ethereum blocks #[derive(Debug, Clone)] @@ -192,6 +194,7 @@ where // execute transactions let mut cumulative_gas_used = 0; + #[cfg(not(feature = "telos"))] let mut receipts = Vec::with_capacity(block.body.transactions.len()); for (sender, transaction) in block.transactions_with_sender() { #[cfg(feature = "telos")] @@ -233,6 +236,7 @@ where // append gas used cumulative_gas_used += result.gas_used(); + #[cfg(not(feature = "telos"))] // Push transaction changeset and calculate header bloom filter for receipt. receipts.push( #[allow(clippy::needless_update)] // side-effect of optimism fields @@ -259,23 +263,31 @@ where new_addresses_using_create_iter.next(); } - #[cfg(feature = "telos")] { - // Perform state diff comparision - let revm_state_diffs = evm.db_mut().transition_state.clone().unwrap_or_default().transitions; - let block_num = block.block.header.number; - println!( - "Compare: block {block_num} {}", - compare_state_diffs( - &mut evm, - revm_state_diffs, - unwrapped_telos_extra_fields.statediffs_account.unwrap_or_default(), - unwrapped_telos_extra_fields.statediffs_accountstate.unwrap_or_default(), - unwrapped_telos_extra_fields.new_addresses_using_create.unwrap_or_default(), - unwrapped_telos_extra_fields.new_addresses_using_openwallet.unwrap_or_default() - ) - ); + #[cfg(feature = "telos")] + { + // Perform state diff comparision + let revm_state_diffs = evm.db_mut().transition_state.clone().unwrap_or_default().transitions; + let block_num = block.block.header.number; + println!( + "Compare: block {block_num} {}", + compare_state_diffs( + &mut evm, + revm_state_diffs, + unwrapped_telos_extra_fields.statediffs_account.clone().unwrap_or_default(), + unwrapped_telos_extra_fields.statediffs_accountstate.clone().unwrap_or_default(), + unwrapped_telos_extra_fields.new_addresses_using_create.clone().unwrap_or_default(), + unwrapped_telos_extra_fields.new_addresses_using_openwallet.clone().unwrap_or_default() + ) + ); } + #[cfg(feature = "telos")] + let receipts = if unwrapped_telos_extra_fields.receipts.is_some() { + unwrapped_telos_extra_fields.receipts.clone().unwrap() + } else { + vec![] + }; + let requests = if self.chain_spec.is_prague_active_at_timestamp(block.timestamp) { // Collect all EIP-6110 deposits let deposit_requests = @@ -288,7 +300,44 @@ where vec![] }; - Ok(EthExecuteOutput { receipts, requests, gas_used: cumulative_gas_used }) + // #[cfg(feature = "telos")] + // { + // let mut addr_to_accstate: HashMap> = HashMap::new(); + + // for sdiff_accstate in unwrapped_telos_extra_fields.clone().statediffs_accountstate.unwrap_or(vec![]) { + // if !addr_to_accstate.contains_key(&sdiff_accstate.address) { + // addr_to_accstate.insert(sdiff_accstate.address, HashMap::new()); + // } + // let mut acc_storage = addr_to_accstate.get_mut(&sdiff_accstate.address).unwrap(); + // acc_storage.insert(sdiff_accstate.key, EvmStorageSlot { original_value: Default::default(), present_value: sdiff_accstate.value, is_cold: false }); + // } + + // let mut state: HashMap = HashMap::new(); + + // for sdiff_acc in unwrapped_telos_extra_fields.clone().statediffs_account.unwrap_or(vec![]) { + // state.insert( + // sdiff_acc.address, + // Account { + // info: AccountInfo { + // balance: sdiff_acc.balance, + // nonce: sdiff_acc.nonce, + // code_hash: B256::from(Sha256::digest(sdiff_acc.code.as_ref()).as_ref()), + // code: Some(Bytecode::LegacyRaw(sdiff_acc.code)), + // }, + // storage: addr_to_accstate.get(&sdiff_acc.address).unwrap_or(&HashMap::new()).clone(), + // status: AccountStatus::Touched | AccountStatus::LoadedAsNotExisting, + // } + // ); + // } + + // evm.db_mut().commit(state); + // } + + Ok(EthExecuteOutput { + receipts, + requests, + gas_used: cumulative_gas_used + }) } } @@ -366,7 +415,12 @@ where let env = self.evm_env_for_block(&block.header, total_difficulty); let output = { let evm = self.executor.evm_config.evm_with_env(&mut self.state, env); - self.executor.execute_state_transitions(block, evm, #[cfg(feature = "telos")] telos_extra_fields) + self.executor.execute_state_transitions( + block, + evm, + #[cfg(feature = "telos")] + telos_extra_fields + ) }?; // 3. apply post execution changes diff --git a/crates/telos/node/Cargo.toml b/crates/telos/node/Cargo.toml index e9012cdf6439d..2570601f84987 100644 --- a/crates/telos/node/Cargo.toml +++ b/crates/telos/node/Cargo.toml @@ -32,6 +32,7 @@ reth-provider.workspace = true reth-rpc.workspace = true reth-stages.workspace = true reth-telos-rpc.workspace = true +reth-telos-rpc-engine-api.workspace = true reth-tracing.workspace = true reth-transaction-pool.workspace = true diff --git a/crates/telos/node/tests/state_bypass.rs b/crates/telos/node/tests/state_bypass.rs new file mode 100644 index 0000000000000..2cb9373b71be9 --- /dev/null +++ b/crates/telos/node/tests/state_bypass.rs @@ -0,0 +1,383 @@ +use std::collections::HashMap; +use std::fs; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; +use alloy_provider::{Provider, ProviderBuilder}; +use reqwest::Url; +use serde_json::json; +use telos_consensus_client::execution_api_client::{ExecutionApiClient, RpcRequest}; +use telos_consensus_client::execution_api_client::ExecutionApiMethod::{ForkChoiceUpdatedV1, NewPayloadV1}; +use tracing::info; +use reth::args::RpcServerArgs; +use reth::builder::NodeConfig; +use reth::primitives::{Address, B256, Bytecode, hex, JumpTable, U256}; +use reth::primitives::hex::FromHex; +use reth::primitives::revm_primitives::{Bytecode as RevmBytecode, LegacyAnalyzedBytecode}; +use reth::revm; +use reth::revm::db::{CacheDB, EmptyDB, StorageWithOriginalValues, states::StorageSlot}; +use reth::revm::{Database, DatabaseCommit, DatabaseRef, Evm, State, TransitionAccount}; +use reth::revm::primitives::{AccountInfo, EvmStorageSlot}; +use reth::rpc::types::engine::ForkchoiceState; +use reth::rpc::types::ExecutionPayloadV1; +use reth::tasks::TaskManager; +use reth_chainspec::{ChainSpecBuilder, TEVMTESTNET}; +use reth_e2e_test_utils::node::NodeTestContext; +use reth_node_builder::NodeBuilder; +use reth_node_telos::{TelosArgs, TelosNode}; +use reth_primitives::Bytes; +use reth_primitives::constants::{EMPTY_ROOT_HASH, MIN_PROTOCOL_BASE_FEE}; +use reth_primitives::revm_primitives::AccountStatus; +use reth_telos_rpc::TelosClient; +use reth_telos_rpc_engine_api::compare::compare_state_diffs; +use reth_telos_rpc_engine_api::structs::{TelosAccountTableRow, TelosAccountStateTableRow, TelosEngineAPIExtraFields}; +use revm::primitives::Account; + +fn init_reth() -> eyre::Result<(NodeConfig, String)> { + let chain_spec = Arc::new( + ChainSpecBuilder::default() + .chain(TEVMTESTNET.chain) + .genesis(TEVMTESTNET.genesis.clone()) + .frontier_activated() + .homestead_activated() + .tangerine_whistle_activated() + .spurious_dragon_activated() + .byzantium_activated() + .constantinople_activated() + .petersburg_activated() + .istanbul_activated() + .berlin_activated() + .build(), + ); + + let mut rpc_config = RpcServerArgs::default().with_unused_ports().with_http(); + rpc_config.auth_jwtsecret = Some(PathBuf::from("tests/assets/jwt.hex")); + + // Node setup + let node_config = NodeConfig::test().with_chain(chain_spec).with_rpc(rpc_config.clone()); + + let jwt = fs::read_to_string(node_config.rpc.auth_jwtsecret.clone().unwrap())?; + Ok((node_config, jwt)) +} + +#[tokio::test] +async fn test_integration_tevm_only() { + tracing_subscriber::fmt::init(); + + let (node_config, jwt_secret) = init_reth().unwrap(); + + let exec = TaskManager::current(); + let exec = exec.executor(); + + reth_tracing::init_test_tracing(); + + let telos_args = TelosArgs { + telos_endpoint: None, + signer_account: Some("rpc.evm".to_string()), + signer_permission: Some("active".to_string()), + signer_key: Some("5Jr65kdYmn33C3UabzhmWDm2PuqbRfPuDStts3ZFNSBLM7TqaiL".to_string()), + gas_cache_seconds: None, + }; + + let node_handle = NodeBuilder::new(node_config.clone()) + .testing_node(exec) + .node(TelosNode::new(telos_args.clone())) + .extend_rpc_modules(move |ctx| { + if telos_args.telos_endpoint.is_some() { + ctx.registry.eth_api().set_telos_client(TelosClient::new(telos_args.into())); + } + + Ok(()) + }) + .launch() + .await + .unwrap(); + + let execution_port = node_handle.node.auth_server_handle().local_addr().port(); + let rpc_port = node_handle.node.rpc_server_handles.rpc.http_local_addr().unwrap().port(); + println!("Starting Reth on RPC port {}!", rpc_port); + let _ = NodeTestContext::new(node_handle.node.clone()).await.unwrap(); + + let custom_balance = U256::from(80085); + + let exec_client = ExecutionApiClient::new(&format!("http://127.0.0.1:{}", execution_port), &jwt_secret).unwrap(); + + let execution_payload = ExecutionPayloadV1 { + parent_hash: B256::from_hex("b25034033c9ca7a40e879ddcc29cf69071a22df06688b5fe8cc2d68b4e0528f9").unwrap(), + fee_recipient: Default::default(), + state_root: EMPTY_ROOT_HASH, + receipts_root: EMPTY_ROOT_HASH, + logs_bloom: Default::default(), + prev_randao: Default::default(), + block_number: 1, + gas_limit: 0x7fffffff, + gas_used: 0, + timestamp: 1728067687, + extra_data: Default::default(), + base_fee_per_gas: U256::try_from(MIN_PROTOCOL_BASE_FEE).unwrap(), + block_hash: B256::from_hex("0a1d73423169c8b4124121d40c0e13eb078621e73effd2d183f9a1d8017537dd").unwrap(), + transactions: vec![], + }; + + let test_addr = Address::from_hex("00000000000000000000000000000000deadbeef").unwrap(); + + let extra_fields = TelosEngineAPIExtraFields { + statediffs_account: Some(vec![TelosAccountTableRow { + removed: false, + address: test_addr, + account: "eosio".to_string(), + nonce: 0, + code: Default::default(), + balance: custom_balance, + }]), + statediffs_accountstate: Some(vec![]), + revision_changes: None, + gasprice_changes: None, + new_addresses_using_create: Some(vec![]), + new_addresses_using_openwallet: Some(vec![]), + receipts: Some(vec![]), + }; + + let block_req = RpcRequest { + method: NewPayloadV1, + params: vec![ + json![execution_payload], + json![extra_fields] + ].into() + }; + + let new_block_result = exec_client.rpc(block_req).await.unwrap(); + + info!("new_block: {:#?}", new_block_result); + + let fork_choice_result = exec_client.rpc(RpcRequest { + method: ForkChoiceUpdatedV1, + params: json![vec![ForkchoiceState { + head_block_hash: execution_payload.block_hash, + safe_block_hash: execution_payload.block_hash, + finalized_block_hash: execution_payload.block_hash + }]] + }).await.unwrap(); + + info!("fork_choice: {:#?}", fork_choice_result); + + + let provider = ProviderBuilder::new() + //.network::() + .on_http(Url::from_str(format!("http://localhost:{}", rpc_port).as_str()).unwrap()); + + let balance = provider.get_balance(test_addr).await.unwrap(); + info!("balance: {:#?}", balance); + + assert_eq!(balance, custom_balance); +} + +#[test] +fn test_db_both_sides_present_but_dif() { + let test_addr = Address::from_str("00000000000000000000000000000000deadbeef").unwrap(); + + let init_balance = U256::from(0); + let custom_balance = U256::from(80085); + + let init_nonce = 0; + let custom_nonce = 69; + + let custom_code = Bytes::from(&hex!("ffff")); + let custom_bytecode = RevmBytecode::LegacyRaw(custom_code.clone()); + + let revm_acc_info = AccountInfo { + balance: init_balance, + nonce: init_nonce, + code_hash: Default::default(), + code: None, + }; + + let mut db = CacheDB::new(EmptyDB::new()); + db.insert_account_info(test_addr, revm_acc_info); + + let mut state = State::builder().with_database(db).build(); + + let mut evm = Evm::builder().with_db(&mut state).build(); + + let statediffs_account = vec![TelosAccountTableRow { + removed: false, + address: test_addr, + account: "eosio".to_string(), + nonce: custom_nonce, + code: custom_code.clone(), + balance: custom_balance, + }]; + + compare_state_diffs( + &mut evm, + HashMap::new(), + statediffs_account.clone(), + vec![], + vec![], + vec![] + ); + + let db_acc = evm.db_mut().basic(test_addr).unwrap().unwrap(); + assert_eq!(db_acc.nonce, statediffs_account[0].nonce); + assert_eq!(db_acc.balance, statediffs_account[0].balance); + assert_eq!(db_acc.code, Some(custom_bytecode)); +} + +#[test] +fn test_revm_state_both_sides_present_but_dif() { + let test_addr = Address::from_str("00000000000000000000000000000000deadbeef").unwrap(); + + let revm_acc_info = AccountInfo { + balance: U256::from(80085), + nonce: 69, + code_hash: Default::default(), + code: None, + }; + + let mut revm_state_diffs = HashMap::new(); + + let mut transition_account = TransitionAccount::new_empty_eip161(HashMap::new()); + + transition_account.info = Some(revm_acc_info); + + revm_state_diffs.insert(test_addr, transition_account); + + let mut db = CacheDB::new(EmptyDB::new()); + + let mut state = State::builder().with_database(db).build(); + + let mut evm = Evm::builder().with_db(&mut state).build(); + + let statediffs_account = vec![TelosAccountTableRow { + removed: false, + address: test_addr, + account: "eosio".to_string(), + nonce: 1, + code: Default::default(), + balance: U256::from(80085), + }]; + + compare_state_diffs( + &mut evm, + revm_state_diffs, + statediffs_account.clone(), + vec![], + vec![], + vec![] + ); + + // let db_acc = evm.db_mut().basic(test_addr).unwrap().unwrap(); + // assert_eq!(db_acc.nonce, statediffs_account[0].nonce); + // assert_eq!(db_acc.balance, statediffs_account[0].balance); + // assert_eq!(db_acc.code, Some(custom_bytecode)); +} + +#[test] +fn test_tevm_only() { + let test_addr = Address::from_str("00000000000000000000000000000000deadbeef").unwrap(); + + let mut db = CacheDB::new(EmptyDB::new()); + + let mut state = State::builder().with_database(db).build(); + + let mut evm = Evm::builder().with_db(&mut state).build(); + + let statediffs_account = vec![TelosAccountTableRow { + removed: false, + address: test_addr, + account: "eosio".to_string(), + nonce: 1, + code: Default::default(), + balance: U256::from(80085), + }]; + + compare_state_diffs( + &mut evm, + HashMap::new(), + statediffs_account.clone(), + vec![], + vec![], + vec![] + ); + + let db_acc = evm.db_mut().basic(test_addr).unwrap().unwrap(); + assert_eq!(db_acc.nonce, statediffs_account[0].nonce); + assert_eq!(db_acc.balance, statediffs_account[0].balance); +} + +#[test] +fn test_accstate_diff_from_storage() { + let test_addr = Address::from_str("00000000000000000000000000000000deadbeef").unwrap(); + + let revm_acc_info = AccountInfo { + balance: U256::from(80085), + nonce: 69, + code_hash: Default::default(), + code: None, + }; + + let key = U256::from(420); + let value = U256::from(0); + let custom_value = U256::from(80085); + + let mut db = CacheDB::new(EmptyDB::new()); + + let mut storage = HashMap::new(); + storage.insert(key, value); + + let mut state = State::builder().with_database(db).build(); + + state.insert_account_with_storage(test_addr, revm_acc_info, storage); + + let mut evm = Evm::builder().with_db(&mut state).build(); + + let statediffs_accountstate = vec![TelosAccountStateTableRow { + removed: false, + address: test_addr, + key, + value: custom_value + }]; + + compare_state_diffs( + &mut evm, + HashMap::new(), + vec![], + statediffs_accountstate.clone(), + vec![], + vec![] + ); + + let db_value = evm.db_mut().storage(test_addr, key).unwrap(); + assert_eq!(db_value, custom_value); +} +#[test] +fn test_accstate_telos_only() { + let test_addr = Address::from_str("00000000000000000000000000000000deadbeef").unwrap(); + + let key = U256::from(420); + let custom_value = U256::from(80085); + + let mut db = CacheDB::new(EmptyDB::new()); + + let mut state = State::builder().with_database(db).build(); + + // state.insert_not_existing(test_addr); + + let mut evm = Evm::builder().with_db(&mut state).build(); + + let statediffs_accountstate = vec![TelosAccountStateTableRow { + removed: false, + address: test_addr, + key, + value: custom_value + }]; + + compare_state_diffs( + &mut evm, + HashMap::new(), + vec![], + statediffs_accountstate.clone(), + vec![], + vec![] + ); +} diff --git a/crates/telos/rpc-engine-api/Cargo.toml b/crates/telos/rpc-engine-api/Cargo.toml index 30e0d56832e94..e9ebe8d99c533 100644 --- a/crates/telos/rpc-engine-api/Cargo.toml +++ b/crates/telos/rpc-engine-api/Cargo.toml @@ -16,6 +16,7 @@ reth-storage-errors.workspace = true revm.workspace = true revm-primitives.workspace = true tracing.workspace = true +sha2 = "0.10.8" [lints] workspace = true diff --git a/crates/telos/rpc-engine-api/src/compare.rs b/crates/telos/rpc-engine-api/src/compare.rs index 5c0367763ed0f..a8996e7e117f5 100644 --- a/crates/telos/rpc-engine-api/src/compare.rs +++ b/crates/telos/rpc-engine-api/src/compare.rs @@ -1,12 +1,32 @@ -use std::collections::HashSet; +use std::collections::{HashSet}; use std::fmt::Display; use alloy_primitives::{Address, B256, U256}; use revm_primitives::HashMap; -use revm::db::AccountStatus; -use revm::{Database, Evm, State, TransitionAccount}; -use tracing::debug; +use revm::db::AccountStatus as DBAccountStatus; +use revm::{Database, DatabaseCommit, Evm, State, TransitionAccount}; +use revm::primitives::{Account, AccountInfo, AccountStatus, Bytecode}; use reth_storage_errors::provider::ProviderError; use crate::structs::{TelosAccountStateTableRow, TelosAccountTableRow}; +use tracing::debug; +use sha2::{Sha256, Digest}; + +fn override_account( + revm_db: &mut &mut State, + row: &TelosAccountTableRow +) where DB: Database { + let mut mod_state = HashMap::default(); + mod_state.insert(row.address, Account { + info: AccountInfo { + balance: row.balance, + nonce: row.nonce, + code_hash: B256::from(Sha256::digest(row.code.as_ref()).as_ref()), + code: Some(Bytecode::LegacyRaw(row.code.clone())), + }, + storage: HashMap::default(), + status: AccountStatus::Touched | AccountStatus::LoadedAsNotExisting, + }); + revm_db.commit(mod_state); +} /// This function compares the state diffs between revm and Telos EVM contract pub fn compare_state_diffs( @@ -19,7 +39,6 @@ pub fn compare_state_diffs( ) -> bool where DB: Database, - DB::Error: Into + Display, { if !revm_state_diffs.is_empty() || !statediffs_account.is_empty() @@ -48,6 +67,8 @@ where statediffs_accountstate_hashmap.insert((row.address,row.key)); } + let panic_mode = false; + for row in &statediffs_account { // Skip if address is created using openwallet and is empty if new_addresses_using_openwallet_hashset.contains(&row.address) && row.balance == U256::ZERO && row.nonce == 0 && row.code.len() == 0 { @@ -59,44 +80,95 @@ where } if let Ok(revm_row) = revm_db.basic(row.address) { if let Some(unwrapped_revm_row) = revm_row { + let mut mod_acc = Account { + info: unwrapped_revm_row.clone(), + storage: HashMap::default(), + status: AccountStatus::Touched | AccountStatus::LoadedAsNotExisting, + }; + let mut modded = false; + // Check balance inequality if unwrapped_revm_row.balance != row.balance { - panic!("Difference in balance, address: {:?} - revm: {:?} - tevm: {:?}",row.address,unwrapped_revm_row.balance,row.balance); + if panic_mode { + panic!("Difference in balance, address: {:?} - revm: {:?} - tevm: {:?}", row.address, unwrapped_revm_row.balance, row.balance); + } + mod_acc.info.balance = row.balance; + modded = true; } // Check nonce inequality if unwrapped_revm_row.nonce != row.nonce { - panic!("Difference in nonce, address: {:?} - revm: {:?} - tevm: {:?}",row.address,unwrapped_revm_row.nonce,row.nonce); + if panic_mode { + panic!("Difference in nonce, address: {:?} - revm: {:?} - tevm: {:?}", row.address, unwrapped_revm_row.nonce, row.nonce); + } + mod_acc.info.nonce = row.nonce; + modded = true; } // Check code size inequality if unwrapped_revm_row.clone().code.is_none() && row.code.len() != 0 || unwrapped_revm_row.clone().code.is_some() && !unwrapped_revm_row.clone().code.unwrap().is_empty() && row.code.len() == 0 { match revm_db.code_by_hash(unwrapped_revm_row.code_hash) { Ok(code_by_hash) => if (code_by_hash.is_empty() && row.code.len() != 0) || (!code_by_hash.is_empty() && row.code.len() == 0) { - panic!("Difference in code existence, address: {:?} - revm: {:?} - tevm: {:?}",row.address,code_by_hash,row.code) + if panic_mode { + panic!("Difference in code existence, address: {:?} - revm: {:?} - tevm: {:?}", row.address, code_by_hash, row.code) + } + if row.code.len() == 0 { + mod_acc.info.code = None; + } else { + mod_acc.info.code = Some(Bytecode::LegacyRaw(row.code.clone())); + } + modded = true; }, - Err(_) => panic!("Difference in code existence, address: {:?} - revm: {:?} - tevm: {:?}",row.address,unwrapped_revm_row.code,row.code), + Err(_) => { + if panic_mode { + panic!("Difference in code existence, address: {:?} - revm: {:?} - tevm: {:?}", row.address, unwrapped_revm_row.code, row.code) + } + if row.code.len() == 0 { + mod_acc.info.code = None; + } else { + mod_acc.info.code = Some(Bytecode::LegacyRaw(row.code.clone())); + } + modded = true; + }, + } + } + // Check code content inequality + if unwrapped_revm_row.clone().code.is_some_and(|code| code.bytes() != row.code) { + if panic_mode { + panic!("Difference in code content, revm: {:?}, tevm: {:?}", unwrapped_revm_row.clone().code.unwrap().bytes(), row.code); } + mod_acc.info.code = Some(Bytecode::LegacyRaw(row.code.clone())); + modded = true; + } + if modded { + let mut mod_state = HashMap::default(); + mod_state.insert(row.address, mod_acc); + revm_db.commit(mod_state); } - // // Check code content inequality - // if unwrapped_revm_row.clone().unwrap().code.is_some() && !unwrapped_revm_row.clone().unwrap().code.unwrap().is_empty() && unwrapped_revm_row.clone().unwrap().code.unwrap().bytes() != row.code { - // panic!("Difference in code content, revm: {:?}, tevm: {:?}",unwrapped_revm_row.clone().unwrap().code.unwrap().bytes(),row.code); - // } } else { // Skip if address is empty on both sides if !(row.balance == U256::ZERO && row.nonce == 0 && row.code.len() == 0) { if let Some(unwrapped_revm_state_diff) = revm_state_diffs.get(&row.address) { - if !(unwrapped_revm_state_diff.status == AccountStatus::Destroyed && row.nonce == 0 && row.balance == U256::ZERO && row.code.len() == 0) { - panic!("A modified `account` table row was found on both revm state and revm state diffs, but seems to be destroyed on just one side, address: {:?}",row.address); + if !(unwrapped_revm_state_diff.status == DBAccountStatus::Destroyed && row.nonce == 0 && row.balance == U256::ZERO && row.code.len() == 0) { + if panic_mode { + panic!("A modified `account` table row was found on both revm state and revm state diffs, but seems to be destroyed on just one side, address: {:?}",row.address); + } + override_account(revm_db, row); } } else { - panic!("A modified `account` table row was found on revm state, but contains no information, address: {:?}",row.address); + if panic_mode { + panic!("A modified `account` table row was found on revm state, but contains no information, address: {:?}", row.address); + } + override_account(revm_db, row); } } } } else { // Skip if address is empty on both sides if !(row.balance == U256::ZERO && row.nonce == 0 && row.code.len() == 0) { - panic!("A modified `account` table row was not found on revm state, address: {:?}",row.address); + if panic_mode { + panic!("A modified `account` table row was not found on revm state, address: {:?}",row.address); + } + override_account(revm_db, row); } } }