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 vm_go() -> Self {
65 ScenarioWorld {
66 current_dir: std::env::current_dir().unwrap(),
67 backend: Backend::VmGoBackend,
68 }
69 }
70
71 pub fn run<P: AsRef<Path>>(self, relative_path: P) {
75 let mut absolute_path = self.current_dir.clone();
76 absolute_path.push(relative_path);
77 match self.backend {
78 Backend::Debugger(mut debugger) => {
79 debugger.run_scenario_file(&absolute_path);
80 }
81 Backend::VmGoBackend => {
82 run_mx_scenario_go(&absolute_path);
83 }
84 }
85 }
86
87 pub(crate) fn get_debugger_backend(&self) -> &DebuggerBackend {
88 if let Backend::Debugger(debugger) = &self.backend {
89 debugger
90 } else {
91 panic!("operation only available for the contract debugger backend")
92 }
93 }
94
95 pub(crate) fn get_mut_debugger_backend(&mut self) -> &mut DebuggerBackend {
96 if let Backend::Debugger(debugger) = &mut self.backend {
97 debugger
98 } else {
99 panic!("operation only available for the contract debugger backend")
100 }
101 }
102
103 pub(crate) fn get_state(&self) -> &BlockchainState {
104 &self.get_debugger_backend().vm_runner.blockchain_mock.state
105 }
106
107 pub(crate) fn get_mut_state(&mut self) -> &mut BlockchainState {
108 &mut self
109 .get_mut_debugger_backend()
110 .vm_runner
111 .blockchain_mock
112 .state
113 }
114
115 pub fn start_trace(&mut self) -> &mut Self {
116 self.get_mut_debugger_backend().trace = Some(ScenarioTrace::default());
117 self
118 }
119
120 pub fn set_current_dir_from_workspace(&mut self, relative_path: &str) -> &mut Self {
123 let mut path = find_current_workspace().unwrap();
124 path.push(relative_path);
125 self.current_dir = path;
126 self
127 }
128
129 pub fn current_dir(&self) -> &PathBuf {
130 &self.current_dir
131 }
132
133 pub fn write_scenario_trace<P: AsRef<Path>>(&mut self, file_path: P) {
135 if let Some(trace) = &mut self.get_mut_debugger_backend().trace {
136 trace.write_scenario_trace(file_path);
137 } else {
138 panic!("scenario trace no initialized")
139 }
140 }
141
142 #[deprecated(
143 since = "0.39.0",
144 note = "Renamed, use `write_scenario_trace` instead."
145 )]
146 pub fn write_mandos_trace<P: AsRef<Path>>(&mut self, file_path: P) {
147 self.write_scenario_trace(file_path);
148 }
149
150 #[cfg(feature = "bls")]
151 pub fn create_aggregated_signature(
152 &mut self,
153 pk_size: usize,
154 message: &[u8],
155 ) -> Result<
156 (multiversx_chain_vm::G1, Vec<multiversx_chain_vm::G2>),
157 multiversx_chain_vm::BlsError,
158 > {
159 multiversx_chain_vm::crypto_functions_bls::create_aggregated_signature(pk_size, message)
160 }
161}