radix_engine/system/system_modules/kernel_trace/
module.rs

1use 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)] // for no_std
38impl<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 {}