diff --git a/framework/base/src/types/interaction/tx_env.rs b/framework/base/src/types/interaction/tx_env.rs index 37e18d7dec..188e304311 100644 --- a/framework/base/src/types/interaction/tx_env.rs +++ b/framework/base/src/types/interaction/tx_env.rs @@ -27,4 +27,7 @@ pub trait TxEnvMockDeployAddress: TxEnv { pub trait TxEnvWithTxHash: TxEnv { fn set_tx_hash(&mut self, tx_hash: H256); + + /// Retrieves current tx hash, while resetting it in self. + fn take_tx_hash(&mut self) -> Option; } diff --git a/framework/scenario/src/facade/world_tx/scenario_exec_call.rs b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs index 8905c7d14d..ca09b9d318 100644 --- a/framework/scenario/src/facade/world_tx/scenario_exec_call.rs +++ b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs @@ -85,7 +85,6 @@ where fn run(self) -> Self::Returns { let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); step_wrapper.env.world.sc_call(&mut step_wrapper.step); step_wrapper.process_result() } @@ -111,7 +110,6 @@ where fn run(self) -> Self::Returns { let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); step_wrapper.env.world.sc_call(&mut step_wrapper.step); step_wrapper.process_result() } @@ -119,8 +117,11 @@ where impl<'w> TxEnvWithTxHash for ScenarioEnvExec<'w> { fn set_tx_hash(&mut self, tx_hash: H256) { - assert!(self.data.tx_hash.is_none(), "tx hash set twice"); - self.data.tx_hash = Some(tx_hash); + self.data.set_tx_hash(tx_hash); + } + + fn take_tx_hash(&mut self) -> Option { + self.data.take_tx_hash() } } diff --git a/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs b/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs index 40fbbaa878..866d4f562f 100644 --- a/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs +++ b/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs @@ -35,7 +35,6 @@ where fn run(self) -> Self::Returns { let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); step_wrapper.env.world.sc_deploy(&mut step_wrapper.step); step_wrapper.process_result() } diff --git a/framework/scenario/src/facade/world_tx/scenario_tx_env.rs b/framework/scenario/src/facade/world_tx/scenario_tx_env.rs index 339ed9b38b..c3a2a1c204 100644 --- a/framework/scenario/src/facade/world_tx/scenario_tx_env.rs +++ b/framework/scenario/src/facade/world_tx/scenario_tx_env.rs @@ -1,5 +1,5 @@ use multiversx_chain_scenario_format::interpret_trait::InterpreterContext; -use multiversx_sc::types::{ManagedAddress, ManagedBuffer, TxEnv, H256}; +use multiversx_sc::types::{ManagedAddress, ManagedBuffer, TxEnv, TxEnvWithTxHash, H256}; use crate::{api::StaticApi, scenario_model::TxExpect, ScenarioWorld}; @@ -33,6 +33,17 @@ impl TxEnv for ScenarioTxEnvData { } } +impl TxEnvWithTxHash for ScenarioTxEnvData { + fn set_tx_hash(&mut self, tx_hash: H256) { + assert!(self.tx_hash.is_none(), "tx hash set twice"); + self.tx_hash = Some(tx_hash); + } + + fn take_tx_hash(&mut self) -> Option { + core::mem::take(&mut self.tx_hash) + } +} + impl ScenarioTxEnvData { pub fn interpreter_context(&self) -> InterpreterContext { self.interpreter_context.clone() diff --git a/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs index f8d03dc6da..62842a6e25 100644 --- a/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs +++ b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs @@ -55,7 +55,6 @@ where let contract_obj = contract_obj_builder(); let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); let (new_address, tx_result) = step_wrapper .env .world @@ -123,7 +122,6 @@ where let contract_obj = contract_obj_builder(); let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); // no endpoint is called per se, but if it is empty, the VM thinks it is a simple transfer of value if step_wrapper.step.tx.function.is_empty() { diff --git a/framework/scenario/src/scenario/model/step/sc_call_step.rs b/framework/scenario/src/scenario/model/step/sc_call_step.rs index 2a25fb2c2f..8d8d71b0e8 100644 --- a/framework/scenario/src/scenario/model/step/sc_call_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_call_step.rs @@ -211,7 +211,10 @@ impl ScCallStep { expect.update_from_response(&tx_response) } } - tx_response.tx_hash = self.explicit_tx_hash.as_ref().map(|vm_hash| vm_hash.as_array().into()); + tx_response.tx_hash = self + .explicit_tx_hash + .as_ref() + .map(|vm_hash| vm_hash.as_array().into()); self.response = Some(tx_response); } } diff --git a/framework/scenario/src/scenario/model/step/sc_deploy_step.rs b/framework/scenario/src/scenario/model/step/sc_deploy_step.rs index 3b22522f69..6090cfd492 100644 --- a/framework/scenario/src/scenario/model/step/sc_deploy_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_deploy_step.rs @@ -141,7 +141,10 @@ impl ScDeployStep { expect.update_from_response(&tx_response) } } - tx_response.tx_hash = self.explicit_tx_hash.as_ref().map(|vm_hash| vm_hash.as_array().into()); + tx_response.tx_hash = self + .explicit_tx_hash + .as_ref() + .map(|vm_hash| vm_hash.as_array().into()); self.response = Some(tx_response); } } diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs index 475326eac7..1d1eb2c9a2 100644 --- a/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs @@ -1,6 +1,6 @@ use multiversx_sc::types::{ - Code, FunctionCall, NotPayable, RHListExec, Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, - TxToSpecified, UpgradeCall, + Code, FunctionCall, NotPayable, RHListExec, Tx, TxEnv, TxEnvWithTxHash, TxFromSpecified, TxGas, + TxPayment, TxToSpecified, UpgradeCall, }; use crate::{ @@ -14,7 +14,7 @@ use super::{address_annotated, gas_annotated, StepWrapper, TxToStep}; impl TxToStep for Tx, RH> where - Env: TxEnv, + Env: TxEnvWithTxHash, From: TxFromSpecified, To: TxToSpecified, Payment: TxPayment, @@ -23,7 +23,7 @@ where { type Step = ScCallStep; - fn tx_to_step(self) -> StepWrapper { + fn tx_to_step(mut self) -> StepWrapper { let mut step = tx_to_sc_call_step( &self.env, self.from, @@ -32,6 +32,7 @@ where self.gas, self.data, ); + step.explicit_tx_hash = self.env.take_tx_hash(); step.expect = Some(self.result_handler.list_tx_expect()); StepWrapper { diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs index 4e49be51b4..1c7532e27a 100644 --- a/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs @@ -1,5 +1,6 @@ use multiversx_sc::types::{ - Code, DeployCall, RHListExec, Tx, TxCodeValue, TxEnv, TxFromSpecified, TxGas, TxPayment, + Code, DeployCall, RHListExec, Tx, TxCodeValue, TxEnv, TxEnvWithTxHash, TxFromSpecified, TxGas, + TxPayment, }; use crate::scenario_model::{ScDeployStep, TxExpect, TxResponse}; @@ -9,7 +10,7 @@ use super::{address_annotated, code_annotated, gas_annotated, StepWrapper, TxToS impl TxToStep for Tx>, RH> where - Env: TxEnv, + Env: TxEnvWithTxHash, From: TxFromSpecified, Payment: TxPayment, Gas: TxGas, @@ -18,9 +19,10 @@ where { type Step = ScDeployStep; - fn tx_to_step(self) -> StepWrapper { + fn tx_to_step(mut self) -> StepWrapper { let mut step = tx_to_sc_deploy_step(&self.env, self.from, self.payment, self.gas, self.data); + step.explicit_tx_hash = self.env.take_tx_hash(); step.expect = Some(self.result_handler.list_tx_expect()); StepWrapper { diff --git a/framework/snippets/src/interactor_tx/interactor_exec_env.rs b/framework/snippets/src/interactor_tx/interactor_exec_env.rs index 6473c50a91..436e65ac0c 100644 --- a/framework/snippets/src/interactor_tx/interactor_exec_env.rs +++ b/framework/snippets/src/interactor_tx/interactor_exec_env.rs @@ -1,6 +1,8 @@ use multiversx_sc_scenario::{ api::StaticApi, - multiversx_sc::types::{ManagedAddress, ManagedBuffer, Tx, TxBaseWithEnv, TxEnv}, + multiversx_sc::types::{ + ManagedAddress, ManagedBuffer, Tx, TxBaseWithEnv, TxEnv, TxEnvWithTxHash, H256, + }, scenario_model::TxExpect, ScenarioTxEnv, ScenarioTxEnvData, }; @@ -44,3 +46,13 @@ impl<'w> ScenarioTxEnv for InteractorEnvExec<'w> { &self.data } } + +impl<'w> TxEnvWithTxHash for InteractorEnvExec<'w> { + fn set_tx_hash(&mut self, tx_hash: H256) { + self.data.set_tx_hash(tx_hash); + } + + fn take_tx_hash(&mut self) -> Option { + self.data.take_tx_hash() + } +}