use steel::*;
use super::EntropyAccount;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct Var {
pub authority: Pubkey,
pub id: u64,
pub provider: Pubkey,
pub commit: [u8; 32],
pub seed: [u8; 32],
pub slot_hash: [u8; 32],
pub value: [u8; 32],
pub samples: u64,
pub is_auto: u64,
pub start_at: u64,
pub end_at: u64,
}
impl Var {
pub fn finalize(&mut self, seed: [u8; 32]) -> ProgramResult {
if self.seed != [0; 32] {
return Ok(());
}
if !self.is_valid(seed) {
return Err(trace("Invalid seed", ProgramError::InvalidInstructionData));
}
self.seed = seed;
self.value = solana_program::keccak::hashv(&[
&self.slot_hash,
&self.seed,
&self.samples.to_le_bytes(),
])
.to_bytes();
Ok(())
}
pub fn is_valid(&self, seed: [u8; 32]) -> bool {
if self.slot_hash == [0; 32] {
return false;
}
if self.value != [0; 32] {
return false;
}
if self.samples == 0 {
return false;
}
let expected_commit = solana_program::keccak::hash(&seed).to_bytes();
expected_commit == self.commit
}
}
account!(EntropyAccount, Var);