solana_syscalls/
logging.rs1use {
2 super::*, solana_program_runtime::memory::translate_vm_slice, solana_sbpf::vm::ContextObject,
3};
4
5declare_builtin_function!(
6 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 ) -> Result<u64, Error> {
16 let cost = invoke_context
17 .get_execution_cost()
18 .syscall_base_cost
19 .max(len);
20 invoke_context.compute_meter.consume_checked(cost)?;
21
22 let check_aligned = invoke_context.get_check_aligned();
23 let memory_mapping = invoke_context.memory_contexts.memory_mapping()?;
24 translate_string_and_do(
25 memory_mapping,
26 addr,
27 len,
28 check_aligned,
29 &mut |string: &str| {
30 stable_log::program_log(&invoke_context.get_log_collector(), string);
31 Ok(0)
32 },
33 )?;
34 Ok(0)
35 }
36);
37
38declare_builtin_function!(
39 SyscallLogU64,
41 fn rust(
42 invoke_context: &mut InvokeContext<'_, '_>,
43 arg1: u64,
44 arg2: u64,
45 arg3: u64,
46 arg4: u64,
47 arg5: u64,
48 ) -> Result<u64, Error> {
49 let cost = invoke_context.get_execution_cost().log_64_units;
50 invoke_context.compute_meter.consume_checked(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 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 ) -> Result<u64, Error> {
71 let cost = invoke_context.get_execution_cost().syscall_base_cost;
72 invoke_context.compute_meter.consume_checked(cost)?;
73
74 ic_logger_msg!(
75 invoke_context.get_log_collector(),
76 "Program consumption: {} units remaining",
77 invoke_context.get_remaining(),
78 );
79 Ok(0)
80 }
81);
82
83declare_builtin_function!(
84 SyscallLogPubkey,
86 fn rust(
87 invoke_context: &mut InvokeContext<'_, '_>,
88 pubkey_addr: u64,
89 _arg2: u64,
90 _arg3: u64,
91 _arg4: u64,
92 _arg5: u64,
93 ) -> Result<u64, Error> {
94 let cost = invoke_context.get_execution_cost().log_pubkey_units;
95 invoke_context.compute_meter.consume_checked(cost)?;
96
97 let check_aligned = invoke_context.get_check_aligned();
98 let memory_mapping = invoke_context.memory_contexts.memory_mapping()?;
99 let pubkey = translate_type::<Pubkey>(
100 memory_mapping,
101 pubkey_addr,
102 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 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 ) -> Result<u64, Error> {
120 let execution_cost = invoke_context.get_execution_cost();
121
122 invoke_context.compute_meter.consume_checked(execution_cost.syscall_base_cost)?;
123
124 let check_aligned = invoke_context.get_check_aligned();
125 let memory_mapping = invoke_context.memory_contexts.memory_mapping()?;
126 let untranslated_fields = translate_slice::<VmSlice<u8>>(
127 memory_mapping,
128 addr,
129 len,
130 check_aligned,
131 )?;
132
133 let cost = execution_cost
134 .syscall_base_cost
135 .saturating_mul(untranslated_fields.len() as u64);
136 invoke_context.compute_meter.consume_checked(cost)?;
137 let cost = untranslated_fields
138 .iter()
139 .fold(0u64, |total, e| total.saturating_add(e.len()));
140 invoke_context.compute_meter.consume_checked(cost)?;
141
142 let mut fields = Vec::with_capacity(untranslated_fields.len());
143
144 for untranslated_field in untranslated_fields {
145 fields.push(translate_vm_slice(untranslated_field, memory_mapping, check_aligned)?);
146 }
147
148 let log_collector = invoke_context.get_log_collector();
149
150 stable_log::program_data(&log_collector, &fields);
151
152 Ok(0)
153 }
154);