diff --git a/etherlink/kernel_latest/revm/src/code_storage.rs b/etherlink/kernel_latest/revm/src/code_storage.rs index 7e4ca9cc18872caaf8f9bfe17512b5fc6c58c895..020a697ff4934bbd003c7ef1cd82d33a165af31b 100644 --- a/etherlink/kernel_latest/revm/src/code_storage.rs +++ b/etherlink/kernel_latest/revm/src/code_storage.rs @@ -101,15 +101,16 @@ impl CodeStorage { } } - #[cfg(test)] - pub fn decrement_code_usage(&self, host: &mut impl Runtime) -> Result { - let number_reference = self.get_ref_count(host)?; - let number_reference = number_reference.saturating_sub(1u64); - self.set_ref_count(host, number_reference)?; + fn decrement_code_usage(&self, host: &mut impl Runtime) -> Result { + let mut number_reference = self.get_ref_count(host)?; + if number_reference != 0 { + // Condition avoids an unnecessary write access + number_reference = number_reference.saturating_sub(1u64); + self.set_ref_count(host, number_reference)?; + } Ok(number_reference) } - #[cfg(test)] pub fn delete(host: &mut impl Runtime, code_hash: &B256) -> Result<(), Error> { let code = Self::new(code_hash)?; if code.exists(host)? { diff --git a/etherlink/kernel_latest/revm/src/database.rs b/etherlink/kernel_latest/revm/src/database.rs index 218d4a9f0b4178aabd9d7e1cee6cdf89e0556dd4..f3bd685608bb4bc821624aa628164cd095382561 100644 --- a/etherlink/kernel_latest/revm/src/database.rs +++ b/etherlink/kernel_latest/revm/src/database.rs @@ -17,7 +17,7 @@ use crate::{ use revm::{ primitives::{Address, HashMap, StorageKey, StorageValue, B256, U256}, - state::{Account, AccountInfo, AccountStatus, Bytecode, EvmStorageSlot}, + state::{Account, AccountInfo, Bytecode, EvmStorage, EvmStorageSlot}, Database, DatabaseCommit, }; use tezos_crypto_rs::hash::{ContractKt1Hash, HashTrait}; @@ -42,6 +42,11 @@ pub struct EtherlinkVMDB<'a, Host: Runtime> { withdrawals: Vec, } +enum AccountState { + Touched((AccountInfo, EvmStorage)), + SelfDestructed(B256), +} + // See: https://github.com/rust-lang/rust-clippy/issues/5787 #[allow(clippy::needless_lifetimes)] impl<'a, Host: Runtime> EtherlinkVMDB<'a, Host> { @@ -81,10 +86,6 @@ pub trait PrecompileDatabase: Database { } impl EtherlinkVMDB<'_, Host> { - pub fn abort(&mut self) { - *self.commit_status = false; - } - pub fn commit_status(&self) -> bool { *self.commit_status } @@ -106,6 +107,79 @@ impl EtherlinkVMDB<'_, Host> { .rollback_transaction(self.host) .map_err(|err| Error::Custom(err.to_string())) } + + fn abort(&mut self) { + *self.commit_status = false; + } + + fn update_account(&mut self, address: Address, account_state: AccountState) { + match self.get_or_create_account(address) { + Ok(mut storage_account) => match account_state { + AccountState::Touched((info, storage)) => { + if let Err(err) = storage_account.set_info(self.host, info) { + self.abort(); + log!( + self.host, + LogError, + "DatabaseCommit `set_info` error: {err:?}" + ); + } + + for ( + key, + EvmStorageSlot { + original_value, + present_value, + .. + }, + ) in storage + { + if original_value != present_value { + if let Err(err) = storage_account.set_storage( + self.host, + &key, + &present_value, + ) { + self.abort(); + log!( + self.host, + LogError, + "DatabaseCommit `set_storage` error: {err:?}" + ); + } + } + } + } + AccountState::SelfDestructed(code_hash) => { + if let Err(err) = storage_account.clear_info(self.host, &code_hash) { + self.abort(); + log!( + self.host, + LogError, + "DatabaseCommit `clear_info` error: {err:?}" + ); + } + + if let Err(err) = storage_account.clear_storage(self.host) { + self.abort(); + log!( + self.host, + LogError, + "DatabaseCommit `clear_storage` error: {err:?}" + ); + } + } + }, + Err(err) => { + self.abort(); + log!( + self.host, + LogError, + "DatabaseCommit `get_or_create_account` error: {err:?}" + ) + } + } + } } impl PrecompileDatabase for EtherlinkVMDB<'_, Host> { @@ -198,65 +272,28 @@ impl Database for EtherlinkVMDB<'_, Host> { impl DatabaseCommit for EtherlinkVMDB<'_, Host> { fn commit(&mut self, changes: HashMap) { - for ( - address, - Account { - info, - storage, - status, - .. - }, - ) in changes - { - // The account is marked as touched, the changes should be commited + for (address, account) in changes { + // The account isn't marked as touched, the changes are not commited // to the database. - if status.contains(AccountStatus::Touched) { - match self.get_or_create_account(address) { - Ok(mut storage_account) => { - if let Err(err) = storage_account.set_info(self.host, info) { - self.abort(); - log!( - self.host, - LogError, - "DatabaseCommit `set_info` error: {err:?}" - ); - } + if !account.is_touched() { + continue; + } - for ( - key, - EvmStorageSlot { - original_value, - present_value, - .. - }, - ) in storage - { - if original_value != present_value { - if let Err(err) = storage_account.set_storage( - self.host, - &key, - &present_value, - ) { - self.abort(); - log!( - self.host, - LogError, - "DatabaseCommit `set_storage` error: {err:?}" - ); - } - } - } - } - Err(err) => { - self.abort(); - log!( - self.host, - LogError, - "DatabaseCommit `get_or_create_account` error: {err:?}" - ) - } - } + // The account is touched and marked as selfdestructed, we clear the + // account. + if account.is_selfdestructed() { + self.update_account( + address, + AccountState::SelfDestructed(account.info.code_hash), + ); + continue; } + + // The account is touched, the changes are naturally commited to the database. + self.update_account( + address, + AccountState::Touched((account.info, account.storage)), + ); } } } diff --git a/etherlink/kernel_latest/revm/src/lib.rs b/etherlink/kernel_latest/revm/src/lib.rs index 355b42dab3060ec5655dcd05c05b800dd460e147..5402fab26c21710bc9915785af7f2f1acf51877e 100644 --- a/etherlink/kernel_latest/revm/src/lib.rs +++ b/etherlink/kernel_latest/revm/src/lib.rs @@ -7,6 +7,7 @@ use crate::{database::PrecompileDatabase, send_outbox_message::Withdrawal}; use database::EtherlinkVMDB; use precompile_provider::EtherlinkPrecompiles; use revm::context::result::EVMError; +use revm::context::tx::TxEnvBuilder; use revm::{ context::{ result::ExecutionResult, transaction::AccessList, BlockEnv, CfgEnv, ContextTr, @@ -113,25 +114,28 @@ fn tx_env<'a, Host: Runtime>( .map_err(|err| Error::Custom(err.to_string()))?; let nonce = storage_account.nonce(host)?; - Ok(TxEnv { - // Setting the transaction type from scratch seems irrelevant - // in the execution. We just set it to legacy be default as - // it's the other parameters that matter here. - tx_type: 0, - caller, - gas_limit, - gas_price, - kind, - value, - data, - nonce, - chain_id: Some(chain_id), - access_list, - gas_priority_fee: None, - blob_hashes: vec![], - max_fee_per_blob_gas: 0, - authorization_list: vec![], - }) + // Using the transaction environment builder helps to + // derive the transaction type directly from the different + // fields of the transaction. + let tx_env = TxEnvBuilder::new() + .caller(caller) + .gas_limit(gas_limit) + .gas_price(gas_price) + .kind(kind) + .value(value) + .data(data) + .nonce(nonce) + .chain_id(Some(chain_id)) + .access_list(access_list) + .build() + .map_err(|err| { + Error::Custom(format!( + "Building the transaction environment failed with: {:?}", + err + )) + })?; + + Ok(tx_env) } type EvmContext<'a, Host> = Evm< diff --git a/etherlink/kernel_latest/revm/src/world_state_handler.rs b/etherlink/kernel_latest/revm/src/world_state_handler.rs index eee4359bd1ca6fba781db695872e78704684b3ce..80b827e2cd4d326382bdf0aaee74b9c5bcb44ced 100644 --- a/etherlink/kernel_latest/revm/src/world_state_handler.rs +++ b/etherlink/kernel_latest/revm/src/world_state_handler.rs @@ -217,6 +217,37 @@ impl StorageAccount { Ok(()) } + fn delete_code( + &mut self, + host: &mut impl Runtime, + code_hash: &B256, + ) -> Result<(), Error> { + if code_hash != &KECCAK_EMPTY { + CodeStorage::delete(host, code_hash)?; + let code_hash_path = concat(&self.path, &CODE_HASH_PATH)?; + if host.store_has(&code_hash_path)?.is_some() { + host.store_delete(&code_hash_path)? + } + } + Ok(()) + } + + pub fn clear_info( + &mut self, + host: &mut impl Runtime, + code_hash: &B256, + ) -> Result<(), Error> { + // If nothing was ever stored state-wise, we have nothing + // to clear, it means the storage account was created and + // destructed within the same transaction. + if host.store_has(&self.path)?.is_some() { + self.set_balance(host, U256::ZERO)?; + self.set_nonce(host, 0)?; + self.delete_code(host, code_hash)?; + } + Ok(()) + } + pub fn storage_path(&self, index: &U256) -> Result { let storage_path = concat(&self.path, &STORAGE_ROOT_PATH)?; let index_path = path_from_u256(index)?; @@ -240,6 +271,14 @@ impl StorageAccount { Ok(host.store_write_all(&path, &value_bytes)?) } + pub fn clear_storage(&mut self, host: &mut impl Runtime) -> Result<(), Error> { + let path = concat(&self.path, &STORAGE_ROOT_PATH)?; + if host.store_has(&path)?.is_some() { + host.store_delete(&path)? + } + Ok(()) + } + fn read_ticket_balance( &self, host: &impl Runtime, diff --git a/etherlink/tezt/tests/evm_rollup.ml b/etherlink/tezt/tests/evm_rollup.ml index ea4861d11099ca086ef5cdf15b6c64eaf25a0f75..955dc466a203c7e5c3d17115104226e19ac65c42 100644 --- a/etherlink/tezt/tests/evm_rollup.ml +++ b/etherlink/tezt/tests/evm_rollup.ml @@ -4,7 +4,7 @@ (* Copyright (c) 2023 Nomadic Labs *) (* Copyright (c) 2023-2024 TriliTech *) (* Copyright (c) 2023 Marigold *) -(* Copyright (c) 2023-2024 Functori *) +(* Copyright (c) 2023-2025 Functori *) (* *) (*****************************************************************************) @@ -603,8 +603,8 @@ let register_proxy ~title ~tags ?kernels ?additional_uses ?additional_config ?admin ?commitment_period ?challenge_window ?eth_bootstrap_accounts ?da_fee_per_byte ?minimum_base_fee_per_gas ?whitelist ?rollup_operator_key ?maximum_allowed_ticks ?maximum_gas_per_transaction ?restricted_rpcs - ?websockets ?enable_fast_withdrawal ?evm_version ?register_revm f protocols - = + ?websockets ?enable_fast_withdrawal ?evm_version ?(enable_revm = false) f + protocols = let register ~enable_dal ~enable_multichain ~enable_revm : unit = register_test ~title @@ -633,8 +633,8 @@ let register_proxy ~title ~tags ?kernels ?additional_uses ?additional_config ~enable_revm ~setup_mode:Setup_proxy in - if register_revm = Some true then - register ~enable_dal:false ~enable_multichain:false ~enable_revm:true ; + if enable_revm then + register ~enable_dal:false ~enable_multichain:false ~enable_revm ; register ~enable_dal:false ~enable_multichain:false ~enable_revm:false ; register ~enable_dal:true ~enable_multichain:false ~enable_revm:false ; register ~enable_dal:false ~enable_multichain:true ~enable_revm:false ; @@ -646,8 +646,8 @@ let register_sequencer ?(return_sequencer = false) ~title ~tags ?kernels ?minimum_base_fee_per_gas ?time_between_blocks ?whitelist ?rollup_operator_key ?maximum_allowed_ticks ?maximum_gas_per_transaction ?restricted_rpcs ?max_blueprints_ahead ?websockets ?evm_version - ?genesis_timestamp ?enable_tx_queue f protocols = - let register ~enable_dal ~enable_multichain : unit = + ?genesis_timestamp ?enable_tx_queue ?(enable_revm = false) f protocols = + let register ~enable_dal ~enable_multichain ~enable_revm : unit = register_test ~title ~tags @@ -672,6 +672,7 @@ let register_sequencer ?(return_sequencer = false) ~title ~tags ?kernels protocols ~enable_dal ~enable_multichain + ~enable_revm ~setup_mode: (Setup_sequencer { @@ -682,17 +683,19 @@ let register_sequencer ?(return_sequencer = false) ~title ~tags ?kernels genesis_timestamp; }) in - register ~enable_dal:false ~enable_multichain:false ; - register ~enable_dal:true ~enable_multichain:false ; - register ~enable_dal:false ~enable_multichain:true ; - register ~enable_dal:true ~enable_multichain:true + if enable_revm then + register ~enable_dal:false ~enable_multichain:false ~enable_revm ; + register ~enable_dal:false ~enable_multichain:false ~enable_revm:false ; + register ~enable_dal:true ~enable_multichain:false ~enable_revm:false ; + register ~enable_dal:false ~enable_multichain:true ~enable_revm:false ; + register ~enable_dal:true ~enable_multichain:true ~enable_revm:false let register_both ~title ~tags ?kernels ?additional_uses ?additional_config ?admin ?commitment_period ?challenge_window ?eth_bootstrap_accounts ?da_fee_per_byte ?minimum_base_fee_per_gas ?time_between_blocks ?whitelist ?rollup_operator_key ?maximum_allowed_ticks ?maximum_gas_per_transaction - ?restricted_rpcs ?max_blueprints_ahead ?websockets ?evm_version f protocols - : unit = + ?restricted_rpcs ?max_blueprints_ahead ?websockets ?evm_version + ?(enable_revm = false) f protocols : unit = register_proxy ~title ~tags @@ -712,6 +715,7 @@ let register_both ~title ~tags ?kernels ?additional_uses ?additional_config ?restricted_rpcs ?websockets ?evm_version + ~enable_revm f protocols ; register_sequencer @@ -735,6 +739,7 @@ let register_both ~title ~tags ?kernels ?additional_uses ?additional_config ?max_blueprints_ahead ?websockets ?evm_version + ~enable_revm f protocols @@ -992,6 +997,7 @@ let test_rpc_getBlockReceipts = ~tags:["evm"; "rpc"; "get_block_receipts"] ~title:"RPC method eth_getBlockReceipts" ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> test_rpc_getBlockReceipts_aux evm_setup let test_rpc_getBlockBy_return_base_fee_per_gas_and_mix_hash = @@ -1002,6 +1008,7 @@ let test_rpc_getBlockBy_return_base_fee_per_gas_and_mix_hash = ~tags:["evm"; "rpc"; "get_block_by_hash"] ~title:"getBlockBy returns base fee per gas and previous random number" ~minimum_base_fee_per_gas:(Wei.to_wei_z @@ Z.of_int 100) + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let evm_node_endpoint = Evm_node.endpoint evm_setup.evm_node in @@ -1222,6 +1229,7 @@ let test_l2_deploy_simple_storage = register_proxy ~tags:["evm"; "l2_deploy"; "simple_storage"] ~title:"Check L2 contract deployment" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let* simple_storage_resolved = simple_storage evm_setup.evm_version in deploy_with_base_checks @@ -1279,6 +1287,7 @@ let test_l2_call_simple_storage = register_proxy ~tags:["evm"; "l2_deploy"; "l2_call"; "simple_storage"] ~title:"Check L2 contract call" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {evm_node; sc_rollup_node; _} = evm_setup in let endpoint = Evm_node.endpoint evm_node in @@ -1348,6 +1357,7 @@ let test_l2_deploy_erc20 = register_proxy ~tags:["evm"; "l2_deploy"; "erc20"; "l2_call"] ~title:"Check L2 erc20 contract deployment" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> (* setup *) let {evm_node; sc_rollup_node; evm_version; _} = evm_setup in @@ -1473,6 +1483,7 @@ let test_deploy_contract_with_push0 = ~tags:["evm"; "deploy"; "push0"] ~title: "Check that a contract containing PUSH0 can successfully be deployed." + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let* shanghai_storage_resolved = shanghai_storage evm_setup.evm_version in deploy_with_base_checks @@ -1508,6 +1519,7 @@ let test_log_index = register_both ~tags:["evm"; "log_index"; "events"] ~title:"Check that log index is correctly computed" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> (* setup *) let {evm_node; _} = evm_setup in @@ -1849,6 +1861,7 @@ let test_rpc_txpool_content = ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx ~time_between_blocks:Nothing ~enable_tx_queue:(Enable false) + ~enable_revm:true (*This test does not work for the tx_queue yet. It needs to be adapted *) @@ fun ~protocol:_ ~evm_setup:{evm_node; produce_block; _} -> @@ -2078,6 +2091,7 @@ let test_simulate = register_proxy ~tags:["evm"; "simulate"] ~title:"A block can be simulated in the rollup node" + ~enable_revm:true (fun ~protocol:_ ~evm_setup:{evm_node; sc_rollup_node; _} -> let*@ block_number = Rpc.block_number evm_node in let* simulation_result = @@ -2109,6 +2123,7 @@ let test_full_blocks = "Check `eth_getBlockByNumber` with full blocks returns the correct \ informations" ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; produce_block; _} -> let txs = read_tx_from_file () @@ -2179,6 +2194,7 @@ let test_eth_call_nullable_recipient = register_both ~tags:["evm"; "eth_call"; "null"] ~title:"Check `eth_call.to` input can be null" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; _} -> let* call_result = Evm_node.( @@ -2199,6 +2215,7 @@ let test_eth_call_contract_create = ~tags:["evm"; "eth_call"; "contract_create"] ~title:"Check eth_call with contract creation" ~kernels:[Latest] + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; _} -> let* call_result = Evm_node.( @@ -2235,6 +2252,7 @@ let test_inject_100_transactions = ~title:"Check blocks can contain more than 64 transactions" ~eth_bootstrap_accounts:Eth_account.lots_of_address ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; produce_block; _} -> (* Retrieves all the messages and prepare them for the current rollup. *) let txs = read_tx_from_file () |> List.map (fun (tx, _hash) -> tx) in @@ -2328,7 +2346,7 @@ let test_eth_call_input = in let title = "eth_call with input instead of data" in let tags = ["evm"; "eth_call"; "simulate"; "input"] in - register_both ~title ~tags test_f + register_both ~title ~tags ~enable_revm:true test_f let test_estimate_gas = let test_f ~protocol:_ ~evm_setup = @@ -2443,7 +2461,7 @@ let test_eth_call_storage_contract = in let title = "Call a view" in let tags = ["evm"; "eth_call"; "simulate"; "simple_storage"] in - register_both ~title ~tags test_f + register_both ~title ~tags ~enable_revm:true test_f let test_eth_call_storage_contract_eth_cli = let test_f ~protocol:_ @@ -2497,7 +2515,7 @@ let test_eth_call_storage_contract_eth_cli = let title = "Call a view through an ethereum client" in let tags = ["evm"; "eth_call"; "simulate"; "simple_storage"] in - register_both ~title ~tags test_f + register_both ~title ~tags ~enable_revm:true test_f let test_preinitialized_evm_kernel = let admin = Constant.bootstrap1 in @@ -2608,7 +2626,7 @@ let test_deposit_and_withdraw = ~admin ~commitment_period ~challenge_window - ~register_revm:true + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup: { @@ -2692,7 +2710,7 @@ let test_withdraw_amount = ~tags:["evm"; "withdraw"; "wei"; "mutez"] ~title:"Minimum amount to withdraw" ~admin - ~register_revm:true + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{endpoint; produce_block; _} -> let sender = Eth_account.bootstrap_accounts.(0) in (* Minimal amount of Wei fails with revert. *) @@ -2747,7 +2765,7 @@ let test_withdraw_via_calls = ~tags:["evm"; "withdraw"; "call"; "staticcall"; "delegatecall"; "callcode"] ~title:"Withdrawal via different kind of calls" ~admin - ~register_revm:true + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:({endpoint; produce_block; evm_version; _} as evm_setup) -> @@ -3121,6 +3139,7 @@ let test_rpc_sendRawTransaction = ~title: "Ensure EVM node returns appropriate hash for any given transactions." ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; _} -> let* tx1 = Cast.craft_tx @@ -3219,6 +3238,7 @@ let test_rpc_getCode = register_both ~tags:["evm"; "rpc"; "get_code"; "simple_storage"] ~title:"RPC method eth_getCode" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let sender = Eth_account.bootstrap_accounts.(0) in let* simple_storage_resolved = simple_storage evm_setup.evm_version in @@ -3236,6 +3256,7 @@ let test_rpc_getTransactionByHash = ~tags:["evm"; "rpc"; "get_transaction_by"; "transaction_by_hash"] ~title:"RPC method eth_getTransactionByHash" ~da_fee_per_byte:(Wei.of_eth_string "0.000004") + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {evm_node; produce_block; _} = evm_setup in let sender = Eth_account.bootstrap_accounts.(0) in @@ -3285,6 +3306,7 @@ let test_rpc_getTransactionByBlockHashAndIndex = ~title:"RPC method eth_getTransactionByBlockHashAndIndex" ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx ~eth_bootstrap_accounts:Eth_account.lots_of_address + ~enable_revm:true @@ fun ~protocol:_ -> test_rpc_getTransactionByBlockArgAndIndex ~by:`Hash let test_rpc_getTransactionByBlockNumberAndIndex = @@ -3293,6 +3315,7 @@ let test_rpc_getTransactionByBlockNumberAndIndex = ~title:"RPC method eth_getTransactionByBlockNumberAndIndex" ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx ~eth_bootstrap_accounts:Eth_account.lots_of_address + ~enable_revm:true @@ fun ~protocol:_ -> test_rpc_getTransactionByBlockArgAndIndex ~by:`Number type storage_migration_results = { @@ -3548,6 +3571,7 @@ let test_cannot_prepayed_leads_to_no_inclusion = "Not being able to prepay a transaction leads to it not being included." ~eth_bootstrap_accounts:[] ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true (* No bootstrap accounts, so no one has funds. *) @@ fun ~protocol:_ ~evm_setup:{evm_node; _} -> (* This is a transfer from Eth_account.bootstrap_accounts.(0) to @@ -3579,6 +3603,7 @@ let test_cannot_prepayed_with_delay_leads_to_no_injection = "Not being able to prepay a transaction that was included leads to it \ not being injected." ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; endpoint; produce_block; _} -> let sender, to_public_key = ( Eth_account.bootstrap_accounts.(0), @@ -3943,6 +3968,7 @@ let test_rpc_getBlockTransactionCountBy = eth_getBlockTransactionCountByNumber" ~eth_bootstrap_accounts:Eth_account.lots_of_address ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {produce_block; evm_node; _} = evm_setup in let txs = read_tx_from_file () |> List.filteri (fun i _ -> i < 5) in @@ -4057,6 +4083,7 @@ let test_simulation_eip2200 = register_both ~tags:["evm"; "loop"; "simulation"; "eip2200"] ~title:"Simulation is EIP2200 resilient" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {produce_block; endpoint; evm_version; _} = evm_setup in let sender = Eth_account.bootstrap_accounts.(0) in @@ -4081,6 +4108,7 @@ let test_rpc_sendRawTransaction_with_consecutive_nonce = ~tags:["evm"; "rpc"; "tx_nonce"] ~title:"Can submit many transactions." ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; produce_block; _} -> (* Nonce: 0*) let* tx_1 = @@ -4126,6 +4154,7 @@ let test_rpc_sendRawTransaction_not_included = ~title: "Tx with nonce too high are not included without previous transactions." ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; endpoint; produce_block; _} -> (* Nonce: 1 *) let* tx = @@ -4155,6 +4184,7 @@ let test_rpc_gasPrice = register_both ~tags:["evm"; "rpc"; "gas_price"] ~title:"RPC methods eth_gasPrice" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:{evm_node; _} -> let expected_gas_price = Wei.of_gwei_string "1" in let* gas_price = @@ -4185,6 +4215,7 @@ let test_rpc_getStorageAt = register_both ~tags:["evm"; "rpc"; "get_storage_at"; "mapping_storage"] ~title:"RPC methods eth_getStorageAt" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {endpoint; evm_node; _} = evm_setup in let sender = Eth_account.bootstrap_accounts.(0) in @@ -4332,6 +4363,7 @@ let test_rpc_getLogs = register_both ~tags:["evm"; "rpc"; "get_logs"; "erc20"] ~title:"Check getLogs RPC" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {evm_node; produce_block; evm_version; _} = evm_setup in let endpoint = Evm_node.endpoint evm_node in @@ -4483,6 +4515,7 @@ let test_l2_nested_create = register_both ~tags:["evm"; "l2_deploy"; "l2_create"; "inter_contract"] ~title:"Check L2 nested create" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {evm_node; produce_block; _} = evm_setup in let endpoint = Evm_node.endpoint evm_node in @@ -4568,6 +4601,7 @@ let test_l2_revert_returns_unused_gas = ~tags:["evm"; "revert"] ~title:"Check L2 revert returns unused gas" ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {evm_node; produce_block; _} = evm_setup in let endpoint = Evm_node.endpoint evm_node in @@ -4611,6 +4645,7 @@ let test_l2_create_collision = register_both ~tags:["evm"; "l2_create"; "collision"] ~title:"Check L2 create collision" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {evm_node; produce_block; evm_version; _} = evm_setup in let endpoint = Evm_node.endpoint evm_node in @@ -4651,6 +4686,7 @@ let test_l2_intermediate_OOG_call = ~title: "Check that an L2 call to a smart contract with an intermediate call \ that runs out of gas still succeeds." + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {evm_node; produce_block; evm_version; _} = evm_setup in let* oog_call_resolved = oog_call evm_version in @@ -4682,6 +4718,7 @@ let test_l2_ether_wallet = register_both ~tags:["evm"; "l2_call"; "wallet"] ~title:"Check ether wallet functions correctly" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let {evm_node; produce_block; evm_version; _} = evm_setup in let endpoint = Evm_node.endpoint evm_node in @@ -4768,6 +4805,7 @@ let test_reboot_gas_limit = for a single run" ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx ~maximum_gas_per_transaction:250_000L + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup: ({evm_node; produce_block; sc_rollup_node; node; evm_version; _} @@ -4921,6 +4959,7 @@ let test_l2_timestamp_opcode = ~tags:["evm"; "timestamp"; "opcode"] ~title:"Check L2 opcode timestamp" ~kernels:[Kernel.Latest] + ~enable_revm:true test let test_migrate_proxy_to_sequencer_future = @@ -5276,6 +5315,7 @@ let test_estimate_gas_out_of_gas = ~kernels:[Kernel.Mainnet] ~tags:["evm"; "estimate_gas"; "simulate"; "loop"] ~title:"estimateGas fails with out of gas for overly costly transaction" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:({evm_node; evm_version; _} as evm_setup) -> let sender = Eth_account.bootstrap_accounts.(0) in let* loop_resolved = loop evm_version in @@ -5327,6 +5367,7 @@ let test_l2_call_selfdetruct_contract_in_same_transaction_and_separate_transacti register_both ~tags:["evm"; "l2_call"; "selfdestruct"; "cancun"] ~title:"Check SELFDESTRUCT's behavior as stated by Cancun's EIP-6780" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:({endpoint; produce_block; evm_version; _} as evm_setup) -> @@ -5399,6 +5440,7 @@ let test_mcopy_opcode = register_both ~tags:["evm"; "mcopy"; "cancun"] ~title:"Check MCOPY's behavior as stated by Cancun's EIP-5656" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:({endpoint; produce_block; evm_version; _} as evm_setup) -> @@ -5458,6 +5500,7 @@ let test_transient_storage = register_both ~tags:["evm"; "transient_storage"; "cancun"] ~title:"Check TSTORE/TLOAD behavior as stated by Cancun's EIP-1153" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:({endpoint; produce_block; evm_version; _} as evm_setup) -> @@ -5593,6 +5636,7 @@ let test_check_estimateGas_enforces_limits = ~kernels:[Latest] ~tags:["evm"; "estimate_gas"; "gas_limit"] ~title:"Check that the eth_estimateGas enforces the kernel gas limit." + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:({evm_node; evm_version; _} as evm_setup) -> let sender = Eth_account.bootstrap_accounts.(0) in let* gas_left_contract = Solidity_contracts.gas_left evm_version in @@ -5739,6 +5783,7 @@ let test_blockhash_opcode = ~max_blueprints_ahead:300 ~tags:["evm"; "blockhash"; "opcode"] ~title:"Check if blockhash opcode returns the actual hash of the block" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup: ({produce_block; endpoint; evm_node; evm_version; _} as evm_setup) @@ -5795,6 +5840,7 @@ let test_block_constants_opcode = ~kernels:[Kernel.Latest] ~tags:["evm"; "block"; "opcode"; "constants"] ~title:"Check block constants in opcode" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup: ({evm_node; produce_block; endpoint; evm_version; _} as evm_setup) @@ -5882,6 +5928,7 @@ let test_revert_is_correctly_propagated = register_both ~tags:["evm"; "revert"] ~title:"Check that the node propagates reverts reason correctly." + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup:({evm_node; evm_version; _} as evm_setup) -> let sender = Eth_account.bootstrap_accounts.(0) in let* error_resolved = error evm_version in @@ -6295,6 +6342,7 @@ let test_rpc_feeHistory = ~kernels:[Latest] ~tags:["evm"; "rpc"; "fee_history"] ~title:"RPC methods eth_feeHistory" + ~enable_revm:true @@ fun ~protocol:_ ~evm_setup -> let* _ = repeat 2 (fun _ -> diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 5ce0d0bf3d99d073ce29943740c85d201a905a44..89833e2eade451ffcd1f7540931d5bfc52088f4b 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -11533,6 +11533,7 @@ let test_estimate_gas_with_block_param = ~tags:["evm"; "eth_estimategas"; "simulate"; "estimate_gas"; "earliest"] ~title:"eth_estimateGas with block parameter" ~time_between_blocks:Nothing + ~use_revm:activate_revm_registration @@ fun {sequencer; evm_version; _} _protocol -> let sender = Eth_account.bootstrap_accounts.(0) in let* gas_consumer = Solidity_contracts.even_block_gas_consumer evm_version in @@ -11592,6 +11593,7 @@ let test_transaction_object expected_type_ name make_transaction = ~time_between_blocks:Nothing ~kernels:[Latest] ~use_dal:Register_without_feature + ~use_revm:activate_revm_registration ~title: (sf "RPC returns the correct transaction object for %s transactions" name) @@ fun {sequencer; _} _protocol -> @@ -11632,7 +11634,9 @@ let test_eip2930_transaction_object = ~chain_id:1337 ~nonce:0 ~gas_price:1_000_000_000 - ~gas:23_300 + (* BASE_CALL_GAS_COST + 1xACCESS_LIST_ADDRESS_COST + 1xACCESS_LIST_STORAGE_KEY_COST + = 21_000 + 2400 + 1900 = 25_300 *) + ~gas:25_300 ~value:Wei.zero ~address:Eth_account.bootstrap_accounts.(1).address) @@ -11696,6 +11700,7 @@ let test_tx_queue = ~kernels:[Latest] (* node only test *) ~use_dal:Register_without_feature ~websockets:false + ~use_revm:activate_revm_registration ~enable_tx_queue: (Config { @@ -11822,6 +11827,7 @@ let test_tx_queue_clear = ~use_dal:Register_without_feature ~websockets:false ~use_multichain:Register_without_feature + ~use_revm:activate_revm_registration (* TODO #7843: Adapt this test to multichain context *) @@ fun { client; @@ -11925,6 +11931,7 @@ let test_tx_queue_nonce = "Submits transactions to an observer with a tx queue and make sure it \ can respond to getTransactionCount." ~use_multichain:Register_without_feature + ~use_revm:activate_revm_registration (* TODO #7843: Adapt this test to multichain context *) @@ fun {sequencer; observer; _} _protocol -> let* () = @@ -12224,6 +12231,7 @@ let test_tx_queue_limit = "Submits transactions to an observer with a tx queue and make sure its \ limit are respected." ~use_multichain:Register_without_feature + ~use_revm:activate_revm_registration (* TODO #7843: Adapt this test to multichain context *) @@ fun {sequencer; observer; _} _protocol -> let* () = @@ -12702,6 +12710,7 @@ let test_block_producer_validation = }) ~title:"Test part of the validation is done when producing blocks." ~use_multichain:Register_without_feature + ~use_revm:activate_revm_registration (* TODO #7843: Adapt this test to multichain context *) @@ fun {sequencer; observer; _} _protocol -> let* () = @@ -13064,6 +13073,7 @@ let test_eip2930_storage_access = ~title:"Check EIP-2930's semantic correctness" ~da_fee:Wei.zero ~time_between_blocks:Nothing + ~use_revm:activate_revm_registration @@ fun {sequencer; evm_version; _} _protocol -> let whale = Eth_account.bootstrap_accounts.(0) in let* eip2930_storage_access =