diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index d901cde7fd..0279bc5222 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -18,7 +18,7 @@ Solana version: 2.1.0 | Program | Binary Size | - | | ------- | ----------- | ------------------------ | -| bench | 1,041,928 | 🔴 **+250,920 (31.72%)** | +| bench | 1,106,136 | 🔴 **+315,128 (39.84%)** | ### Notable changes diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 05e8434f23..314364fae3 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -29,7 +29,7 @@ use solana_program::instruction::{AccountMeta, Instruction}; use solana_sdk::account_utils::StateMut; use solana_sdk::bpf_loader; use solana_sdk::bpf_loader_deprecated; -use solana_sdk::bpf_loader_upgradeable::{self, UpgradeableLoaderState}; +use solana_sdk::bpf_loader_upgradeable::{self, get_program_data_address, UpgradeableLoaderState}; use solana_sdk::commitment_config::CommitmentConfig; use solana_sdk::compute_budget::ComputeBudgetInstruction; use solana_sdk::pubkey::Pubkey; @@ -3989,12 +3989,14 @@ fn create_idl_account( let mut instructions = Vec::new(); let data = serialize_idl_ix(anchor_lang::idl::IdlInstruction::Create { data_len })?; let program_signer = Pubkey::find_program_address(&[], program_id).0; + let program_data_address = get_program_data_address(program_id); let accounts = vec![ AccountMeta::new_readonly(keypair.pubkey(), true), AccountMeta::new(idl_address, false), AccountMeta::new_readonly(program_signer, false), AccountMeta::new_readonly(solana_program::system_program::ID, false), AccountMeta::new_readonly(*program_id, false), + AccountMeta::new_readonly(program_data_address, false), ]; instructions.push(Instruction { program_id: *program_id, diff --git a/lang/syn/src/codegen/program/entry.rs b/lang/syn/src/codegen/program/entry.rs index 350e814f3b..779a6adeb9 100644 --- a/lang/syn/src/codegen/program/entry.rs +++ b/lang/syn/src/codegen/program/entry.rs @@ -1,9 +1,8 @@ use crate::Program; -use heck::CamelCase; use quote::quote; pub fn generate(program: &Program) -> proc_macro2::TokenStream { - let name: proc_macro2::TokenStream = program.name.to_string().to_camel_case().parse().unwrap(); + let name = program.struct_name(); quote! { #[cfg(not(feature = "no-entrypoint"))] anchor_lang::solana_program::entrypoint!(entry); diff --git a/lang/syn/src/codegen/program/handlers.rs b/lang/syn/src/codegen/program/handlers.rs index 1eb6d0214f..ecab0759d1 100644 --- a/lang/syn/src/codegen/program/handlers.rs +++ b/lang/syn/src/codegen/program/handlers.rs @@ -10,7 +10,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { let program_name = &program.name; // A constant token stream that stores the accounts and functions, required to live // inside the target program in order to get the program ID. - let idl_accounts_and_functions = idl_accounts_and_functions(); + let idl_accounts_and_functions = idl_accounts_and_functions(&program.struct_name()); let non_inlined_idl: proc_macro2::TokenStream = { quote! { // Entry for all IDL related instructions. Use the "no-idl" feature diff --git a/lang/syn/src/codegen/program/idl.rs b/lang/syn/src/codegen/program/idl.rs index f45173c2f5..f8c5950973 100644 --- a/lang/syn/src/codegen/program/idl.rs +++ b/lang/syn/src/codegen/program/idl.rs @@ -1,6 +1,8 @@ use quote::quote; -pub fn idl_accounts_and_functions() -> proc_macro2::TokenStream { +pub fn idl_accounts_and_functions( + program_struct_ident: &proc_macro2::TokenStream, +) -> proc_macro2::TokenStream { quote! { use anchor_lang::idl::ERASED_AUTHORITY; @@ -50,8 +52,11 @@ pub fn idl_accounts_and_functions() -> proc_macro2::TokenStream { // The system program. pub system_program: Program<'info, System>, // The program whose state is being constructed. - #[account(executable)] - pub program: AccountInfo<'info>, + #[account(constraint = program.programdata_address()? == Some(program_data.key()))] + pub program: Program<'info, program::#program_struct_ident>, + // Program's data account necessary to check the upgrade authority. + #[account(constraint = program_data.upgrade_authority_address == Some(from.key()))] + pub program_data: Account<'info, ProgramData>, } // Accounts for Idl instructions. diff --git a/lang/syn/src/lib.rs b/lang/syn/src/lib.rs index 33bc08b7cd..cf13a5f7f6 100644 --- a/lang/syn/src/lib.rs +++ b/lang/syn/src/lib.rs @@ -13,6 +13,7 @@ pub(crate) mod hash; use codegen::accounts as accounts_codegen; use codegen::program as program_codegen; +use heck::CamelCase; use parser::accounts as accounts_parser; use parser::program as program_parser; use proc_macro2::{Span, TokenStream}; @@ -41,6 +42,13 @@ pub struct Program { pub fallback_fn: Option, } +impl Program { + /// Get program struct name (in PascalCase). + pub fn struct_name(&self) -> proc_macro2::TokenStream { + self.name.to_string().to_camel_case().parse().unwrap() + } +} + impl Parse for Program { fn parse(input: ParseStream) -> ParseResult { let program_mod = ::parse(input)?; diff --git a/tests/bench/bench.json b/tests/bench/bench.json index cb6c0edc3d..36e1127f90 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -933,7 +933,7 @@ "solanaVersion": "2.1.0", "result": { "binarySize": { - "bench": 1041928 + "bench": 1106136 }, "computeUnits": { "accountInfo1": 571,