Browse Source

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

cryptopapi997 1 year ago
parent
commit
b76d1bf04b

+ 1 - 0
CHANGELOG.md

@@ -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
 

+ 2 - 2
lang/attribute/program/src/declare_program/mods/internal.rs

@@ -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)* }

+ 5 - 2
lang/syn/src/codegen/accounts/__client_accounts.rs

@@ -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 {

+ 5 - 2
lang/syn/src/codegen/accounts/__cpi_client_accounts.rs

@@ -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 {

+ 2 - 2
lang/syn/src/codegen/accounts/mod.rs

@@ -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