use hayabusa_ser::{FromBytesUnchecked, RawZcDeserialize, Deserialize, Zc};
use hayabusa_utility::fail_with_ctx;
use pinocchio::{
account_info::{AccountInfo, Ref}, hint::unlikely, program_error::ProgramError, pubkey::Pubkey
};
pub const MAX_MULTISIG_SIGNERS: usize = 11;
#[repr(C)]
pub struct Multisig {
m: u8,
n: u8,
is_initialized: u8,
signers: [Pubkey; MAX_MULTISIG_SIGNERS],
}
impl Zc for Multisig {}
impl Deserialize for Multisig {}
unsafe impl RawZcDeserialize for Multisig {
fn try_deserialize_raw<'a>(account_info: &'a AccountInfo) -> hayabusa_errors::Result<Ref<'a, Self>> {
if unlikely(account_info.data_len() != Self::LEN) {
fail_with_ctx!(
"HAYABUSA_SER_MULTISIG_ACCOUNT_DATA_TOO_SHORT",
ProgramError::InvalidAccountData,
account_info.key(),
&u32::to_le_bytes(account_info.data_len() as u32),
);
}
if unlikely(!account_info.is_owned_by(&crate::ID)) {
fail_with_ctx!(
"HAYABUSA_SER_MULTISIG_INVALID_OWNER",
ProgramError::InvalidAccountOwner,
account_info.key(),
account_info.owner(),
);
}
Ok(Ref::map(account_info.try_borrow_data()?, |d| unsafe {
Self::from_bytes_unchecked(d)
}))
}
}
impl FromBytesUnchecked for Multisig {}
impl Multisig {
pub const LEN: usize = size_of::<Multisig>();
#[inline(always)]
pub const fn required_signers(&self) -> u8 {
self.m
}
#[inline(always)]
pub const fn signers_len(&self) -> usize {
self.n as usize
}
#[inline(always)]
pub fn signers(&self) -> &[Pubkey] {
unsafe { self.signers.get_unchecked(..self.signers_len()) }
}
#[inline(always)]
pub fn is_initialized(&self) -> bool {
self.is_initialized != 0
}
}