multiversx_sc_scenario/scenario/run_vm/
vm_runner.rs

1use multiversx_chain_vm::{
2    executor_impl::new_experimental_executor,
3    host::runtime::{Runtime, RuntimeRef, RuntimeWeakRef},
4};
5use multiversx_chain_vm_executor::Executor;
6
7use crate::{
8    executor::{
9        composite::CompositeExecutor,
10        debug::{ContractDebugExecutor, ContractMapRef},
11    },
12    multiversx_chain_vm::BlockchainMock,
13    scenario::{model::*, ScenarioRunner},
14};
15
16use super::ExecutorConfig;
17
18/// Wraps calls to the blockchain mock,
19/// while implementing the StepRunner interface.
20#[derive(Default, Debug)]
21pub struct ScenarioVMRunner {
22    pub contract_map_ref: ContractMapRef,
23    pub blockchain_mock: BlockchainMock,
24    pub executor_config: ExecutorConfig,
25}
26
27impl ScenarioVMRunner {
28    pub fn new() -> Self {
29        let contract_map_ref = ContractMapRef::new();
30        let blockchain_mock = BlockchainMock::default();
31        ScenarioVMRunner {
32            contract_map_ref,
33            blockchain_mock,
34            executor_config: ExecutorConfig::default(),
35        }
36    }
37
38    fn create_executor(
39        &self,
40        config: &ExecutorConfig,
41        weak: RuntimeWeakRef,
42    ) -> Box<dyn Executor + Send + Sync> {
43        match config {
44            ExecutorConfig::Debugger => Box::new(ContractDebugExecutor::new(
45                weak,
46                self.contract_map_ref.clone(),
47            )),
48            ExecutorConfig::Custom(f) => f(weak),
49            ExecutorConfig::Experimental => new_experimental_executor(weak),
50            ExecutorConfig::CompiledFeatureIfElse {
51                if_compiled,
52                fallback,
53            } => {
54                if cfg!(feature = "compiled-sc-tests") {
55                    self.create_executor(if_compiled, weak)
56                } else {
57                    self.create_executor(fallback, weak)
58                }
59            }
60            ExecutorConfig::Composite(list) => Box::new(CompositeExecutor::new(
61                list.iter()
62                    .map(|sub_config| self.create_executor(sub_config, weak.clone()))
63                    .collect(),
64            )),
65        }
66    }
67
68    pub fn create_debugger_runtime(&self) -> RuntimeRef {
69        RuntimeRef::new_cyclic(|weak| {
70            let executor = self.create_executor(&self.executor_config, weak);
71            Runtime::new(self.blockchain_mock.vm.clone(), executor)
72        })
73    }
74}
75
76impl ScenarioRunner for ScenarioVMRunner {
77    fn run_external_steps(&mut self, _step: &ExternalStepsStep) {
78        panic!("cannot call directly as such")
79    }
80
81    fn run_set_state_step(&mut self, step: &SetStateStep) {
82        self.perform_set_state(step);
83    }
84
85    fn run_sc_call_step(&mut self, step: &mut ScCallStep) {
86        self.perform_sc_call_update_results(step);
87    }
88
89    fn run_multi_sc_call_step(&mut self, steps: &mut [ScCallStep]) {
90        for step in steps {
91            self.perform_sc_call_update_results(step);
92        }
93    }
94
95    fn run_multi_sc_deploy_step(&mut self, steps: &mut [ScDeployStep]) {
96        for step in steps.iter_mut() {
97            self.perform_sc_deploy_update_results(step);
98        }
99    }
100
101    fn run_sc_query_step(&mut self, step: &mut ScQueryStep) {
102        self.perform_sc_query_update_results(step);
103    }
104
105    fn run_sc_deploy_step(&mut self, step: &mut ScDeployStep) {
106        self.perform_sc_deploy_update_results(step);
107    }
108
109    fn run_transfer_step(&mut self, step: &TransferStep) {
110        self.perform_transfer(step);
111    }
112
113    fn run_validator_reward_step(&mut self, step: &ValidatorRewardStep) {
114        self.perform_validator_reward(step);
115    }
116
117    fn run_check_state_step(&mut self, step: &CheckStateStep) {
118        self.perform_check_state(step);
119    }
120
121    fn run_dump_state_step(&mut self) {
122        self.perform_dump_state();
123    }
124}