use std::cell::Ref;
use crate::{Pubkey, *};
#[derive(Clone, Copy, Debug, bytemuck::Pod, bytemuck::Zeroable)]
#[repr(C)]
pub struct RandomnessAccountData {
pub authority: Pubkey,
pub queue: Pubkey,
pub seed_slothash: [u8; 32],
pub seed_slot: u64,
pub oracle: Pubkey,
pub reveal_slot: u64,
pub value: [u8; 32],
_ebuf2: [u8; 96],
_ebuf1: [u8; 128],
}
impl Discriminator for RandomnessAccountData {
const DISCRIMINATOR: &'static [u8] = &[10, 66, 229, 135, 220, 239, 217, 114];
}
impl Owner for RandomnessAccountData {
fn owner() -> Pubkey {
if crate::utils::is_devnet() {
get_sb_program_id("devnet")
} else {
get_sb_program_id("mainnet")
}
}
}
cfg_anchor! {
impl_account_deserialize!(RandomnessAccountData);
}
impl RandomnessAccountData {
pub const fn size() -> usize {
std::mem::size_of::<Self>() + 8
}
pub fn get_value(&self, clock_slot: u64) -> std::result::Result<[u8; 32], OnDemandError> {
if clock_slot != self.reveal_slot {
return Err(OnDemandError::SwitchboardRandomnessTooOld);
}
Ok(self.value)
}
pub fn is_revealable(&self, clock_slot: u64) -> bool {
self.seed_slot < clock_slot
}
pub fn parse<'info>(
data: Ref<'info, &mut [u8]>,
) -> std::result::Result<Ref<'info, Self>, OnDemandError> {
if data.len() < Self::DISCRIMINATOR.len() {
return Err(OnDemandError::InvalidDiscriminator);
}
let mut disc_bytes = [0u8; 8];
disc_bytes.copy_from_slice(&data[..8]);
if disc_bytes != *Self::DISCRIMINATOR {
return Err(OnDemandError::InvalidDiscriminator);
}
let expected_size = std::mem::size_of::<Self>() + 8;
if data.len() < expected_size {
return Err(OnDemandError::InvalidData);
}
let slice_to_parse = &data[8..expected_size];
if slice_to_parse.len() != std::mem::size_of::<Self>() {
return Err(OnDemandError::InvalidData);
}
match bytemuck::try_from_bytes::<Self>(slice_to_parse) {
Ok(_) => {
Ok(Ref::map(data, |data: &&mut [u8]| {
bytemuck::from_bytes(&data[8..std::mem::size_of::<Self>() + 8])
}))
}
Err(_) => Err(OnDemandError::AccountDeserializeError),
}
}
cfg_client! {
pub async fn fetch_async(
client: &crate::RpcClient,
pubkey: Pubkey,
) -> std::result::Result<Self, crate::OnDemandError> {
let pubkey = pubkey.to_bytes().into();
crate::client::fetch_zerocopy_account(client, pubkey).await
}
}
}