use crate::{
account::{AccountView, Ref},
error::ProgramError,
hint::unlikely,
impl_sysvar_get,
sysvars::Sysvar,
Address,
};
pub const CLOCK_ID: Address = Address::new_from_array([
6, 167, 213, 23, 24, 199, 116, 201, 40, 86, 99, 152, 105, 29, 94, 182, 139, 94, 184, 163, 155,
75, 109, 92, 115, 85, 91, 33, 0, 0, 0, 0,
]);
pub type Slot = u64;
pub type Epoch = u64;
pub type UnixTimestamp = i64;
#[repr(C)]
#[cfg_attr(feature = "copy", derive(Copy))]
#[derive(Clone, Debug)]
pub struct Clock {
pub slot: Slot,
pub epoch_start_timestamp: UnixTimestamp,
pub epoch: Epoch,
pub leader_schedule_epoch: Epoch,
pub unix_timestamp: UnixTimestamp,
}
pub const DEFAULT_TICKS_PER_SLOT: u64 = 64;
pub const DEFAULT_TICKS_PER_SECOND: u64 = 160;
pub const DEFAULT_MS_PER_SLOT: u64 = 1_000 * DEFAULT_TICKS_PER_SLOT / DEFAULT_TICKS_PER_SECOND;
impl Sysvar for Clock {
impl_sysvar_get!(CLOCK_ID, 0);
}
impl Clock {
pub const LEN: usize = 8 + 8 + 8 + 8 + 8;
#[inline]
pub fn from_account_view(account_view: &AccountView) -> Result<Ref<'_, Clock>, ProgramError> {
if unlikely(account_view.address() != &CLOCK_ID) {
return Err(ProgramError::InvalidArgument);
}
Ok(Ref::map(account_view.try_borrow()?, |data| unsafe {
Self::from_bytes_unchecked(data)
}))
}
#[inline]
pub unsafe fn from_account_view_unchecked(
account_view: &AccountView,
) -> Result<&Self, ProgramError> {
if unlikely(account_view.address() != &CLOCK_ID) {
return Err(ProgramError::InvalidArgument);
}
Ok(Self::from_bytes_unchecked(account_view.borrow_unchecked()))
}
#[inline]
pub fn from_bytes(bytes: &[u8]) -> Result<&Self, ProgramError> {
if bytes.len() < Self::LEN {
return Err(ProgramError::InvalidArgument);
}
if !bytes.as_ptr().cast::<Clock>().is_aligned() {
return Err(ProgramError::InvalidArgument);
}
Ok(unsafe { Self::from_bytes_unchecked(bytes) })
}
#[inline]
pub unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self {
&*(bytes.as_ptr() as *const Clock)
}
}