diff --git a/framework/snippets/src/multi.rs b/framework/snippets/src/multi.rs index 973b159858..dd9cd3288a 100644 --- a/framework/snippets/src/multi.rs +++ b/framework/snippets/src/multi.rs @@ -5,5 +5,5 @@ mod interactor_step; mod step_buffer; pub use homogenous_tx_buffer::HomogenousTxBuffer; -pub use interactor_step::InteractorStep; +pub use interactor_step::{InteractorStep, InteractorStepRef}; pub use step_buffer::StepBuffer; diff --git a/framework/snippets/src/multi/homogenous_tx_buffer.rs b/framework/snippets/src/multi/homogenous_tx_buffer.rs index a4e4e75c92..b9afa69e1b 100644 --- a/framework/snippets/src/multi/homogenous_tx_buffer.rs +++ b/framework/snippets/src/multi/homogenous_tx_buffer.rs @@ -3,7 +3,7 @@ use multiversx_sc_scenario::{ tuple_util::NestedTupleFlatten, types::{RHListExec, TxBaseWithEnv}, }, - scenario::tx_to_step::{StepWithResponse, StepWrapper, TxToStep}, + scenario::tx_to_step::{StepWrapper, TxToStep}, scenario_model::TxResponse, ScenarioTxEnvData, }; @@ -33,7 +33,7 @@ impl InteractorBase { impl<'w, Step, RH> HomogenousTxBuffer<'w, Step, RH> where - Step: InteractorStep + StepWithResponse, + Step: InteractorStep, RH: RHListExec, RH::ListReturns: NestedTupleFlatten, { @@ -54,7 +54,7 @@ where pub async fn run(mut self) -> Vec<::Unpacked> { let mut step_buffer = StepBuffer::default(); for step in &mut self.steps { - step_buffer.refs.push(&mut step.step); + step_buffer.refs.push(step.step.as_interactor_step()); } self.env.world.multi_sc_exec(step_buffer).await; diff --git a/framework/snippets/src/multi/interactor_multi_sc_exec.rs b/framework/snippets/src/multi/interactor_multi_sc_exec.rs index 658896d8f0..e940dabb9c 100644 --- a/framework/snippets/src/multi/interactor_multi_sc_exec.rs +++ b/framework/snippets/src/multi/interactor_multi_sc_exec.rs @@ -1,10 +1,13 @@ -use multiversx_sdk_http::GatewayHttpProxy; - use super::interactor_multi_sc_process::{update_nonces_and_sign_tx, SenderSet, Txs}; +use super::InteractorStepRef; use crate::sdk::data::transaction::Transaction; -use crate::{network_response, InteractorBase, InteractorStep, StepBuffer}; +use crate::sdk::gateway::GatewayAsyncService; +use crate::{network_response, InteractorBase, StepBuffer}; -impl InteractorBase { +impl InteractorBase +where + GatewayProxy: GatewayAsyncService, +{ pub async fn multi_sc_exec(&mut self, mut buffer: StepBuffer<'_>) { for step in buffer.refs.iter_mut() { step.run_step(&mut self.pre_runners); @@ -45,7 +48,7 @@ impl InteractorBase { } } -fn retrieve_senders(sc_call_steps: &[&mut dyn InteractorStep]) -> SenderSet { +fn retrieve_senders(sc_call_steps: &[InteractorStepRef]) -> SenderSet { let mut senders = SenderSet::new(); for sc_call_step in sc_call_steps { diff --git a/framework/snippets/src/multi/interactor_step.rs b/framework/snippets/src/multi/interactor_step.rs index 4d27b59496..93a93d6a9e 100644 --- a/framework/snippets/src/multi/interactor_step.rs +++ b/framework/snippets/src/multi/interactor_step.rs @@ -1,56 +1,66 @@ use crate::sdk::data::transaction::Transaction; use multiversx_sc_scenario::{ mandos_system::ScenarioRunner, + scenario::tx_to_step::StepWithResponse, scenario_model::{AddressValue, ScCallStep, ScDeployStep, TxResponse}, }; -use multiversx_sdk_http::GatewayHttpProxy; +use multiversx_sdk::gateway::GatewayAsyncService; use crate::InteractorBase; -/// Describes a scenario step that can be executed in an interactor. -pub trait InteractorStep { - fn to_transaction(&self, interactor: &InteractorBase) -> Transaction; - - fn sender_address(&self) -> &AddressValue; - - fn run_step(&mut self, step_runner: &mut dyn ScenarioRunner); - - fn set_response(&mut self, tx_response: TxResponse); +pub enum InteractorStepRef<'a> { + ScCall(&'a mut ScCallStep), + ScDeploy(&'a mut ScDeployStep), } -impl InteractorStep for ScCallStep { - fn to_transaction(&self, interactor: &InteractorBase) -> Transaction { - interactor.tx_call_to_blockchain_tx(&self.tx) +impl<'a> InteractorStepRef<'a> { + pub fn to_transaction( + &self, + interactor: &InteractorBase, + ) -> Transaction { + match self { + InteractorStepRef::ScCall(sc_call) => interactor.tx_call_to_blockchain_tx(&sc_call.tx), + InteractorStepRef::ScDeploy(sc_deploy) => { + interactor.sc_deploy_to_blockchain_tx(sc_deploy) + }, + } } - fn sender_address(&self) -> &AddressValue { - &self.tx.from + pub fn sender_address(&self) -> &AddressValue { + match self { + InteractorStepRef::ScCall(sc_call) => &sc_call.tx.from, + InteractorStepRef::ScDeploy(sc_deploy) => &sc_deploy.tx.from, + } } - fn run_step(&mut self, step_runner: &mut dyn ScenarioRunner) { - let mut clone = self.clone(); - step_runner.run_sc_call_step(&mut clone); // TODO: make mutability uniform + pub fn run_step(&mut self, step_runner: &mut dyn ScenarioRunner) { + match self { + InteractorStepRef::ScCall(sc_call) => step_runner.run_sc_call_step(sc_call), + InteractorStepRef::ScDeploy(sc_deploy) => step_runner.run_sc_deploy_step(sc_deploy), + } } - fn set_response(&mut self, response: TxResponse) { - self.save_response(response); + pub fn set_response(&mut self, tx_response: TxResponse) { + match self { + InteractorStepRef::ScCall(sc_call) => sc_call.save_response(tx_response), + InteractorStepRef::ScDeploy(sc_deploy) => sc_deploy.save_response(tx_response), + } } } -impl InteractorStep for ScDeployStep { - fn to_transaction(&self, interactor: &InteractorBase) -> Transaction { - interactor.sc_deploy_to_blockchain_tx(self) - } - - fn sender_address(&self) -> &AddressValue { - &self.tx.from - } +/// Describes a scenario step that can be executed in an interactor. +pub trait InteractorStep: StepWithResponse { + fn as_interactor_step(&mut self) -> InteractorStepRef<'_>; +} - fn run_step(&mut self, step_runner: &mut dyn ScenarioRunner) { - step_runner.run_sc_deploy_step(self); +impl InteractorStep for ScCallStep { + fn as_interactor_step(&mut self) -> InteractorStepRef<'_> { + InteractorStepRef::ScCall(self) } +} - fn set_response(&mut self, response: TxResponse) { - self.save_response(response); +impl InteractorStep for ScDeployStep { + fn as_interactor_step(&mut self) -> InteractorStepRef<'_> { + InteractorStepRef::ScDeploy(self) } } diff --git a/framework/snippets/src/multi/step_buffer.rs b/framework/snippets/src/multi/step_buffer.rs index 529b790ff5..b25835f319 100644 --- a/framework/snippets/src/multi/step_buffer.rs +++ b/framework/snippets/src/multi/step_buffer.rs @@ -1,10 +1,10 @@ use multiversx_sc_scenario::scenario_model::{ScCallStep, ScDeployStep}; -use crate::InteractorStep; +use super::InteractorStepRef; #[derive(Default)] pub struct StepBuffer<'a> { - pub refs: Vec<&'a mut dyn InteractorStep>, + pub refs: Vec>, } impl<'a> StepBuffer<'a> { @@ -17,7 +17,7 @@ impl<'a> StepBuffer<'a> { 'b: 'a, S: AsMut, { - self.refs.push(step.as_mut()); + self.refs.push(InteractorStepRef::ScCall(step.as_mut())); } pub fn add_sc_call_vec<'b, S>(&'a mut self, steps: &'b mut Vec) @@ -26,7 +26,7 @@ impl<'a> StepBuffer<'a> { S: AsMut, { for step in steps { - self.refs.push(step.as_mut()); + self.refs.push(InteractorStepRef::ScCall(step.as_mut())); } } @@ -37,7 +37,7 @@ impl<'a> StepBuffer<'a> { { let mut buffer = Self::default(); for step in steps { - buffer.refs.push(step.as_mut()); + buffer.refs.push(InteractorStepRef::ScCall(step.as_mut())); } buffer } @@ -49,12 +49,8 @@ impl<'a> StepBuffer<'a> { { let mut buffer = Self::default(); for step in steps { - buffer.refs.push(step.as_mut()); + buffer.refs.push(InteractorStepRef::ScDeploy(step.as_mut())); } buffer } - - pub fn to_refs_vec(&'a self) -> Vec<&'a dyn InteractorStep> { - self.refs.iter().map(|r| &**r).collect() - } }