solana_invoke/
lib.rs

1#![doc = include_str!("../README.md")]
2#![allow(unexpected_cfgs)]
3
4use solana_account_info::AccountInfo;
5use solana_instruction::Instruction;
6use solana_program_entrypoint::ProgramResult;
7
8mod stable_instruction_borrowed;
9
10pub fn invoke(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult {
11    invoke_signed(instruction, account_infos, &[])
12}
13
14pub fn invoke_unchecked(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult {
15    invoke_signed_unchecked(instruction, account_infos, &[])
16}
17
18pub fn invoke_signed(
19    instruction: &Instruction,
20    account_infos: &[AccountInfo],
21    signers_seeds: &[&[&[u8]]],
22) -> ProgramResult {
23    // Check that the account RefCells are consistent with the request
24    for account_meta in instruction.accounts.iter() {
25        for account_info in account_infos.iter() {
26            if account_meta.pubkey == *account_info.key {
27                if account_meta.is_writable {
28                    let _ = account_info.try_borrow_mut_lamports()?;
29                    let _ = account_info.try_borrow_mut_data()?;
30                } else {
31                    let _ = account_info.try_borrow_lamports()?;
32                    let _ = account_info.try_borrow_data()?;
33                }
34                break;
35            }
36        }
37    }
38
39    invoke_signed_unchecked(instruction, account_infos, signers_seeds)
40}
41
42#[cfg(target_os = "solana")]
43use solana_define_syscall::definitions::sol_invoke_signed_rust;
44
45#[cfg(not(target_os = "solana"))]
46unsafe fn sol_invoke_signed_rust(_: *const u8, _: *const u8, _: u64, _: *const u8, _: u64) -> u64 {
47    unimplemented!("only supported with `target_os = \"solana\"")
48}
49
50pub fn invoke_signed_unchecked(
51    instruction: &Instruction,
52    account_infos: &[AccountInfo],
53    signers_seeds: &[&[&[u8]]],
54) -> ProgramResult {
55    use stable_instruction_borrowed::StableInstructionBorrowed;
56    let stable = StableInstructionBorrowed::new(instruction);
57    let instruction_addr = stable.instruction_addr();
58
59    let result = unsafe {
60        sol_invoke_signed_rust(
61            instruction_addr,
62            account_infos as *const _ as *const u8,
63            account_infos.len() as u64,
64            signers_seeds as *const _ as *const u8,
65            signers_seeds.len() as u64,
66        )
67    };
68
69    match result {
70        solana_program_entrypoint::SUCCESS => Ok(()),
71        _ => Err(result.into()),
72    }
73}