From dee77cc0ac2f91e6e786172998b9219903c0e252 Mon Sep 17 00:00:00 2001 From: pikatos Date: Sun, 11 Aug 2024 00:59:31 +0200 Subject: [PATCH 1/2] EVM: refactor ExecutionOutcome.{is_success, reason, result} --- .../kernel_evm/evm_execution/src/handler.rs | 134 ++++++++++-------- etherlink/kernel_evm/evm_execution/src/lib.rs | 24 ++-- etherlink/kernel_evm/kernel/src/apply.rs | 8 +- .../kernel/src/block_in_progress.rs | 3 +- etherlink/kernel_evm/kernel/src/bridge.rs | 16 +-- etherlink/kernel_evm/kernel/src/simulation.rs | 44 +++--- 6 files changed, 126 insertions(+), 103 deletions(-) diff --git a/etherlink/kernel_evm/evm_execution/src/handler.rs b/etherlink/kernel_evm/evm_execution/src/handler.rs index ffdc0c098d60..458c3bfbb662 100644 --- a/etherlink/kernel_evm/evm_execution/src/handler.rs +++ b/etherlink/kernel_evm/evm_execution/src/handler.rs @@ -48,26 +48,48 @@ use tezos_smart_rollup_encoding::michelson::{MichelsonContract, MichelsonPair}; use tezos_smart_rollup_encoding::outbox::OutboxMessage; use tezos_smart_rollup_storage::StorageError; -/// Extends ExitReason with our own errors. It avoids using -/// ExitError::Other() and matching on strings. +/// Withdrawal interface of the ticketer contract +pub type RouterInterface = MichelsonPair; + +/// Outbox message that implements RouterInterface, ready to be encoded and posted +pub type Withdrawal = OutboxMessage; + #[derive(Debug, Eq, PartialEq)] -pub enum ExtendedExitReason { - Exit(ExitReason), +pub enum ExecutionResult { + TransferSucceeded, + ContractDeployed(H160, Vec), + CallSucceeded(ExitSucceed, Vec), + CallReverted(Vec), + Error(ExitError), + FatalError(ExitFatal), OutOfTicks, } -impl From for ExtendedExitReason { - fn from(e: ExitReason) -> Self { - Self::Exit(e) +impl ExecutionResult { + pub const fn is_success(&self) -> bool { + matches!( + self, + ExecutionResult::TransferSucceeded + | ExecutionResult::ContractDeployed(_, _) + | ExecutionResult::CallSucceeded(_, _) + ) + } + pub fn output(&self) -> Option<&[u8]> { + match self { + ExecutionResult::ContractDeployed(_, output) + | ExecutionResult::CallSucceeded(_, output) + | ExecutionResult::CallReverted(output) => Some(output.as_slice()), + _ => None, + } + } + pub const fn new_address(&self) -> Option { + match self { + ExecutionResult::ContractDeployed(new_address, _) => Some(*new_address), + _ => None, + } } } -/// Withdrawal interface of the ticketer contract -pub type RouterInterface = MichelsonPair; - -/// Outbox message that implements RouterInterface, ready to be encoded and posted -pub type Withdrawal = OutboxMessage; - /// Outcome of making the [EvmHandler] run an Ethereum transaction /// /// Be it contract -call, -create or simple transfer, the handler will update the world @@ -77,15 +99,10 @@ pub type Withdrawal = OutboxMessage; pub struct ExecutionOutcome { /// How much gas was used for processing an entire transaction. pub gas_used: u64, - /// The sputnik reason for ending execution. In case of transfers, this is made up - /// (sputnik Doesn't execute those - we do). - pub reason: ExtendedExitReason, - /// In case of create- transactions, this field contains address of the new contract - pub new_address: Option, /// Logs generated by the transaction. pub logs: Vec, /// Result of the execution - pub result: Option>, + pub result: ExecutionResult, /// Withdrawals generated by the transaction. This field will be empty if the /// transaction fails (or if the transaction doesn't produce any withdrawals). pub withdrawals: Vec, @@ -95,10 +112,13 @@ pub struct ExecutionOutcome { impl ExecutionOutcome { pub const fn is_success(&self) -> bool { - matches!( - self.reason, - ExtendedExitReason::Exit(ExitReason::Succeed(_)) - ) + self.result.is_success() + } + pub fn output(&self) -> Option<&[u8]> { + self.result.output() + } + pub const fn new_address(&self) -> Option { + self.result.new_address() } } @@ -141,6 +161,18 @@ fn ethereum_error_to_exit_reason(exit_reason: &EthereumError) -> ExitReason { } } +fn ethereum_error_to_execution_result(error: &EthereumError) -> ExecutionResult { + match error { + EthereumError::EthereumAccountError(AccountStorageError::NonceOverflow) => { + ExecutionResult::Error(ExitError::MaxNonce) + } + _ => ExecutionResult::FatalError(ExitFatal::Other(Cow::from(format!( + "{:?}", + error + )))), + } +} + pub enum TransferExitReason { Returned, OutOfFund, @@ -1455,9 +1487,7 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { /// executing, such state is the sort of thing that may cause panic. fn commit_initial_transaction( &mut self, - new_address: Option, - result: Vec, - reason: ExitReason, + result: ExecutionResult, ) -> Result { let number_of_tx_layer = self.evm_account_storage.stack_depth(); log!(self.host, Debug, "Committing initial transaction"); @@ -1504,10 +1534,8 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { Ok(ExecutionOutcome { gas_used, - reason: reason.into(), - new_address, logs: last_layer.logs, - result: Some(result), + result, withdrawals: last_layer.withdrawals, estimated_ticks_used: self.estimated_ticks_used, }) @@ -1525,8 +1553,7 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { /// executing, such state is the sort of thing that may cause panic. fn rollback_initial_transaction( &mut self, - result: Option>, - reason: ExtendedExitReason, + result: ExecutionResult, ) -> Result { let number_of_tx_layer = self.evm_account_storage.stack_depth(); log!(self.host, Debug, "Rolling back the initial transaction"); @@ -1563,8 +1590,6 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { Ok(ExecutionOutcome { gas_used, - reason, - new_address: None, logs: vec![], result, withdrawals: vec![], @@ -1587,17 +1612,15 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { r ); - self.commit_initial_transaction( - new_address, - result, - ExitReason::Succeed(r), - ) + self.commit_initial_transaction(if let Some(new_address) = new_address { + ExecutionResult::ContractDeployed(new_address, result) + } else { + ExecutionResult::CallSucceeded(r, result) + }) + } + Ok((ExitReason::Revert(ExitRevert::Reverted), _, result)) => { + self.rollback_initial_transaction(ExecutionResult::CallReverted(result)) } - Ok((ExitReason::Revert(ExitRevert::Reverted), _, result)) => self - .rollback_initial_transaction( - Some(result), - ExitReason::Revert(ExitRevert::Reverted).into(), - ), Ok((ExitReason::Error(error), _, _)) => { log!( self.host, @@ -1606,13 +1629,12 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { error ); - self.rollback_initial_transaction(None, ExitReason::Error(error).into()) + self.rollback_initial_transaction(ExecutionResult::Error(error)) } Ok((ExitReason::Fatal(ExitFatal::Other(cow_str)), _, _)) => { - self.rollback_initial_transaction( - None, - ExitReason::Fatal(ExitFatal::Other(cow_str.clone())).into(), - )?; + self.rollback_initial_transaction(ExecutionResult::FatalError( + ExitFatal::Other(cow_str.clone()), + ))?; Err(EthereumError::WrappedError(cow_str)) } Ok((ExitReason::Fatal(fatal_error), _, _)) => { @@ -1623,10 +1645,9 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { fatal_error ); - self.rollback_initial_transaction( - None, - ExitReason::Fatal(fatal_error).into(), - ) + self.rollback_initial_transaction(ExecutionResult::FatalError( + fatal_error, + )) } Err(EthereumError::OutOfTicks) => { log!( @@ -1635,7 +1656,7 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { "The initial transaction exhausted the allocated ticks." ); - self.rollback_initial_transaction(None, ExtendedExitReason::OutOfTicks) + self.rollback_initial_transaction(ExecutionResult::OutOfTicks) } Err(err) => { log!( @@ -1645,10 +1666,9 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { err ); - self.rollback_initial_transaction( - None, - ethereum_error_to_exit_reason(&err).into(), - )?; + self.rollback_initial_transaction(ethereum_error_to_execution_result( + &err, + ))?; Err(err) } } diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index e8f031979f72..3dba4c0d16bb 100644 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -13,8 +13,7 @@ use alloc::borrow::Cow; use alloc::collections::TryReserveError; use crypto::hash::{ContractKt1Hash, HashTrait}; use evm::executor::stack::PrecompileFailure; -use evm::ExitReason; -use handler::EvmHandler; +use handler::{EvmHandler, ExecutionResult}; use host::{path::RefPath, runtime::Runtime}; use primitive_types::{H160, H256, U256}; use tezos_ethereum::block::BlockConstants; @@ -49,7 +48,7 @@ use trace::{ CallTrace, CallTracerConfig, CallTracerInput, StructLoggerInput, TracerInput, }; -use crate::{handler::ExtendedExitReason, storage::tracer}; +use crate::storage::tracer; #[derive(Error, Clone, Copy, Debug, Eq, PartialEq)] pub enum DurableStorageError { @@ -136,7 +135,7 @@ pub enum EthereumError { fn trace_outcome( handler: EvmHandler, is_success: bool, - output: &Option>, + output: Option<&[u8]>, gas_used: u64, transaction_hash: Option, ) -> Result<(), EthereumError> { @@ -185,9 +184,8 @@ where Host: Runtime, { fn do_refund(outcome: &handler::ExecutionOutcome, pay_for_gas: bool) -> bool { - match outcome.reason { - ExtendedExitReason::Exit(ExitReason::Revert(_)) - | ExtendedExitReason::OutOfTicks => pay_for_gas, + match outcome.result { + ExecutionResult::CallReverted(_) | ExecutionResult::OutOfTicks => pay_for_gas, _ => pay_for_gas && outcome.is_success(), } } @@ -232,7 +230,7 @@ where match result { Ok(result) => { - if result.reason == ExtendedExitReason::OutOfTicks && retriable { + if result.result == ExecutionResult::OutOfTicks && retriable { // The nonce must be incremented before the execution. Details here: https://gitlab.com/tezos/tezos/-/merge_requests/11998. // In the EVM logic, the nonce is never decremented // But with the ticks model, if the execution raises an 'out of ticks' error and if the transaction is 'retriable', the nonce must not be incremented @@ -244,7 +242,7 @@ where // In case of `OutOfTicks` and the transaction can be // retried, the gas is entirely refunded as it will be // repaid in the next attempt - if result.reason == ExtendedExitReason::OutOfTicks && retriable { + if result.result == ExecutionResult::OutOfTicks && retriable { log!( handler.borrow_host(), Debug, @@ -267,7 +265,7 @@ where trace_outcome( handler, result.is_success(), - &result.result, + result.output(), result.gas_used, transaction_hash, )? @@ -288,12 +286,12 @@ where if base_call_type != "CREATE" { call_trace.add_to(address); } else { - call_trace.add_to(result.new_address); + call_trace.add_to(result.new_address()); } call_trace.add_gas(gas_limit); call_trace - .add_output(result.result.as_ref().map(|res| res.to_vec())); + .add_output(result.output().as_ref().map(|res| res.to_vec())); if with_logs { call_trace.add_logs(Some(result.logs.clone())) @@ -316,7 +314,7 @@ where .. })) = tracer { - trace_outcome(handler, false, &None, 0, transaction_hash)? + trace_outcome(handler, false, None, 0, transaction_hash)? } else if let Some(CallTracer(CallTracerInput { transaction_hash, .. diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index abfa49f0a731..1339173162b2 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -10,7 +10,9 @@ use ethereum::Log; use evm_execution::account_storage::{EthereumAccount, EthereumAccountStorage}; use evm_execution::fa_bridge::deposit::FaDeposit; use evm_execution::fa_bridge::execute_fa_deposit; -use evm_execution::handler::{ExecutionOutcome, ExtendedExitReason, RouterInterface}; +use evm_execution::handler::{ + ExecutionOutcome, ExecutionResult as ExecutionOutcomeResult, RouterInterface, +}; use evm_execution::precompiles::PrecompileBTreeMap; use evm_execution::run_transaction; use evm_execution::storage::tracer; @@ -373,7 +375,7 @@ fn apply_ethereum_transaction_common( ( execution_outcome.gas_used.into(), execution_outcome.estimated_ticks_used, - execution_outcome.reason == ExtendedExitReason::OutOfTicks, + execution_outcome.result == ExecutionOutcomeResult::OutOfTicks, ) } None => { @@ -556,7 +558,7 @@ pub fn handle_transaction_result( if let Some(outcome) = &mut execution_outcome { log!(host, Debug, "Transaction executed, outcome: {:?}", outcome); log!(host, Benchmarking, "gas_used: {:?}", outcome.gas_used); - log!(host, Benchmarking, "reason: {:?}", outcome.reason); + log!(host, Benchmarking, "reason: {:?}", outcome.result); fee_updates.modify_outcome(outcome); for message in outcome.withdrawals.drain(..) { let outbox_message: OutboxMessage = message; diff --git a/etherlink/kernel_evm/kernel/src/block_in_progress.rs b/etherlink/kernel_evm/kernel/src/block_in_progress.rs index a7834bb5489a..815fd4ebdb66 100644 --- a/etherlink/kernel_evm/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_evm/kernel/src/block_in_progress.rs @@ -439,6 +439,7 @@ impl BlockInProgress { match execution_outcome { Some(outcome) => { let is_success = outcome.is_success(); + let contract_address = outcome.new_address(); let log_iter = outcome.logs.into_iter(); let logs: Vec = log_iter .enumerate() @@ -457,7 +458,7 @@ impl BlockInProgress { cumulative_gas_used: cumulative_gas, effective_gas_price, gas_used: U256::from(outcome.gas_used), - contract_address: outcome.new_address, + contract_address, logs_bloom: TransactionReceipt::logs_to_bloom(&logs), logs, type_, diff --git a/etherlink/kernel_evm/kernel/src/bridge.rs b/etherlink/kernel_evm/kernel/src/bridge.rs index 4ccc682917a6..5f1bf96da0f3 100644 --- a/etherlink/kernel_evm/kernel/src/bridge.rs +++ b/etherlink/kernel_evm/kernel/src/bridge.rs @@ -7,11 +7,11 @@ use std::borrow::Cow; use ethereum::Log; -use evm::{Config, ExitError, ExitReason, ExitSucceed}; +use evm::{Config, ExitError}; use evm_execution::{ abi::{ABI_H160_LEFT_PADDING, ABI_U32_LEFT_PADDING}, account_storage::{account_path, AccountStorageError, EthereumAccountStorage}, - handler::ExecutionOutcome, + handler::{ExecutionOutcome, ExecutionResult}, EthereumError, }; use primitive_types::{H160, H256, U256}; @@ -190,15 +190,15 @@ pub fn execute_deposit( account_path(&deposit.receiver).map_err(AccountStorageError::from)?; let mut to_account = evm_account_storage.get_or_create(host, &to_account_path)?; - let exit_reason = match to_account.balance_add(host, deposit.amount) { - Ok(()) => ExitReason::Succeed(ExitSucceed::Returned), + let result = match to_account.balance_add(host, deposit.amount) { + Ok(()) => ExecutionResult::TransferSucceeded, Err(err) => { log!(host, Info, "Deposit failed with {:?}", err); - ExitReason::Error(ExitError::Other(Cow::from("Deposit failed"))) + ExecutionResult::Error(ExitError::Other(Cow::from("Deposit failed"))) } }; - let logs = if exit_reason.is_succeed() { + let logs = if result.is_success() { vec![deposit.event_log()] } else { vec![] @@ -210,10 +210,8 @@ pub fn execute_deposit( let execution_outcome = ExecutionOutcome { gas_used, - reason: exit_reason.into(), - new_address: None, logs, - result: None, + result, withdrawals: vec![], estimated_ticks_used, }; diff --git a/etherlink/kernel_evm/kernel/src/simulation.rs b/etherlink/kernel_evm/kernel/src/simulation.rs index caf60a9a407d..865e15585e41 100644 --- a/etherlink/kernel_evm/kernel/src/simulation.rs +++ b/etherlink/kernel_evm/kernel/src/simulation.rs @@ -20,11 +20,13 @@ use crate::{ tick_model, CONFIG, }; -use evm::ExitReason; use evm_execution::account_storage::account_path; -use evm_execution::handler::ExtendedExitReason; use evm_execution::trace::TracerInput; -use evm_execution::{account_storage, handler::ExecutionOutcome, precompiles}; +use evm_execution::{ + account_storage, + handler::{ExecutionOutcome, ExecutionResult as ExecutionOutcomeResult}, + precompiles, +}; use evm_execution::{run_transaction, EthereumError}; use primitive_types::{H160, U256}; use rlp::{Decodable, DecoderError, Encodable, Rlp}; @@ -214,25 +216,27 @@ impl From, EthereumError>> fn from(result: Result, EthereumError>) -> Self { match result { Ok(Some(ExecutionOutcome { - gas_used, - reason: ExtendedExitReason::Exit(ExitReason::Succeed(_)), - result, - .. - })) => Self::Ok(SimulationResult::Ok(ExecutionResult { - value: result, - gas_used: Some(gas_used), - })), - Ok(Some(ExecutionOutcome { - reason: ExtendedExitReason::Exit(ExitReason::Revert(_)), - result, - .. - })) => Self::Ok(SimulationResult::Err(result.unwrap_or_default())), + gas_used, result, .. + })) if result.is_success() => { + Self::Ok(SimulationResult::Ok(ExecutionResult { + value: result.output().map(|x| x.to_vec()), + gas_used: Some(gas_used), + })) + } + Ok(Some( + outcome @ ExecutionOutcome { + result: ExecutionOutcomeResult::CallReverted(_), + .. + }, + )) => Self::Ok(SimulationResult::Err( + outcome.output().unwrap_or_default().to_vec(), + )), Ok(Some(ExecutionOutcome { - reason: ExtendedExitReason::OutOfTicks, + result: ExecutionOutcomeResult::OutOfTicks, .. })) => Self::Err(String::from(OUT_OF_TICKS_MSG)), - Ok(Some(ExecutionOutcome { reason, .. })) => { - let msg = format!("The transaction failed: {:?}.", reason); + Ok(Some(ExecutionOutcome { result, .. })) => { + let msg = format!("The transaction failed: {:?}.", result); Self::Err(msg) } Ok(None) => Self::Err(String::from( @@ -578,7 +582,7 @@ impl TxValidation { None, ) { Ok(Some(ExecutionOutcome { - reason: ExtendedExitReason::OutOfTicks, + result: ExecutionOutcomeResult::OutOfTicks, .. })) => Self::to_error(OUT_OF_TICKS_MSG), Ok(None) => Self::to_error(CANNOT_PREPAY), -- GitLab From a494bb2a7ff9563f91eeedf49ef6c69700131e8b Mon Sep 17 00:00:00 2001 From: pikatos Date: Mon, 12 Aug 2024 12:39:11 +0200 Subject: [PATCH 2/2] EVM: update tests --- .../evm_execution/src/fa_bridge/tests.rs | 14 +- .../kernel_evm/evm_execution/src/handler.rs | 28 +-- etherlink/kernel_evm/evm_execution/src/lib.rs | 215 ++++++++---------- .../evm_execution/src/precompiles/blake2.rs | 2 +- .../evm_execution/src/precompiles/ecdsa.rs | 12 +- .../src/precompiles/fa_bridge.rs | 16 +- .../evm_execution/src/precompiles/hash.rs | 13 +- .../evm_execution/src/precompiles/modexp.rs | 13 +- .../src/precompiles/withdrawal.rs | 30 ++- .../src/precompiles/zero_knowledge.rs | 16 +- etherlink/kernel_evm/kernel/src/fees.rs | 14 +- etherlink/kernel_evm/kernel/src/simulation.rs | 2 +- 12 files changed, 171 insertions(+), 204 deletions(-) diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs index 4e0091ea8beb..fd142bbac57c 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs @@ -4,7 +4,7 @@ use alloy_primitives::FixedBytes; use alloy_sol_types::SolEvent; -use evm::{ExitError, ExitReason}; +use evm::ExitError; use primitive_types::{H160, U256}; use tezos_smart_rollup_mock::MockHost; @@ -16,7 +16,7 @@ use crate::{ get_storage_flag, kernel_wrapper, run_fa_deposit, ticket_balance_add, ticket_balance_get, token_wrapper, withdrawal_counter_next, }, - handler::ExtendedExitReason, + handler::ExecutionResult, }; #[test] @@ -34,7 +34,7 @@ fn fa_deposit_reached_wrapper_contract() { &caller, 0, ) - .new_address + .new_address() .unwrap(); let deposit = dummy_fa_deposit(ticket, Some(proxy)); @@ -235,7 +235,7 @@ fn fa_deposit_proxy_state_reverted_if_ticket_balance_overflows() { &caller, 100500, ) - .new_address + .new_address() .unwrap(); let deposit = dummy_fa_deposit(ticket, Some(proxy)); @@ -297,7 +297,7 @@ fn fa_withdrawal_executed_via_l2_proxy_contract() { &caller, 0, ) - .new_address + .new_address() .unwrap(); let withdrawal = dummy_fa_withdrawal(ticket, sender, proxy); @@ -418,7 +418,7 @@ fn fa_withdrawal_fails_due_to_faulty_l2_proxy() { withdrawal_counter_next(&mock_runtime, &evm_account_storage) ); assert!( - matches!(res.reason, ExtendedExitReason::Exit(ExitReason::Error(ExitError::Other(err))) if err.contains("Proxy contract does not exist")) + matches!(res.result, ExecutionResult::Error(ExitError::Other(err)) if err.contains("Proxy contract does not exist")) ); } @@ -450,6 +450,6 @@ fn fa_withdrawal_fails_due_to_insufficient_balance() { withdrawal_counter_next(&mock_runtime, &evm_account_storage) ); assert!( - matches!(res.reason, ExtendedExitReason::Exit(ExitReason::Error(ExitError::Other(err))) if err.contains("Insufficient ticket balance")) + matches!(res.result, ExecutionResult::Error(ExitError::Other(err)) if err.contains("Insufficient ticket balance")) ); } diff --git a/etherlink/kernel_evm/evm_execution/src/handler.rs b/etherlink/kernel_evm/evm_execution/src/handler.rs index 458c3bfbb662..5ac5c3b87ecf 100644 --- a/etherlink/kernel_evm/evm_execution/src/handler.rs +++ b/etherlink/kernel_evm/evm_execution/src/handler.rs @@ -4011,12 +4011,12 @@ mod test { .create_contract(caller, Some(U256::one()), code, None) .unwrap(); - let suicided_contract = result.new_address.unwrap(); + let suicided_contract = result.new_address().unwrap(); - assert_eq!( - result.reason, - ExitReason::Succeed(ExitSucceed::Suicided).into() - ); + assert!(matches!( + result.result, + ExecutionResult::ContractDeployed(_, _) + )); assert_eq!(get_balance(&mut handler, &withdrawal_contract), U256::one()); assert_eq!(get_balance(&mut handler, &caller), U256::from(999999999)); assert!(!handler.exists(suicided_contract)); @@ -4478,12 +4478,8 @@ mod test { assert_eq!( Ok(ExecutionOutcome { gas_used: 53839, // costs 53841 on ethereum - reason: ExtendedExitReason::Exit(ExitReason::Succeed( - ExitSucceed::Stopped - )), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), withdrawals: vec![], estimated_ticks_used: 40549308 }), @@ -4645,8 +4641,8 @@ mod test { assert_eq!(result.gas_used, 27836); assert_eq!( - result.reason, - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Returned)) + result.result, + ExecutionResult::CallSucceeded(ExitSucceed::Returned, vec![0]) ); } @@ -4713,8 +4709,8 @@ mod test { assert_eq!(result.gas_used, expected_gas); assert_eq!( - result.reason, - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Suicided)) + result.result, + ExecutionResult::CallSucceeded(ExitSucceed::Suicided, vec![]) ); // At the end of the transaction, any account touched by the execution of that transaction @@ -4802,8 +4798,8 @@ mod test { assert_eq!(result.gas_used, expected_gas); assert_eq!( - result.reason, - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)) + result.result, + ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]) ); } } diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index 3dba4c0d16bb..e42ae10c8d05 100644 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -373,7 +373,7 @@ mod test { EthereumAccountStorage, }; use evm::executor::stack::Log; - use evm::{ExitError, ExitReason, ExitRevert, ExitSucceed, Opcode}; + use evm::{ExitError, ExitSucceed, Opcode}; use handler::ExecutionOutcome; use host::runtime::Runtime; use primitive_types::{H160, H256}; @@ -570,10 +570,8 @@ mod test { let expected_result = Ok(Some(ExecutionOutcome { gas_used: config.gas_transaction_call, - reason: ExitReason::Error(ExitError::OutOfFund).into(), - new_address: None, logs: vec![], - result: None, + result: ExecutionResult::Error(ExitError::OutOfFund), withdrawals: vec![], estimated_ticks_used: 0, })); @@ -637,10 +635,8 @@ mod test { let expected_result = Ok(Some(ExecutionOutcome { gas_used: config.gas_transaction_call, - reason: ExitReason::Succeed(ExitSucceed::Stopped).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), withdrawals: vec![], estimated_ticks_used: 0, })); @@ -698,10 +694,8 @@ mod test { let expected_result = Ok(Some(ExecutionOutcome { gas_used: 0, - reason: ExitReason::Error(ExitError::OutOfFund).into(), - new_address: None, logs: vec![], - result: None, + result: ExecutionResult::Error(ExitError::OutOfFund), withdrawals: vec![], estimated_ticks_used: 0, })); @@ -766,7 +760,8 @@ mod test { let result = result.unwrap(); assert!(result.is_success(), "transaction should have succeeded"); assert_eq!( - new_address, result.new_address, + new_address, + result.new_address(), "Contract addess not its expected value" ); @@ -798,8 +793,11 @@ mod test { ); let result = result.unwrap(); assert!(result.is_success(), "transaction should have succeeded"); - assert!(result.result.is_some(), "Call should have returned a value"); - let value = U256::from_little_endian(result.result.unwrap().as_slice()); + assert!( + result.output().is_some(), + "Call should have returned a value" + ); + let value = U256::from_little_endian(result.output().unwrap()); assert_eq!(U256::zero(), value, "unexpected result value"); let call_data_set = hex::decode(STORAGE_CONTRACT_CALL_SET42).unwrap(); @@ -829,8 +827,11 @@ mod test { ); let result = result.unwrap(); assert!(result.is_success(), "transaction should have succeeded"); - assert!(result.result.is_some(), "Call should have returned a value"); - let value = U256::from_big_endian(result.result.unwrap().as_slice()); + assert!( + result.output().is_some(), + "Call should have returned a value" + ); + let value = U256::from_big_endian(result.output().unwrap()); assert_eq!(U256::zero(), value, "unexpected result value"); let result2 = run_transaction( @@ -859,8 +860,11 @@ mod test { ); let result = result.unwrap(); assert!(result.is_success(), "transaction should have succeeded"); - assert!(result.result.is_some(), "Call should have returned a value"); - let value = U256::from_big_endian(result.result.unwrap().as_slice()); + assert!( + result.output().is_some(), + "Call should have returned a value" + ); + let value = U256::from_big_endian(result.output().unwrap()); assert_eq!(U256::from(42), value, "unexpected result value"); } @@ -916,7 +920,7 @@ mod test { assert!(result.is_success()); assert_eq!( Some(H160::from_str("907823e0a92f94355968feb2cbf0fbb594fe3214").unwrap()), - result.new_address + result.new_address() ); } @@ -964,10 +968,8 @@ mod test { let expected_result = Ok(Some(ExecutionOutcome { gas_used: 0, - reason: ExitReason::Error(ExitError::DesignatedInvalid).into(), - new_address: None, logs: vec![], - result: None, + result: ExecutionResult::Error(ExitError::DesignatedInvalid), withdrawals: vec![], estimated_ticks_used: 1187236, })); @@ -1022,10 +1024,8 @@ mod test { // Assert let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Stopped).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), withdrawals: vec![], estimated_ticks_used: 0, })); @@ -1171,10 +1171,8 @@ mod test { // Assert let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Returned, vec![]), withdrawals: vec![], estimated_ticks_used: 64163, })); @@ -1236,10 +1234,8 @@ mod test { // Assert let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Revert(ExitRevert::Reverted).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallReverted(vec![]), withdrawals: vec![], estimated_ticks_used: 63539, })); @@ -1297,10 +1293,8 @@ mod test { // Assert let expected_result = Ok(Some(ExecutionOutcome { gas_used: 0, - reason: ExitReason::Error(ExitError::DesignatedInvalid).into(), - new_address: None, logs: vec![], - result: None, + result: ExecutionResult::Error(ExitError::DesignatedInvalid), withdrawals: vec![], estimated_ticks_used: 52333, })); @@ -1355,10 +1349,8 @@ mod test { let expected_result = Ok(Some(ExecutionOutcome { gas_used: 0, - reason: ExitReason::Error(ExitError::DesignatedInvalid).into(), - new_address: None, logs: vec![], - result: None, + result: ExecutionResult::Error(ExitError::DesignatedInvalid), withdrawals: vec![], estimated_ticks_used: 63539, })); @@ -1420,10 +1412,8 @@ mod test { // Assert let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![], - result: Some(vec![1u8; 32]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Returned, vec![1u8; 32]), withdrawals: vec![], estimated_ticks_used: 42_000 + 35 * 32, })); @@ -1481,10 +1471,11 @@ mod test { "0000000000000000000000007156526fbd7a3c72969b54f64e42c10fbb768c8a"; let expected_result = Ok(Some(ExecutionOutcome { gas_used: 25676, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![], - result: Some(hex::decode(expected_address).unwrap()), + result: ExecutionResult::CallSucceeded( + ExitSucceed::Returned, + hex::decode(expected_address).unwrap(), + ), withdrawals: vec![], estimated_ticks_used: 30_000_000, })); @@ -1679,10 +1670,8 @@ mod test { // _all_ the gas allocated to the call (so 0xFFFF or 65535) let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Stopped).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), withdrawals: vec![], estimated_ticks_used: 532678536, })); @@ -1774,11 +1763,9 @@ mod test { // expect to spend _all_ the gas. let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Stopped).into(), - new_address: None, // No logs were produced logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), withdrawals: vec![], estimated_ticks_used: 532095791, })); @@ -1899,10 +1886,8 @@ mod test { let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Stopped).into(), - new_address: None, logs: vec![log_record1, log_record2], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), withdrawals: vec![], estimated_ticks_used: 48062519, })); @@ -2007,10 +1992,8 @@ mod test { let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Stopped).into(), - new_address: None, logs: vec![log_record1], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), withdrawals: vec![], estimated_ticks_used: 47793126, })); @@ -2102,10 +2085,8 @@ mod test { + 5124; // execution gas cost (taken at face value from tests) let expected_result = ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Stopped).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), withdrawals: vec![], estimated_ticks_used: 50578554, }; @@ -2220,10 +2201,8 @@ mod test { let expected_result = Ok(Some(ExecutionOutcome { gas_used: all_the_gas, - reason: ExitReason::Error(ExitError::InvalidCode(Opcode::INVALID)).into(), - new_address: None, logs: vec![], - result: None, + result: ExecutionResult::Error(ExitError::InvalidCode(Opcode::INVALID)), withdrawals: vec![], estimated_ticks_used: 50630887, })); @@ -2324,10 +2303,11 @@ mod test { // Assert let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![], - result: Some(chain_id_bytes.into()), + result: ExecutionResult::CallSucceeded( + ExitSucceed::Returned, + chain_id_bytes.into(), + ), withdrawals: vec![], estimated_ticks_used: 166052, })); @@ -2408,10 +2388,11 @@ mod test { // Assert let expected_result = Ok(Some(ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![], - result: Some(base_fee_per_gas_bytes.into()), + result: ExecutionResult::CallSucceeded( + ExitSucceed::Returned, + base_fee_per_gas_bytes.into(), + ), withdrawals: vec![], estimated_ticks_used: 166070, })); @@ -2811,10 +2792,8 @@ mod test { // Assert let result = unwrap_outcome!(&result, false); assert_eq!( - ExtendedExitReason::Exit(ExitReason::Error(ExitError::InvalidCode(Opcode( - 0xef - )))), - result.reason + ExecutionResult::Error(ExitError::InvalidCode(Opcode(0xef))), + result.result ); } @@ -2838,10 +2817,10 @@ mod test { // Assert let result = unwrap_outcome!(&result); - assert_eq!( - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Returned)), - result.reason - ); + assert!(matches!( + result.result, + ExecutionResult::ContractDeployed(_, _) + )); } // Test case from https://eips.ethereum.org/EIPS/eip-684 @@ -2908,11 +2887,11 @@ mod test { ); let result = unwrap_outcome!(&result, false); - match &result.reason { - ExtendedExitReason::Exit(ExitReason::Error(ExitError::CreateCollision)) => (), - exit_error => panic!( - "ExitReason: {:?}. Expect ExitReason::Error(ExitError::CreateCollision)", - exit_error + match &result.result { + ExecutionResult::Error(ExitError::CreateCollision) => (), + result => panic!( + "ExecutionResult: {:?}. Expect ExecutionResult::Error(ExitError::CreateCollision)", + result ), } } @@ -2992,8 +2971,8 @@ mod test { let result_init = unwrap_outcome!(&result_init, true); - match &result_init.reason { - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)) => { + match &result_init.result { + ExecutionResult::ContractDeployed(_, _) => { let contract = EthereumAccount::from_address(&contract_address).unwrap(); let caller_nonce = contract.nonce(&mock_runtime).unwrap_or_default(); // Check that even if the contract fails to create another contract (due to a collision), @@ -3009,9 +2988,9 @@ mod test { .unwrap_or_default(); assert_eq!(sub_contract_nonce, 1); } - exit_error => panic!( - "ExitReason: {:?}. Expect ExitReason::Succeed(ExitSucceed::Stopped)", - exit_error + result => panic!( + "ExecutionResult: {:?}. Expect ExecutionResult::ContractDeployed(_)", + result ), } } @@ -3102,8 +3081,8 @@ mod test { let result_init = unwrap_outcome!(&result_init, true); - match &result_init.reason { - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)) => { + match &result_init.result { + ExecutionResult::ContractDeployed(_, _) => { // Check that even if the contract fails to create another contract (due to a collision), // the nonce of contract_address is still bumped let contract = EthereumAccount::from_address(&contract_address).unwrap(); @@ -3118,9 +3097,9 @@ mod test { .unwrap_or_default(); assert_eq!(sub_contract_nonce, original_sub_nonce); } - exit_error => panic!( - "ExitReason: {:?}. Expect ExitReason::Succeed(ExitSucceed::Stopped)", - exit_error + result => panic!( + "ExecutionResult: {:?}. Expect ExecutionResult::ContractDeployed(_)", + result ), } } @@ -3182,11 +3161,11 @@ mod test { ); let result = unwrap_outcome!(&result, false); - match &result.reason { - ExtendedExitReason::Exit(ExitReason::Error(ExitError::CreateCollision)) => (), - exit_error => panic!( - "ExitReason: {:?}. Expect ExitReason::Error(ExitError::CreateCollision)", - exit_error + match &result.result { + ExecutionResult::Error(ExitError::CreateCollision) => (), + result => panic!( + "ExecutionResult: {:?}. Expect ExecutionResult::Error(ExitError::CreateCollision)", + result ), } } @@ -3230,8 +3209,7 @@ mod test { ); let result = unwrap_outcome!(result); - let ExecutionOutcome { new_address, .. } = result; - let address = new_address.unwrap(); + let address = result.new_address().unwrap(); let smart_contract = EthereumAccount::from_address(&address).unwrap(); assert_eq!(smart_contract.nonce(&host).unwrap(), 1) @@ -3295,8 +3273,8 @@ mod test { let callee_nonce = account.nonce(&host).unwrap(); assert_eq!( - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)), - result.unwrap().unwrap().reason, + ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), + result.unwrap().unwrap().result, ); assert_eq!(callee_nonce, 0); assert_eq!(caller_nonce, 1); @@ -3393,10 +3371,10 @@ mod test { .unwrap_or_default(); let exec_result = unwrap_outcome!(result, true); - assert_eq!( - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)), - exec_result.reason, - ); + assert!(matches!( + exec_result.result, + ExecutionResult::ContractDeployed(_, _) + )); assert_eq!( nonce_of_should_not_create, 0, "Nonce of the contract that should not be created is not 0" @@ -3486,8 +3464,8 @@ mod test { let caller_nonce = caller.nonce(&host).unwrap(); assert_eq!( - ExtendedExitReason::OutOfTicks, - result.unwrap().unwrap().reason, + ExecutionResult::OutOfTicks, + result.unwrap().unwrap().result, "Contract creation was expected to fail and run out of ticks: \n" ); assert_eq!( @@ -3508,8 +3486,8 @@ mod test { let caller_nonce = caller.nonce(&host).unwrap(); assert_eq!( - ExtendedExitReason::OutOfTicks, - result.unwrap().unwrap().reason, + ExecutionResult::OutOfTicks, + result.unwrap().unwrap().result, "Contract creation was expected to fail and run out of ticks: \n" ); assert_ne!( @@ -3737,10 +3715,10 @@ mod test { get_nonce(&mut host, &mut evm_account_storage, &internal_address); let caller_nonce = get_nonce(&mut host, &mut evm_account_storage, &caller); - assert_eq!( - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)), - result.unwrap().unwrap().reason, - ); + assert!(matches!( + result.unwrap().unwrap().result, + ExecutionResult::ContractDeployed(_, _) + )); assert_eq!(caller_nonce, 1); assert_eq!(internal_address_nonce, 2); @@ -3847,8 +3825,8 @@ mod test { // The initial call succeeds assert_eq!( - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)), - result.reason + ExecutionResult::CallSucceeded(ExitSucceed::Stopped, vec![]), + result.result, ) } @@ -3927,10 +3905,10 @@ mod test { assert_eq!(storage_2, one); // The initial call succeeds - assert_eq!( - ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)), - result.reason - ) + assert!(matches!( + result.result, + ExecutionResult::ContractDeployed(_, _) + )) } #[test] @@ -3975,6 +3953,9 @@ mod test { ) .unwrap(); - assert_eq!(result.unwrap().unwrap().result.unwrap(), return_expected); + assert_eq!( + *result.unwrap().unwrap().result.output().unwrap(), + return_expected + ); } } diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs index 4d5143f69787..415975584323 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs @@ -319,7 +319,7 @@ mod tests { let expected = hex::decode(test.expected).unwrap(); - assert_eq!(Some(expected), outcome.result); + assert_eq!(Some(expected.as_slice()), outcome.output()); } } } diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs index 65c5c6ee0a13..e00883ae43f1 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs @@ -171,7 +171,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(Some(vec![]), outcome.result); + assert_eq!(Some(&[] as &[u8]), outcome.output()); } #[test] @@ -192,7 +192,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(Some(vec![]), outcome.result); + assert_eq!(Some(&[] as &[u8]), outcome.output()); } #[test] @@ -275,7 +275,7 @@ mod tests { assert!(outcome.is_success()); assert_eq!( hex::encode(expected_output), - hex::encode(outcome.result.unwrap()) + hex::encode(outcome.output().unwrap()) ); } @@ -295,7 +295,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); - assert!(outcome.result.unwrap().is_empty()); + assert!(outcome.output().unwrap().is_empty()); } #[test] @@ -314,7 +314,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); - assert!(outcome.result.unwrap().is_empty()); + assert!(outcome.output().unwrap().is_empty()); } #[test] @@ -344,7 +344,7 @@ mod tests { assert!(outcome.is_success()); assert_eq!( hex::encode(expected_output), - hex::encode(outcome.result.unwrap()) + hex::encode(outcome.output().unwrap()) ); } } diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs index 5d85a859c2ab..2433e64a05d1 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs @@ -158,7 +158,7 @@ mod tests { use std::str::FromStr; use alloy_sol_types::SolCall; - use evm::{Config, ExitError, ExitReason}; + use evm::{Config, ExitError}; use primitive_types::{H160, U256}; use tezos_smart_rollup_mock::MockHost; @@ -171,7 +171,7 @@ mod tests { kernel_wrapper, set_balance, ticket_balance_add, ticket_id, }, }, - handler::{EvmHandler, ExecutionOutcome, ExtendedExitReason}, + handler::{EvmHandler, ExecutionOutcome, ExecutionResult}, precompiles::{self, FA_BRIDGE_PRECOMPILE_ADDRESS}, transaction::TransactionContext, utilities::{bigint_to_u256, keccak256_hash}, @@ -226,7 +226,7 @@ mod tests { ); assert!(!outcome.is_success()); assert!( - matches!(outcome.reason, ExtendedExitReason::Exit(ExitReason::Error(ExitError::Other(err))) if err.contains("unexpected selector")) + matches!(outcome.result, ExecutionResult::Error(ExitError::Other(err)) if err.contains("unexpected selector")) ); } @@ -247,7 +247,7 @@ mod tests { ); assert!(!outcome.is_success()); assert!( - matches!(outcome.reason, ExtendedExitReason::Exit(ExitReason::Error(ExitError::Other(err))) if err.contains("gas limit too low")) + matches!(outcome.result, ExecutionResult::Error(ExitError::Other(err)) if err.contains("gas limit too low")) ); } @@ -275,7 +275,7 @@ mod tests { ); assert!(!outcome.is_success()); assert!( - matches!(outcome.reason, ExtendedExitReason::Exit(ExitReason::Error(ExitError::Other(err))) if err.contains("unexpected value transfer")) + matches!(outcome.result, ExecutionResult::Error(ExitError::Other(err)) if err.contains("unexpected value transfer")) ); } @@ -296,7 +296,7 @@ mod tests { ); assert!(!outcome.is_success()); assert!( - matches!(outcome.reason, ExtendedExitReason::Exit(ExitReason::Error(ExitError::Other(err))) if err.contains("static call not allowed")) + matches!(outcome.result, ExecutionResult::Error(ExitError::Other(err)) if err.contains("static call not allowed")) ); } @@ -338,7 +338,7 @@ mod tests { assert!(!outcome.is_success()); assert!( - matches!(outcome.reason, ExtendedExitReason::Exit(ExitReason::Error(ExitError::Other(err))) if err.contains("delegate call not allowed")) + matches!(outcome.result, ExecutionResult::Error(ExitError::Other(err)) if err.contains("delegate call not allowed")) ); } @@ -358,7 +358,7 @@ mod tests { ); assert!(!outcome.is_success()); assert!( - matches!(outcome.reason, ExtendedExitReason::Exit(ExitReason::Error(ExitError::Other(err))) if err.contains("parsing failed")) + matches!(outcome.result, ExecutionResult::Error(ExitError::Other(err)) if err.contains("parsing failed")) ); } diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs index b3e468b42141..21edc8885e05 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs @@ -92,11 +92,12 @@ pub fn ripemd160_precompile( #[cfg(test)] mod tests { - use evm::{ExitReason, ExitSucceed}; + use evm::ExitSucceed; use primitive_types::H160; use crate::{ - handler::ExecutionOutcome, precompiles::test_helpers::execute_precompiled, + handler::{ExecutionOutcome, ExecutionResult}, + precompiles::test_helpers::execute_precompiled, }; #[test] @@ -118,10 +119,8 @@ mod tests { let expected = ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![], - result: Some(expected_hash), + result: ExecutionResult::CallSucceeded(ExitSucceed::Returned, expected_hash), withdrawals: vec![], estimated_ticks_used: 75_000, }; @@ -148,10 +147,8 @@ mod tests { let expected = ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![], - result: Some(expected_hash), + result: ExecutionResult::CallSucceeded(ExitSucceed::Returned, expected_hash), withdrawals: vec![], estimated_ticks_used: 70_000, }; diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs index 8162be4898df..e24b15477913 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs @@ -214,11 +214,10 @@ mod tick { #[cfg(test)] mod tests { - use evm::ExitReason; use primitive_types::H160; use crate::{ - handler::ExtendedExitReason, precompiles::test_helpers::execute_precompiled, + handler::ExecutionResult, precompiles::test_helpers::execute_precompiled, }; struct ModexpTestCase { @@ -402,7 +401,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(hex::encode(outcome.result.unwrap()), test.expected,); + assert_eq!(hex::encode(outcome.output().unwrap()), test.expected); } } @@ -415,7 +414,7 @@ mod tests { let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!("", hex::encode(outcome.result.unwrap())); + assert_eq!("", hex::encode(outcome.output().unwrap())); } // All the tests for ecAdd, ecMul, ecPrecompile were taken from: @@ -437,10 +436,10 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); - match outcome.reason { - ExtendedExitReason::Exit(ExitReason::Error(_)) => (), + match outcome.result { + ExecutionResult::Error(_) => (), _ => panic!("The execution should exit with an error."), } - assert!(outcome.result.is_none()); + assert!(outcome.output().is_none()); } } diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs index 971dd6197095..687900e930b5 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs @@ -305,7 +305,7 @@ fn event_log( #[cfg(test)] mod tests { use crate::{ - handler::{ExecutionOutcome, Withdrawal}, + handler::{ExecutionOutcome, ExecutionResult, Withdrawal}, precompiles::{ test_helpers::{execute_precompiled, DUMMY_TICKETER}, withdrawal::WITHDRAWAL_EVENT_TOPIC, @@ -313,7 +313,7 @@ mod tests { }, }; use alloy_sol_types::SolEvent; - use evm::{ExitReason, ExitRevert, ExitSucceed, Transfer}; + use evm::{ExitSucceed, Transfer}; use pretty_assertions::assert_eq; use primitive_types::{H160, H256, U256}; use sha3::{Digest, Keccak256}; @@ -476,10 +476,11 @@ mod tests { let expected = ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![expected_log], - result: Some(expected_output), + result: ExecutionResult::CallSucceeded( + ExitSucceed::Returned, + expected_output, + ), withdrawals: vec![message], estimated_ticks_used: 880_000, }; @@ -553,10 +554,11 @@ mod tests { let expected = ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Succeed(ExitSucceed::Returned).into(), - new_address: None, logs: vec![expected_log], - result: Some(expected_output), + result: ExecutionResult::CallSucceeded( + ExitSucceed::Returned, + expected_output, + ), withdrawals: vec![message], // TODO (#6426): estimate the ticks consumption of precompiled contracts estimated_ticks_used: 880_000, @@ -591,10 +593,8 @@ mod tests { let expected = ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Revert(ExitRevert::Reverted).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallReverted(vec![]), withdrawals: vec![], estimated_ticks_used: 880_000, }; @@ -613,10 +613,8 @@ mod tests { let expected = ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Revert(ExitRevert::Reverted).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallReverted(vec![]), withdrawals: vec![], estimated_ticks_used: 880_000, }; @@ -638,10 +636,8 @@ mod tests { let expected = ExecutionOutcome { gas_used: expected_gas, - reason: ExitReason::Revert(ExitRevert::Reverted).into(), - new_address: None, logs: vec![], - result: Some(vec![]), + result: ExecutionResult::CallReverted(vec![]), withdrawals: vec![], estimated_ticks_used: 880_000, }; diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs index bc4f4e7995ba..fdaecf3e151b 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs @@ -327,7 +327,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(outcome.result.unwrap(), expected); + assert_eq!(*outcome.output().unwrap(), expected); // zero sum test let input = hex::decode( @@ -355,7 +355,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(outcome.result.unwrap(), expected); + assert_eq!(*outcome.output().unwrap(), expected); // no input test let input = [0u8; 0]; @@ -376,7 +376,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(outcome.result.unwrap(), expected); + assert_eq!(*outcome.output().unwrap(), expected); // point not on curve fail let input = hex::decode( @@ -425,7 +425,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(outcome.result.unwrap(), expected); + assert_eq!(*outcome.output().unwrap(), expected); // zero multiplication test let input = hex::decode( @@ -452,7 +452,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(outcome.result.unwrap(), expected); + assert_eq!(*outcome.output().unwrap(), expected); // no input test let input = [0u8; 0]; @@ -473,7 +473,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(outcome.result.unwrap(), expected); + assert_eq!(*outcome.output().unwrap(), expected); // point not on curve fail let input = hex::decode( @@ -529,7 +529,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(outcome.result.unwrap(), expected); + assert_eq!(*outcome.output().unwrap(), expected); // no input test let input = [0u8; 0]; @@ -548,7 +548,7 @@ mod tests { assert!(result.is_ok()); let outcome = result.unwrap(); assert!(outcome.is_success()); - assert_eq!(outcome.result.unwrap(), expected); + assert_eq!(*outcome.output().unwrap(), expected); // point not on curve fail let input = hex::decode( diff --git a/etherlink/kernel_evm/kernel/src/fees.rs b/etherlink/kernel_evm/kernel/src/fees.rs index 5c544846025a..e12a619d3ffe 100644 --- a/etherlink/kernel_evm/kernel/src/fees.rs +++ b/etherlink/kernel_evm/kernel/src/fees.rs @@ -308,11 +308,8 @@ fn gas_as_u64(gas_for_fees: U256) -> Result { #[cfg(test)] mod tests { use super::*; - use evm::{ExitReason, ExitSucceed}; - use evm_execution::{ - account_storage::{account_path, EthereumAccountStorage}, - handler::ExtendedExitReason, - }; + use evm::ExitSucceed; + use evm_execution::account_storage::{account_path, EthereumAccountStorage}; use primitive_types::{H160, U256}; use tezos_smart_rollup_mock::MockHost; @@ -540,10 +537,11 @@ mod tests { fn mock_execution_outcome(gas_used: u64) -> ExecutionOutcome { ExecutionOutcome { gas_used, - reason: ExtendedExitReason::Exit(ExitReason::Succeed(ExitSucceed::Stopped)), - new_address: None, logs: Vec::new(), - result: None, + result: evm_execution::handler::ExecutionResult::CallSucceeded( + ExitSucceed::Stopped, + vec![], + ), withdrawals: Vec::new(), estimated_ticks_used: 1, } diff --git a/etherlink/kernel_evm/kernel/src/simulation.rs b/etherlink/kernel_evm/kernel/src/simulation.rs index 865e15585e41..5bf6704f1a7f 100644 --- a/etherlink/kernel_evm/kernel/src/simulation.rs +++ b/etherlink/kernel_evm/kernel/src/simulation.rs @@ -947,7 +947,7 @@ mod tests { outcome.is_some(), "execution should have produced some outcome" ); - outcome.unwrap().new_address.unwrap() + outcome.unwrap().new_address().unwrap() } #[test] -- GitLab