sui_adapter_latest/
execution_mode.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use move_core_types::language_storage::TypeTag;
5use std::marker::PhantomData;
6use sui_types::error::{ExecutionError, ExecutionErrorTrait};
7use sui_types::execution_status::ExecutionFailure;
8use sui_types::{execution::ExecutionResult, transaction::Argument};
9
10pub type TransactionIndex = usize;
11
12pub trait ExecutionMode {
13    /// All updates to a Arguments used in that Command
14    type ArgumentUpdates;
15    /// the gathered results from batched executions
16    type ExecutionResults;
17    /// The error type produced during execution
18    type Error: ExecutionErrorTrait;
19
20    /// Controls the calling of arbitrary Move functions
21    fn allow_arbitrary_function_calls() -> bool;
22
23    /// Controls the ability to instantiate any Move function parameter with a Pure call arg.
24    ///  In other words, you can instantiate any struct or object or other value with its BCS byte
25    fn allow_arbitrary_values() -> bool;
26
27    /// Do not perform conservation checks after execution.
28    fn skip_conservation_checks() -> bool;
29
30    /// If not set, the package ID should be calculated like an object and an
31    /// UpgradeCap is produced
32    fn packages_are_predefined() -> bool;
33
34    fn empty_results() -> Self::ExecutionResults;
35
36    const TRACK_EXECUTION: bool;
37
38    fn add_argument_update(
39        acc: &mut Self::ArgumentUpdates,
40        arg: Argument,
41        bytes: Vec<u8>,
42        type_: TypeTag,
43    ) -> Result<(), ExecutionError>;
44
45    fn finish_command(
46        acc: &mut Self::ExecutionResults,
47        argument_updates: Vec<(Argument, Vec<u8>, TypeTag)>,
48        command_result: Vec<(Vec<u8>, TypeTag)>,
49    ) -> Result<(), ExecutionError>;
50}
51
52#[derive(Copy, Clone)]
53pub struct Normal<E = ExecutionFailure>(PhantomData<fn() -> E>);
54
55impl<E> ExecutionMode for Normal<E>
56where
57    E: ExecutionErrorTrait,
58{
59    type ArgumentUpdates = ();
60    type ExecutionResults = ();
61    type Error = E;
62
63    fn allow_arbitrary_function_calls() -> bool {
64        false
65    }
66
67    fn allow_arbitrary_values() -> bool {
68        false
69    }
70
71    fn skip_conservation_checks() -> bool {
72        false
73    }
74
75    fn packages_are_predefined() -> bool {
76        false
77    }
78
79    fn empty_results() -> Self::ExecutionResults {}
80
81    const TRACK_EXECUTION: bool = false;
82
83    fn add_argument_update(
84        _acc: &mut Self::ArgumentUpdates,
85        _arg: Argument,
86        _bytes: Vec<u8>,
87        _type_: TypeTag,
88    ) -> Result<(), ExecutionError> {
89        invariant_violation!("should not be called");
90    }
91
92    fn finish_command(
93        _acc: &mut Self::ExecutionResults,
94        _argument_updates: Vec<(Argument, Vec<u8>, TypeTag)>,
95        _command_result: Vec<(Vec<u8>, TypeTag)>,
96    ) -> Result<(), ExecutionError> {
97        invariant_violation!("should not be called");
98    }
99}
100
101#[derive(Copy, Clone)]
102pub struct Genesis;
103
104impl ExecutionMode for Genesis {
105    type ArgumentUpdates = ();
106    type ExecutionResults = ();
107    type Error = ExecutionError;
108
109    fn allow_arbitrary_function_calls() -> bool {
110        true
111    }
112
113    fn allow_arbitrary_values() -> bool {
114        true
115    }
116
117    fn packages_are_predefined() -> bool {
118        true
119    }
120
121    fn skip_conservation_checks() -> bool {
122        false
123    }
124
125    fn empty_results() -> Self::ExecutionResults {}
126
127    const TRACK_EXECUTION: bool = false;
128
129    fn add_argument_update(
130        _acc: &mut Self::ArgumentUpdates,
131        _arg: Argument,
132        _bytes: Vec<u8>,
133        _type_: TypeTag,
134    ) -> Result<(), ExecutionError> {
135        invariant_violation!("should not be called");
136    }
137
138    fn finish_command(
139        _acc: &mut Self::ExecutionResults,
140        _argument_updates: Vec<(Argument, Vec<u8>, TypeTag)>,
141        _command_result: Vec<(Vec<u8>, TypeTag)>,
142    ) -> Result<(), ExecutionError> {
143        invariant_violation!("should not be called");
144    }
145}
146
147#[derive(Copy, Clone)]
148pub struct System<E = ExecutionError>(PhantomData<fn() -> E>);
149
150/// Execution mode for executing a system transaction, including the epoch change
151/// transaction and the consensus commit prologue. In this mode, we allow calls to
152/// any function bypassing visibility.
153impl<E> ExecutionMode for System<E>
154where
155    E: ExecutionErrorTrait,
156{
157    type ArgumentUpdates = ();
158    type ExecutionResults = ();
159    type Error = E;
160
161    fn allow_arbitrary_function_calls() -> bool {
162        // allows bypassing visibility for system calls
163        true
164    }
165
166    fn allow_arbitrary_values() -> bool {
167        // For AuthenticatorStateUpdate, we need to be able to pass in a vector of
168        // JWKs, so we need to allow arbitrary values.
169        true
170    }
171
172    fn skip_conservation_checks() -> bool {
173        false
174    }
175
176    fn packages_are_predefined() -> bool {
177        true
178    }
179
180    fn empty_results() -> Self::ExecutionResults {}
181
182    const TRACK_EXECUTION: bool = false;
183
184    fn add_argument_update(
185        _acc: &mut Self::ArgumentUpdates,
186        _arg: Argument,
187        _bytes: Vec<u8>,
188        _type_: TypeTag,
189    ) -> Result<(), ExecutionError> {
190        invariant_violation!("should not be called");
191    }
192
193    fn finish_command(
194        _acc: &mut Self::ExecutionResults,
195        _argument_updates: Vec<(Argument, Vec<u8>, TypeTag)>,
196        _command_result: Vec<(Vec<u8>, TypeTag)>,
197    ) -> Result<(), ExecutionError> {
198        invariant_violation!("should not be called");
199    }
200}
201
202/// WARNING! Using this mode will bypass all normal checks around Move entry functions! This
203/// includes the various rules for function arguments, meaning any object can be created just from
204/// BCS bytes!
205pub struct DevInspect<const SKIP_ALL_CHECKS: bool>;
206
207impl<const SKIP_ALL_CHECKS: bool> ExecutionMode for DevInspect<SKIP_ALL_CHECKS> {
208    type ArgumentUpdates = Vec<(Argument, Vec<u8>, TypeTag)>;
209    type ExecutionResults = Vec<ExecutionResult>;
210    type Error = ExecutionError;
211
212    fn allow_arbitrary_function_calls() -> bool {
213        SKIP_ALL_CHECKS
214    }
215
216    fn allow_arbitrary_values() -> bool {
217        SKIP_ALL_CHECKS
218    }
219
220    fn skip_conservation_checks() -> bool {
221        SKIP_ALL_CHECKS
222    }
223
224    fn packages_are_predefined() -> bool {
225        false
226    }
227
228    fn empty_results() -> Self::ExecutionResults {
229        vec![]
230    }
231
232    const TRACK_EXECUTION: bool = true;
233
234    fn add_argument_update(
235        acc: &mut Self::ArgumentUpdates,
236        arg: Argument,
237        bytes: Vec<u8>,
238        type_: TypeTag,
239    ) -> Result<(), ExecutionError> {
240        acc.push((arg, bytes, type_));
241        Ok(())
242    }
243
244    fn finish_command(
245        acc: &mut Self::ExecutionResults,
246        argument_updates: Vec<(Argument, Vec<u8>, TypeTag)>,
247        command_result: Vec<(Vec<u8>, TypeTag)>,
248    ) -> Result<(), ExecutionError> {
249        acc.push((argument_updates, command_result));
250        Ok(())
251    }
252}