diff --git a/etherlink/kernel_latest/tezos/src/operation_result.rs b/etherlink/kernel_latest/tezos/src/operation_result.rs index 7b2a8634ee98b3e27e8231e8f28e90c08cad1711..324668a31c258a9695bdb8b646f660b56f938a5b 100644 --- a/etherlink/kernel_latest/tezos/src/operation_result.rs +++ b/etherlink/kernel_latest/tezos/src/operation_result.rs @@ -251,6 +251,17 @@ pub enum OperationResultSum { Transfer(OperationResult), } +pub fn is_applied(res: &OperationResultSum) -> bool { + match res { + OperationResultSum::Reveal(op_res) => { + matches!(op_res.result, ContentResult::Applied(_)) + } + OperationResultSum::Transfer(op_res) => { + matches!(op_res.result, ContentResult::Applied(_)) + } + } +} + pub fn produce_operation_result( balance_updates: Vec, result: Result, diff --git a/etherlink/kernel_latest/tezos_execution/src/lib.rs b/etherlink/kernel_latest/tezos_execution/src/lib.rs index 04dee56ca02c9fc1242019a3a9aa0f197d1d8ead..63e8825bcf22611f5fd7bf14117bf431b826302f 100644 --- a/etherlink/kernel_latest/tezos_execution/src/lib.rs +++ b/etherlink/kernel_latest/tezos_execution/src/lib.rs @@ -14,8 +14,8 @@ use num_traits::ops::checked::CheckedSub; use tezos_crypto_rs::{base58::FromBase58CheckError, PublicKeyWithHash}; use tezos_data_encoding::enc::BinError; use tezos_data_encoding::types::Narith; -use tezos_evm_logging::{log, Level::*}; -use tezos_evm_runtime::runtime::Runtime; +use tezos_evm_logging::{log, Level::*, Verbosity}; +use tezos_evm_runtime::{runtime::Runtime, safe_storage::SafeStorage}; use tezos_smart_rollup::types::{Contract, PublicKey, PublicKeyHash}; use tezos_tezlink::operation::Operation; use tezos_tezlink::operation_result::{BalanceTooLow, TransferTarget, UpdateOrigin}; @@ -24,7 +24,7 @@ use tezos_tezlink::{ ManagerOperation, OperationContent, Parameter, RevealContent, TransferContent, }, operation_result::{ - produce_operation_result, Balance, BalanceUpdate, OperationError, + is_applied, produce_operation_result, Balance, BalanceUpdate, OperationError, OperationResultSum, Reveal, RevealError, RevealSuccess, TransferError, TransferSuccess, }, @@ -40,6 +40,8 @@ type ExecutionResult = Result, ApplyKernelError>; #[derive(Error, Debug, PartialEq, Eq)] pub enum ApplyKernelError { + #[error("Host failed with a runtime error {0}")] + HostRuntimeError(#[from] tezos_smart_rollup_host::runtime::RuntimeError), #[error("Apply operation failed on a storage manipulation {0}")] StorageError(tezos_storage::error::Error), #[error("Apply operation failed because of a b58 conversion {0}")] @@ -354,19 +356,27 @@ pub fn apply_operation( operation.content.clone().into(); let source = &manager_operation.source; - log!( + + let mut safe_host = SafeStorage { host, + world_state: context::contracts::root(context).unwrap(), + }; + + log!( + safe_host, Debug, "Going to run a Tezos Manager Operation from {}", source ); + safe_host.start()?; + let mut account = TezlinkImplicitAccount::from_public_key_hash(context, source)?; - log!(host, Debug, "Verifying that the operation is valid"); + log!(safe_host, Debug, "Verifying that the operation is valid"); let validity_result = validate::is_valid_tezlink_operation( - host, + &safe_host, &account, &operation.branch, operation.content.into(), @@ -376,28 +386,37 @@ pub fn apply_operation( let new_balance = match validity_result { Ok(new_balance) => new_balance, Err(validity_err) => { - log!(host, Debug, "Operation is invalid, exiting apply_operation"); + log!( + safe_host, + Debug, + "Operation is invalid, exiting apply_operation" + ); // TODO: Don't force the receipt to a reveal receipt let receipt = produce_operation_result::( vec![], Err(OperationError::Validation(validity_err)), ); + safe_host.revert()?; return Ok(OperationResultSum::Reveal(receipt)); } }; - log!(host, Debug, "Operation is valid"); + log!(safe_host, Debug, "Operation is valid"); - log!(host, Debug, "Updates balance to pay fees"); - account.set_balance(host, &new_balance)?; + log!(safe_host, Debug, "Updates balance to pay fees"); + account.set_balance(&mut safe_host, &new_balance)?; let (src_delta, block_fees) = compute_fees_balance_updates(source, &manager_operation.fee) .map_err(ApplyKernelError::BigIntError)?; + safe_host.promote()?; + safe_host.promote_trace()?; + safe_host.start()?; + let receipt = match manager_operation.operation { OperationContent::Reveal(RevealContent { pk, proof: _ }) => { - let reveal_result = reveal(host, source, &mut account, &pk)?; + let reveal_result = reveal(&mut safe_host, source, &mut account, &pk)?; let manager_result = produce_operation_result(vec![src_delta, block_fees], reveal_result); OperationResultSum::Reveal(manager_result) @@ -407,14 +426,27 @@ pub fn apply_operation( destination, parameters, }) => { - let transfer_result = - transfer(host, context, source, &amount, &destination, parameters)?; + let transfer_result = transfer( + &mut safe_host, + context, + source, + &amount, + &destination, + parameters, + )?; let manager_result = produce_operation_result(vec![src_delta, block_fees], transfer_result); OperationResultSum::Transfer(manager_result) } }; + if is_applied(&receipt) { + safe_host.promote()?; + safe_host.promote_trace()?; + } else { + safe_host.revert()?; + } + Ok(receipt) } @@ -665,6 +697,12 @@ mod tests { let source = bootstrap1(); + // We need to have something written in the durable storage + // to avoid getting an error when initializing the safe_storage + let other = bootstrap2(); + + init_account(&mut host, &other.pkh); + let operation = make_reveal_operation(15, 1, 4, 5, source); let receipt =