2021-06-09 13:02:50 -07:00
|
|
|
use crate::error::ErrorCode;
|
2021-08-31 00:27:26 -07:00
|
|
|
use crate::{Accounts, AccountsExit, Key, ToAccountInfo, ToAccountInfos, ToAccountMetas};
|
2021-01-15 20:10:24 -08:00
|
|
|
use solana_program::account_info::AccountInfo;
|
2021-01-20 17:13:02 -08:00
|
|
|
use solana_program::entrypoint::ProgramResult;
|
2021-01-15 20:10:24 -08:00
|
|
|
use solana_program::instruction::AccountMeta;
|
|
|
|
use solana_program::program_error::ProgramError;
|
|
|
|
use solana_program::pubkey::Pubkey;
|
2021-01-14 22:35:50 -08:00
|
|
|
use std::ops::{Deref, DerefMut};
|
|
|
|
|
|
|
|
/// Container for sysvars.
|
2021-01-15 20:10:24 -08:00
|
|
|
pub struct Sysvar<'info, T: solana_program::sysvar::Sysvar> {
|
2021-01-14 22:35:50 -08:00
|
|
|
info: AccountInfo<'info>,
|
|
|
|
account: T,
|
|
|
|
}
|
|
|
|
|
2021-01-15 20:10:24 -08:00
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> Sysvar<'info, T> {
|
2021-01-14 22:35:50 -08:00
|
|
|
pub fn from_account_info(
|
|
|
|
acc_info: &AccountInfo<'info>,
|
|
|
|
) -> Result<Sysvar<'info, T>, ProgramError> {
|
|
|
|
Ok(Sysvar {
|
|
|
|
info: acc_info.clone(),
|
2021-06-27 17:09:46 -07:00
|
|
|
account: T::from_account_info(acc_info)?,
|
2021-01-14 22:35:50 -08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-09 00:54:37 -08:00
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> Clone for Sysvar<'info, T> {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
Self {
|
|
|
|
info: self.info.clone(),
|
|
|
|
account: T::from_account_info(&self.info).unwrap(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 20:10:24 -08:00
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> Accounts<'info> for Sysvar<'info, T> {
|
2021-01-14 22:35:50 -08:00
|
|
|
fn try_accounts(
|
|
|
|
_program_id: &Pubkey,
|
|
|
|
accounts: &mut &[AccountInfo<'info>],
|
2021-06-15 17:15:51 -07:00
|
|
|
_ix_data: &[u8],
|
2021-01-14 22:35:50 -08:00
|
|
|
) -> Result<Self, ProgramError> {
|
2021-02-15 21:52:54 -08:00
|
|
|
if accounts.is_empty() {
|
2021-06-09 13:02:50 -07:00
|
|
|
return Err(ErrorCode::AccountNotEnoughKeys.into());
|
2021-01-14 22:35:50 -08:00
|
|
|
}
|
|
|
|
let account = &accounts[0];
|
|
|
|
*accounts = &accounts[1..];
|
|
|
|
Sysvar::from_account_info(account)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 20:10:24 -08:00
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> ToAccountMetas for Sysvar<'info, T> {
|
2021-01-23 00:18:50 -08:00
|
|
|
fn to_account_metas(&self, _is_signer: Option<bool>) -> Vec<AccountMeta> {
|
2021-01-14 22:35:50 -08:00
|
|
|
vec![AccountMeta::new_readonly(*self.info.key, false)]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 20:10:24 -08:00
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> ToAccountInfos<'info> for Sysvar<'info, T> {
|
2021-01-14 22:35:50 -08:00
|
|
|
fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
|
|
|
|
vec![self.info.clone()]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-31 00:27:26 -07:00
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> AsRef<AccountInfo<'info>> for Sysvar<'info, T> {
|
|
|
|
fn as_ref(&self) -> &AccountInfo<'info> {
|
|
|
|
&self.info
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 20:10:24 -08:00
|
|
|
impl<'a, T: solana_program::sysvar::Sysvar> Deref for Sysvar<'a, T> {
|
2021-01-14 22:35:50 -08:00
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.account
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 20:10:24 -08:00
|
|
|
impl<'a, T: solana_program::sysvar::Sysvar> DerefMut for Sysvar<'a, T> {
|
2021-01-14 22:35:50 -08:00
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
|
|
&mut self.account
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-15 20:10:24 -08:00
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> ToAccountInfo<'info> for Sysvar<'info, T> {
|
2021-01-14 22:35:50 -08:00
|
|
|
fn to_account_info(&self) -> AccountInfo<'info> {
|
|
|
|
self.info.clone()
|
|
|
|
}
|
|
|
|
}
|
2021-01-20 17:13:02 -08:00
|
|
|
|
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> AccountsExit<'info> for Sysvar<'info, T> {
|
|
|
|
fn exit(&self, _program_id: &Pubkey) -> ProgramResult {
|
|
|
|
// no-op
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
2021-08-31 00:27:26 -07:00
|
|
|
|
|
|
|
impl<'info, T: solana_program::sysvar::Sysvar> Key for Sysvar<'info, T> {
|
|
|
|
fn key(&self) -> Pubkey {
|
|
|
|
*self.info.key
|
|
|
|
}
|
|
|
|
}
|