pub mod account_info;
pub mod cpi;
pub mod system;
pub use account_info::*;
use solana_program::{
entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, NON_DUP_MARKER},
pubkey::Pubkey,
};
use std::slice::from_raw_parts;
#[allow(clippy::cast_ptr_alignment, clippy::missing_safety_doc)]
#[inline(always)]
pub unsafe fn deserialize<'a, const MAX_ACCOUNTS: usize>(
input: *mut u8,
accounts: *mut std::mem::MaybeUninit<AccountInfo>,
) -> (&'a Pubkey, usize, &'a [u8]) {
let mut offset: usize = 0;
let total_accounts = *(input.add(offset) as *const u64) as usize;
let count = if total_accounts <= MAX_ACCOUNTS {
total_accounts
} else {
#[cfg(feature = "logging")]
solana_program::log::sol_log("🟡 Number of accounts exceeds MAX_ACCOUNTS");
MAX_ACCOUNTS
};
offset += std::mem::size_of::<u64>();
for i in 0..count {
let duplicate_info = *(input.add(offset) as *const u8);
if duplicate_info == NON_DUP_MARKER {
let account_info: *mut Account = input.add(offset) as *mut _;
offset += std::mem::size_of::<Account>();
offset += (*account_info).data_len as usize;
offset += MAX_PERMITTED_DATA_INCREASE;
offset += (offset as *const u8).align_offset(BPF_ALIGN_OF_U128);
offset += std::mem::size_of::<u64>();
(*account_info).borrow_state = 0b_0000_0000;
std::ptr::write(
accounts.add(i),
std::mem::MaybeUninit::new(AccountInfo {
raw: account_info as *const _ as *mut _,
}),
);
} else {
offset += 8;
std::ptr::copy_nonoverlapping(
accounts.add(duplicate_info as usize),
accounts.add(i),
1,
);
}
}
for _ in count..total_accounts {
let duplicate_info = *(input.add(offset) as *const u8);
if duplicate_info == NON_DUP_MARKER {
let account_info: *mut Account = input.add(offset) as *mut _;
offset += std::mem::size_of::<Account>();
offset += (*account_info).data_len as usize;
offset += MAX_PERMITTED_DATA_INCREASE;
offset += (offset as *const u8).align_offset(BPF_ALIGN_OF_U128);
offset += std::mem::size_of::<u64>(); } else {
offset += 8;
}
}
#[allow(clippy::cast_ptr_alignment)]
let instruction_data_len = *(input.add(offset) as *const u64) as usize;
offset += std::mem::size_of::<u64>();
let instruction_data = { from_raw_parts(input.add(offset), instruction_data_len) };
offset += instruction_data_len;
let program_id: &Pubkey = &*(input.add(offset) as *const Pubkey);
(program_id, count, instruction_data)
}