Skip to content

Commit

Permalink
lang: use phantomdata in account type instead of '_account: T' (#1155)
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-schaaf committed Dec 27, 2021
1 parent 3e475a2 commit 22c2c30
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 81 deletions.
42 changes: 16 additions & 26 deletions lang/src/accounts/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,32 @@ use solana_program::instruction::AccountMeta;
use solana_program::program_error::ProgramError;
use solana_program::pubkey::Pubkey;
use std::fmt;
use std::marker::PhantomData;
use std::ops::Deref;

/// Account container that checks ownership on deserialization.
#[derive(Clone)]
pub struct Program<'info, T: Id + AccountDeserialize + Clone> {
_account: T,
pub struct Program<'info, T: Id + Clone> {
info: AccountInfo<'info>,
programdata_address: Option<Pubkey>,
_phantom: PhantomData<T>,
}

impl<'info, T: Id + AccountDeserialize + Clone + fmt::Debug> fmt::Debug for Program<'info, T> {
impl<'info, T: Id + Clone + fmt::Debug> fmt::Debug for Program<'info, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Program")
.field("account", &self._account)
.field("info", &self.info)
.field("programdata_address", &self.programdata_address)
.finish()
}
}

impl<'a, T: Id + AccountDeserialize + Clone> Program<'a, T> {
fn new(
info: AccountInfo<'a>,
_account: T,
programdata_address: Option<Pubkey>,
) -> Program<'a, T> {
impl<'a, T: Id + Clone> Program<'a, T> {
fn new(info: AccountInfo<'a>, programdata_address: Option<Pubkey>) -> Program<'a, T> {
Self {
info,
_account,
programdata_address,
_phantom: PhantomData,
}
}

Expand Down Expand Up @@ -75,23 +71,17 @@ impl<'a, T: Id + AccountDeserialize + Clone> Program<'a, T> {
None
};

// Programs have no data so use an empty slice.
let mut empty = &[][..];
Ok(Program::new(
info.clone(),
T::try_deserialize(&mut empty)?,
programdata_address,
))
Ok(Program::new(info.clone(), programdata_address))
}

pub fn programdata_address(&self) -> Option<Pubkey> {
self.programdata_address
}
}

impl<'info, T: Id + Clone> Accounts<'info> for Program<'info, T>
impl<'info, T> Accounts<'info> for Program<'info, T>
where
T: Id + AccountDeserialize,
T: Id + Clone,
{
#[inline(never)]
fn try_accounts(
Expand All @@ -108,7 +98,7 @@ where
}
}

impl<'info, T: Id + AccountDeserialize + Clone> ToAccountMetas for Program<'info, T> {
impl<'info, T: Id + Clone> ToAccountMetas for Program<'info, T> {
fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
let is_signer = is_signer.unwrap_or(self.info.is_signer);
let meta = match self.info.is_writable {
Expand All @@ -119,33 +109,33 @@ impl<'info, T: Id + AccountDeserialize + Clone> ToAccountMetas for Program<'info
}
}

impl<'info, T: Id + AccountDeserialize + Clone> ToAccountInfos<'info> for Program<'info, T> {
impl<'info, T: Id + Clone> ToAccountInfos<'info> for Program<'info, T> {
fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
vec![self.info.clone()]
}
}

impl<'info, T: Id + AccountDeserialize + Clone> ToAccountInfo<'info> for Program<'info, T> {
impl<'info, T: Id + Clone> ToAccountInfo<'info> for Program<'info, T> {
fn to_account_info(&self) -> AccountInfo<'info> {
self.info.clone()
}
}

impl<'info, T: Id + AccountDeserialize + Clone> AsRef<AccountInfo<'info>> for Program<'info, T> {
impl<'info, T: Id + Clone> AsRef<AccountInfo<'info>> for Program<'info, T> {
fn as_ref(&self) -> &AccountInfo<'info> {
&self.info
}
}

