1use iota_types::{
6 error::ExecutionError, execution::ExecutionResult, transaction::Argument, transfer::Receiving,
7};
8use move_core_types::language_storage::TypeTag;
9
10use crate::{
11 execution_value::{RawValueType, Value},
12 type_resolver::TypeTagResolver,
13};
14
15pub type TransactionIndex = usize;
16
17pub trait ExecutionMode {
18 type ArgumentUpdates;
20 type ExecutionResults;
22
23 fn allow_arbitrary_function_calls() -> bool;
25
26 fn allow_arbitrary_values() -> bool;
30
31 fn skip_conservation_checks() -> bool;
33
34 fn packages_are_predefined() -> bool;
37
38 fn empty_arguments() -> Self::ArgumentUpdates;
39
40 fn empty_results() -> Self::ExecutionResults;
41
42 fn add_argument_update(
43 resolver: &impl TypeTagResolver,
44 acc: &mut Self::ArgumentUpdates,
45 arg: Argument,
46 _new_value: &Value,
47 ) -> Result<(), ExecutionError>;
48
49 fn finish_command(
50 resolver: &impl TypeTagResolver,
51 acc: &mut Self::ExecutionResults,
52 argument_updates: Self::ArgumentUpdates,
53 command_result: &[Value],
54 ) -> Result<(), ExecutionError>;
55
56 fn allow_auth_context() -> bool;
59}
60
61#[derive(Copy, Clone)]
62pub struct Normal;
63
64impl ExecutionMode for Normal {
65 type ArgumentUpdates = ();
66 type ExecutionResults = ();
67
68 fn allow_arbitrary_function_calls() -> bool {
69 false
70 }
71
72 fn allow_arbitrary_values() -> bool {
73 false
74 }
75
76 fn skip_conservation_checks() -> bool {
77 false
78 }
79
80 fn packages_are_predefined() -> bool {
81 false
82 }
83
84 fn empty_arguments() -> Self::ArgumentUpdates {}
85
86 fn empty_results() -> Self::ExecutionResults {}
87
88 fn add_argument_update(
89 _resolver: &impl TypeTagResolver,
90 _acc: &mut Self::ArgumentUpdates,
91 _arg: Argument,
92 _new_value: &Value,
93 ) -> Result<(), ExecutionError> {
94 Ok(())
95 }
96
97 fn finish_command(
98 _resolver: &impl TypeTagResolver,
99 _acc: &mut Self::ExecutionResults,
100 _argument_updates: Self::ArgumentUpdates,
101 _command_result: &[Value],
102 ) -> Result<(), ExecutionError> {
103 Ok(())
104 }
105
106 fn allow_auth_context() -> bool {
107 false
108 }
109}
110
111#[derive(Copy, Clone)]
112pub struct Genesis;
113
114impl ExecutionMode for Genesis {
115 type ArgumentUpdates = ();
116 type ExecutionResults = ();
117
118 fn allow_arbitrary_function_calls() -> bool {
119 true
120 }
121
122 fn allow_arbitrary_values() -> bool {
123 true
124 }
125
126 fn packages_are_predefined() -> bool {
127 true
128 }
129
130 fn skip_conservation_checks() -> bool {
131 false
132 }
133
134 fn empty_arguments() -> Self::ArgumentUpdates {}
135
136 fn empty_results() -> Self::ExecutionResults {}
137
138 fn add_argument_update(
139 _resolver: &impl TypeTagResolver,
140 _acc: &mut Self::ArgumentUpdates,
141 _arg: Argument,
142 _new_value: &Value,
143 ) -> Result<(), ExecutionError> {
144 Ok(())
145 }
146
147 fn finish_command(
148 _resolver: &impl TypeTagResolver,
149 _acc: &mut Self::ExecutionResults,
150 _argument_updates: Self::ArgumentUpdates,
151 _command_result: &[Value],
152 ) -> Result<(), ExecutionError> {
153 Ok(())
154 }
155
156 fn allow_auth_context() -> bool {
157 false
158 }
159}
160
161#[derive(Copy, Clone)]
162pub struct System;
163
164impl ExecutionMode for System {
168 type ArgumentUpdates = ();
169 type ExecutionResults = ();
170
171 fn allow_arbitrary_function_calls() -> bool {
172 true
174 }
175
176 fn allow_arbitrary_values() -> bool {
177 true
180 }
181
182 fn skip_conservation_checks() -> bool {
183 false
184 }
185
186 fn packages_are_predefined() -> bool {
187 true
188 }
189
190 fn empty_arguments() -> Self::ArgumentUpdates {}
191
192 fn empty_results() -> Self::ExecutionResults {}
193
194 fn add_argument_update(
195 _resolver: &impl TypeTagResolver,
196 _acc: &mut Self::ArgumentUpdates,
197 _arg: Argument,
198 _new_value: &Value,
199 ) -> Result<(), ExecutionError> {
200 Ok(())
201 }
202
203 fn finish_command(
204 _resolver: &impl TypeTagResolver,
205 _acc: &mut Self::ExecutionResults,
206 _argument_updates: Self::ArgumentUpdates,
207 _command_result: &[Value],
208 ) -> Result<(), ExecutionError> {
209 Ok(())
210 }
211
212 fn allow_auth_context() -> bool {
213 false
214 }
215}
216
217#[derive(Copy, Clone)]
218pub struct Authentication;
219
220impl ExecutionMode for Authentication {
221 type ArgumentUpdates = ();
222 type ExecutionResults = ();
223
224 fn allow_arbitrary_function_calls() -> bool {
225 false
226 }
227
228 fn allow_arbitrary_values() -> bool {
229 false
230 }
231
232 fn skip_conservation_checks() -> bool {
233 false
234 }
235
236 fn packages_are_predefined() -> bool {
237 false
238 }
239
240 fn empty_arguments() -> Self::ArgumentUpdates {}
241
242 fn empty_results() -> Self::ExecutionResults {}
243
244 fn add_argument_update(
245 _resolver: &impl TypeTagResolver,
246 _acc: &mut Self::ArgumentUpdates,
247 _arg: Argument,
248 _new_value: &Value,
249 ) -> Result<(), ExecutionError> {
250 Ok(())
251 }
252
253 fn finish_command(
254 _resolver: &impl TypeTagResolver,
255 _acc: &mut Self::ExecutionResults,
256 _argument_updates: Self::ArgumentUpdates,
257 _command_result: &[Value],
258 ) -> Result<(), ExecutionError> {
259 Ok(())
260 }
261
262 fn allow_auth_context() -> bool {
263 true
264 }
265}
266
267pub struct DevInspect<const SKIP_ALL_CHECKS: bool>;
271
272impl<const SKIP_ALL_CHECKS: bool> ExecutionMode for DevInspect<SKIP_ALL_CHECKS> {
273 type ArgumentUpdates = Vec<(Argument, Vec<u8>, TypeTag)>;
274 type ExecutionResults = Vec<ExecutionResult>;
275
276 fn allow_arbitrary_function_calls() -> bool {
277 SKIP_ALL_CHECKS
278 }
279
280 fn allow_arbitrary_values() -> bool {
281 SKIP_ALL_CHECKS
282 }
283
284 fn skip_conservation_checks() -> bool {
285 SKIP_ALL_CHECKS
286 }
287
288 fn packages_are_predefined() -> bool {
289 false
290 }
291
292 fn empty_arguments() -> Self::ArgumentUpdates {
293 vec![]
294 }
295
296 fn empty_results() -> Self::ExecutionResults {
297 vec![]
298 }
299
300 fn add_argument_update(
301 resolver: &impl TypeTagResolver,
302 acc: &mut Self::ArgumentUpdates,
303 arg: Argument,
304 new_value: &Value,
305 ) -> Result<(), ExecutionError> {
306 let (bytes, type_tag) = value_to_bytes_and_tag(resolver, new_value)?;
307 acc.push((arg, bytes, type_tag));
308 Ok(())
309 }
310
311 fn finish_command(
312 resolver: &impl TypeTagResolver,
313 acc: &mut Self::ExecutionResults,
314 argument_updates: Self::ArgumentUpdates,
315 command_result: &[Value],
316 ) -> Result<(), ExecutionError> {
317 let command_bytes = command_result
318 .iter()
319 .map(|value| value_to_bytes_and_tag(resolver, value))
320 .collect::<Result<_, _>>()?;
321 acc.push((argument_updates, command_bytes));
322 Ok(())
323 }
324
325 fn allow_auth_context() -> bool {
326 false
327 }
328}
329
330fn value_to_bytes_and_tag(
331 resolver: &impl TypeTagResolver,
332 value: &Value,
333) -> Result<(Vec<u8>, TypeTag), ExecutionError> {
334 let (type_tag, bytes) = match value {
335 Value::Object(obj) => {
336 let tag = resolver.get_type_tag(&obj.type_)?;
337 let mut bytes = vec![];
338 obj.write_bcs_bytes(&mut bytes, None)?;
339 (tag, bytes)
340 }
341 Value::Raw(RawValueType::Any, bytes) => {
342 (TypeTag::Vector(Box::new(TypeTag::U8)), bytes.clone())
344 }
345 Value::Raw(RawValueType::Loaded { ty, .. }, bytes) => {
346 let tag = resolver.get_type_tag(ty)?;
347 (tag, bytes.clone())
348 }
349 Value::Receiving(id, seqno, _) => (
350 Receiving::type_tag(),
351 Receiving::new(*id, *seqno).to_bcs_bytes(),
352 ),
353 };
354 Ok((bytes, type_tag))
355}