unchecked_account.rs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. //! Explicit wrapper for AccountInfo types to emphasize
  2. //! that no checks are performed
  3. use crate::error::ErrorCode;
  4. use crate::{Accounts, AccountsExit, Key, ToAccountInfo, ToAccountInfos, ToAccountMetas};
  5. use solana_program::account_info::AccountInfo;
  6. use solana_program::entrypoint::ProgramResult;
  7. use solana_program::instruction::AccountMeta;
  8. use solana_program::program_error::ProgramError;
  9. use solana_program::pubkey::Pubkey;
  10. use std::ops::Deref;
  11. /// Explicit wrapper for AccountInfo types to emphasize
  12. /// that no checks are performed
  13. #[derive(Debug, Clone)]
  14. pub struct UncheckedAccount<'info>(AccountInfo<'info>);
  15. impl<'info> UncheckedAccount<'info> {
  16. pub fn try_from(acc_info: AccountInfo<'info>) -> Self {
  17. Self(acc_info)
  18. }
  19. }
  20. impl<'info> Accounts<'info> for UncheckedAccount<'info> {
  21. fn try_accounts(
  22. _program_id: &Pubkey,
  23. accounts: &mut &[AccountInfo<'info>],
  24. _ix_data: &[u8],
  25. ) -> Result<Self, ProgramError> {
  26. if accounts.is_empty() {
  27. return Err(ErrorCode::AccountNotEnoughKeys.into());
  28. }
  29. let account = &accounts[0];
  30. *accounts = &accounts[1..];
  31. Ok(UncheckedAccount(account.clone()))
  32. }
  33. }
  34. impl<'info> ToAccountMetas for UncheckedAccount<'info> {
  35. fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
  36. let is_signer = is_signer.unwrap_or(self.is_signer);
  37. let meta = match self.is_writable {
  38. false => AccountMeta::new_readonly(*self.key, is_signer),
  39. true => AccountMeta::new(*self.key, is_signer),
  40. };
  41. vec![meta]
  42. }
  43. }
  44. impl<'info> ToAccountInfos<'info> for UncheckedAccount<'info> {
  45. fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
  46. vec![self.0.clone()]
  47. }
  48. }
  49. impl<'info> ToAccountInfo<'info> for UncheckedAccount<'info> {
  50. fn to_account_info(&self) -> AccountInfo<'info> {
  51. self.0.clone()
  52. }
  53. }
  54. impl<'info> AccountsExit<'info> for UncheckedAccount<'info> {
  55. fn exit(&self, _program_id: &Pubkey) -> ProgramResult {
  56. // no-op
  57. Ok(())
  58. }
  59. }
  60. impl<'info> Key for UncheckedAccount<'info> {
  61. fn key(&self) -> Pubkey {
  62. *self.key
  63. }
  64. }
  65. impl<'info> Deref for UncheckedAccount<'info> {
  66. type Target = AccountInfo<'info>;
  67. fn deref(&self) -> &Self::Target {
  68. &self.0
  69. }
  70. }