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 if let CreateNodeEvent::Start(node_id, node_module_init) = event {
80 let mut module_substate_keys = BTreeMap::<&PartitionNumber, Vec<&SubstateKey>>::new();
81 for (module_id, m) in *node_module_init {
82 for substate_key in m.keys() {
83 module_substate_keys
84 .entry(module_id)
85 .or_default()
86 .push(substate_key);
87 }
88 }
89 let message = format!(
90 "Creating node: id = {:?}, type = {:?}, substates = {:?}, module 0 = {:?}",
91 node_id,
92 node_id.entity_type(),
93 module_substate_keys,
94 node_module_init.get(&PartitionNumber(0))
95 )
96 .red();
97 log!(api, "{}", message);
98 }
99
100 Ok(())
101 }
102
103 fn on_drop_node(api: &mut ModuleApi, event: &DropNodeEvent) -> Result<(), RuntimeError> {
104 if let DropNodeEvent::Start(node_id) = event {
105 log!(api, "Dropping node: id = {:?}", node_id);
106 }
107 Ok(())
108 }
109
110 fn on_open_substate(
111 api: &mut ModuleApi,
112 event: &OpenSubstateEvent,
113 ) -> Result<(), RuntimeError> {
114 match event {
115 OpenSubstateEvent::Start {
116 node_id,
117 partition_num,
118 substate_key,
119 flags,
120 } => {
121 log!(
122 api,
123 "Locking substate: node id = {:?}, partition_num = {:?}, substate_key = {:?}, flags = {:?}",
124 node_id,
125 partition_num,
126 substate_key,
127 flags
128 );
129 }
130 OpenSubstateEvent::IOAccess(..) => {}
131 OpenSubstateEvent::End {
132 handle,
133 node_id,
134 size,
135 } => {
136 log!(
137 api,
138 "Substate locked: node id = {:?}, handle = {:?}",
139 node_id,
140 handle
141 );
142 }
143 }
144
145 Ok(())
146 }
147
148 fn on_read_substate(
149 api: &mut ModuleApi,
150 event: &ReadSubstateEvent,
151 ) -> Result<(), RuntimeError> {
152 match event {
153 ReadSubstateEvent::OnRead {
154 handle,
155 value,
156 device,
157 } => {
158 log!(
159 api,
160 "Reading substate: handle = {}, size = {}, device = {:?}",
161 handle,
162 value.len(),
163 device
164 );
165 }
166 ReadSubstateEvent::IOAccess(_) => {}
167 }
168
169 Ok(())
170 }
171
172 fn on_write_substate(
173 api: &mut ModuleApi,
174 event: &WriteSubstateEvent,
175 ) -> Result<(), RuntimeError> {
176 if let WriteSubstateEvent::Start { handle, value } = event {
177 log!(
178 api,
179 "Writing substate: handle = {}, size = {}",
180 handle,
181 value.len()
182 );
183 }
184
185 Ok(())
186 }
187
188 fn on_close_substate(
189 api: &mut ModuleApi,
190 event: &CloseSubstateEvent,
191 ) -> Result<(), RuntimeError> {
192 match event {
193 CloseSubstateEvent::Start(lock_handle) => {
194 log!(api, "Substate close: handle = {} ", lock_handle);
195 }
196 }
197 Ok(())
198 }
199}
200
201impl PrivilegedSystemModule for KernelTraceModule {}