gemachain_program/
program.rs1use crate::{
2 account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, pubkey::Pubkey,
3};
4
5pub fn invoke(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult {
10 invoke_signed(instruction, account_infos, &[])
11}
12
13pub fn invoke_signed(
18 instruction: &Instruction,
19 account_infos: &[AccountInfo],
20 signers_seeds: &[&[&[u8]]],
21) -> ProgramResult {
22 for account_meta in instruction.accounts.iter() {
24 for account_info in account_infos.iter() {
25 if account_meta.pubkey == *account_info.key {
26 if account_meta.is_writable {
27 let _ = account_info.try_borrow_mut_carats()?;
28 let _ = account_info.try_borrow_mut_data()?;
29 } else {
30 let _ = account_info.try_borrow_carats()?;
31 let _ = account_info.try_borrow_data()?;
32 }
33 break;
34 }
35 }
36 }
37
38 #[cfg(target_arch = "bpf")]
39 {
40 extern "C" {
41 fn gema_invoke_signed_rust(
42 instruction_addr: *const u8,
43 account_infos_addr: *const u8,
44 account_infos_len: u64,
45 signers_seeds_addr: *const u8,
46 signers_seeds_len: u64,
47 ) -> u64;
48 }
49
50 let result = unsafe {
51 gema_invoke_signed_rust(
52 instruction as *const _ as *const u8,
53 account_infos as *const _ as *const u8,
54 account_infos.len() as u64,
55 signers_seeds as *const _ as *const u8,
56 signers_seeds.len() as u64,
57 )
58 };
59 match result {
60 crate::entrypoint::SUCCESS => Ok(()),
61 _ => Err(result.into()),
62 }
63 }
64
65 #[cfg(not(target_arch = "bpf"))]
66 crate::program_stubs::gema_invoke_signed(instruction, account_infos, signers_seeds)
67}
68
69pub const MAX_RETURN_DATA: usize = 1024;
71
72pub fn set_return_data(data: &[u8]) {
74 #[cfg(target_arch = "bpf")]
75 {
76 extern "C" {
77 fn gema_set_return_data(data: *const u8, length: u64);
78 }
79
80 unsafe { gema_set_return_data(data.as_ptr(), data.len() as u64) };
81 }
82
83 #[cfg(not(target_arch = "bpf"))]
84 crate::program_stubs::gema_set_return_data(data)
85}
86
87pub fn get_return_data() -> Option<(Pubkey, Vec<u8>)> {
89 #[cfg(target_arch = "bpf")]
90 {
91 use std::cmp::min;
92
93 extern "C" {
94 fn gema_get_return_data(data: *mut u8, length: u64, program_id: *mut Pubkey) -> u64;
95 }
96
97 let mut buf = [0u8; MAX_RETURN_DATA];
98 let mut program_id = Pubkey::default();
99
100 let size =
101 unsafe { gema_get_return_data(buf.as_mut_ptr(), buf.len() as u64, &mut program_id) };
102
103 if size == 0 {
104 None
105 } else {
106 let size = min(size as usize, MAX_RETURN_DATA);
107 Some((program_id, buf[..size as usize].to_vec()))
108 }
109 }
110
111 #[cfg(not(target_arch = "bpf"))]
112 crate::program_stubs::gema_get_return_data()
113}