sysvar.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. use crate::error::ErrorCode;
  2. use crate::{Accounts, AccountsExit, Key, ToAccountInfo, ToAccountInfos, ToAccountMetas};
  3. use solana_program::account_info::AccountInfo;
  4. use solana_program::entrypoint::ProgramResult;
  5. use solana_program::instruction::AccountMeta;
  6. use solana_program::program_error::ProgramError;
  7. use solana_program::pubkey::Pubkey;
  8. use std::ops::{Deref, DerefMut};
  9. /// Container for sysvars.
  10. pub struct Sysvar<'info, T: solana_program::sysvar::Sysvar> {
  11. info: AccountInfo<'info>,
  12. account: T,
  13. }
  14. impl<'info, T: solana_program::sysvar::Sysvar> Sysvar<'info, T> {
  15. pub fn from_account_info(
  16. acc_info: &AccountInfo<'info>,
  17. ) -> Result<Sysvar<'info, T>, ProgramError> {
  18. Ok(Sysvar {
  19. info: acc_info.clone(),
  20. account: T::from_account_info(acc_info)?,
  21. })
  22. }
  23. }
  24. impl<'info, T: solana_program::sysvar::Sysvar> Clone for Sysvar<'info, T> {
  25. fn clone(&self) -> Self {
  26. Self {
  27. info: self.info.clone(),
  28. account: T::from_account_info(&self.info).unwrap(),
  29. }
  30. }
  31. }
  32. impl<'info, T: solana_program::sysvar::Sysvar> Accounts<'info> for Sysvar<'info, T> {
  33. fn try_accounts(
  34. _program_id: &Pubkey,
  35. accounts: &mut &[AccountInfo<'info>],
  36. _ix_data: &[u8],
  37. ) -> Result<Self, ProgramError> {
  38. if accounts.is_empty() {
  39. return Err(ErrorCode::AccountNotEnoughKeys.into());
  40. }
  41. let account = &accounts[0];
  42. *accounts = &accounts[1..];
  43. Sysvar::from_account_info(account)
  44. }
  45. }
  46. impl<'info, T: solana_program::sysvar::Sysvar> ToAccountMetas for Sysvar<'info, T> {
  47. fn to_account_metas(&self, _is_signer: Option<bool>) -> Vec<AccountMeta> {
  48. vec![AccountMeta::new_readonly(*self.info.key, false)]
  49. }
  50. }
  51. impl<'info, T: solana_program::sysvar::Sysvar> ToAccountInfos<'info> for Sysvar<'info, T> {
  52. fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
  53. vec![self.info.clone()]
  54. }
  55. }
  56. impl<'info, T: solana_program::sysvar::Sysvar> AsRef<AccountInfo<'info>> for Sysvar<'info, T> {
  57. fn as_ref(&self) -> &AccountInfo<'info> {
  58. &self.info
  59. }
  60. }
  61. impl<'a, T: solana_program::sysvar::Sysvar> Deref for Sysvar<'a, T> {
  62. type Target = T;
  63. fn deref(&self) -> &Self::Target {
  64. &self.account
  65. }
  66. }
  67. impl<'a, T: solana_program::sysvar::Sysvar> DerefMut for Sysvar<'a, T> {
  68. fn deref_mut(&mut self) -> &mut Self::Target {
  69. &mut self.account
  70. }
  71. }
  72. impl<'info, T: solana_program::sysvar::Sysvar> ToAccountInfo<'info> for Sysvar<'info, T> {
  73. fn to_account_info(&self) -> AccountInfo<'info> {
  74. self.info.clone()
  75. }
  76. }
  77. impl<'info, T: solana_program::sysvar::Sysvar> AccountsExit<'info> for Sysvar<'info, T> {
  78. fn exit(&self, _program_id: &Pubkey) -> ProgramResult {
  79. // no-op
  80. Ok(())
  81. }
  82. }
  83. impl<'info, T: solana_program::sysvar::Sysvar> Key for Sysvar<'info, T> {
  84. fn key(&self) -> Pubkey {
  85. *self.info.key
  86. }
  87. }