impl<'info, T: Id + AccountDeserialize + Clone> Deref for Program<'info, T> {
impl<'info, T: Id + Clone> Deref for Program<'info, T> {
type Target = AccountInfo<'info>;

fn deref(&self) -> &Self::Target {
&self.info
}
}

impl<'info, T: AccountDeserialize + Id + Clone> AccountsExit<'info> for Program<'info, T> {
impl<'info, T: Id + Clone> AccountsExit<'info> for Program<'info, T> {
fn exit(&self, _program_id: &Pubkey) -> ProgramResult {
// No-op.
Ok(())
Expand Down
11 changes: 0 additions & 11 deletions lang/src/system_program.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
use crate::*;
use solana_program::program_error::ProgramError;
use solana_program::pubkey::Pubkey;

pub use solana_program::system_program::ID;

#[derive(Debug, Clone)]
pub struct System;

impl anchor_lang::AccountDeserialize for System {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self, ProgramError> {
System::try_deserialize_unchecked(buf)
}

fn try_deserialize_unchecked(_buf: &mut &[u8]) -> Result<Self, ProgramError> {
Ok(System)
}
}

impl anchor_lang::Id for System {
fn id() -> Pubkey {
ID
Expand Down
10 changes: 0 additions & 10 deletions lang/syn/src/codegen/program/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,6 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
#[derive(Clone)]
pub struct #name;

impl anchor_lang::AccountDeserialize for #name {
fn try_deserialize(buf: &mut &[u8]) -> std::result::Result<Self, anchor_lang::solana_program::program_error::ProgramError> {
#name::try_deserialize_unchecked(buf)
}

fn try_deserialize_unchecked(_buf: &mut &[u8]) -> std::result::Result<Self, anchor_lang::solana_program::program_error::ProgramError> {
Ok(#name)
}
}

impl anchor_lang::Id for #name {
fn id() -> Pubkey {
ID
Expand Down
11 changes: 0 additions & 11 deletions spl/src/associated_token.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use anchor_lang::solana_program::account_info::AccountInfo;
use anchor_lang::solana_program::entrypoint::ProgramResult;
use anchor_lang::solana_program::program_error::ProgramError;
use anchor_lang::solana_program::pubkey::Pubkey;
use anchor_lang::{Accounts, CpiContext};

Expand Down Expand Up @@ -41,16 +40,6 @@ pub struct Create<'info> {
#[derive(Clone)]
pub struct AssociatedToken;

impl anchor_lang::AccountDeserialize for AssociatedToken {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self, ProgramError> {
AssociatedToken::try_deserialize_unchecked(buf)
}

fn try_deserialize_unchecked(_buf: &mut &[u8]) -> Result<Self, ProgramError> {
Ok(AssociatedToken)
}
}

impl anchor_lang::Id for AssociatedToken {
fn id() -> Pubkey {
ID
Expand Down
17 changes: 0 additions & 17 deletions spl/src/dex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,23 +289,6 @@ pub struct InitializeMarket<'info> {
#[derive(Clone)]
pub struct Dex;

impl anchor_lang::AccountDeserialize for Dex {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self, ProgramError> {
Dex::try_deserialize_unchecked(buf)
}

fn try_deserialize_unchecked(_buf: &mut &[u8]) -> Result<Self, ProgramError> {
Ok(Dex)
}
}

impl anchor_lang::AccountSerialize for Dex {
fn try_serialize<W: Write>(&self, _writer: &mut W) -> Result<(), ProgramError> {
// no-op
Ok(())
}
}

impl anchor_lang::Id for Dex {
fn id() -> Pubkey {
ID
Expand Down
6 changes: 0 additions & 6 deletions spl/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,12 +363,6 @@ impl Deref for Mint {
#[derive(Clone)]
pub struct Token;

impl anchor_lang::AccountDeserialize for Token {
fn try_deserialize_unchecked(_buf: &mut &[u8]) -> Result<Self, ProgramError> {
Ok(Token)
}
}

impl anchor_lang::Id for Token {
fn id() -> Pubkey {
ID
Expand Down

0 comments on commit 22c2c30

Please sign in to comment.