Skip to main content

rialo_s_bpf_loader_program/syscalls/
logging.rs

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