solana_bpf_loader_program/syscalls/
logging.rs1use {super::*, solana_sbpf::vm::ContextObject};
2
3declare_builtin_function!(
4 SyscallLog,
6 fn rust(
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, Error> {
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 &mut |string: &str| {
27 stable_log::program_log(&invoke_context.get_log_collector(), string);
28 Ok(0)
29 },
30 )?;
31 Ok(0)
32 }
33);
34
35declare_builtin_function!(
36 SyscallLogU64,
38 fn rust(
39 invoke_context: &mut InvokeContext,
40 arg1: u64,
41 arg2: u64,
42 arg3: u64,
43 arg4: u64,
44 arg5: u64,
45 _memory_mapping: &mut MemoryMapping,
46 ) -> Result<u64, Error> {
47 let cost = invoke_context.get_compute_budget().log_64_units;
48 consume_compute_meter(invoke_context, cost)?;
49
50 stable_log::program_log(
51 &invoke_context.get_log_collector(),
52 &format!("{arg1:#x}, {arg2:#x}, {arg3:#x}, {arg4:#x}, {arg5:#x}"),
53 );
54 Ok(0)
55 }
56);
57
58declare_builtin_function!(
59 SyscallLogBpfComputeUnits,
61 fn rust(
62 invoke_context: &mut InvokeContext,
63 _arg1: u64,
64 _arg2: u64,
65 _arg3: u64,
66 _arg4: u64,
67 _arg5: u64,
68 _memory_mapping: &mut MemoryMapping,
69 ) -> Result<u64, Error> {
70 let cost = invoke_context.get_compute_budget().syscall_base_cost;
71 consume_compute_meter(invoke_context, cost)?;
72
73 ic_logger_msg!(
74 invoke_context.get_log_collector(),
75 "Program consumption: {} units remaining",
76 invoke_context.get_remaining(),
77 );
78 Ok(0)
79 }
80);
81
82declare_builtin_function!(
83 SyscallLogPubkey,
85 fn rust(
86 invoke_context: &mut InvokeContext,
87 pubkey_addr: u64,
88 _arg2: u64,
89 _arg3: u64,
90 _arg4: u64,
91 _arg5: u64,
92 memory_mapping: &mut MemoryMapping,
93 ) -> Result<u64, Error> {
94 let cost = invoke_context.get_compute_budget().log_pubkey_units;
95 consume_compute_meter(invoke_context, cost)?;
96
97 let pubkey = translate_type::<Pubkey>(
98 memory_mapping,
99 pubkey_addr,
100 invoke_context.get_check_aligned(),
101 )?;
102 stable_log::program_log(&invoke_context.get_log_collector(), &pubkey.to_string());
103 Ok(0)
104 }
105);
106
107declare_builtin_function!(
108 SyscallLogData,
110 fn rust(
111 invoke_context: &mut InvokeContext,
112 addr: u64,
113 len: u64,
114 _arg3: u64,
115 _arg4: u64,
116 _arg5: u64,
117 memory_mapping: &mut MemoryMapping,
118 ) -> Result<u64, Error> {
119 let budget = invoke_context.get_compute_budget();
120
121 consume_compute_meter(invoke_context, budget.syscall_base_cost)?;
122
123 let untranslated_fields = translate_slice_of_slices::<u8>(
124 memory_mapping,
125 addr,
126 len,
127 invoke_context.get_check_aligned(),
128 )?;
129
130 consume_compute_meter(
131 invoke_context,
132 budget
133 .syscall_base_cost
134 .saturating_mul(untranslated_fields.len() as u64),
135 )?;
136 consume_compute_meter(
137 invoke_context,
138 untranslated_fields
139 .iter()
140 .fold(0, |total, e| total.saturating_add(e.len())),
141 )?;
142
143 let mut fields = Vec::with_capacity(untranslated_fields.len());
144
145 for untranslated_field in untranslated_fields {
146 fields.push(untranslated_field.translate(memory_mapping, invoke_context.get_check_aligned())?);
147 }
148
149 let log_collector = invoke_context.get_log_collector();
150
151 stable_log::program_data(&log_collector, &fields);
152
153 Ok(0)
154 }
155);