radix_engine/kernel/
kernel_api.rs

1use super::call_frame::*;
2use crate::errors::*;
3use crate::internal_prelude::*;
4use crate::kernel::kernel_callback_api::*;
5use crate::track::interface::*;
6use radix_engine_interface::api::field_api::*;
7use radix_substate_store_interface::db_key_mapper::*;
8
9pub struct DroppedNode {
10    pub substates: NodeSubstates,
11    pub pinned_to_heap: bool,
12}
13
14// Following the convention of Linux Kernel API, https://www.kernel.org/doc/htmldocs/kernel-api/,
15// all methods are prefixed by the subsystem of kernel.
16
17/// API for managing nodes
18pub trait KernelNodeApi {
19    /// Pin a node to it's current device.
20    fn kernel_pin_node(&mut self, node_id: NodeId) -> Result<(), RuntimeError>;
21
22    /// Allocates a new node id useable for create_node
23    fn kernel_allocate_node_id(&mut self, entity_type: EntityType) -> Result<NodeId, RuntimeError>;
24
25    /// Creates a new RENode
26    fn kernel_create_node(
27        &mut self,
28        node_id: NodeId,
29        node_substates: NodeSubstates,
30    ) -> Result<(), RuntimeError>;
31
32    fn kernel_create_node_from(
33        &mut self,
34        node_id: NodeId,
35        partitions: BTreeMap<PartitionNumber, (NodeId, PartitionNumber)>,
36    ) -> Result<(), RuntimeError>;
37
38    /// Removes an RENode. Owned children will be possessed by the call frame.
39    ///
40    /// Dropped substates can't necessary be added back due to visibility loss.
41    /// Clients should consider the return value as "raw data".
42    fn kernel_drop_node(&mut self, node_id: &NodeId) -> Result<DroppedNode, RuntimeError>;
43}
44
45/// API for managing substates within nodes
46pub trait KernelSubstateApi<L> {
47    /// Marks a substate as transient, or a substate which was never and will never be persisted
48    fn kernel_mark_substate_as_transient(
49        &mut self,
50        node_id: NodeId,
51        partition_num: PartitionNumber,
52        key: SubstateKey,
53    ) -> Result<(), RuntimeError>;
54
55    /// Locks a substate to make available for reading and/or writing
56    fn kernel_open_substate_with_default<F: FnOnce() -> IndexedScryptoValue>(
57        &mut self,
58        node_id: &NodeId,
59        partition_num: PartitionNumber,
60        substate_key: &SubstateKey,
61        flags: LockFlags,
62        default: Option<F>,
63        lock_data: L,
64    ) -> Result<SubstateHandle, RuntimeError>;
65
66    fn kernel_open_substate(
67        &mut self,
68        node_id: &NodeId,
69        partition_num: PartitionNumber,
70        substate_key: &SubstateKey,
71        flags: LockFlags,
72        lock_data: L,
73    ) -> Result<SubstateHandle, RuntimeError> {
74        self.kernel_open_substate_with_default(
75            node_id,
76            partition_num,
77            substate_key,
78            flags,
79            None::<fn() -> IndexedScryptoValue>,
80            lock_data,
81        )
82    }
83
84    /// Retrieves info related to a lock
85    fn kernel_get_lock_data(&mut self, lock_handle: SubstateHandle) -> Result<L, RuntimeError>;
86
87    /// Drops the handle on some substate, if the handle is a force write, updates are flushed.
88    /// No updates should occur if an error is returned.
89    fn kernel_close_substate(&mut self, lock_handle: SubstateHandle) -> Result<(), RuntimeError>;
90
91    /// Reads the value of the substate locked by the given lock handle
92    fn kernel_read_substate(
93        &mut self,
94        lock_handle: SubstateHandle,
95    ) -> Result<&IndexedScryptoValue, RuntimeError>;
96
97    /// Writes a value to the substate locked by the given lock handle
98    fn kernel_write_substate(
99        &mut self,
100        lock_handle: SubstateHandle,
101        value: IndexedScryptoValue,
102    ) -> Result<(), RuntimeError>;
103
104    /// Sets a value to a substate without checking for the original value.
105    ///
106    /// Clients must ensure that this isn't used in conjunction with shardable
107    /// substates; otherwise, the behavior is undefined
108    fn kernel_set_substate(
109        &mut self,
110        node_id: &NodeId,
111        partition_num: PartitionNumber,
112        substate_key: SubstateKey,
113        value: IndexedScryptoValue,
114    ) -> Result<(), RuntimeError>;
115
116    /// Removes a substate from a node and returns the original value.
117    ///
118    /// Clients must ensure that this isn't used in conjunction with virtualized
119    /// substates; otherwise, the behavior is undefined
120    fn kernel_remove_substate(
121        &mut self,
122        node_id: &NodeId,
123        partition_num: PartitionNumber,
124        substate_key: &SubstateKey,
125    ) -> Result<Option<IndexedScryptoValue>, RuntimeError>;
126
127    /// Reads substates under a node in sorted lexicographical order
128    ///
129    /// Clients must ensure that this isn't used in conjunction with virtualized
130    /// substates; otherwise, the behavior is undefined
131    fn kernel_scan_sorted_substates(
132        &mut self,
133        node_id: &NodeId,
134        partition_num: PartitionNumber,
135        count: u32,
136    ) -> Result<Vec<(SortedKey, IndexedScryptoValue)>, RuntimeError>;
137
138    fn kernel_scan_keys<K: SubstateKeyContent>(
139        &mut self,
140        node_id: &NodeId,
141        partition_num: PartitionNumber,
142        count: u32,
143    ) -> Result<Vec<SubstateKey>, RuntimeError>;
144
145    fn kernel_drain_substates<K: SubstateKeyContent>(
146        &mut self,
147        node_id: &NodeId,
148        partition_num: PartitionNumber,
149        count: u32,
150    ) -> Result<Vec<(SubstateKey, IndexedScryptoValue)>, RuntimeError>;
151}
152
153#[derive(Debug, Clone)]
154pub struct KernelInvocation<C> {
155    pub call_frame_data: C,
156    pub args: IndexedScryptoValue,
157}
158
159impl<C: CallFrameReferences> KernelInvocation<C> {
160    #[allow(clippy::len_without_is_empty)]
161    pub fn len(&self) -> usize {
162        self.call_frame_data.len() + self.args.len()
163    }
164}
165
166/// API for invoking a function creating a new call frame and passing
167/// control to the callee
168pub trait KernelInvokeApi<C> {
169    fn kernel_invoke(
170        &mut self,
171        invocation: Box<KernelInvocation<C>>,
172    ) -> Result<IndexedScryptoValue, RuntimeError>;
173}
174
175/// API for managing multiple call frame stacks
176pub trait KernelStackApi {
177    type CallFrameData;
178
179    /// Gets the stack id which is currently being used
180    fn kernel_get_stack_id(&mut self) -> Result<usize, RuntimeError>;
181
182    /// Achieves a context switch by switching the underlying callframe/stack
183    fn kernel_switch_stack(&mut self, id: usize) -> Result<(), RuntimeError>;
184
185    /// Moves the objects in a scrypto value from the current call frame to another stack
186    fn kernel_send_to_stack(
187        &mut self,
188        id: usize,
189        value: &IndexedScryptoValue,
190    ) -> Result<(), RuntimeError>;
191
192    /// Sets the call frame data for the current call frame
193    fn kernel_set_call_frame_data(&mut self, data: Self::CallFrameData)
194        -> Result<(), RuntimeError>;
195
196    /// Returns the owned nodes of the current call frame
197    fn kernel_get_owned_nodes(&mut self) -> Result<Vec<NodeId>, RuntimeError>;
198}
199
200pub struct SystemState<'a, M: KernelCallbackObject> {
201    pub system: &'a mut M,
202    pub current_call_frame: &'a M::CallFrameData,
203    pub caller_call_frame: &'a M::CallFrameData,
204}
205
206/// Internal API for system modules only.
207///
208/// TODO: Do not use uncosted API within protocol
209/// The uncosted APIs should be used by non-consensus related system modules only, i.e. kernel
210/// trace and execution trace. All other usages should be migrated away, ideally as a whole.
211pub trait KernelInternalApi {
212    type System: KernelCallbackObject;
213
214    /// Returns the system.
215    #[inline]
216    fn kernel_get_system(&mut self) -> &mut Self::System {
217        self.kernel_get_system_state().system
218    }
219
220    /// Returns the system state.
221    fn kernel_get_system_state(&mut self) -> SystemState<'_, Self::System>;
222
223    /// Returns the current stack depth.
224    ///
225    /// Used by kernel trace, execution trace and costing system modules only.
226    fn kernel_get_current_stack_depth_uncosted(&self) -> usize;
227
228    /// Returns the current stack id.
229    ///
230    /// Used by kernel trace, execution trace, costing system modules and `start_lock_fee` system function only.
231    fn kernel_get_current_stack_id_uncosted(&self) -> usize;
232
233    /// Returns the visibility of a node.
234    ///
235    /// Used by auth system module and `actor_get_node_id` system function only.
236    fn kernel_get_node_visibility_uncosted(&self, node_id: &NodeId) -> NodeVisibility;
237
238    /// Returns the value of a substate.
239    ///
240    /// Used by execution trace system module only.
241    fn kernel_read_substate_uncosted(
242        &self,
243        node_id: &NodeId,
244        partition_num: PartitionNumber,
245        substate_key: &SubstateKey,
246    ) -> Option<&IndexedScryptoValue>;
247}
248
249pub trait KernelApi:
250    KernelNodeApi
251    + KernelSubstateApi<<Self::CallbackObject as KernelCallbackObject>::LockData>
252    + KernelInvokeApi<<Self::CallbackObject as KernelCallbackObject>::CallFrameData>
253    + KernelStackApi<CallFrameData = <Self::CallbackObject as KernelCallbackObject>::CallFrameData>
254    + KernelInternalApi<System = Self::CallbackObject>
255{
256    type CallbackObject: KernelCallbackObject;
257}