From 54c07be51153cae0af4ba03949d7552724474b21 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 12 Mar 2022 15:59:30 -0500 Subject: [PATCH] lang: impl Key for Pubkey (#1601) --- CHANGELOG.md | 1 + lang/src/accounts/account.rs | 14 ++++++++++++-- lang/src/accounts/account_info.rs | 8 +++++++- lang/src/accounts/account_loader.rs | 8 +++++++- lang/src/accounts/cpi_account.rs | 7 +++++++ lang/src/accounts/cpi_state.rs | 9 ++++++++- lang/src/accounts/loader.rs | 11 +++++++++-- lang/src/accounts/program.rs | 11 +++++++++-- lang/src/accounts/program_account.rs | 9 ++++++++- lang/src/accounts/signer.rs | 8 +++++++- lang/src/accounts/state.rs | 8 +++++++- lang/src/accounts/system_account.rs | 6 ++++++ lang/src/accounts/sysvar.rs | 8 +++++++- lang/src/accounts/unchecked_account.rs | 8 +++++++- lang/src/lib.rs | 7 ++----- lang/syn/src/codegen/accounts/constraints.rs | 2 +- 16 files changed, 105 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90e3789acf..5ca01d359b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ incremented for features. * ts: Fix the loss of strict typing using the `methods` namespace on builder functions ([#1539](https://github.com/project-serum/anchor/pull/1539)). * spl: Update `spl/governance` to use new errors ([#1582](https://github.com/project-serum/anchor/pull/1582)). * client: Fix `Cluster`'s `FromStr` implementation ([#1362](https://github.com/project-serum/anchor/pull/1362)). +* lang: implement `Key` for `Pubkey` again, so `associated_token::*` constraints can use pubkey targets again ([#1601](https://github.com/project-serum/anchor/pull/1601)). ### Breaking diff --git a/lang/src/accounts/account.rs b/lang/src/accounts/account.rs index 915cce4adc..6c645322a8 100644 --- a/lang/src/accounts/account.rs +++ b/lang/src/accounts/account.rs @@ -2,10 +2,14 @@ use crate::bpf_writer::BpfWriter; use crate::error::ErrorCode; -use crate::*; +use crate::{ + AccountDeserialize, AccountSerialize, Accounts, AccountsClose, AccountsExit, Key, Owner, + Result, ToAccountInfo, ToAccountInfos, ToAccountMetas, +}; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; +use solana_program::system_program; use std::collections::BTreeMap; use std::fmt; use std::ops::{Deref, DerefMut}; @@ -235,7 +239,7 @@ impl<'info, T: AccountSerialize + AccountDeserialize + Owner + Clone + fmt::Debu } } -impl<'a, T: AccountSerialize + AccountDeserialize + Owner + Clone> Account<'a, T> { +impl<'a, T: AccountSerialize + AccountDeserialize + crate::Owner + Clone> Account<'a, T> { fn new(info: AccountInfo<'a>, account: T) -> Account<'a, T> { Self { info, account } } @@ -411,3 +415,9 @@ impl<'a, T: AccountSerialize + AccountDeserialize + Owner + Clone> DerefMut for &mut self.account } } + +impl<'info, T: AccountSerialize + AccountDeserialize + Owner + Clone> Key for Account<'info, T> { + fn key(&self) -> Pubkey { + *self.info.key + } +} diff --git a/lang/src/accounts/account_info.rs b/lang/src/accounts/account_info.rs index 25374c45b0..de23283add 100644 --- a/lang/src/accounts/account_info.rs +++ b/lang/src/accounts/account_info.rs @@ -3,7 +3,7 @@ //! should be used instead. use crate::error::ErrorCode; -use crate::{Accounts, AccountsExit, Result, ToAccountInfos, ToAccountMetas}; +use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas}; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; @@ -43,3 +43,9 @@ impl<'info> ToAccountInfos<'info> for AccountInfo<'info> { } impl<'info> AccountsExit<'info> for AccountInfo<'info> {} + +impl<'info> Key for AccountInfo<'info> { + fn key(&self) -> Pubkey { + *self.key + } +} diff --git a/lang/src/accounts/account_loader.rs b/lang/src/accounts/account_loader.rs index 149333fb61..01454bd5ba 100644 --- a/lang/src/accounts/account_loader.rs +++ b/lang/src/accounts/account_loader.rs @@ -3,7 +3,7 @@ use crate::bpf_writer::BpfWriter; use crate::error::ErrorCode; use crate::{ - Accounts, AccountsClose, AccountsExit, Owner, Result, ToAccountInfo, ToAccountInfos, + Accounts, AccountsClose, AccountsExit, Key, Owner, Result, ToAccountInfo, ToAccountInfos, ToAccountMetas, ZeroCopy, }; use arrayref::array_ref; @@ -267,3 +267,9 @@ impl<'info, T: ZeroCopy + Owner> ToAccountInfos<'info> for AccountLoader<'info, vec![self.acc_info.clone()] } } + +impl<'info, T: ZeroCopy + Owner> Key for AccountLoader<'info, T> { + fn key(&self) -> Pubkey { + *self.acc_info.key + } +} diff --git a/lang/src/accounts/cpi_account.rs b/lang/src/accounts/cpi_account.rs index c6332f17f4..5f9567894e 100644 --- a/lang/src/accounts/cpi_account.rs +++ b/lang/src/accounts/cpi_account.rs @@ -119,3 +119,10 @@ where Self::new(a.to_account_info(), Box::new(a.into_inner())) } } + +#[allow(deprecated)] +impl<'info, T: AccountDeserialize + Clone> Key for CpiAccount<'info, T> { + fn key(&self) -> Pubkey { + *self.info.key + } +} diff --git a/lang/src/accounts/cpi_state.rs b/lang/src/accounts/cpi_state.rs index 2ce75b3aae..401dabfa37 100644 --- a/lang/src/accounts/cpi_state.rs +++ b/lang/src/accounts/cpi_state.rs @@ -2,7 +2,7 @@ use crate::error::ErrorCode; #[allow(deprecated)] use crate::{accounts::state::ProgramState, context::CpiStateContext}; use crate::{ - AccountDeserialize, AccountSerialize, Accounts, AccountsExit, Result, ToAccountInfos, + AccountDeserialize, AccountSerialize, Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas, }; use solana_program::account_info::AccountInfo; @@ -139,3 +139,10 @@ impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AccountsExit<'info for CpiState<'info, T> { } + +#[allow(deprecated)] +impl<'info, T: AccountSerialize + AccountDeserialize + Clone> Key for CpiState<'info, T> { + fn key(&self) -> Pubkey { + *self.inner.info.key + } +} diff --git a/lang/src/accounts/loader.rs b/lang/src/accounts/loader.rs index f2758e4452..19885f8d53 100644 --- a/lang/src/accounts/loader.rs +++ b/lang/src/accounts/loader.rs @@ -1,8 +1,8 @@ use crate::bpf_writer::BpfWriter; use crate::error::ErrorCode; use crate::{ - Accounts, AccountsClose, AccountsExit, Result, ToAccountInfo, ToAccountInfos, ToAccountMetas, - ZeroCopy, + Accounts, AccountsClose, AccountsExit, Key, Result, ToAccountInfo, ToAccountInfos, + ToAccountMetas, ZeroCopy, }; use arrayref::array_ref; use solana_program::account_info::AccountInfo; @@ -214,3 +214,10 @@ impl<'info, T: ZeroCopy> ToAccountInfos<'info> for Loader<'info, T> { vec![self.acc_info.clone()] } } + +#[allow(deprecated)] +impl<'info, T: ZeroCopy> Key for Loader<'info, T> { + fn key(&self) -> Pubkey { + *self.acc_info.key + } +} diff --git a/lang/src/accounts/program.rs b/lang/src/accounts/program.rs index 1a20af98dc..146749aea3 100644 --- a/lang/src/accounts/program.rs +++ b/lang/src/accounts/program.rs @@ -1,7 +1,8 @@ //! Type validating that the account is the given Program - use crate::error::ErrorCode; -use crate::*; +use crate::{ + AccountDeserialize, Accounts, AccountsExit, Id, Key, Result, ToAccountInfos, ToAccountMetas, +}; use solana_program::account_info::AccountInfo; use solana_program::bpf_loader_upgradeable::{self, UpgradeableLoaderState}; use solana_program::instruction::AccountMeta; @@ -178,3 +179,9 @@ impl<'info, T: Id + Clone> Deref for Program<'info, T> { } impl<'info, T: AccountDeserialize + Id + Clone> AccountsExit<'info> for Program<'info, T> {} + +impl<'info, T: AccountDeserialize + Id + Clone> Key for Program<'info, T> { + fn key(&self) -> Pubkey { + *self.info.key + } +} diff --git a/lang/src/accounts/program_account.rs b/lang/src/accounts/program_account.rs index 9119c37c65..ef7550dbd2 100644 --- a/lang/src/accounts/program_account.rs +++ b/lang/src/accounts/program_account.rs @@ -3,7 +3,7 @@ use crate::accounts::cpi_account::CpiAccount; use crate::bpf_writer::BpfWriter; use crate::error::ErrorCode; use crate::{ - AccountDeserialize, AccountSerialize, Accounts, AccountsClose, AccountsExit, Result, + AccountDeserialize, AccountSerialize, Accounts, AccountsClose, AccountsExit, Key, Result, ToAccountInfo, ToAccountInfos, ToAccountMetas, }; use solana_program::account_info::AccountInfo; @@ -184,3 +184,10 @@ where Self::new(a.to_account_info(), Deref::deref(&a).clone()) } } + +#[allow(deprecated)] +impl<'info, T: AccountSerialize + AccountDeserialize + Clone> Key for ProgramAccount<'info, T> { + fn key(&self) -> Pubkey { + *self.inner.info.key + } +} diff --git a/lang/src/accounts/signer.rs b/lang/src/accounts/signer.rs index ffd0fc2ba0..2cec796ce3 100644 --- a/lang/src/accounts/signer.rs +++ b/lang/src/accounts/signer.rs @@ -1,6 +1,6 @@ //! Type validating that the account signed the transaction use crate::error::ErrorCode; -use crate::*; +use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas}; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; @@ -103,3 +103,9 @@ impl<'info> Deref for Signer<'info> { &self.info } } + +impl<'info> Key for Signer<'info> { + fn key(&self) -> Pubkey { + *self.info.key + } +} diff --git a/lang/src/accounts/state.rs b/lang/src/accounts/state.rs index 164f4b9023..14c3f87819 100644 --- a/lang/src/accounts/state.rs +++ b/lang/src/accounts/state.rs @@ -3,7 +3,7 @@ use crate::accounts::cpi_account::CpiAccount; use crate::bpf_writer::BpfWriter; use crate::error::ErrorCode; use crate::{ - AccountDeserialize, AccountSerialize, Accounts, AccountsExit, Result, ToAccountInfo, + AccountDeserialize, AccountSerialize, Accounts, AccountsExit, Key, Result, ToAccountInfo, ToAccountInfos, ToAccountMetas, }; use solana_program::account_info::AccountInfo; @@ -161,3 +161,9 @@ pub fn address(program_id: &Pubkey) -> Pubkey { let owner = program_id; Pubkey::create_with_seed(&base, seed, owner).unwrap() } + +impl<'info, T: AccountSerialize + AccountDeserialize + Clone> Key for ProgramState<'info, T> { + fn key(&self) -> Pubkey { + *self.inner.info.key + } +} diff --git a/lang/src/accounts/system_account.rs b/lang/src/accounts/system_account.rs index 30cc33eaf8..a47ceafc7c 100644 --- a/lang/src/accounts/system_account.rs +++ b/lang/src/accounts/system_account.rs @@ -82,3 +82,9 @@ impl<'info> Deref for SystemAccount<'info> { &self.info } } + +impl<'info> Key for SystemAccount<'info> { + fn key(&self) -> Pubkey { + *self.info.key + } +} diff --git a/lang/src/accounts/sysvar.rs b/lang/src/accounts/sysvar.rs index 3c10ee45a7..e2e8336fa4 100644 --- a/lang/src/accounts/sysvar.rs +++ b/lang/src/accounts/sysvar.rs @@ -1,7 +1,7 @@ //! Type validating that the account is a sysvar and deserializing it use crate::error::ErrorCode; -use crate::{Accounts, AccountsExit, Result, ToAccountInfos, ToAccountMetas}; +use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas}; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; @@ -114,3 +114,9 @@ impl<'a, T: solana_program::sysvar::Sysvar> DerefMut for Sysvar<'a, T> { } impl<'info, T: solana_program::sysvar::Sysvar> AccountsExit<'info> for Sysvar<'info, T> {} + +impl<'info, T: solana_program::sysvar::Sysvar> Key for Sysvar<'info, T> { + fn key(&self) -> Pubkey { + *self.info.key + } +} diff --git a/lang/src/accounts/unchecked_account.rs b/lang/src/accounts/unchecked_account.rs index d28d6e1f54..7357619694 100644 --- a/lang/src/accounts/unchecked_account.rs +++ b/lang/src/accounts/unchecked_account.rs @@ -2,7 +2,7 @@ //! that no checks are performed use crate::error::ErrorCode; -use crate::{Accounts, AccountsExit, Result, ToAccountInfos, ToAccountMetas}; +use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas}; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; @@ -68,3 +68,9 @@ impl<'info> Deref for UncheckedAccount<'info> { &self.0 } } + +impl<'info> Key for UncheckedAccount<'info> { + fn key(&self) -> Pubkey { + *self.0.key + } +} diff --git a/lang/src/lib.rs b/lang/src/lib.rs index f8d7472da8..56ca51731f 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -224,12 +224,9 @@ pub trait Key { fn key(&self) -> Pubkey; } -impl<'info, T> Key for T -where - T: AsRef>, -{ +impl Key for Pubkey { fn key(&self) -> Pubkey { - *self.as_ref().key + *self } } diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs index 95afd3d1dc..475e24da20 100644 --- a/lang/syn/src/codegen/accounts/constraints.rs +++ b/lang/syn/src/codegen/accounts/constraints.rs @@ -558,7 +558,7 @@ fn generate_constraint_seeds(f: &Field, c: &ConstraintSeedsGroup) -> proc_macro2 .program_seed .clone() // If they specified a seeds::program to use when deriving the PDA, use it. - .map(|program_id| quote! { #program_id }) + .map(|program_id| quote! { #program_id.key() }) // Otherwise fall back to the current program's program_id. .unwrap_or(quote! { program_id });