From 3506d2533f19b120f144f19ee8f4dffd4c1cca23 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 2 Apr 2024 21:55:10 +0300 Subject: [PATCH] Tx -> Step conversion refactor - part 1 --- framework/scenario/src/facade/world_tx.rs | 1 - .../facade/world_tx/scenario_env_deploy.rs | 20 +- .../src/facade/world_tx/scenario_env_exec.rs | 24 +-- .../src/facade/world_tx/scenario_env_query.rs | 17 +- .../src/facade/world_tx/scenario_env_util.rs | 175 ------------------ .../src/{scenario/mod.rs => scenario.rs} | 1 + framework/scenario/src/scenario/tx_to_step.rs | 11 ++ .../scenario/tx_to_step/step_annotation.rs | 40 ++++ .../src/scenario/tx_to_step/step_wrapper.rs | 48 +++++ .../scenario/tx_to_step/tx_to_step_call.rs | 75 ++++++++ .../scenario/tx_to_step/tx_to_step_deploy.rs | 67 +++++++ .../scenario/tx_to_step/tx_to_step_query.rs | 44 +++++ .../scenario/tx_to_step/tx_to_step_trait.rs | 17 ++ .../tx_to_step/tx_to_step_transfer.rs | 58 ++++++ .../snippets/src/itx/interactor_env_deploy.rs | 41 ++-- .../snippets/src/itx/interactor_env_exec.rs | 39 ++-- .../snippets/src/itx/interactor_env_query.rs | 36 ++-- .../snippets/src/itx/interactor_env_transf.rs | 18 +- 18 files changed, 448 insertions(+), 284 deletions(-) delete mode 100644 framework/scenario/src/facade/world_tx/scenario_env_util.rs rename framework/scenario/src/{scenario/mod.rs => scenario.rs} (91%) create mode 100644 framework/scenario/src/scenario/tx_to_step.rs create mode 100644 framework/scenario/src/scenario/tx_to_step/step_annotation.rs create mode 100644 framework/scenario/src/scenario/tx_to_step/step_wrapper.rs create mode 100644 framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs create mode 100644 framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs create mode 100644 framework/scenario/src/scenario/tx_to_step/tx_to_step_query.rs create mode 100644 framework/scenario/src/scenario/tx_to_step/tx_to_step_trait.rs create mode 100644 framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs diff --git a/framework/scenario/src/facade/world_tx.rs b/framework/scenario/src/facade/world_tx.rs index 0ccbdd9514..b72fe5b88c 100644 --- a/framework/scenario/src/facade/world_tx.rs +++ b/framework/scenario/src/facade/world_tx.rs @@ -5,7 +5,6 @@ mod scenario_env; mod scenario_env_deploy; mod scenario_env_exec; mod scenario_env_query; -pub mod scenario_env_util; mod scenario_rh_impl; pub use expr::*; diff --git a/framework/scenario/src/facade/world_tx/scenario_env_deploy.rs b/framework/scenario/src/facade/world_tx/scenario_env_deploy.rs index ef7b2a243f..c218f06869 100644 --- a/framework/scenario/src/facade/world_tx/scenario_env_deploy.rs +++ b/framework/scenario/src/facade/world_tx/scenario_env_deploy.rs @@ -12,11 +12,12 @@ use multiversx_sc::{ use crate::{ api::StaticApi, + scenario::tx_to_step::TxToStep, scenario_model::{AddressValue, BytesValue, ScCallStep, ScDeployStep, TxResponse}, ScenarioEnvExec, ScenarioTxEnv, ScenarioTxRun, ScenarioWorld, }; -use super::{scenario_env_util::*, ScenarioTxEnvData}; +use super::ScenarioTxEnvData; impl<'w, From, Payment, Gas, CodeValue, RH> ScenarioTxRun for Tx< @@ -39,11 +40,9 @@ where type Returns = ::Unpacked; fn run(self) -> Self::Returns { - let mut step = - tx_to_sc_deploy_step(&self.env, self.from, self.payment, self.gas, self.data); - step.expect = Some(self.result_handler.list_tx_expect()); - self.env.world.sc_deploy(&mut step); - process_result(step.response, self.result_handler) + let mut step_wrapper = self.tx_to_step(); + step_wrapper.env.world.sc_deploy(&mut step_wrapper.step); + step_wrapper.process_result() } } @@ -70,10 +69,11 @@ impl ScenarioWorld { let env = self.new_env_data(); let tx_base = TxBaseWithEnv::new_with_env(env); let tx = f(tx_base); - let mut step = tx_to_sc_deploy_step(&tx.env, tx.from, tx.payment, tx.gas, tx.data); - self.sc_deploy(&mut step); - step.expect = Some(tx.result_handler.list_tx_expect()); - process_result(step.response, tx.result_handler); + + let mut step_wrapper = tx.tx_to_step(); + self.sc_deploy(&mut step_wrapper.step); + step_wrapper.process_result(); + self } } diff --git a/framework/scenario/src/facade/world_tx/scenario_env_exec.rs b/framework/scenario/src/facade/world_tx/scenario_env_exec.rs index 8ea522c410..3c292bd650 100644 --- a/framework/scenario/src/facade/world_tx/scenario_env_exec.rs +++ b/framework/scenario/src/facade/world_tx/scenario_env_exec.rs @@ -12,11 +12,12 @@ use multiversx_sc::{ use crate::{ api::StaticApi, + scenario::tx_to_step::TxToStep, scenario_model::{AddressValue, BytesValue, ScCallStep, ScDeployStep, TxExpect, TxResponse}, ScenarioTxEnv, ScenarioTxRun, ScenarioWorld, }; -use super::{scenario_env_util::*, ScenarioTxEnvData}; +use super::ScenarioTxEnvData; /// Environment for executing transactions. pub struct ScenarioEnvExec<'w> { @@ -61,17 +62,9 @@ where type Returns = ::Unpacked; fn run(self) -> Self::Returns { - let mut step = tx_to_sc_call_step( - &self.env, - self.from, - self.to, - self.payment, - self.gas, - self.data, - ); - step.expect = Some(self.result_handler.list_tx_expect()); - self.env.world.sc_call(&mut step); - process_result(step.response, self.result_handler) + let mut step_wrapper = self.tx_to_step(); + step_wrapper.env.world.sc_call(&mut step_wrapper.step); + step_wrapper.process_result() } } @@ -97,10 +90,9 @@ impl ScenarioWorld { let env = self.new_env_data(); let tx_base = TxBaseWithEnv::new_with_env(env); let tx = f(tx_base); - let mut step = tx_to_sc_call_step(&tx.env, tx.from, tx.to, tx.payment, tx.gas, tx.data); - step.expect = Some(tx.result_handler.list_tx_expect()); - self.sc_call(&mut step); - process_result(step.response, tx.result_handler); + let mut step_wrapper = tx.tx_to_step(); + self.sc_call(&mut step_wrapper.step); + step_wrapper.process_result(); self } } diff --git a/framework/scenario/src/facade/world_tx/scenario_env_query.rs b/framework/scenario/src/facade/world_tx/scenario_env_query.rs index dac9e68d83..08246b0f81 100644 --- a/framework/scenario/src/facade/world_tx/scenario_env_query.rs +++ b/framework/scenario/src/facade/world_tx/scenario_env_query.rs @@ -10,12 +10,11 @@ use multiversx_sc::{ use crate::{ api::StaticApi, + scenario::tx_to_step::TxToQueryStep, scenario_model::{TxExpect, TxResponse}, ScenarioTxEnv, ScenarioTxEnvData, ScenarioTxRun, ScenarioWorld, }; -use super::scenario_env_util::*; - pub struct ScenarioEnvQuery<'w> { pub world: &'w mut ScenarioWorld, pub data: ScenarioTxEnvData, @@ -55,10 +54,9 @@ where type Returns = ::Unpacked; fn run(self) -> Self::Returns { - let mut step = tx_to_sc_query_step(&self.env, self.to, self.data); - step.expect = Some(self.result_handler.list_tx_expect()); - self.env.world.sc_query(&mut step); - process_result(step.response, self.result_handler) + let mut step_wrapper = self.tx_to_query_step(); + step_wrapper.env.world.sc_query(&mut step_wrapper.step); + step_wrapper.process_result() } } @@ -80,10 +78,9 @@ impl ScenarioWorld { let env = self.new_env_data(); let tx_base = TxBaseWithEnv::new_with_env(env); let tx = f(tx_base); - let mut step = tx_to_sc_query_step(&tx.env, tx.to, tx.data); - self.sc_query(&mut step); - step.expect = Some(tx.result_handler.list_tx_expect()); - process_result(step.response, tx.result_handler); + let mut step_wrapper = tx.tx_to_query_step(); + self.sc_query(&mut step_wrapper.step); + step_wrapper.process_result(); self } } diff --git a/framework/scenario/src/facade/world_tx/scenario_env_util.rs b/framework/scenario/src/facade/world_tx/scenario_env_util.rs deleted file mode 100644 index 8334b22cfb..0000000000 --- a/framework/scenario/src/facade/world_tx/scenario_env_util.rs +++ /dev/null @@ -1,175 +0,0 @@ -use multiversx_chain_scenario_format::serde_raw::ValueSubTree; -use multiversx_sc::{ - tuple_util::NestedTupleFlatten, - types::{ - AnnotatedValue, Code, DeployCall, FunctionCall, ManagedAddress, ManagedBuffer, RHListExec, - Tx, TxBaseWithEnv, TxCodeSource, TxCodeSourceSpecified, TxCodeValue, TxEnv, - TxFromSpecified, TxGas, TxGasValue, TxPayment, TxToSpecified, - }, -}; - -use crate::{ - api::StaticApi, - scenario_model::{ - AddressValue, BigUintValue, BytesValue, ScCallStep, ScDeployStep, ScQueryStep, - TransferStep, TxResponse, U64Value, - }, - ScenarioEnvExec, ScenarioWorld, -}; - -pub fn address_annotated(env: &Env, from: Addr) -> AddressValue -where - Env: TxEnv, - Addr: AnnotatedValue>, -{ - let annotation = from.annotation(env).to_string(); - AddressValue { - value: from.into_value(env).to_address(), - original: ValueSubTree::Str(annotation), - } -} - -pub fn code_annotated(env: &Env, code: Code) -> BytesValue -where - Env: TxEnv, - CodeValue: TxCodeValue, -{ - let annotation = code.0.annotation(env).to_string(); - BytesValue { - value: code.0.into_value(env).to_vec(), - original: ValueSubTree::Str(annotation), - } -} - -pub fn gas_annotated(env: &Env, gas: Gas) -> U64Value -where - Env: TxEnv, - Gas: TxGas, -{ - let annotation = gas.gas_annotation(env).to_string(); - U64Value { - value: gas.gas_value(env), - original: ValueSubTree::Str(annotation), - } -} - -pub fn tx_to_sc_call_step( - env: &Env, - from: From, - to: To, - payment: Payment, - gas: Gas, - data: FunctionCall, -) -> ScCallStep -where - Env: TxEnv, - From: TxFromSpecified, - To: TxToSpecified, - Payment: TxPayment, - Gas: TxGas, -{ - let mut step = ScCallStep::new() - .from(address_annotated(env, from)) - .to(address_annotated(env, to)) - .function(data.function_name.to_string().as_str()); - for arg in data.arg_buffer.iter_buffers() { - step.tx.arguments.push(arg.to_vec().into()); - } - - step.tx.gas_limit = gas_annotated(env, gas); - - let full_payment_data = payment.into_full_payment_data(env); - if let Some(annotated_egld_payment) = full_payment_data.egld { - step.tx.egld_value = annotated_egld_payment.into(); - } - - step -} - -pub fn tx_to_sc_deploy_step( - env: &Env, - from: From, - payment: Payment, - gas: Gas, - data: DeployCall>, -) -> ScDeployStep -where - Env: TxEnv, - From: TxFromSpecified, - Payment: TxPayment, - Gas: TxGas, - CodeValue: TxCodeValue, -{ - let mut step = ScDeployStep::new() - .from(address_annotated(env, from)) - .code(code_annotated(env, data.code_source)); - for arg in data.arg_buffer.iter_buffers() { - step.tx.arguments.push(arg.to_vec().into()); - } - - step.tx.gas_limit = gas_annotated(env, gas); - - let full_payment_data = payment.into_full_payment_data(env); - if let Some(annotated_egld_payment) = full_payment_data.egld { - step.tx.egld_value = annotated_egld_payment.into(); - } - - step -} - -pub fn tx_to_sc_query_step(env: &Env, to: To, data: FunctionCall) -> ScQueryStep -where - Env: TxEnv, - To: TxToSpecified, -{ - let mut step = ScQueryStep::new() - .to(address_annotated(env, to)) - .function(data.function_name.to_string().as_str()); - for arg in data.arg_buffer.iter_buffers() { - step.tx.arguments.push(arg.to_vec().into()); - } - - step -} - -pub fn tx_to_transfer_step( - env: &Env, - from: From, - to: To, - payment: Payment, - gas: Gas, -) -> TransferStep -where - Env: TxEnv, - From: TxFromSpecified, - To: TxToSpecified, - Payment: TxPayment, - Gas: TxGas, -{ - let mut step = TransferStep::new() - .from(address_annotated(env, from)) - .to(address_annotated(env, to)); - - step.tx.gas_limit = gas_annotated(env, gas); - - let full_payment_data = payment.into_full_payment_data(env); - if let Some(annotated_egld_payment) = full_payment_data.egld { - step.tx.egld_value = annotated_egld_payment.into(); - } - - step -} - -pub fn process_result( - response: Option, - result_handler: RH, -) -> ::Unpacked -where - Env: TxEnv, - RH: RHListExec, - RH::ListReturns: NestedTupleFlatten, -{ - let response = response.expect("step did not return result"); - let tuple_result = result_handler.list_process_result(&response); - tuple_result.flatten_unpack() -} diff --git a/framework/scenario/src/scenario/mod.rs b/framework/scenario/src/scenario.rs similarity index 91% rename from framework/scenario/src/scenario/mod.rs rename to framework/scenario/src/scenario.rs index 3ffd41300f..70f8f5f285 100644 --- a/framework/scenario/src/scenario/mod.rs +++ b/framework/scenario/src/scenario.rs @@ -4,6 +4,7 @@ pub mod run_list; pub mod run_trace; pub mod run_vm; mod scenario_runner; +pub mod tx_to_step; pub use parse_util::{parse_scenario, parse_scenario_raw}; pub use scenario_runner::ScenarioRunner; diff --git a/framework/scenario/src/scenario/tx_to_step.rs b/framework/scenario/src/scenario/tx_to_step.rs new file mode 100644 index 0000000000..601d4d9b71 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step.rs @@ -0,0 +1,11 @@ +mod step_annotation; +mod step_wrapper; +mod tx_to_step_call; +mod tx_to_step_deploy; +mod tx_to_step_query; +mod tx_to_step_trait; +mod tx_to_step_transfer; + +pub use step_annotation::*; +pub use step_wrapper::StepWrapper; +pub use tx_to_step_trait::*; diff --git a/framework/scenario/src/scenario/tx_to_step/step_annotation.rs b/framework/scenario/src/scenario/tx_to_step/step_annotation.rs new file mode 100644 index 0000000000..2defb50786 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/step_annotation.rs @@ -0,0 +1,40 @@ +use multiversx_chain_scenario_format::serde_raw::ValueSubTree; +use multiversx_sc::types::{AnnotatedValue, Code, ManagedAddress, TxCodeValue, TxEnv, TxGas}; + +use crate::scenario_model::{AddressValue, BytesValue, U64Value}; + +pub fn address_annotated(env: &Env, from: Addr) -> AddressValue +where + Env: TxEnv, + Addr: AnnotatedValue>, +{ + let annotation = from.annotation(env).to_string(); + AddressValue { + value: from.into_value(env).to_address(), + original: ValueSubTree::Str(annotation), + } +} + +pub fn code_annotated(env: &Env, code: Code) -> BytesValue +where + Env: TxEnv, + CodeValue: TxCodeValue, +{ + let annotation = code.0.annotation(env).to_string(); + BytesValue { + value: code.0.into_value(env).to_vec(), + original: ValueSubTree::Str(annotation), + } +} + +pub fn gas_annotated(env: &Env, gas: Gas) -> U64Value +where + Env: TxEnv, + Gas: TxGas, +{ + let annotation = gas.gas_annotation(env).to_string(); + U64Value { + value: gas.gas_value(env), + original: ValueSubTree::Str(annotation), + } +} diff --git a/framework/scenario/src/scenario/tx_to_step/step_wrapper.rs b/framework/scenario/src/scenario/tx_to_step/step_wrapper.rs new file mode 100644 index 0000000000..9d9a0199d5 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/step_wrapper.rs @@ -0,0 +1,48 @@ +use multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{RHListExec, TxEnv}, +}; + +use crate::scenario_model::{ScCallStep, ScDeployStep, ScQueryStep, TxResponse}; + +pub struct StepWrapper { + pub env: Env, + pub step: Step, + pub result_handler: RH, +} + +impl StepWrapper +where + Env: TxEnv, + Step: StepWithResponse, + RH: RHListExec, + RH::ListReturns: NestedTupleFlatten, +{ + pub fn process_result(self) -> ::Unpacked { + let response = self.step.into_response(); + let tuple_result = self.result_handler.list_process_result(&response); + tuple_result.flatten_unpack() + } +} + +pub trait StepWithResponse { + fn into_response(self) -> TxResponse; +} + +impl StepWithResponse for ScCallStep { + fn into_response(self) -> TxResponse { + self.response.expect("SC call step did not return result") + } +} + +impl StepWithResponse for ScDeployStep { + fn into_response(self) -> TxResponse { + self.response.expect("SC deploy step did not return result") + } +} + +impl StepWithResponse for ScQueryStep { + fn into_response(self) -> TxResponse { + self.response.expect("SC query step did not return result") + } +} 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 new file mode 100644 index 0000000000..dc4850b845 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs @@ -0,0 +1,75 @@ +use multiversx_sc::types::{ + FunctionCall, RHListExec, Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, TxToSpecified, +}; + +use crate::scenario_model::{ScCallStep, TxExpect, TxResponse}; + +use super::{address_annotated, gas_annotated, StepWrapper, TxToStep}; + +impl TxToStep + for Tx, RH> +where + Env: TxEnv, + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, + RH: RHListExec, +{ + type Env = Env; + + type Step = ScCallStep; + + type RH = RH; + + fn tx_to_step(self) -> StepWrapper { + let mut step = tx_to_sc_call_step( + &self.env, + self.from, + self.to, + self.payment, + self.gas, + self.data, + ); + step.expect = Some(self.result_handler.list_tx_expect()); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_sc_call_step( + env: &Env, + from: From, + to: To, + payment: Payment, + gas: Gas, + data: FunctionCall, +) -> ScCallStep +where + Env: TxEnv, + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, +{ + let mut step = ScCallStep::new() + .from(address_annotated(env, from)) + .to(address_annotated(env, to)) + .function(data.function_name.to_string().as_str()); + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step.tx.gas_limit = gas_annotated(env, gas); + + let full_payment_data = payment.into_full_payment_data(env); + if let Some(annotated_egld_payment) = full_payment_data.egld { + step.tx.egld_value = annotated_egld_payment.into(); + } + + step +} 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 new file mode 100644 index 0000000000..4378bbb682 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs @@ -0,0 +1,67 @@ +use multiversx_sc::types::{ + Code, DeployCall, RHListExec, Tx, TxCodeValue, TxEnv, TxFromSpecified, TxGas, TxPayment, +}; + +use crate::scenario_model::{ScDeployStep, TxExpect, TxResponse}; + +use super::{address_annotated, code_annotated, gas_annotated, StepWrapper, TxToStep}; + +impl TxToStep + for Tx>, RH> +where + Env: TxEnv, + From: TxFromSpecified, + Payment: TxPayment, + Gas: TxGas, + CodeValue: TxCodeValue, + RH: RHListExec, +{ + type Env = Env; + + type Step = ScDeployStep; + + type RH = RH; + + fn tx_to_step(self) -> StepWrapper { + let mut step = + tx_to_sc_deploy_step(&self.env, self.from, self.payment, self.gas, self.data); + step.expect = Some(self.result_handler.list_tx_expect()); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_sc_deploy_step( + env: &Env, + from: From, + payment: Payment, + gas: Gas, + data: DeployCall>, +) -> ScDeployStep +where + Env: TxEnv, + From: TxFromSpecified, + Payment: TxPayment, + Gas: TxGas, + CodeValue: TxCodeValue, +{ + let mut step = ScDeployStep::new() + .from(address_annotated(env, from)) + .code(code_annotated(env, data.code_source)); + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step.tx.gas_limit = gas_annotated(env, gas); + + let full_payment_data = payment.into_full_payment_data(env); + if let Some(annotated_egld_payment) = full_payment_data.egld { + step.tx.egld_value = annotated_egld_payment.into(); + } + + step +} diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_query.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_query.rs new file mode 100644 index 0000000000..427a8e62ce --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_query.rs @@ -0,0 +1,44 @@ +use multiversx_sc::types::{FunctionCall, RHListExec, Tx, TxEnv, TxToSpecified}; + +use crate::scenario_model::{ScQueryStep, TxExpect, TxResponse}; + +use super::{address_annotated, StepWrapper, TxToQueryStep}; + +impl TxToQueryStep for Tx, RH> +where + Env: TxEnv, + To: TxToSpecified, + RH: RHListExec, +{ + type Env = Env; + + type Step = ScQueryStep; + + type RH = RH; + + fn tx_to_query_step(self) -> StepWrapper { + let mut step = tx_to_sc_query_step(&self.env, self.to, self.data); + step.expect = Some(self.result_handler.list_tx_expect()); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_sc_query_step(env: &Env, to: To, data: FunctionCall) -> ScQueryStep +where + Env: TxEnv, + To: TxToSpecified, +{ + let mut step = ScQueryStep::new() + .to(address_annotated(env, to)) + .function(data.function_name.to_string().as_str()); + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step +} diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_trait.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_trait.rs new file mode 100644 index 0000000000..708e7c8eea --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_trait.rs @@ -0,0 +1,17 @@ +use super::StepWrapper; + +pub trait TxToStep { + type Env; + type Step; + type RH; + + fn tx_to_step(self) -> StepWrapper; +} + +pub trait TxToQueryStep { + type Env; + type Step; + type RH; + + fn tx_to_query_step(self) -> StepWrapper; +} diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs new file mode 100644 index 0000000000..c2f31e6ff4 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs @@ -0,0 +1,58 @@ +use multiversx_sc::types::{Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, TxToSpecified}; + +use crate::scenario_model::TransferStep; + +use super::{address_annotated, gas_annotated, StepWrapper, TxToStep}; + +impl TxToStep for Tx +where + Env: TxEnv, + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, +{ + type Env = Env; + + type Step = TransferStep; + + type RH = (); + + fn tx_to_step(self) -> StepWrapper { + let step = tx_to_transfer_step(&self.env, self.from, self.to, self.payment, self.gas); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_transfer_step( + env: &Env, + from: From, + to: To, + payment: Payment, + gas: Gas, +) -> TransferStep +where + Env: TxEnv, + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, +{ + let mut step = TransferStep::new() + .from(address_annotated(env, from)) + .to(address_annotated(env, to)); + + step.tx.gas_limit = gas_annotated(env, gas); + + let full_payment_data = payment.into_full_payment_data(env); + if let Some(annotated_egld_payment) = full_payment_data.egld { + step.tx.egld_value = annotated_egld_payment.into(); + } + + step +} diff --git a/framework/snippets/src/itx/interactor_env_deploy.rs b/framework/snippets/src/itx/interactor_env_deploy.rs index 6fdd9dfb48..bf5e8e61bc 100644 --- a/framework/snippets/src/itx/interactor_env_deploy.rs +++ b/framework/snippets/src/itx/interactor_env_deploy.rs @@ -10,7 +10,7 @@ use multiversx_sc_scenario::{ TxFromSpecified, TxGas, TxPayment, TxToSpecified, }, }, - scenario_env_util::*, + scenario::tx_to_step::{StepWrapper, TxToStep}, scenario_model::{AddressValue, BytesValue, ScCallStep, ScDeployStep, TxResponse}, ScenarioEnvExec, ScenarioTxEnv, ScenarioTxEnvData, ScenarioTxRun, ScenarioWorld, }; @@ -24,9 +24,7 @@ where RH: RHListExec>, RH::ListReturns: NestedTupleFlatten, { - world: &'w mut Interactor, - sc_deploy_step: ScDeployStep, - result_handler: RH, + step_wrapper: StepWrapper, ScDeployStep, RH>, } impl<'w, From, Payment, Gas, CodeValue, RH> InteractorPrepareAsync @@ -50,12 +48,8 @@ where type Exec = InteractorDeployStep<'w, RH>; fn prepare_async(self) -> Self::Exec { - let mut sc_deploy_step = - tx_to_sc_deploy_step(&self.env, self.from, self.payment, self.gas, self.data); InteractorDeployStep { - world: self.env.world, - sc_deploy_step, - result_handler: self.result_handler, + step_wrapper: self.tx_to_step(), } } } @@ -65,11 +59,13 @@ where RH: RHListExec>, RH::ListReturns: NestedTupleFlatten, { - pub async fn run(self) -> ::Unpacked { - let mut step = self.sc_deploy_step; - step.expect = Some(self.result_handler.list_tx_expect()); - self.world.sc_deploy(&mut step).await; - process_result(step.response, self.result_handler) + pub async fn run(mut self) -> ::Unpacked { + self.step_wrapper + .env + .world + .sc_deploy(&mut self.step_wrapper.step) + .await; + self.step_wrapper.process_result() } } @@ -96,10 +92,11 @@ impl Interactor { let env = self.new_env_data(); let tx_base = TxBaseWithEnv::new_with_env(env); let tx = f(tx_base); - let mut step = tx_to_sc_deploy_step(&tx.env, tx.from, tx.payment, tx.gas, tx.data); - step.expect = Some(tx.result_handler.list_tx_expect()); - self.sc_deploy(&mut step).await; - process_result(step.response, tx.result_handler); + + let mut step_wrapper = tx.tx_to_step(); + self.sc_deploy(&mut step_wrapper.step); + step_wrapper.process_result(); + self } @@ -129,9 +126,9 @@ impl Interactor { let env = self.new_env_data(); let tx_base = TxBaseWithEnv::new_with_env(env); let tx = f(tx_base); - let mut step = tx_to_sc_deploy_step(&tx.env, tx.from, tx.payment, tx.gas, tx.data); - step.expect = Some(tx.result_handler.list_tx_expect()); - self.sc_deploy(&mut step).await; - process_result(step.response, tx.result_handler) + + let mut step_wrapper = tx.tx_to_step(); + self.sc_deploy(&mut step_wrapper.step); + step_wrapper.process_result() } } diff --git a/framework/snippets/src/itx/interactor_env_exec.rs b/framework/snippets/src/itx/interactor_env_exec.rs index 235a580853..8e6b4dc69c 100644 --- a/framework/snippets/src/itx/interactor_env_exec.rs +++ b/framework/snippets/src/itx/interactor_env_exec.rs @@ -10,7 +10,7 @@ use multiversx_sc_scenario::{ TxFromSpecified, TxGas, TxPayment, TxToSpecified, }, }, - scenario_env_util::*, + scenario::tx_to_step::{StepWrapper, TxToStep}, scenario_model::{AddressValue, BytesValue, ScCallStep, ScDeployStep, TxExpect, TxResponse}, ScenarioTxEnv, ScenarioTxEnvData, ScenarioTxRun, ScenarioWorld, }; @@ -52,9 +52,7 @@ where RH: RHListExec>, RH::ListReturns: NestedTupleFlatten, { - world: &'w mut Interactor, - sc_call_step: ScCallStep, - result_handler: RH, + step_wrapper: StepWrapper, ScCallStep, RH>, } impl<'w, From, To, Payment, Gas, RH> InteractorPrepareAsync @@ -70,18 +68,8 @@ where type Exec = InteractorCallStep<'w, RH>; fn prepare_async(self) -> Self::Exec { - let mut sc_call_step = tx_to_sc_call_step( - &self.env, - self.from, - self.to, - self.payment, - self.gas, - self.data, - ); InteractorCallStep { - world: self.env.world, - sc_call_step, - result_handler: self.result_handler, + step_wrapper: self.tx_to_step(), } } } @@ -91,11 +79,13 @@ where RH: RHListExec>, RH::ListReturns: NestedTupleFlatten, { - pub async fn run(self) -> ::Unpacked { - let mut step = self.sc_call_step; - step.expect = Some(self.result_handler.list_tx_expect()); - self.world.sc_call(&mut step).await; - process_result(step.response, self.result_handler) + pub async fn run(mut self) -> ::Unpacked { + self.step_wrapper + .env + .world + .sc_call(&mut self.step_wrapper.step) + .await; + self.step_wrapper.process_result() } } @@ -121,10 +111,11 @@ impl Interactor { let env = self.new_env_data(); let tx_base = TxBaseWithEnv::new_with_env(env); let tx = f(tx_base); - let mut step = tx_to_sc_call_step(&tx.env, tx.from, tx.to, tx.payment, tx.gas, tx.data); - step.expect = Some(tx.result_handler.list_tx_expect()); - self.sc_call(&mut step).await; - process_result(step.response, tx.result_handler); + + let mut step_wrapper = tx.tx_to_step(); + self.sc_call(&mut step_wrapper.step).await; + step_wrapper.process_result(); + self } } diff --git a/framework/snippets/src/itx/interactor_env_query.rs b/framework/snippets/src/itx/interactor_env_query.rs index 052fc8cc12..881fc6b861 100644 --- a/framework/snippets/src/itx/interactor_env_query.rs +++ b/framework/snippets/src/itx/interactor_env_query.rs @@ -9,7 +9,7 @@ use multiversx_sc_scenario::{ TxBaseWithEnv, TxEnv, TxFromSpecified, TxGas, TxPayment, TxToSpecified, }, }, - scenario_env_util::*, + scenario::tx_to_step::{StepWrapper, TxToQueryStep}, scenario_model::{ScQueryStep, TxExpect, TxResponse}, ScenarioTxEnv, ScenarioTxEnvData, ScenarioTxRun, ScenarioWorld, }; @@ -50,9 +50,7 @@ where RH: RHListExec>, RH::ListReturns: NestedTupleFlatten, { - world: &'w mut Interactor, - sc_query_step: ScQueryStep, - result_handler: RH, + step_wrapper: StepWrapper, ScQueryStep, RH>, } impl<'w, To, RH> InteractorPrepareAsync @@ -65,11 +63,8 @@ where type Exec = InteractorQueryStep<'w, RH>; fn prepare_async(self) -> Self::Exec { - let mut sc_query_step = tx_to_sc_query_step(&self.env, self.to, self.data); InteractorQueryStep { - world: self.env.world, - sc_query_step, - result_handler: self.result_handler, + step_wrapper: self.tx_to_query_step(), } } } @@ -79,11 +74,13 @@ where RH: RHListExec>, RH::ListReturns: NestedTupleFlatten, { - pub async fn run(self) -> ::Unpacked { - let mut step = self.sc_query_step; - step.expect = Some(self.result_handler.list_tx_expect()); - self.world.sc_query(&mut step).await; - process_result(step.response, self.result_handler) + pub async fn run(mut self) -> ::Unpacked { + self.step_wrapper + .env + .world + .sc_query(&mut self.step_wrapper.step) + .await; + self.step_wrapper.process_result() } } @@ -105,10 +102,15 @@ impl Interactor { let env = self.new_env_data(); let tx_base = TxBaseWithEnv::new_with_env(env); let tx = f(tx_base); - let mut step = tx_to_sc_query_step(&tx.env, tx.to, tx.data); - step.expect = Some(tx.result_handler.list_tx_expect()); - self.sc_query(&mut step).await; - process_result(step.response, tx.result_handler); + + let mut step_wrapper = tx.tx_to_query_step(); + self.sc_query(&mut step_wrapper.step).await; + step_wrapper.process_result(); + + // let mut step = tx_to_sc_query_step(&tx.env, tx.to, tx.data); + // step.expect = Some(tx.result_handler.list_tx_expect()); + // self.sc_query(&mut step).await; + // process_result(step.response, tx.result_handler); self } } diff --git a/framework/snippets/src/itx/interactor_env_transf.rs b/framework/snippets/src/itx/interactor_env_transf.rs index 19a161b18f..33b977dbac 100644 --- a/framework/snippets/src/itx/interactor_env_transf.rs +++ b/framework/snippets/src/itx/interactor_env_transf.rs @@ -10,7 +10,7 @@ use multiversx_sc_scenario::{ TxFromSpecified, TxGas, TxPayment, TxToSpecified, }, }, - scenario_env_util::*, + scenario::tx_to_step::{StepWrapper, TxToStep}, scenario_model::{ AddressValue, BytesValue, ScCallStep, ScDeployStep, TransferStep, TxResponse, }, @@ -20,8 +20,7 @@ use multiversx_sc_scenario::{ use crate::{Interactor, InteractorEnvExec, InteractorPrepareAsync}; pub struct InteractorTransferStep<'w> { - world: &'w mut Interactor, - step: TransferStep, + step_wrapper: StepWrapper, TransferStep, ()>, } impl<'w, From, To, Payment, Gas> InteractorPrepareAsync @@ -35,17 +34,18 @@ where type Exec = InteractorTransferStep<'w>; fn prepare_async(self) -> Self::Exec { - let mut sc_call_step = - tx_to_transfer_step(&self.env, self.from, self.to, self.payment, self.gas); InteractorTransferStep { - world: self.env.world, - step: sc_call_step, + step_wrapper: self.tx_to_step(), } } } impl<'w> InteractorTransferStep<'w> { - pub async fn run(self) { - self.world.transfer(self.step).await; + pub async fn run(mut self) { + self.step_wrapper + .env + .world + .transfer(self.step_wrapper.step) + .await; } }