solana_bpf_loader_program/syscalls/
logging.rs1use {super::*, crate::declare_syscall, solana_rbpf::vm::ContextObject};
2
3declare_syscall!(
4 SyscallLog,
6 fn inner_call(
7 invoke_context: &mut InvokeContext,
8 addr: u64,
9 len: u64,
10 _arg3: u64,
11 _arg4: u64,
12 _arg5: u64,
13 memory_mapping: &mut MemoryMapping,
14 ) -> Result<u64, EbpfError> {
15 let cost = invoke_context
16 .get_compute_budget()
17 .syscall_base_cost
18 .max(len);
19 consume_compute_meter(invoke_context, cost)?;
20
21 translate_string_and_do(
22 memory_mapping,
23 addr,
24 len,
25 invoke_context.get_check_aligned(),
26 invoke_context.get_check_size(),
27 &mut |string: &str| {
28 stable_log::program_log(&invoke_context.get_log_collector(), string);
29 Ok(0)
30 },
31 )?;
32 Ok(0)
33 }
34);
35
36declare_syscall!(
37 SyscallLogU64,
39 fn inner_call(
40 invoke_context: &mut InvokeContext,
41 arg1: u64,
42 arg2: u64,
43 arg3: u64,
44 arg4: u64,
45 arg5: u64,
46 _memory_mapping: &mut MemoryMapping,
47 ) -> Result<u64, EbpfError> {
48 let cost = invoke_context.get_compute_budget().log_64_units;
49 consume_compute_meter(invoke_context, cost)?;
50
51 stable_log::program_log(
52 &invoke_context.get_log_collector(),
53 &format!("{arg1:#x}, {arg2:#x}, {arg3:#x}, {arg4:#x}, {arg5:#x}"),
54 );
55 Ok(0)
56 }
57);
58
59declare_syscall!(
60 SyscallLogBpfComputeUnits,
62 fn inner_call(
63 invoke_context: &mut InvokeContext,
64 _arg1: u64,
65 _arg2: u64,
66 _arg3: u64,
67 _arg4: u64,
68 _arg5: u64,
69 _memory_mapping: &mut MemoryMapping,
70 ) -> Result<u64, EbpfError> {
71 let cost = invoke_context.get_compute_budget().syscall_base_cost;
72 consume_compute_meter(invoke_context, 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_syscall!(
84 SyscallLogPubkey,
86 fn inner_call(
87 invoke_context: &mut InvokeContext,
88 pubkey_addr: u64,
89 _arg2: u64,
90 _arg3: u64,
91 _arg4: u64,
92 _arg5: u64,
93 memory_mapping: &mut MemoryMapping,
94 ) -> Result<u64, EbpfError> {
95 let cost = invoke_context.get_compute_budget().log_pubkey_units;
96 consume_compute_meter(invoke_context, cost)?;
97
98 let pubkey = translate_type::<Pubkey>(
99 memory_mapping,
100 pubkey_addr,
101 invoke_context.get_check_aligned(),
102 )?;
103 stable_log::program_log(&invoke_context.get_log_collector(), &pubkey.to_string());
104 Ok(0)
105 }
106);
107
108declare_syscall!(
109 SyscallLogData,
111 fn inner_call(
112 invoke_context: &mut InvokeContext,
113 addr: u64,
114 len: u64,
115 _arg3: u64,
116 _arg4: u64,
117 _arg5: u64,
118 memory_mapping: &mut MemoryMapping,
119 ) -> Result<u64, EbpfError> {
120 let budget = invoke_context.get_compute_budget();
121
122 consume_compute_meter(invoke_context, budget.syscall_base_cost)?;
123
124 let untranslated_fields = translate_slice::<&[u8]>(
125 memory_mapping,
126 addr,
127 len,
128 invoke_context.get_check_aligned(),
129 invoke_context.get_check_size(),
130 )?;
131
132 consume_compute_meter(
133 invoke_context,
134 budget
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() as u64)),
143 )?;
144
145 let mut fields = Vec::with_capacity(untranslated_fields.len());
146
147 for untranslated_field in untranslated_fields {
148 fields.push(translate_slice::<u8>(
149 memory_mapping,
150 untranslated_field.as_ptr() as *const _ as u64,
151 untranslated_field.len() as u64,
152 invoke_context.get_check_aligned(),
153 invoke_context.get_check_size(),
154 )?);
155 }
156
157 let log_collector = invoke_context.get_log_collector();
158
159 stable_log::program_data(&log_collector, &fields);
160
161 Ok(0)
162 }
163);