solana_sysvar/
program_stubs.rs1#![cfg(not(target_os = "solana"))]
4
5use {
6 base64::{prelude::BASE64_STANDARD, Engine},
7 solana_account_info::AccountInfo,
8 solana_instruction::Instruction,
9 solana_instruction_error::UNSUPPORTED_SYSVAR,
10 solana_program_error::ProgramResult,
11 solana_program_memory::stubs,
12 solana_pubkey::Pubkey,
13 std::sync::{Arc, RwLock},
14};
15
16lazy_static::lazy_static! {
17 static ref SYSCALL_STUBS: Arc<RwLock<Box<dyn SyscallStubs>>> = Arc::new(RwLock::new(Box::new(DefaultSyscallStubs {})));
18}
19
20pub fn set_syscall_stubs(syscall_stubs: Box<dyn SyscallStubs>) -> Box<dyn SyscallStubs> {
23 std::mem::replace(&mut SYSCALL_STUBS.write().unwrap(), syscall_stubs)
24}
25
26pub trait SyscallStubs: Sync + Send {
27 fn sol_log(&self, message: &str) {
28 println!("{message}");
29 }
30 fn sol_log_compute_units(&self) {
31 sol_log("SyscallStubs: sol_log_compute_units() not available");
32 }
33 fn sol_remaining_compute_units(&self) -> u64 {
34 sol_log("SyscallStubs: sol_remaining_compute_units() defaulting to 0");
35 0
36 }
37 fn sol_invoke_signed(
38 &self,
39 _instruction: &Instruction,
40 _account_infos: &[AccountInfo],
41 _signers_seeds: &[&[&[u8]]],
42 ) -> ProgramResult {
43 sol_log("SyscallStubs: sol_invoke_signed() not available");
44 Ok(())
45 }
46 fn sol_get_sysvar(
47 &self,
48 _sysvar_id_addr: *const u8,
49 _var_addr: *mut u8,
50 _offset: u64,
51 _length: u64,
52 ) -> u64 {
53 UNSUPPORTED_SYSVAR
54 }
55 fn sol_get_clock_sysvar(&self, _var_addr: *mut u8) -> u64 {
56 UNSUPPORTED_SYSVAR
57 }
58 fn sol_get_epoch_schedule_sysvar(&self, _var_addr: *mut u8) -> u64 {
59 UNSUPPORTED_SYSVAR
60 }
61 fn sol_get_fees_sysvar(&self, _var_addr: *mut u8) -> u64 {
62 UNSUPPORTED_SYSVAR
63 }
64 fn sol_get_rent_sysvar(&self, _var_addr: *mut u8) -> u64 {
65 UNSUPPORTED_SYSVAR
66 }
67 fn sol_get_epoch_rewards_sysvar(&self, _var_addr: *mut u8) -> u64 {
68 UNSUPPORTED_SYSVAR
69 }
70 fn sol_get_last_restart_slot(&self, _var_addr: *mut u8) -> u64 {
71 UNSUPPORTED_SYSVAR
72 }
73 fn sol_get_epoch_stake(&self, _vote_address: *const u8) -> u64 {
74 0
75 }
76 unsafe fn sol_memcpy(&self, dst: *mut u8, src: *const u8, n: usize) {
78 stubs::sol_memcpy(dst, src, n)
79 }
80 unsafe fn sol_memmove(&self, dst: *mut u8, src: *const u8, n: usize) {
82 stubs::sol_memmove(dst, src, n)
83 }
84 unsafe fn sol_memcmp(&self, s1: *const u8, s2: *const u8, n: usize, result: *mut i32) {
86 stubs::sol_memcmp(s1, s2, n, result)
87 }
88 unsafe fn sol_memset(&self, s: *mut u8, c: u8, n: usize) {
90 stubs::sol_memset(s, c, n)
91 }
92 fn sol_get_return_data(&self) -> Option<(Pubkey, Vec<u8>)> {
93 None
94 }
95 fn sol_set_return_data(&self, _data: &[u8]) {}
96 fn sol_log_data(&self, fields: &[&[u8]]) {
97 println!(
98 "data: {}",
99 fields
100 .iter()
101 .map(|v| BASE64_STANDARD.encode(v))
102 .collect::<Vec<_>>()
103 .join(" ")
104 );
105 }
106 fn sol_get_processed_sibling_instruction(&self, _index: usize) -> Option<Instruction> {
107 None
108 }
109 fn sol_get_stack_height(&self) -> u64 {
110 0
111 }
112}
113
114struct DefaultSyscallStubs {}
115impl SyscallStubs for DefaultSyscallStubs {}
116
117pub fn sol_log(message: &str) {
118 SYSCALL_STUBS.read().unwrap().sol_log(message);
119}
120
121pub fn sol_log_64(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) {
122 sol_log(&format!(
123 "{arg1:#x}, {arg2:#x}, {arg3:#x}, {arg4:#x}, {arg5:#x}"
124 ));
125}
126
127pub fn sol_log_compute_units() {
128 SYSCALL_STUBS.read().unwrap().sol_log_compute_units();
129}
130
131pub fn sol_remaining_compute_units() -> u64 {
132 SYSCALL_STUBS.read().unwrap().sol_remaining_compute_units()
133}
134
135pub fn sol_invoke_signed(
136 instruction: &Instruction,
137 account_infos: &[AccountInfo],
138 signers_seeds: &[&[&[u8]]],
139) -> ProgramResult {
140 SYSCALL_STUBS
141 .read()
142 .unwrap()
143 .sol_invoke_signed(instruction, account_infos, signers_seeds)
144}
145
146pub fn sol_get_epoch_stake(vote_address: *const u8) -> u64 {
147 SYSCALL_STUBS
148 .read()
149 .unwrap()
150 .sol_get_epoch_stake(vote_address)
151}
152
153pub fn sol_get_return_data() -> Option<(Pubkey, Vec<u8>)> {
154 SYSCALL_STUBS.read().unwrap().sol_get_return_data()
155}
156
157pub fn sol_set_return_data(data: &[u8]) {
158 SYSCALL_STUBS.read().unwrap().sol_set_return_data(data)
159}
160
161pub fn sol_log_data(data: &[&[u8]]) {
162 SYSCALL_STUBS.read().unwrap().sol_log_data(data)
163}
164
165pub fn sol_get_processed_sibling_instruction(index: usize) -> Option<Instruction> {
166 SYSCALL_STUBS
167 .read()
168 .unwrap()
169 .sol_get_processed_sibling_instruction(index)
170}
171
172pub fn sol_get_stack_height() -> u64 {
173 SYSCALL_STUBS.read().unwrap().sol_get_stack_height()
174}