lang: Fix using optional accounts with `declare_program!` (#2967)

This commit is contained in:
cryptopapi997 2024-05-20 22:09:08 +02:00 committed by GitHub
parent 4540c8253a
commit b76d1bf04b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 15 additions and 8 deletions

View File

@ -31,6 +31,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- lang: Fix using const generics with `declare_program!` ([#2965](https://github.com/coral-xyz/anchor/pull/2965)).
- lang: Fix using `Vec<u8>` type with `declare_program!` ([#2966](https://github.com/coral-xyz/anchor/pull/2966)).
- lang: Fix `ProgramError::ArithmeticOverflow` not found error ([#2975](https://github.com/coral-xyz/anchor/pull/2975)).
- lang: Fix using optional accounts with `declare_program!` ([#2967](https://github.com/coral-xyz/anchor/pull/2967)).
### Breaking

View File

@ -107,7 +107,7 @@ fn gen_internal_accounts(idl: &Idl) -> proc_macro2::TokenStream {
fn gen_internal_accounts_common(
idl: &Idl,
gen_accounts: impl Fn(&AccountsStruct) -> proc_macro2::TokenStream,
gen_accounts: impl Fn(&AccountsStruct, proc_macro2::TokenStream) -> proc_macro2::TokenStream,
) -> proc_macro2::TokenStream {
let accounts = idl
.instructions
@ -171,7 +171,7 @@ fn gen_internal_accounts_common(
let accs_struct = syn::parse2(accs_struct).expect("Failed to parse as syn::ItemStruct");
let accs_struct =
accounts::parse(&accs_struct).expect("Failed to parse accounts struct");
gen_accounts(&accs_struct)
gen_accounts(&accs_struct, get_canonical_program_id())
});
quote! { #(#accounts)* }

View File

@ -6,7 +6,10 @@ use std::str::FromStr;
// Generates the private `__client_accounts` mod implementation, containing
// a generated struct mapping 1-1 to the `Accounts` struct, except with
// `Pubkey`s as the types. This is generated for Rust *clients*.
pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
pub fn generate(
accs: &AccountsStruct,
program_id: proc_macro2::TokenStream,
) -> proc_macro2::TokenStream {
let name = &accs.ident;
let account_mod_name: proc_macro2::TokenStream = format!(
"__client_accounts_{}",
@ -103,7 +106,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
if let Some(#name) = &self.#name {
account_metas.push(#meta(*#name, #is_signer));
} else {
account_metas.push(anchor_lang::solana_program::instruction::AccountMeta::new_readonly(crate::ID, false));
account_metas.push(anchor_lang::solana_program::instruction::AccountMeta::new_readonly(#program_id, false));
}
}
} else {

View File

@ -7,7 +7,10 @@ use quote::quote;
// Generates the private `__cpi_client_accounts` mod implementation, containing
// a generated struct mapping 1-1 to the `Accounts` struct, except with
// `AccountInfo`s as the types. This is generated for CPI clients.
pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
pub fn generate(
accs: &AccountsStruct,
program_id: proc_macro2::TokenStream,
) -> proc_macro2::TokenStream {
let name = &accs.ident;
let account_mod_name: proc_macro2::TokenStream = format!(
"__cpi_client_accounts_{}",
@ -104,7 +107,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
if let Some(#name) = &self.#name {
account_metas.push(#meta(anchor_lang::Key::key(#name), #is_signer));
} else {
account_metas.push(anchor_lang::solana_program::instruction::AccountMeta::new_readonly(crate::ID, false));
account_metas.push(anchor_lang::solana_program::instruction::AccountMeta::new_readonly(#program_id, false));
}
}
} else {

View File

@ -21,8 +21,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
let impl_exit = exit::generate(accs);
let bumps_struct = bumps::generate(accs);
let __client_accounts_mod = __client_accounts::generate(accs);
let __cpi_client_accounts_mod = __cpi_client_accounts::generate(accs);
let __client_accounts_mod = __client_accounts::generate(accs, quote!(crate::ID));
let __cpi_client_accounts_mod = __cpi_client_accounts::generate(accs, quote!(crate::ID));
let ret = quote! {
#impl_try_accounts