radix_engine/system/system_modules/kernel_trace/
module.rs1use crate::errors::RuntimeError;
2use crate::internal_prelude::*;
3use crate::kernel::call_frame::CallFrameMessage;
4use crate::kernel::kernel_api::KernelInvocation;
5use crate::kernel::kernel_callback_api::*;
6use crate::system::actor::Actor;
7use crate::system::module::*;
8use crate::system::system_callback::*;
9use colored::Colorize;
10use radix_engine_interface::types::SubstateKey;
11use sbor::rust::collections::BTreeMap;
12
13#[derive(Debug, Clone)]
14pub struct KernelTraceModule;
15
16#[macro_export]
17macro_rules! log {
18 ( $api: expr, $msg: expr $( , $arg:expr )* ) => {
19 #[cfg(not(feature = "alloc"))]
20 println!("{}[{}] {}", " ".repeat($api.current_stack_depth_uncosted()), $api.current_stack_depth_uncosted(), sbor::rust::format!($msg, $( $arg ),*));
21 };
22}
23
24impl InitSystemModule for KernelTraceModule {
25 #[cfg(feature = "resource_tracker")]
26 fn init(&mut self) -> Result<(), BootloadingError> {
27 panic!("KernelTraceModule should be disabled for feature resource_tracker!")
28 }
29}
30impl ResolvableSystemModule for KernelTraceModule {
31 #[inline]
32 fn resolve_from_system(system: &mut impl HasModules) -> &mut Self {
33 &mut system.modules_mut().kernel_trace
34 }
35}
36
37#[allow(unused_variables)] impl<ModuleApi: SystemModuleApiFor<Self>> SystemModule<ModuleApi> for KernelTraceModule {
39 fn before_invoke(
40 api: &mut ModuleApi,
41 invocation: &KernelInvocation<Actor>,
42 ) -> Result<(), RuntimeError> {
43 let message = format!(
44 "Invoking: fn = {:?}, input size = {}",
45 invocation.call_frame_data,
46 invocation.len(),
47 )
48 .green();
49
50 log!(api, "{}", message);
51 log!(api, "Sending nodes: {:?}", invocation.args.owned_nodes());
52 log!(api, "Sending refs: {:?}", invocation.args.references());
53 Ok(())
54 }
55
56 fn on_execution_finish(
57 api: &mut ModuleApi,
58 message: &CallFrameMessage,
59 ) -> Result<(), RuntimeError> {
60 log!(api, "Returning nodes: {:?}", message.move_nodes);
61 log!(api, "Returning refs: {:?}", message.copy_global_references);
62 Ok(())
63 }
64
65 fn after_invoke(api: &mut ModuleApi, output: &IndexedScryptoValue) -> Result<(), RuntimeError> {
66 log!(api, "Exiting: output size = {}", output.len());
67 Ok(())
68 }
69
70 fn on_allocate_node_id(
71 api: &mut ModuleApi,
72 entity_type: EntityType,
73 ) -> Result<(), RuntimeError> {
74 log!(api, "Allocating node id: entity_type = {:?}", entity_type);
75 Ok(())
76 }
77
78 fn on_create_node(api: &mut ModuleApi, event: &CreateNodeEvent) -> Result<(), RuntimeError> {
79 match event {
80 CreateNodeEvent::Start(node_id, node_module_init) => {
81 let mut module_substate_keys =
82 BTreeMap::<&PartitionNumber, Vec<&SubstateKey>>::new();
83 for (module_id, m) in *node_module_init {
84 for (substate_key, _) in m {
85 module_substate_keys
86 .entry(module_id)
87 .or_default()
88 .push(substate_key);
89 }
90 }
91 let message = format!(
92 "Creating node: id = {:?}, type = {:?}, substates = {:?}, module 0 = {:?}",
93 node_id,
94 node_id.entity_type(),
95 module_substate_keys,
96 node_module_init.get(&PartitionNumber(0))
97 )
98 .red();
99 log!(api, "{}", message);
100 }
101 _ => {}
102 }
103
104 Ok(())
105 }
106
107 fn on_drop_node(api: &mut ModuleApi, event: &DropNodeEvent) -> Result<(), RuntimeError> {
108 match event {
109 DropNodeEvent::Start(node_id) => {
110 log!(api, "Dropping node: id = {:?}", node_id);
111 }
112 _ => {}
113 }
114 Ok(())
115 }
116
117 fn on_open_substate(
118 api: &mut ModuleApi,
119 event: &OpenSubstateEvent,
120 ) -> Result<(), RuntimeError> {
121 match event {
122 OpenSubstateEvent::Start {
123 node_id,
124 partition_num,
125 substate_key,
126 flags,
127 } => {
128 log!(
129 api,
130 "Locking substate: node id = {:?}, partition_num = {:?}, substate_key = {:?}, flags = {:?}",
131 node_id,
132 partition_num,
133 substate_key,
134 flags
135 );
136 }
137 OpenSubstateEvent::IOAccess(..) => {}
138 OpenSubstateEvent::End {
139 handle,
140 node_id,
141 size,
142 } => {
143 log!(
144 api,
145 "Substate locked: node id = {:?}, handle = {:?}",
146 node_id,
147 handle
148 );
149 }
150 }
151
152 Ok(())
153 }
154
155 fn on_read_substate(
156 api: &mut ModuleApi,
157 event: &ReadSubstateEvent,
158 ) -> Result<(), RuntimeError> {
159 match event {
160 ReadSubstateEvent::OnRead {
161 handle,
162 value,
163 device,
164 } => {
165 log!(
166 api,
167 "Reading substate: handle = {}, size = {}, device = {:?}",
168 handle,
169 value.len(),
170 device
171 );
172 }
173 ReadSubstateEvent::IOAccess(_) => {}
174 }
175
176 Ok(())
177 }
178
179 fn on_write_substate(
180 api: &mut ModuleApi,
181 event: &WriteSubstateEvent,
182 ) -> Result<(), RuntimeError> {
183 match event {
184 WriteSubstateEvent::Start { handle, value } => {
185 log!(
186 api,
187 "Writing substate: handle = {}, size = {}",
188 handle,
189 value.len()
190 );
191 }
192 _ => {}
193 }
194
195 Ok(())
196 }
197
198 fn on_close_substate(
199 api: &mut ModuleApi,
200 event: &CloseSubstateEvent,
201 ) -> Result<(), RuntimeError> {
202 match event {
203 CloseSubstateEvent::Start(lock_handle) => {
204 log!(api, "Substate close: handle = {} ", lock_handle);
205 }
206 }
207 Ok(())
208 }
209}
210
211impl PrivilegedSystemModule for KernelTraceModule {}