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        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 {}