anchor_lang/accounts/
sysvar.rs1use {
4 crate::{
5 error::ErrorCode,
6 solana_program::{account_info::AccountInfo, instruction::AccountMeta, pubkey::Pubkey},
7 Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas,
8 },
9 solana_sysvar::{Sysvar as SolanaSysvar, SysvarSerialize as SolanaSysvarSerialize},
10 std::{
11 collections::BTreeSet,
12 fmt,
13 ops::{Deref, DerefMut},
14 },
15};
16
17pub struct Sysvar<'info, T: SolanaSysvar> {
39 info: &'info AccountInfo<'info>,
40 account: T,
41}
42
43impl<T: SolanaSysvarSerialize + fmt::Debug> fmt::Debug for Sysvar<'_, T> {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 f.debug_struct("Sysvar")
46 .field("info", &self.info)
47 .field("account", &self.account)
48 .finish()
49 }
50}
51
52impl<'info, T: SolanaSysvarSerialize> Sysvar<'info, T> {
53 pub fn from_account_info(acc_info: &'info AccountInfo<'info>) -> Result<Sysvar<'info, T>> {
54 match T::from_account_info(acc_info) {
55 Ok(val) => Ok(Sysvar {
56 info: acc_info,
57 account: val,
58 }),
59 Err(_) => Err(ErrorCode::AccountSysvarMismatch.into()),
60 }
61 }
62}
63
64impl<T: SolanaSysvarSerialize> Clone for Sysvar<'_, T> {
65 fn clone(&self) -> Self {
66 Self {
67 info: self.info,
68 account: T::from_account_info(self.info).unwrap(),
69 }
70 }
71}
72
73impl<'info, B, T: SolanaSysvarSerialize> Accounts<'info, B> for Sysvar<'info, T> {
74 fn try_accounts(
75 _program_id: &Pubkey,
76 accounts: &mut &'info [AccountInfo<'info>],
77 _ix_data: &[u8],
78 _bumps: &mut B,
79 _reallocs: &mut BTreeSet<Pubkey>,
80 ) -> Result<Self> {
81 if accounts.is_empty() {
82 return Err(ErrorCode::AccountNotEnoughKeys.into());
83 }
84 let account = &accounts[0];
85 *accounts = &accounts[1..];
86 Sysvar::from_account_info(account)
87 }
88}
89
90impl<T: SolanaSysvarSerialize> ToAccountMetas for Sysvar<'_, T> {
91 fn to_account_metas(&self, _is_signer: Option<bool>) -> Vec<AccountMeta> {
92 vec![AccountMeta::new_readonly(*self.info.key, false)]
93 }
94}
95
96impl<'info, T: SolanaSysvarSerialize> ToAccountInfos<'info> for Sysvar<'info, T> {
97 fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
98 vec![self.info.clone()]
99 }
100}
101
102impl<'info, T: SolanaSysvarSerialize> AsRef<AccountInfo<'info>> for Sysvar<'info, T> {
103 fn as_ref(&self) -> &AccountInfo<'info> {
104 self.info
105 }
106}
107
108impl<T: SolanaSysvarSerialize> Deref for Sysvar<'_, T> {
109 type Target = T;
110
111 fn deref(&self) -> &Self::Target {
112 &self.account
113 }
114}
115
116impl<T: SolanaSysvarSerialize> DerefMut for Sysvar<'_, T> {
117 fn deref_mut(&mut self) -> &mut Self::Target {
118 &mut self.account
119 }
120}
121
122impl<'info, T: SolanaSysvarSerialize> AccountsExit<'info> for Sysvar<'info, T> {}
123
124impl<T: SolanaSysvarSerialize> Key for Sysvar<'_, T> {
125 fn key(&self) -> Pubkey {
126 *self.info.key
127 }
128}