Skip to content

Instantly share code, notes, and snippets.

@mgild
Created August 6, 2024 15:42
Show Gist options
  • Save mgild/2039dc7c82a943a5852ac1a888bdd753 to your computer and use it in GitHub Desktop.
Save mgild/2039dc7c82a943a5852ac1a888bdd753 to your computer and use it in GitHub Desktop.
use anchor_lang::prelude::*;
use arrayref::array_ref;
use bytemuck;
use crate::SwitchboardError;
#[repr(C)]
#[derive(bytemuck::Pod, bytemuck::Zeroable, Debug, Clone, Copy)]
pub struct SlotHash {
pub slot: u64,
pub hash: [u8; 32],
}
// Need to binary search since slots are often skipped
pub fn find_idx(slot_hashes: &[SlotHash], slot: u64) -> Option<usize> {
slot_hashes.binary_search_by(|x| slot.cmp(&x.slot)).ok()
}
pub struct SlotHashSysvar;
impl<'a> SlotHashSysvar {
pub fn get_slothash(slot_sysvar: &AccountInfo<'a>, slot: u64) -> Result<[u8; 32]> {
let slot_hashes = slot_sysvar;
let slots_data = slot_hashes.data.borrow();
let slots: &[u8] = array_ref![slots_data, 8, 20_480];
// 20_480 / 40 = 512
let slots: &[SlotHash] = bytemuck::cast_slice::<u8, SlotHash>(slots);
if slot > slots[0].slot {
msg!("Error: Your provided slot is too new. Please use confirmed commitment for your connection and processed for simulation.");
return Err(error!(SwitchboardError::InvalidSlotNumber));
}
let idx = find_idx(&slots[..], slot).unwrap();
let signed_slot = slots[idx];
assert_eq!(signed_slot.slot, slot);
Ok(signed_slot.hash)
}
pub fn parse(data: &'a [u8]) -> &'a [SlotHash] {
bytemuck::cast_slice::<u8, SlotHash>(&data[8..])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment