multiversx_sc_scenario/facade/
scenario_world.rs1use multiversx_chain_vm::{blockchain::state::BlockchainState, schedule::GasScheduleVersion};
2
3use crate::{
4 scenario::{
5 run_trace::ScenarioTrace,
6 run_vm::{ExecutorConfig, ScenarioVMRunner},
7 },
8 vm_go_tool::run_mx_scenario_go,
9};
10use multiversx_sc_meta_lib::tools::find_current_workspace;
11use std::path::{Path, PathBuf};
12
13use super::debugger_backend::DebuggerBackend;
14
15pub struct ScenarioWorld {
22 pub(crate) current_dir: PathBuf,
23 pub(crate) backend: Backend,
24}
25
26pub(crate) enum Backend {
27 Debugger(Box<DebuggerBackend>),
28 VmGoBackend,
29}
30
31impl Default for ScenarioWorld {
32 fn default() -> Self {
33 Self::debugger()
34 }
35}
36
37impl ScenarioWorld {
38 pub fn debugger() -> Self {
39 ScenarioWorld {
40 current_dir: std::env::current_dir().unwrap(),
41 backend: Backend::Debugger(Box::new(DebuggerBackend {
42 vm_runner: ScenarioVMRunner::new(),
43 trace: None,
44 })),
45 }
46 }
47
48 pub fn new() -> Self {
50 Self::debugger()
51 }
52
53 pub fn executor_config(mut self, config: ExecutorConfig) -> Self {
54 self.get_mut_debugger_backend().vm_runner.executor_config = config;
55 self
56 }
57
58 pub fn gas_schedule(mut self, gas_schedule: GasScheduleVersion) -> Self {
59 let vm = &mut self.get_mut_debugger_backend().vm_runner.blockchain_mock.vm;
60 vm.change_gas_schedule(gas_schedule.load_gas_schedule());
61 self
62 }
63
64 pub fn insert_ghost_accounts(mut self) -> Self {
68 let vm = &mut self.get_mut_debugger_backend().vm_runner.blockchain_mock.vm;
69 vm.set_insert_ghost_accounts(true);
70 self
71 }
72
73 pub fn vm_go() -> Self {
74 ScenarioWorld {
75 current_dir: std::env::current_dir().unwrap(),
76 backend: Backend::VmGoBackend,
77 }
78 }
79
80 pub fn run<P: AsRef<Path>>(self, relative_path: P) {
84 let mut absolute_path = self.current_dir.clone();
85 absolute_path.push(relative_path);
86 match self.backend {
87 Backend::Debugger(mut debugger) => {
88 debugger.run_scenario_file(&absolute_path);
89 }
90 Backend::VmGoBackend => {
91 run_mx_scenario_go(&absolute_path);
92 }
93 }
94 }
95
96 pub(crate) fn get_debugger_backend(&self) -> &DebuggerBackend {
97 if let Backend::Debugger(debugger) = &self.backend {
98 debugger
99 } else {
100 panic!("operation only available for the contract debugger backend")
101 }
102 }
103
104 pub(crate) fn get_mut_debugger_backend(&mut self) -> &mut DebuggerBackend {
105 if let Backend::Debugger(debugger) = &mut self.backend {
106 debugger
107 } else {
108 panic!("operation only available for the contract debugger backend")
109 }
110 }
111
112 pub(crate) fn get_state(&self) -> &BlockchainState {
113 &self.get_debugger_backend().vm_runner.blockchain_mock.state
114 }
115
116 pub(crate) fn get_mut_state(&mut self) -> &mut BlockchainState {
117 &mut self
118 .get_mut_debugger_backend()
119 .vm_runner
120 .blockchain_mock
121 .state
122 }
123
124 pub fn start_trace(&mut self) -> &mut Self {
125 self.get_mut_debugger_backend().trace = Some(ScenarioTrace::default());
126 self
127 }
128
129 pub fn set_current_dir_from_workspace(&mut self, relative_path: &str) -> &mut Self {
132 let mut path = find_current_workspace().unwrap();
133 path.push(relative_path);
134 self.current_dir = path;
135 self
136 }
137
138 pub fn current_dir(&self) -> &PathBuf {
139 &self.current_dir
140 }
141
142 pub fn write_scenario_trace<P: AsRef<Path>>(&mut self, file_path: P) {
144 if let Some(trace) = &mut self.get_mut_debugger_backend().trace {
145 trace.write_scenario_trace(file_path);
146 } else {
147 panic!("scenario trace no initialized")
148 }
149 }
150
151 #[deprecated(
152 since = "0.39.0",
153 note = "Renamed, use `write_scenario_trace` instead."
154 )]
155 pub fn write_mandos_trace<P: AsRef<Path>>(&mut self, file_path: P) {
156 self.write_scenario_trace(file_path);
157 }
158
159 #[cfg(feature = "bls")]
160 pub fn create_aggregated_signature(
161 &mut self,
162 pk_size: usize,
163 message: &[u8],
164 ) -> Result<
165 (multiversx_chain_vm::G1, Vec<multiversx_chain_vm::G2>),
166 multiversx_chain_vm::BlsError,
167 > {
168 multiversx_chain_vm::crypto_functions_bls::create_aggregated_signature(pk_size, message)
169 }
170}