agave_syscalls/
logging.rs

1use {
2    super::*, solana_program_runtime::memory::translate_vm_slice, solana_sbpf::vm::ContextObject,
3};
4
5declare_builtin_function!(
6    /// Log a user's info message
7    SyscallLog,
8    fn rust(
9        invoke_context: &mut InvokeContext,
10        addr: u64,
11        len: u64,
12        _arg3: u64,
13        _arg4: u64,
14        _arg5: u64,
15        memory_mapping: &mut MemoryMapping,
16    ) -> Result<u64, Error> {
17        let cost = invoke_context
18            .get_execution_cost()
19            .syscall_base_cost
20            .max(len);
21        consume_compute_meter(invoke_context, cost)?;
22
23        translate_string_and_do(
24            memory_mapping,
25            addr,
26            len,
27            invoke_context.get_check_aligned(),
28            &mut |string: &str| {
29                stable_log::program_log(&invoke_context.get_log_collector(), string);
30                Ok(0)
31            },
32        )?;
33        Ok(0)
34    }
35);
36
37declare_builtin_function!(
38    /// Log 5 64-bit values
39    SyscallLogU64,
40    fn rust(
41        invoke_context: &mut InvokeContext,
42        arg1: u64,
43        arg2: u64,
44        arg3: u64,
45        arg4: u64,
46        arg5: u64,
47        _memory_mapping: &mut MemoryMapping,
48    ) -> Result<u64, Error> {
49        let cost = invoke_context.get_execution_cost().log_64_units;
50        consume_compute_meter(invoke_context, cost)?;
51
52        stable_log::program_log(
53            &invoke_context.get_log_collector(),
54            &format!("{arg1:#x}, {arg2:#x}, {arg3:#x}, {arg4:#x}, {arg5:#x}"),
55        );
56        Ok(0)
57    }
58);
59
60declare_builtin_function!(
61    /// Log current compute consumption
62    SyscallLogBpfComputeUnits,
63    fn rust(
64        invoke_context: &mut InvokeContext,
65        _arg1: u64,
66        _arg2: u64,
67        _arg3: u64,
68        _arg4: u64,
69        _arg5: u64,
70        _memory_mapping: &mut MemoryMapping,
71    ) -> Result<u64, Error> {
72        let cost = invoke_context.get_execution_cost().syscall_base_cost;
73        consume_compute_meter(invoke_context, cost)?;
74
75        ic_logger_msg!(
76            invoke_context.get_log_collector(),
77            "Program consumption: {} units remaining",
78            invoke_context.get_remaining(),
79        );
80        Ok(0)
81    }
82);
83
84declare_builtin_function!(
85    /// Log a [`Pubkey`] as a base58 string
86    SyscallLogPubkey,
87    fn rust(
88        invoke_context: &mut InvokeContext,
89        pubkey_addr: u64,
90        _arg2: u64,
91        _arg3: u64,
92        _arg4: u64,
93        _arg5: u64,
94        memory_mapping: &mut MemoryMapping,
95    ) -> Result<u64, Error> {
96        let cost = invoke_context.get_execution_cost().log_pubkey_units;
97        consume_compute_meter(invoke_context, cost)?;
98
99        let pubkey = translate_type::<Pubkey>(
100            memory_mapping,
101            pubkey_addr,
102            invoke_context.get_check_aligned(),
103        )?;
104        stable_log::program_log(&invoke_context.get_log_collector(), &pubkey.to_string());
105        Ok(0)
106    }
107);
108
109declare_builtin_function!(
110    /// Log data handling
111    SyscallLogData,
112    fn rust(
113        invoke_context: &mut InvokeContext,
114        addr: u64,
115        len: u64,
116        _arg3: u64,
117        _arg4: u64,
118        _arg5: u64,
119        memory_mapping: &mut MemoryMapping,
120    ) -> Result<u64, Error> {
121        let execution_cost = invoke_context.get_execution_cost();
122
123        consume_compute_meter(invoke_context, execution_cost.syscall_base_cost)?;
124
125        let untranslated_fields = translate_slice::<VmSlice<u8>>(
126            memory_mapping,
127            addr,
128            len,
129            invoke_context.get_check_aligned(),
130        )?;
131
132        consume_compute_meter(
133            invoke_context,
134            execution_cost
135                .syscall_base_cost
136                .saturating_mul(untranslated_fields.len() as u64),
137        )?;
138        consume_compute_meter(
139            invoke_context,
140            untranslated_fields
141                .iter()
142                .fold(0, |total, e| total.saturating_add(e.len())),
143        )?;
144
145        let mut fields = Vec::with_capacity(untranslated_fields.len());
146
147        for untranslated_field in untranslated_fields {
148            fields.push(translate_vm_slice(untranslated_field, memory_mapping, invoke_context.get_check_aligned())?);
149        }
150
151        let log_collector = invoke_context.get_log_collector();
152
153        stable_log::program_data(&log_collector, &fields);
154
155        Ok(0)
156    }
157);