#[cfg(feature = "anchor")]
use anchor_lang::solana_program;
use solana_program::account_info::AccountInfo;
use anyhow::Error as AnyhowError;
use crate::sysvar::ed25519_sysvar::{Ed25519Sysvar, ParsedEd25519SignatureDataRef};
#[derive(Copy, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct Instructions;
#[cfg(feature = "anchor")]
impl anchor_lang::solana_program::sysvar::SysvarId for Instructions {
fn id() -> solana_program::pubkey::Pubkey {
solana_program::sysvar::instructions::id().to_bytes().into()
}
fn check_id(id: &solana_program::pubkey::Pubkey) -> bool {
solana_program::sysvar::instructions::id() == id.to_bytes().into()
}
}
#[cfg(feature = "anchor")]
impl anchor_lang::solana_program::sysvar::Sysvar for Instructions {
fn size_of() -> usize {
0 }
fn from_account_info(
_account_info: &anchor_lang::prelude::AccountInfo,
) -> Result<Self, solana_program::program_error::ProgramError> {
Ok(Self {})
}
}
impl Instructions {
pub fn parse_ed25519_from_data(
data: &[u8],
) -> Result<([ParsedEd25519SignatureDataRef<'_>; 8], u8, &[u8], u64, u8), AnyhowError> {
Ed25519Sysvar::parse_instruction_zero_copy(data).map_err(|e| e)
}
#[inline(always)]
pub fn parse_data(index: usize, data: &[u8]) -> &[u8] {
use solana_program_ed25519_dalek_bump::serialize_utils::read_u16;
let mut current = 0;
assert!(data.len() >= 2);
let num_instructions = read_u16(&mut current, data).unwrap();
assert!(index < num_instructions as usize);
current += index * 2;
let start = read_u16(&mut current, data).unwrap();
current = start as usize;
current += 34;
let data_len = read_u16(&mut current, data).unwrap();
&data[current..current + data_len as usize]
}
#[inline(always)]
pub fn parse_instruction_0_data<'a>(ai: &AccountInfo<'a>) -> &'a [u8] {
unsafe {
let slice_ptr = (*std::rc::Rc::as_ptr(&ai.data)).as_ptr();
let base = (*slice_ptr).as_ptr();
let mut p = base.add(2);
let cursor = (p as *const u16).read_unaligned() as usize;
p = base.add(cursor);
let _ = 1u8 / !*p;
p = p.add(34);
let data_len = (p as *const u16).read_unaligned() as usize;
p = p.add(2);
core::slice::from_raw_parts(p, data_len)
}
}
}
#[inline(always)]
fn min_branchless(a: u16, b: u16) -> usize {
let mask = ((a < b) as i16).wrapping_neg() as u16;
((a & mask) | (b & !mask)) as usize
}