Skip to main content

rialo_s_invoke/
lib.rs

1#![allow(unsafe_code)]
2#![allow(clippy::ptr_as_ptr)]
3#![allow(unexpected_cfgs)]
4
5use rialo_s_account_info::AccountInfo;
6use rialo_s_instruction::Instruction;
7use rialo_s_program_entrypoint::ProgramResult;
8
9#[cfg(all(target_os = "solana", not(target_arch = "riscv64")))]
10mod stable_instruction_borrowed;
11
12pub fn invoke(instruction: &Instruction, account_infos: &[AccountInfo<'_>]) -> ProgramResult {
13    invoke_signed(instruction, account_infos, &[])
14}
15
16pub fn invoke_unchecked(
17    instruction: &Instruction,
18    account_infos: &[AccountInfo<'_>],
19) -> ProgramResult {
20    invoke_signed_unchecked(instruction, account_infos, &[])
21}
22
23pub fn invoke_signed(
24    instruction: &Instruction,
25    account_infos: &[AccountInfo<'_>],
26    signers_seeds: &[&[&[u8]]],
27) -> ProgramResult {
28    // Check that the account RefCells are consistent with the request
29    for account_meta in instruction.accounts.iter() {
30        for account_info in account_infos.iter() {
31            if account_meta.pubkey == *account_info.key {
32                if account_meta.is_writable {
33                    let _ = account_info.try_borrow_mut_kelvins()?;
34                    let _ = account_info.try_borrow_mut_data()?;
35                } else {
36                    let _ = account_info.try_borrow_kelvins()?;
37                    let _ = account_info.try_borrow_data()?;
38                }
39                break;
40            }
41        }
42    }
43
44    invoke_signed_unchecked(instruction, account_infos, signers_seeds)
45}
46
47#[cfg(target_os = "solana")]
48use rialo_s_define_syscall::definitions::rlo_invoke_signed_rust;
49
50#[cfg(not(target_os = "solana"))]
51#[allow(dead_code)]
52unsafe fn rlo_invoke_signed_rust(_: *const u8, _: *const u8, _: u64, _: *const u8, _: u64) -> u64 {
53    unimplemented!("only supported with `target_os = \"solana\"")
54}
55
56#[allow(unused_variables)]
57pub fn invoke_signed_unchecked(
58    instruction: &Instruction,
59    account_infos: &[AccountInfo<'_>],
60    signers_seeds: &[&[&[u8]]],
61) -> ProgramResult {
62    #[cfg(all(target_os = "solana", not(target_arch = "riscv64")))]
63    {
64        // BPF: Use StableInstruction (existing behavior)
65        use stable_instruction_borrowed::StableInstructionBorrowed;
66        let stable = StableInstructionBorrowed::new(instruction);
67        let instruction_addr = stable.instruction_addr();
68
69        let result = unsafe {
70            rlo_invoke_signed_rust(
71                instruction_addr,
72                account_infos as *const _ as *const u8,
73                account_infos.len() as u64,
74                signers_seeds as *const _ as *const u8,
75                signers_seeds.len() as u64,
76            )
77        };
78
79        match result {
80            rialo_s_program_entrypoint::SUCCESS => Ok(()),
81            _ => Err(result.into()),
82        }
83    }
84
85    #[cfg(all(target_os = "solana", target_arch = "riscv64"))]
86    {
87        // RISC-V: Use HostInstruction (correct layout for loader)
88        use rialo_s_cpi::{marshal_accounts, marshal_instruction};
89
90        let host_instruction = marshal_instruction(instruction);
91        let host_accounts = marshal_accounts(account_infos);
92
93        let result = unsafe {
94            rlo_invoke_signed_rust(
95                &host_instruction as *const _ as *const u8,
96                host_accounts.as_ptr() as *const u8,
97                host_accounts.len() as u64,
98                signers_seeds as *const _ as *const u8,
99                signers_seeds.len() as u64,
100            )
101        };
102
103        match result {
104            rialo_s_program_entrypoint::SUCCESS => Ok(()),
105            _ => Err(result.into()),
106        }
107    }
108
109    #[cfg(not(target_os = "solana"))]
110    Ok(())
111}