1pub mod account_info;
17pub mod cpi;
18pub mod system;
19
20pub use account_info::*;
21
22use solana_program::{
23 entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, NON_DUP_MARKER},
24 pubkey::Pubkey,
25};
26use std::slice::from_raw_parts;
27
28#[allow(clippy::cast_ptr_alignment, clippy::missing_safety_doc)]
33#[inline(always)]
34pub unsafe fn deserialize<'a, const MAX_ACCOUNTS: usize>(
35 input: *mut u8,
36 accounts: *mut std::mem::MaybeUninit<AccountInfo>,
37) -> (&'a Pubkey, usize, &'a [u8]) {
38 let mut offset: usize = 0;
39
40 let total_accounts = *(input.add(offset) as *const u64) as usize;
42
43 let count = if total_accounts <= MAX_ACCOUNTS {
45 total_accounts
46 } else {
47 #[cfg(feature = "logging")]
48 solana_program::log::sol_log("🟡 Number of accounts exceeds MAX_ACCOUNTS");
49
50 MAX_ACCOUNTS
51 };
52
53 offset += std::mem::size_of::<u64>();
54
55 for i in 0..count {
56 let duplicate_info = *(input.add(offset) as *const u8);
57 if duplicate_info == NON_DUP_MARKER {
58 let account_info: *mut Account = input.add(offset) as *mut _;
62
63 offset += std::mem::size_of::<Account>();
64 offset += (*account_info).data_len as usize;
65 offset += MAX_PERMITTED_DATA_INCREASE;
66 offset += (offset as *const u8).align_offset(BPF_ALIGN_OF_U128);
67 offset += std::mem::size_of::<u64>(); (*account_info).borrow_state = 0b_0000_0000;
71
72 std::ptr::write(
73 accounts.add(i),
74 std::mem::MaybeUninit::new(AccountInfo {
75 raw: account_info as *const _ as *mut _,
76 }),
77 );
78 } else {
79 offset += 8;
80 std::ptr::copy_nonoverlapping(
82 accounts.add(duplicate_info as usize),
83 accounts.add(i),
84 1,
85 );
86 }
87 }
88
89 for _ in count..total_accounts {
93 let duplicate_info = *(input.add(offset) as *const u8);
94
95 if duplicate_info == NON_DUP_MARKER {
96 let account_info: *mut Account = input.add(offset) as *mut _;
97 offset += std::mem::size_of::<Account>();
98 offset += (*account_info).data_len as usize;
99 offset += MAX_PERMITTED_DATA_INCREASE;
100 offset += (offset as *const u8).align_offset(BPF_ALIGN_OF_U128);
101 offset += std::mem::size_of::<u64>(); } else {
103 offset += 8;
104 }
105 }
106
107 #[allow(clippy::cast_ptr_alignment)]
109 let instruction_data_len = *(input.add(offset) as *const u64) as usize;
110 offset += std::mem::size_of::<u64>();
111
112 let instruction_data = { from_raw_parts(input.add(offset), instruction_data_len) };
113 offset += instruction_data_len;
114
115 let program_id: &Pubkey = &*(input.add(offset) as *const Pubkey);
117
118 (program_id, count, instruction_data)
119}