diff --git a/contracts/examples/adder/tests/adder_blackbox_test.rs b/contracts/examples/adder/tests/adder_blackbox_test.rs index 73d6fecd5f..9f155c4e3a 100644 --- a/contracts/examples/adder/tests/adder_blackbox_test.rs +++ b/contracts/examples/adder/tests/adder_blackbox_test.rs @@ -63,5 +63,18 @@ fn adder_blackbox() { .check_account(ADDER_ADDRESS) .check_storage("str:sum", "6"); + world + .tx() + .from(OWNER_ADDRESS) + .to(ADDER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .upgrade(100u64) + .code(CODE_PATH) + .run(); + + world + .check_account(ADDER_ADDRESS) + .check_storage("str:sum", "100"); + world.write_scenario_trace("trace1.scen.json"); } 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 42a29ef378..8905c7d14d 100644 --- a/framework/scenario/src/facade/world_tx/scenario_exec_call.rs +++ b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs @@ -1,14 +1,15 @@ use multiversx_sc::{ tuple_util::NestedTupleFlatten, types::{ - heap::H256, FunctionCall, ManagedAddress, ManagedBuffer, RHListExec, Tx, TxBaseWithEnv, - TxEnv, TxEnvMockDeployAddress, TxEnvWithTxHash, TxFromSpecified, TxGas, TxPayment, - TxToSpecified, + heap::H256, Code, FunctionCall, ManagedAddress, ManagedBuffer, NotPayable, RHListExec, Tx, + TxBaseWithEnv, TxEnv, TxEnvMockDeployAddress, TxEnvWithTxHash, TxFromSpecified, TxGas, + TxPayment, TxToSpecified, UpgradeCall, }, }; use crate::{ api::StaticApi, + imports::MxscPath, scenario::tx_to_step::{address_annotated, TxToStep}, scenario_model::{SetStateStep, TxExpect, TxResponse}, ScenarioTxEnv, ScenarioTxRun, ScenarioWorld, @@ -90,6 +91,32 @@ where } } +impl<'w, From, To, RH> ScenarioTxRun + for Tx< + ScenarioEnvExec<'w>, + From, + To, + NotPayable, + (), + UpgradeCall, Code>>, + RH, + > +where + From: TxFromSpecified>, + To: TxToSpecified>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + 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() + } +} + 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"); 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 7daa8ac810..475326eac7 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,8 +1,13 @@ use multiversx_sc::types::{ - FunctionCall, RHListExec, Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, TxToSpecified, + Code, FunctionCall, NotPayable, RHListExec, Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, + TxToSpecified, UpgradeCall, }; -use crate::scenario_model::{ScCallStep, TxESDT, TxExpect, TxResponse}; +use crate::{ + imports::MxscPath, + scenario_model::{ScCallStep, TxESDT, TxExpect, TxResponse}, + ScenarioEnvExec, +}; use super::{address_annotated, gas_annotated, StepWrapper, TxToStep}; @@ -75,3 +80,53 @@ where step } + +impl<'w, From, To, RH> TxToStep, RH> + for Tx< + ScenarioEnvExec<'w>, + From, + To, + NotPayable, + (), + UpgradeCall, Code>>, + RH, + > +where + From: TxFromSpecified>, + To: TxToSpecified>, + RH: RHListExec>, +{ + type Step = ScCallStep; + + fn tx_to_step(self) -> StepWrapper, Self::Step, RH> { + let mut step = tx_to_sc_call_upgrade_step(&self.env, self.from, 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_call_upgrade_step<'a, 'w: 'a, From, To>( + env: &'a ScenarioEnvExec<'w>, + from: From, + to: To, + data: UpgradeCall, Code>, +) -> ScCallStep +where + From: TxFromSpecified>, + To: TxToSpecified>, +{ + let mut step = ScCallStep::new() + .from(address_annotated(env, &from)) + .to(address_annotated(env, &to)) + .function("upgrade"); + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step +}