solana_program/
instruction.rs1#[cfg(feature = "frozen-abi")]
2use solana_frozen_abi_macro::AbiExample;
3pub use solana_instruction::{
4 error::InstructionError, AccountMeta, Instruction, ProcessedSiblingInstruction,
5 TRANSACTION_LEVEL_STACK_HEIGHT,
6};
7use {
8 bincode::serialize, serde::Serialize, solana_pubkey::Pubkey, solana_sanitize::Sanitize,
9 solana_short_vec as short_vec,
10};
11
12#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
20#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
21#[serde(rename_all = "camelCase")]
22pub struct CompiledInstruction {
23 pub program_id_index: u8,
25 #[serde(with = "short_vec")]
27 pub accounts: Vec<u8>,
28 #[serde(with = "short_vec")]
30 pub data: Vec<u8>,
31}
32
33impl Sanitize for CompiledInstruction {}
34
35impl CompiledInstruction {
36 pub fn new<T: Serialize>(program_ids_index: u8, data: &T, accounts: Vec<u8>) -> Self {
37 let data = serialize(data).unwrap();
38 Self {
39 program_id_index: program_ids_index,
40 accounts,
41 data,
42 }
43 }
44
45 pub fn new_from_raw_parts(program_id_index: u8, data: Vec<u8>, accounts: Vec<u8>) -> Self {
46 Self {
47 program_id_index,
48 accounts,
49 data,
50 }
51 }
52
53 pub fn program_id<'a>(&self, program_ids: &'a [Pubkey]) -> &'a Pubkey {
54 &program_ids[self.program_id_index as usize]
55 }
56}
57
58pub fn get_processed_sibling_instruction(index: usize) -> Option<Instruction> {
71 #[cfg(target_os = "solana")]
72 {
73 let mut meta = ProcessedSiblingInstruction::default();
74 let mut program_id = solana_pubkey::Pubkey::default();
75
76 if 1 == unsafe {
77 solana_instruction::syscalls::sol_get_processed_sibling_instruction(
78 index as u64,
79 &mut meta,
80 &mut program_id,
81 &mut u8::default(),
82 &mut AccountMeta::default(),
83 )
84 } {
85 let mut data = Vec::new();
86 let mut accounts = Vec::new();
87 data.resize_with(meta.data_len as usize, u8::default);
88 accounts.resize_with(meta.accounts_len as usize, AccountMeta::default);
89
90 let _ = unsafe {
91 solana_instruction::syscalls::sol_get_processed_sibling_instruction(
92 index as u64,
93 &mut meta,
94 &mut program_id,
95 data.as_mut_ptr(),
96 accounts.as_mut_ptr(),
97 )
98 };
99
100 Some(Instruction::new_with_bytes(program_id, &data, accounts))
101 } else {
102 None
103 }
104 }
105
106 #[cfg(not(target_os = "solana"))]
107 crate::program_stubs::sol_get_processed_sibling_instruction(index)
108}
109
110pub fn get_stack_height() -> usize {
114 #[cfg(target_os = "solana")]
115 unsafe {
116 solana_instruction::syscalls::sol_get_stack_height() as usize
117 }
118
119 #[cfg(not(target_os = "solana"))]
120 {
121 crate::program_stubs::sol_get_stack_height() as usize
122 }
123}
124
125#[doc(hidden)]
130pub fn checked_add(a: u64, b: u64) -> Result<u64, InstructionError> {
131 a.checked_add(b).ok_or(InstructionError::InsufficientFunds)
132}