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    pub fn len(&self) -> usize {
161        self.call_frame_data.len() + self.args.len()
162    }
163}
164
165/// API for invoking a function creating a new call frame and passing
166/// control to the callee
167pub trait KernelInvokeApi<C> {
168    fn kernel_invoke(
169        &mut self,
170        invocation: Box<KernelInvocation<C>>,
171    ) -> Result<IndexedScryptoValue, RuntimeError>;
172}
173
174/// API for managing multiple call frame stacks
175pub trait KernelStackApi {
176    type CallFrameData;
177
178    /// Gets the stack id which is currently being used
179    fn kernel_get_stack_id(&mut self) -> Result<usize, RuntimeError>;
180
181    /// Achieves a context switch by switching the underlying callframe/stack
182    fn kernel_switch_stack(&mut self, id: usize) -> Result<(), RuntimeError>;
183
184    /// Moves the objects in a scrypto value from the current call frame to another stack
185    fn kernel_send_to_stack(
186        &mut self,
187        id: usize,
188        value: &IndexedScryptoValue,
189    ) -> Result<(), RuntimeError>;
190
191    /// Sets the call frame data for the current call frame
192    fn kernel_set_call_frame_data(&mut self, data: Self::CallFrameData)
193        -> Result<(), RuntimeError>;
194
195    /// Returns the owned nodes of the current call frame
196    fn kernel_get_owned_nodes(&mut self) -> Result<Vec<NodeId>, RuntimeError>;
197}
198
199pub struct SystemState<'a, M: KernelCallbackObject> {
200    pub system: &'a mut M,
201    pub current_call_frame: &'a M::CallFrameData,
202    pub caller_call_frame: &'a M::CallFrameData,
203}
204
205/// Internal API for system modules only.
206///
207/// TODO: Do not use uncosted API within protocol
208/// The uncosted APIs should be used by non-consensus related system modules only, i.e. kernel
209/// trace and execution trace. All other usages should be migrated away, ideally as a whole.
210pub trait KernelInternalApi {
211    type System: KernelCallbackObject;
212
213    /// Returns the system.
214    #[inline]
215    fn kernel_get_system(&mut self) -> &mut Self::System {
216        self.kernel_get_system_state().system
217    }
218
219    /// Returns the system state.
220    fn kernel_get_system_state(&mut self) -> SystemState<'_, Self::System>;
221
222    /// Returns the current stack depth.
223    ///
224    /// Used by kernel trace, execution trace and costing system modules only.
225    fn kernel_get_current_stack_depth_uncosted(&self) -> usize;
226
227    /// Returns the current stack id.
228    ///
229    /// Used by kernel trace, execution trace, costing system modules and `start_lock_fee` system function only.
230    fn kernel_get_current_stack_id_uncosted(&self) -> usize;
231
232    /// Returns the visibility of a node.
233    ///
234    /// Used by auth system module and `actor_get_node_id` system function only.
235    fn kernel_get_node_visibility_uncosted(&self, node_id: &NodeId) -> NodeVisibility;
236
237    /// Returns the value of a substate.
238    ///
239    /// Used by execution trace system module only.
240    fn kernel_read_substate_uncosted(
241        &self,
242        node_id: &NodeId,
243        partition_num: PartitionNumber,
244        substate_key: &SubstateKey,
245    ) -> Option<&IndexedScryptoValue>;
246}
247
248pub trait KernelApi:
249    KernelNodeApi
250    + KernelSubstateApi<<Self::CallbackObject as KernelCallbackObject>::LockData>
251    + KernelInvokeApi<<Self::CallbackObject as KernelCallbackObject>::CallFrameData>
252    + KernelStackApi<CallFrameData = <Self::CallbackObject as KernelCallbackObject>::CallFrameData>
253    + KernelInternalApi<System = Self::CallbackObject>
254{
255    type CallbackObject: KernelCallbackObject;
256}