gemachain_program/
log.rs

1//! @brief Gemachain Rust-based BPF program logging
2
3use crate::account_info::AccountInfo;
4
5#[macro_export]
6#[deprecated(since = "1.4.14", note = "Please use `msg` macro instead")]
7macro_rules! info {
8    ($msg:expr) => {
9        $crate::log::gema_log($msg)
10    };
11    ($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr) => {
12        $crate::log::gema_log_64(
13            $arg1 as u64,
14            $arg2 as u64,
15            $arg3 as u64,
16            $arg4 as u64,
17            $arg5 as u64,
18        )
19    };
20}
21
22/// Print a message to the log
23///
24/// There are two fast forms:
25/// 1. Single string: `msg!("hi")`
26/// 2. 5 integers: `msg!(1, 2, 3, 4, 5)`
27///
28/// The third form is more generic and incurs a very large runtime overhead so it should be used
29/// with care:
30/// 3. Generalized format string: `msg!("Hello {}: 1, 2, {}", "World", 3)`
31///
32#[macro_export]
33macro_rules! msg {
34    ($msg:expr) => {
35        $crate::log::gema_log($msg)
36    };
37    ($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr) => {
38        $crate::log::gema_log_64(
39            $arg1 as u64,
40            $arg2 as u64,
41            $arg3 as u64,
42            $arg4 as u64,
43            $arg5 as u64,
44        )
45    };
46    ($($arg:tt)*) => ($crate::log::gema_log(&format!($($arg)*)));
47}
48
49/// Print a string to the log
50///
51/// @param message - Message to print
52#[inline]
53pub fn gema_log(message: &str) {
54    #[cfg(target_arch = "bpf")]
55    unsafe {
56        gema_log_(message.as_ptr(), message.len() as u64);
57    }
58
59    #[cfg(not(target_arch = "bpf"))]
60    crate::program_stubs::gema_log(message);
61}
62
63#[cfg(target_arch = "bpf")]
64extern "C" {
65    fn gema_log_(message: *const u8, len: u64);
66}
67
68/// Print 64-bit values represented as hexadecimal to the log
69///
70/// @param argx - integer arguments to print
71
72#[inline]
73pub fn gema_log_64(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) {
74    #[cfg(target_arch = "bpf")]
75    unsafe {
76        gema_log_64_(arg1, arg2, arg3, arg4, arg5);
77    }
78
79    #[cfg(not(target_arch = "bpf"))]
80    crate::program_stubs::gema_log_64(arg1, arg2, arg3, arg4, arg5);
81}
82
83#[cfg(target_arch = "bpf")]
84extern "C" {
85    fn gema_log_64_(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64);
86}
87
88/// Print some slices as base64
89///
90/// @param data - The slices to print
91pub fn gema_log_data(data: &[&[u8]]) {
92    #[cfg(target_arch = "bpf")]
93    {
94        extern "C" {
95            fn gema_log_data(data: *const u8, data_len: u64);
96        }
97
98        unsafe { gema_log_data(data as *const _ as *const u8, data.len() as u64) };
99    }
100
101    #[cfg(not(target_arch = "bpf"))]
102    crate::program_stubs::gema_log_data(data);
103}
104
105/// Print the hexadecimal representation of a slice
106///
107/// @param slice - The array to print
108#[allow(dead_code)]
109pub fn gema_log_slice(slice: &[u8]) {
110    for (i, s) in slice.iter().enumerate() {
111        msg!(0, 0, 0, i, *s);
112    }
113}
114
115/// Print the hexadecimal representation of the program's input parameters
116///
117/// @param ka - A pointer to an array of `AccountInfo` to print
118/// @param data - A pointer to the instruction data to print
119#[allow(dead_code)]
120pub fn gema_log_params(accounts: &[AccountInfo], data: &[u8]) {
121    for (i, account) in accounts.iter().enumerate() {
122        msg!("AccountInfo");
123        msg!(0, 0, 0, 0, i);
124        msg!("- Is signer");
125        msg!(0, 0, 0, 0, account.is_signer);
126        msg!("- Key");
127        account.key.log();
128        msg!("- Carats");
129        msg!(0, 0, 0, 0, account.carats());
130        msg!("- Account data length");
131        msg!(0, 0, 0, 0, account.data_len());
132        msg!("- Owner");
133        account.owner.log();
134    }
135    msg!("Instruction data");
136    gema_log_slice(data);
137}
138
139/// Print the remaining compute units the program may consume
140#[inline]
141pub fn gema_log_compute_units() {
142    #[cfg(target_arch = "bpf")]
143    unsafe {
144        gema_log_compute_units_();
145    }
146    #[cfg(not(target_arch = "bpf"))]
147    crate::program_stubs::gema_log_compute_units();
148}
149
150#[cfg(target_arch = "bpf")]
151extern "C" {
152    fn gema_log_compute_units_();
153}