radix_engine/system/
module.rs

1use crate::errors::RuntimeError;
2use crate::internal_prelude::*;
3use crate::kernel::call_frame::CallFrameMessage;
4use crate::kernel::kernel_api::*;
5use crate::kernel::kernel_callback_api::*;
6use crate::system::actor::Actor;
7
8use super::system_callback::*;
9use super::system_callback_api::*;
10
11/// We use a zero-cost `SystemModuleApiImpl` wrapper instead of just implementing
12/// on `K` for a few reasons:
13/// * Separation of APIs - we avoid exposing a `SystemModuleApi` directly if someone
14///   happens to have a SystemBasedKernelApi, as that might be confusing.
15/// * Trait coherence - even if `SystemModuleApi` were moved to a different crate,
16///   this would still work
17pub struct SystemModuleApiImpl<'a, K: KernelInternalApi + ?Sized> {
18    api: &'a mut K,
19}
20
21impl<'a, K: KernelInternalApi + ?Sized> SystemModuleApiImpl<'a, K> {
22    #[inline]
23    pub fn new(api: &'a mut K) -> Self {
24        Self { api }
25    }
26
27    #[inline]
28    pub fn api_ref(&self) -> &K {
29        &self.api
30    }
31
32    #[inline]
33    pub fn api(&mut self) -> &mut K {
34        &mut self.api
35    }
36}
37
38pub trait SystemModuleApi {
39    type SystemCallback: SystemCallbackObject;
40
41    fn system(&mut self) -> &mut System<Self::SystemCallback>;
42
43    fn system_state(&mut self) -> SystemState<'_, System<Self::SystemCallback>>;
44
45    fn current_stack_depth_uncosted(&self) -> usize;
46
47    fn current_stack_id_uncosted(&self) -> usize;
48}
49
50impl<'a, V: SystemCallbackObject, K: KernelInternalApi<System = System<V>> + ?Sized> SystemModuleApi
51    for SystemModuleApiImpl<'a, K>
52{
53    type SystemCallback = V;
54
55    fn system(&mut self) -> &mut K::System {
56        self.api.kernel_get_system()
57    }
58
59    fn system_state(&mut self) -> SystemState<'_, K::System> {
60        self.api.kernel_get_system_state()
61    }
62
63    fn current_stack_depth_uncosted(&self) -> usize {
64        self.api.kernel_get_current_stack_depth_uncosted()
65    }
66
67    fn current_stack_id_uncosted(&self) -> usize {
68        self.api.kernel_get_current_stack_id_uncosted()
69    }
70}
71
72pub trait ResolvableSystemModule {
73    fn resolve_from_system(system: &mut impl HasModules) -> &mut Self;
74}
75
76pub trait SystemModuleApiFor<M: ResolvableSystemModule + ?Sized>: SystemModuleApi {
77    fn module(&mut self) -> &mut M {
78        M::resolve_from_system(self.system())
79    }
80}
81
82impl<
83        'a,
84        V: SystemCallbackObject,
85        K: KernelInternalApi<System = System<V>> + ?Sized,
86        M: ResolvableSystemModule + ?Sized,
87    > SystemModuleApiFor<M> for SystemModuleApiImpl<'a, K>
88{
89}
90
91pub trait InitSystemModule {
92    //======================
93    // System module setup
94    //======================
95    #[inline(always)]
96    fn init(&mut self) -> Result<(), BootloadingError> {
97        Ok(())
98    }
99
100    #[inline(always)]
101    fn on_teardown(&mut self) -> Result<(), RuntimeError> {
102        Ok(())
103    }
104}
105
106pub trait PrivilegedSystemModule {
107    #[inline(always)]
108    fn privileged_before_invoke(
109        _api: &mut impl SystemBasedKernelApi,
110        _invocation: &KernelInvocation<Actor>,
111    ) -> Result<(), RuntimeError> {
112        Ok(())
113    }
114}
115
116pub trait SystemModule<ModuleApi: SystemModuleApiFor<Self>>:
117    InitSystemModule + ResolvableSystemModule + PrivilegedSystemModule
118{
119    //======================
120    // Invocation events
121    //
122    // -> BeforeInvoke
123    //        -> ExecutionStart
124    //        -> ExecutionFinish
125    // -> AfterInvoke
126    //======================
127
128    #[inline(always)]
129    fn before_invoke(
130        _api: &mut ModuleApi,
131        _invocation: &KernelInvocation<Actor>,
132    ) -> Result<(), RuntimeError> {
133        Ok(())
134    }
135
136    #[inline(always)]
137    fn on_execution_start(_api: &mut ModuleApi) -> Result<(), RuntimeError> {
138        Ok(())
139    }
140
141    #[inline(always)]
142    fn on_execution_finish(
143        _api: &mut ModuleApi,
144        _message: &CallFrameMessage,
145    ) -> Result<(), RuntimeError> {
146        Ok(())
147    }
148
149    #[inline(always)]
150    fn after_invoke(
151        _api: &mut ModuleApi,
152        _output: &IndexedScryptoValue,
153    ) -> Result<(), RuntimeError> {
154        Ok(())
155    }
156
157    //======================
158    // RENode events
159    //======================
160
161    #[inline(always)]
162    fn on_pin_node(_api: &mut ModuleApi, _node_id: &NodeId) -> Result<(), RuntimeError> {
163        Ok(())
164    }
165
166    #[inline(always)]
167    fn on_allocate_node_id(
168        _api: &mut ModuleApi,
169        _entity_type: EntityType,
170    ) -> Result<(), RuntimeError> {
171        Ok(())
172    }
173
174    #[inline(always)]
175    fn on_create_node(_api: &mut ModuleApi, _event: &CreateNodeEvent) -> Result<(), RuntimeError> {
176        Ok(())
177    }
178
179    #[inline(always)]
180    fn on_move_module(_api: &mut ModuleApi, _event: &MoveModuleEvent) -> Result<(), RuntimeError> {
181        Ok(())
182    }
183
184    #[inline(always)]
185    fn on_drop_node(_api: &mut ModuleApi, _event: &DropNodeEvent) -> Result<(), RuntimeError> {
186        Ok(())
187    }
188
189    //======================
190    // Substate events
191    //======================
192    #[inline(always)]
193    fn on_mark_substate_as_transient(
194        _api: &mut ModuleApi,
195        _node_id: &NodeId,
196        _partition_number: &PartitionNumber,
197        _substate_key: &SubstateKey,
198    ) -> Result<(), RuntimeError> {
199        Ok(())
200    }
201
202    #[inline(always)]
203    fn on_open_substate(
204        _api: &mut ModuleApi,
205        _event: &OpenSubstateEvent,
206    ) -> Result<(), RuntimeError> {
207        Ok(())
208    }
209
210    #[inline(always)]
211    fn on_read_substate(
212        _api: &mut ModuleApi,
213        _event: &ReadSubstateEvent,
214    ) -> Result<(), RuntimeError> {
215        Ok(())
216    }
217
218    #[inline(always)]
219    fn on_write_substate(
220        _api: &mut ModuleApi,
221        _event: &WriteSubstateEvent,
222    ) -> Result<(), RuntimeError> {
223        Ok(())
224    }
225
226    #[inline(always)]
227    fn on_close_substate(
228        _api: &mut ModuleApi,
229        _event: &CloseSubstateEvent,
230    ) -> Result<(), RuntimeError> {
231        Ok(())
232    }
233
234    #[inline(always)]
235    fn on_set_substate(
236        _api: &mut ModuleApi,
237        _event: &SetSubstateEvent,
238    ) -> Result<(), RuntimeError> {
239        Ok(())
240    }
241
242    #[inline(always)]
243    fn on_remove_substate(
244        _api: &mut ModuleApi,
245        _event: &RemoveSubstateEvent,
246    ) -> Result<(), RuntimeError> {
247        Ok(())
248    }
249
250    #[inline(always)]
251    fn on_scan_keys(_api: &mut ModuleApi, _event: &ScanKeysEvent) -> Result<(), RuntimeError> {
252        Ok(())
253    }
254
255    #[inline(always)]
256    fn on_drain_substates(
257        _api: &mut ModuleApi,
258        _event: &DrainSubstatesEvent,
259    ) -> Result<(), RuntimeError> {
260        Ok(())
261    }
262
263    #[inline(always)]
264    fn on_scan_sorted_substates(
265        _api: &mut ModuleApi,
266        _event: &ScanSortedSubstatesEvent,
267    ) -> Result<(), RuntimeError> {
268        Ok(())
269    }
270
271    fn on_get_stack_id(_api: &mut ModuleApi) -> Result<(), RuntimeError> {
272        Ok(())
273    }
274
275    fn on_switch_stack(_api: &mut ModuleApi) -> Result<(), RuntimeError> {
276        Ok(())
277    }
278
279    fn on_send_to_stack(_api: &mut ModuleApi, _data_len: usize) -> Result<(), RuntimeError> {
280        Ok(())
281    }
282
283    fn on_set_call_frame_data(_api: &mut ModuleApi, _data_len: usize) -> Result<(), RuntimeError> {
284        Ok(())
285    }
286
287    fn on_get_owned_nodes(_api: &mut ModuleApi) -> Result<(), RuntimeError> {
288        Ok(())
289    }
290}