From b4253923c4d7922ba686f1a82b51e093bf1314bf Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 20:02:39 +0530 Subject: [PATCH 01/39] feat: Add duplicate mutable account constraint --- lang/src/error.rs | 3 ++ lang/syn/src/codegen/accounts/constraints.rs | 5 ++ lang/syn/src/codegen/accounts/try_accounts.rs | 52 +++++++++++++++++++ lang/syn/src/lib.rs | 10 ++++ lang/syn/src/parser/accounts/constraints.rs | 14 +++++ 5 files changed, 84 insertions(+) diff --git a/lang/src/error.rs b/lang/src/error.rs index 967d6cdbc6..284b0a0709 100644 --- a/lang/src/error.rs +++ b/lang/src/error.rs @@ -177,6 +177,9 @@ pub enum ErrorCode { /// 2039 - A transfer hook extension transfer hook program id constraint was violated #[msg("A transfer hook extension transfer hook program id constraint was violated")] ConstraintMintTransferHookExtensionProgramId, + /// 2040 - A duplicate mutable account constraint was violated + #[msg("A duplicate mutable account constraint was violated")] + ConstraintDuplicateMutableAccount, // Require /// 2500 - A require expression was violated diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs index d385eb1df9..fbbfa04169 100644 --- a/lang/syn/src/codegen/accounts/constraints.rs +++ b/lang/syn/src/codegen/accounts/constraints.rs @@ -76,6 +76,7 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec { init, zeroed, mutable, + dup, signer, has_one, raw, @@ -111,6 +112,9 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec { if let Some(c) = mutable { constraints.push(Constraint::Mut(c)); } + if let Some(c) = dup { + constraints.push(Constraint::Dup(c)); + } if let Some(c) = signer { constraints.push(Constraint::Signer(c)); } @@ -149,6 +153,7 @@ fn generate_constraint( Constraint::Init(c) => generate_constraint_init(f, c, accs), Constraint::Zeroed(c) => generate_constraint_zeroed(f, c, accs), Constraint::Mut(c) => generate_constraint_mut(f, c), + Constraint::Dup(_) => quote! {}, // No-op: dup is handled by duplicate checking logic Constraint::HasOne(c) => generate_constraint_has_one(f, c, accs), Constraint::Signer(c) => generate_constraint_signer(f, c), Constraint::Raw(c) => generate_constraint_raw(&f.ident, c), diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index 56b13375e5..38b05cc08e 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -157,6 +157,9 @@ pub fn generate_constraints(accs: &AccountsStruct) -> proc_macro2::TokenStream { .map(|f| constraints::generate(f, accs)) .collect(); + // Generate duplicate mutable account validation + let duplicate_checks = generate_duplicate_mutable_checks(accs); + // Constraint checks for each account fields. let access_checks: Vec = non_init_fields .iter() @@ -168,6 +171,7 @@ pub fn generate_constraints(accs: &AccountsStruct) -> proc_macro2::TokenStream { quote! { #(#init_fields)* + #duplicate_checks #(#access_checks)* } } @@ -202,3 +206,51 @@ fn is_init(af: &AccountField) -> bool { AccountField::Field(f) => f.constraints.init.is_some(), } } + +// Generates duplicate mutable account validation logic +fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::TokenStream { + // Find all mutable account fields that don't have dup constraint + let check_required_fields: Vec<_> = accs + .fields + .iter() + .filter_map(|af| match af { + AccountField::Field(f) if f.constraints.is_mutable() && !f.constraints.is_dup() => { + Some(f) + } + _ => None, + }) + .collect(); + + if check_required_fields.len() <= 1 { + // If there's 0 or 1 fields to check, no duplicates possible + return quote! {}; + } + + // Generate validation code using BTreeSet like realloc pattern + let field_keys: Vec<_> = check_required_fields + .iter() + .map(|f| { + let name = &f.ident; + quote! { #name.key() } + }) + .collect(); + + let field_name_strs: Vec<_> = check_required_fields + .iter() + .map(|f| f.ident.to_string()) + .collect(); + + quote! { + // Duplicate mutable account validation - using pattern similar to realloc + { + let mut __mutable_accounts = std::collections::BTreeSet::new(); + #( + if !__mutable_accounts.insert(#field_keys) { + return Err(anchor_lang::error::Error::from( + anchor_lang::error::ErrorCode::ConstraintDuplicateMutableAccount + ).with_account_name(#field_name_strs)); + } + )* + } + } +} diff --git a/lang/syn/src/lib.rs b/lang/syn/src/lib.rs index 554b22e47c..f721d51e5e 100644 --- a/lang/syn/src/lib.rs +++ b/lang/syn/src/lib.rs @@ -678,6 +678,7 @@ pub struct ConstraintGroup { pub init: Option, pub zeroed: Option, pub mutable: Option, + pub dup: Option, pub signer: Option, pub owner: Option, pub rent_exempt: Option, @@ -702,6 +703,10 @@ impl ConstraintGroup { self.mutable.is_some() } + pub fn is_dup(&self) -> bool { + self.dup.is_some() + } + pub fn is_signer(&self) -> bool { self.signer.is_some() } @@ -720,6 +725,7 @@ pub enum Constraint { Init(ConstraintInitGroup), Zeroed(ConstraintZeroed), Mut(ConstraintMut), + Dup(ConstraintDup), Signer(ConstraintSigner), HasOne(ConstraintHasOne), Raw(ConstraintRaw), @@ -742,6 +748,7 @@ pub enum ConstraintToken { Init(Context), Zeroed(Context), Mut(Context), + Dup(Context), Signer(Context), HasOne(Context), Raw(Context), @@ -807,6 +814,9 @@ pub struct ConstraintMut { pub error: Option, } +#[derive(Debug, Clone)] +pub struct ConstraintDup {} + #[derive(Debug, Clone)] pub struct ConstraintReallocGroup { pub payer: Expr, diff --git a/lang/syn/src/parser/accounts/constraints.rs b/lang/syn/src/parser/accounts/constraints.rs index 39617ea486..8abda63ca6 100644 --- a/lang/syn/src/parser/accounts/constraints.rs +++ b/lang/syn/src/parser/accounts/constraints.rs @@ -50,6 +50,7 @@ pub fn parse_token(stream: ParseStream) -> ParseResult { "executable" => { ConstraintToken::Executable(Context::new(ident.span(), ConstraintExecutable {})) } + "dup" => ConstraintToken::Dup(Context::new(ident.span(), ConstraintDup {})), "mint" => { stream.parse::()?; stream.parse::()?; @@ -543,6 +544,7 @@ pub struct ConstraintGroupBuilder<'ty> { pub realloc: Option>, pub realloc_payer: Option>, pub realloc_zero: Option>, + pub dup: Option>, } impl<'ty> ConstraintGroupBuilder<'ty> { @@ -588,6 +590,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> { realloc: None, realloc_payer: None, realloc_zero: None, + dup: None, } } @@ -800,6 +803,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> { realloc, realloc_payer, realloc_zero, + dup, } = self; // Converts Option> -> Option. @@ -1031,6 +1035,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> { seeds, token_account: if !is_init {token_account} else {None}, mint: if !is_init {mint} else {None}, + dup: into_inner!(dup), }) } @@ -1093,6 +1098,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> { ConstraintToken::ExtensionPermanentDelegate(c) => { self.add_extension_permanent_delegate(c) } + ConstraintToken::Dup(c) => self.add_dup(c), } } @@ -1675,4 +1681,12 @@ impl<'ty> ConstraintGroupBuilder<'ty> { self.extension_permanent_delegate.replace(c); Ok(()) } + + fn add_dup(&mut self, c: Context) -> ParseResult<()> { + if self.dup.is_some() { + return Err(ParseError::new(c.span(), "dup already provided")); + } + self.dup.replace(c); + Ok(()) + } } From 505727e80e801bd2722f137b680c782e877c1279 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 20:15:52 +0530 Subject: [PATCH 02/39] feat: tests for duplicate mutable accounts --- tests/duplicate-mutable-accounts/Anchor.toml | 9 ++ tests/duplicate-mutable-accounts/Cargo.toml | 8 ++ tests/duplicate-mutable-accounts/package.json | 19 ++++ .../duplicate-mutable-accounts/Cargo.toml | 17 ++++ .../duplicate-mutable-accounts/Xargo.toml | 2 + .../duplicate-mutable-accounts/src/lib.rs | 74 ++++++++++++++++ .../tests/duplicate-mutable-accounts.ts | 88 +++++++++++++++++++ .../duplicate-mutable-accounts/tsconfig.json | 11 +++ 8 files changed, 228 insertions(+) create mode 100644 tests/duplicate-mutable-accounts/Anchor.toml create mode 100644 tests/duplicate-mutable-accounts/Cargo.toml create mode 100644 tests/duplicate-mutable-accounts/package.json create mode 100644 tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/Cargo.toml create mode 100644 tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/Xargo.toml create mode 100644 tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs create mode 100644 tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts create mode 100644 tests/duplicate-mutable-accounts/tsconfig.json diff --git a/tests/duplicate-mutable-accounts/Anchor.toml b/tests/duplicate-mutable-accounts/Anchor.toml new file mode 100644 index 0000000000..c839ab54b0 --- /dev/null +++ b/tests/duplicate-mutable-accounts/Anchor.toml @@ -0,0 +1,9 @@ +[provider] +cluster = "localnet" +wallet = "~/.config/solana/id.json" + +[programs.localnet] +declare_id = "4D6rvpR7TSPwmFottLGa5gpzMcJ76kN8bimQHV9rogjH" + +[scripts] +test = "yarn run ts-mocha -t 1000000 tests/*.ts" diff --git a/tests/duplicate-mutable-accounts/Cargo.toml b/tests/duplicate-mutable-accounts/Cargo.toml new file mode 100644 index 0000000000..36c9df94de --- /dev/null +++ b/tests/duplicate-mutable-accounts/Cargo.toml @@ -0,0 +1,8 @@ +[workspace] +members = [ + "programs/duplicate-mutable-accounts", +] +resolver = "2" + +[profile.release] +overflow-checks = true diff --git a/tests/duplicate-mutable-accounts/package.json b/tests/duplicate-mutable-accounts/package.json new file mode 100644 index 0000000000..0996041cf8 --- /dev/null +++ b/tests/duplicate-mutable-accounts/package.json @@ -0,0 +1,19 @@ +{ + "name": "duplicate-mutable-accounts", + "version": "0.31.1", + "license": "(MIT OR Apache-2.0)", + "homepage": "https://github.com/coral-xyz/anchor#readme", + "bugs": { + "url": "https://github.com/coral-xyz/anchor/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/coral-xyz/anchor.git" + }, + "engines": { + "node": ">=17" + }, + "scripts": { + "test": "anchor test" + } +} diff --git a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/Cargo.toml b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/Cargo.toml new file mode 100644 index 0000000000..e88eab0ec7 --- /dev/null +++ b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "duplicate-mutable-accounts" +version = "0.1.0" +description = "Created with Anchor" +edition = "2018" + +[lib] +crate-type = ["cdylib", "lib"] +name = "duplicate_mutable_accounts" + +[features] +no-entrypoint = [] +cpi = ["no-entrypoint"] +idl-build = ["anchor-lang/idl-build"] + +[dependencies] +anchor-lang = { path = "../../../../lang" } \ No newline at end of file diff --git a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/Xargo.toml b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/Xargo.toml new file mode 100644 index 0000000000..1744f098ae --- /dev/null +++ b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] \ No newline at end of file diff --git a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs new file mode 100644 index 0000000000..4c21601f49 --- /dev/null +++ b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs @@ -0,0 +1,74 @@ +use anchor_lang::prelude::*; + +// Intentionally different program id than the one defined in Anchor.toml. +declare_id!("4D6rvpR7TSPwmFottLGa5gpzMcJ76kN8bimQHV9rogjH"); + +#[program] +pub mod duplicate_mutable_accounts { + use super::*; + + pub fn initialize(ctx: Context, initial: u64) -> Result<()> { + ctx.accounts.data_account.count = initial; + Ok(()) + } + + // This one should FAIL if the same mutable account is passed twice + // (Anchor disallows duplicate mutable accounts here). + pub fn fails_duplicate_mutable(ctx: Context) -> Result<()> { + ctx.accounts.account1.count += 1; + ctx.accounts.account2.count += 1; + Ok(()) + } + + // This one should SUCCEED even if the same account is passed twice, + // thanks to the `dup` constraint. + pub fn allows_duplicate_mutable(ctx: Context) -> Result<()> { + ctx.accounts.account1.count += 1; + ctx.accounts.account2.count += 1; + Ok(()) + } + + // Readonly duplicates should always be fine: we just read (no mutation). + pub fn allows_duplicate_readonly(_ctx: Context) -> Result<()> { + Ok(()) + } +} + +#[account] +pub struct Counter { + pub count: u64, +} + +#[derive(Accounts)] +pub struct Initialize<'info> { + #[account(init, payer = user, space = 8 + 8)] + pub data_account: Account<'info, Counter>, + #[account(mut)] + pub user: Signer<'info>, + pub system_program: Program<'info, System>, +} + +// No extra accounts here, because tests only pass account1 and account2. +#[derive(Accounts)] +pub struct FailsDuplicateMutable<'info> { + #[account(mut)] + pub account1: Account<'info, Counter>, + #[account(mut)] + pub account2: Account<'info, Counter>, +} + +// Allow the same mutable account to be supplied twice. +#[derive(Accounts)] +pub struct AllowsDuplicateMutable<'info> { + #[account(mut)] + pub account1: Account<'info, Counter>, + #[account(mut, dup)] + pub account2: Account<'info, Counter>, +} + +// Readonly accounts (no `mut`), duplicates allowed by nature. +#[derive(Accounts)] +pub struct AllowsDuplicateReadonly<'info> { + pub account1: Account<'info, Counter>, + pub account2: Account<'info, Counter>, +} diff --git a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts new file mode 100644 index 0000000000..55cf32fec3 --- /dev/null +++ b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts @@ -0,0 +1,88 @@ +import * as anchor from "@coral-xyz/anchor"; +import { Program, AnchorError } from "@coral-xyz/anchor"; +import { DuplicateMutableAccounts } from "../target/types/duplicate_mutable_accounts"; +import { assert } from "chai"; + +describe("duplicate-mutable-accounts", () => { + anchor.setProvider(anchor.AnchorProvider.env()); + const provider = anchor.getProvider() as anchor.AnchorProvider; + const program = anchor.workspace + .DuplicateMutableAccounts as Program; + + // Payer used by #[account(init, payer = user, ...)] + const user_wallet = anchor.web3.Keypair.generate(); + + // Two regular system accounts to hold Counter state (must sign on init) + const dataAccount1 = anchor.web3.Keypair.generate(); + const dataAccount2 = anchor.web3.Keypair.generate(); + + it("Initialize accounts", async () => { + // 1) Fund user_wallet so it can pay rent + const airdropSig = await provider.connection.requestAirdrop( + user_wallet.publicKey, + 2 * anchor.web3.LAMPORTS_PER_SOL + ); + await provider.connection.confirmTransaction(airdropSig); + + // 2) Create & init dataAccount1 (must sign with dataAccount1) + await program.methods + .initialize(new anchor.BN(100)) + .accounts({ + dataAccount: dataAccount1.publicKey, + user: user_wallet.publicKey, + systemProgram: anchor.web3.SystemProgram.programId, + }) + .signers([user_wallet, dataAccount1]) // <- include the new account keypair + .rpc(); + + // 3) Create & init dataAccount2 + await program.methods + .initialize(new anchor.BN(300)) + .accounts({ + dataAccount: dataAccount2.publicKey, + user: user_wallet.publicKey, + systemProgram: anchor.web3.SystemProgram.programId, + }) + .signers([user_wallet, dataAccount2]) // <- include the new account keypair + .rpc(); + }); + + it("Should fail with duplicate mutable accounts", async () => { + // Ensure the accounts are initialized + const account1 = await program.account.counter.fetch(dataAccount1.publicKey); + const account2 = await program.account.counter.fetch(dataAccount2.publicKey); + assert.strictEqual(account1.count.toNumber(), 100); + assert.strictEqual(account2.count.toNumber(), 300); + + try { + await program.methods + .failsDuplicateMutable() + .accounts({ + account1: dataAccount1.publicKey, + account2: dataAccount1.publicKey, // <- SAME account to trigger the check + }) + .rpc(); + assert.fail("Expected duplicate mutable violation"); + } catch (e) { + assert.instanceOf(e, AnchorError); + const err = e as AnchorError; + assert.strictEqual( + err.error.errorCode.code, + "ConstraintDuplicateMutableAccount" + ); + assert.strictEqual(err.error.errorCode.number, 2040); + } + }); + + it("Should succeed with duplicate mutable accounts", async () => { + // This instruction MUST have `#[account(mut, dup)]` on at least one account + await program.methods + .allowsDuplicateMutable() + .accounts({ + account1: dataAccount1.publicKey, + account2: dataAccount1.publicKey, // same account allowed via `dup` + }) + .rpc(); + assert.ok(true); + }); +}); diff --git a/tests/duplicate-mutable-accounts/tsconfig.json b/tests/duplicate-mutable-accounts/tsconfig.json new file mode 100644 index 0000000000..c7f23d9eaf --- /dev/null +++ b/tests/duplicate-mutable-accounts/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai", "node"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2015"], + "module": "commonjs", + "target": "es6", + "esModuleInterop": true, + "skipLibCheck": true + } +} From e42b1bc8579d89addd63990ec54c166fa8c24639 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 20:17:02 +0530 Subject: [PATCH 03/39] feat: add test for duplicate mutable accounts in workflow --- .github/workflows/reusable-tests.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/reusable-tests.yaml b/.github/workflows/reusable-tests.yaml index 7b8af78491..fd7e892d2e 100644 --- a/.github/workflows/reusable-tests.yaml +++ b/.github/workflows/reusable-tests.yaml @@ -416,6 +416,8 @@ jobs: path: tests/declare-program - cmd: cd tests/typescript && anchor test --skip-lint && npx tsc --noEmit path: tests/typescript + - cmd: cd tests/duplicate-mutable-accounts && anchor test --skip-lint + path: tests/duplicate-mutable-accounts # zero-copy tests cause `/usr/bin/ld: final link failed: No space left on device` # on GitHub runners. It is likely caused by `cargo test-sbf` since all other tests # don't have this problem. From da757c886b5253a98c688a0eea414d1aa01a5858 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 20:19:39 +0530 Subject: [PATCH 04/39] style(tests): prettier --- .../tests/duplicate-mutable-accounts.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts index 55cf32fec3..057b67f689 100644 --- a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts +++ b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts @@ -49,8 +49,12 @@ describe("duplicate-mutable-accounts", () => { it("Should fail with duplicate mutable accounts", async () => { // Ensure the accounts are initialized - const account1 = await program.account.counter.fetch(dataAccount1.publicKey); - const account2 = await program.account.counter.fetch(dataAccount2.publicKey); + const account1 = await program.account.counter.fetch( + dataAccount1.publicKey + ); + const account2 = await program.account.counter.fetch( + dataAccount2.publicKey + ); assert.strictEqual(account1.count.toNumber(), 100); assert.strictEqual(account2.count.toNumber(), 300); From b077343be608ea50271b0fa2e7b3623de0934935 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 20:30:52 +0530 Subject: [PATCH 05/39] chore: update benchmarks --- bench/BINARY_SIZE.md | 6 +- bench/COMPUTE_UNITS.md | 178 ++++++++++++++++++++--------------------- tests/bench/bench.json | 50 ++++++------ 3 files changed, 117 insertions(+), 117 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index ae72928761..852400310a 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -16,9 +16,9 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.1.0 -| Program | Binary Size | - | -| ------- | ----------- | --- | -| bench | 1,041,928 | - | +| Program | Binary Size | - | +| ------- | ----------- | ---------------------- | +| bench | 1,089,928 | 🔴 **+48,000 (4.61%)** | ### Notable changes diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index c519b8246f..68a87703ae 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -16,95 +16,95 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.1.0 -| Instruction | Compute Units | - | -| --------------------------- | ------------- | --- | -| accountInfo1 | 571 | - | -| accountInfo2 | 895 | - | -| accountInfo4 | 1,553 | - | -| accountInfo8 | 2,923 | - | -| accountEmptyInit1 | 5,083 | - | -| accountEmpty1 | 645 | - | -| accountEmptyInit2 | 9,301 | - | -| accountEmpty2 | 1,007 | - | -| accountEmptyInit4 | 17,764 | - | -| accountEmpty4 | 1,724 | - | -| accountEmptyInit8 | 34,723 | - | -| accountEmpty8 | 3,163 | - | -| accountSizedInit1 | 5,192 | - | -| accountSized1 | 693 | - | -| accountSizedInit2 | 9,489 | - | -| accountSized2 | 1,075 | - | -| accountSizedInit4 | 18,170 | - | -| accountSized4 | 1,848 | - | -| accountSizedInit8 | 35,433 | - | -| accountSized8 | 3,387 | - | -| accountUnsizedInit1 | 5,305 | - | -| accountUnsized1 | 746 | - | -| accountUnsizedInit2 | 9,759 | - | -| accountUnsized2 | 1,163 | - | -| accountUnsizedInit4 | 18,603 | - | -| accountUnsized4 | 2,002 | - | -| accountUnsizedInit8 | 35,993 | - | -| accountUnsized8 | 3,673 | - | -| boxedAccountEmptyInit1 | 5,175 | - | -| boxedAccountEmpty1 | 734 | - | -| boxedAccountEmptyInit2 | 9,414 | - | -| boxedAccountEmpty2 | 1,116 | - | -| boxedAccountEmptyInit4 | 17,918 | - | -| boxedAccountEmpty4 | 1,872 | - | -| boxedAccountEmptyInit8 | 34,953 | - | -| boxedAccountEmpty8 | 3,401 | - | -| boxedAccountSizedInit1 | 5,271 | - | -| boxedAccountSized1 | 783 | - | -| boxedAccountSizedInit2 | 9,583 | - | -| boxedAccountSized2 | 1,190 | - | -| boxedAccountSizedInit4 | 18,230 | - | -| boxedAccountSized4 | 1,996 | - | -| boxedAccountSizedInit8 | 35,553 | - | -| boxedAccountSized8 | 3,628 | - | -| boxedAccountUnsizedInit1 | 5,371 | - | -| boxedAccountUnsized1 | 836 | - | -| boxedAccountUnsizedInit2 | 9,759 | - | -| boxedAccountUnsized2 | 1,270 | - | -| boxedAccountUnsizedInit4 | 18,558 | - | -| boxedAccountUnsized4 | 2,132 | - | -| boxedAccountUnsizedInit8 | 36,185 | - | -| boxedAccountUnsized8 | 3,881 | - | -| boxedInterfaceAccountMint1 | 1,351 | - | -| boxedInterfaceAccountMint2 | 2,123 | - | -| boxedInterfaceAccountMint4 | 3,656 | - | -| boxedInterfaceAccountMint8 | 6,738 | - | -| boxedInterfaceAccountToken1 | 2,011 | - | -| boxedInterfaceAccountToken2 | 3,431 | - | -| boxedInterfaceAccountToken4 | 6,260 | - | -| boxedInterfaceAccountToken8 | 11,934 | - | -| interfaceAccountMint1 | 1,476 | - | -| interfaceAccountMint2 | 2,489 | - | -| interfaceAccountMint4 | 4,511 | - | -| interfaceAccountMint8 | 8,550 | - | -| interfaceAccountToken1 | 2,111 | - | -| interfaceAccountToken2 | 3,729 | - | -| interfaceAccountToken4 | 6,955 | - | -| interface1 | 769 | - | -| interface2 | 912 | - | -| interface4 | 1,189 | - | -| interface8 | 1,748 | - | -| program1 | 779 | - | -| program2 | 920 | - | -| program4 | 1,193 | - | -| program8 | 1,744 | - | -| signer1 | 774 | - | -| signer2 | 1,064 | - | -| signer4 | 1,637 | - | -| signer8 | 2,788 | - | -| systemAccount1 | 796 | - | -| systemAccount2 | 1,096 | - | -| systemAccount4 | 1,689 | - | -| systemAccount8 | 2,880 | - | -| uncheckedAccount1 | 783 | - | -| uncheckedAccount2 | 1,056 | - | -| uncheckedAccount4 | 1,594 | - | -| uncheckedAccount8 | 2,679 | - | +| Instruction | Compute Units | - | +| --------------------------- | ------------- | --------------------- | +| accountInfo1 | 571 | - | +| accountInfo2 | 895 | - | +| accountInfo4 | 1,553 | - | +| accountInfo8 | 2,923 | - | +| accountEmptyInit1 | 5,323 | 🔴 **+240 (4.72%)** | +| accountEmpty1 | 645 | - | +| accountEmptyInit2 | 9,720 | 🔴 **+419 (4.50%)** | +| accountEmpty2 | 1,007 | - | +| accountEmptyInit4 | 18,562 | 🔴 **+798 (4.49%)** | +| accountEmpty4 | 1,724 | - | +| accountEmptyInit8 | 36,524 | 🔴 **+1,801 (5.19%)** | +| accountEmpty8 | 3,163 | - | +| accountSizedInit1 | 5,432 | 🔴 **+240 (4.62%)** | +| accountSized1 | 693 | - | +| accountSizedInit2 | 9,912 | 🔴 **+423 (4.46%)** | +| accountSized2 | 1,075 | - | +| accountSizedInit4 | 19,032 | 🔴 **+862 (4.74%)** | +| accountSized4 | 1,848 | - | +| accountSizedInit8 | 37,282 | 🔴 **+1,849 (5.22%)** | +| accountSized8 | 3,387 | - | +| accountUnsizedInit1 | 5,546 | 🔴 **+241 (4.54%)** | +| accountUnsized1 | 746 | - | +| accountUnsizedInit2 | 10,184 | 🔴 **+425 (4.35%)** | +| accountUnsized2 | 1,163 | - | +| accountUnsizedInit4 | 19,397 | 🔴 **+794 (4.27%)** | +| accountUnsized4 | 2,002 | - | +| accountUnsizedInit8 | 37,830 | 🔴 **+1,837 (5.10%)** | +| accountUnsized8 | 3,673 | - | +| boxedAccountEmptyInit1 | 5,416 | 🔴 **+241 (4.66%)** | +| boxedAccountEmpty1 | 734 | - | +| boxedAccountEmptyInit2 | 9,840 | 🔴 **+426 (4.53%)** | +| boxedAccountEmpty2 | 1,116 | - | +| boxedAccountEmptyInit4 | 18,682 | 🔴 **+764 (4.26%)** | +| boxedAccountEmpty4 | 1,872 | - | +| boxedAccountEmptyInit8 | 36,497 | 🔴 **+1,544 (4.42%)** | +| boxedAccountEmpty8 | 3,401 | - | +| boxedAccountSizedInit1 | 5,512 | 🔴 **+241 (4.57%)** | +| boxedAccountSized1 | 783 | - | +| boxedAccountSizedInit2 | 10,009 | 🔴 **+426 (4.45%)** | +| boxedAccountSized2 | 1,190 | - | +| boxedAccountSizedInit4 | 19,098 | 🔴 **+868 (4.76%)** | +| boxedAccountSized4 | 1,996 | - | +| boxedAccountSizedInit8 | 37,173 | 🔴 **+1,620 (4.56%)** | +| boxedAccountSized8 | 3,628 | - | +| boxedAccountUnsizedInit1 | 5,612 | 🔴 **+241 (4.49%)** | +| boxedAccountUnsized1 | 836 | - | +| boxedAccountUnsizedInit2 | 10,185 | 🔴 **+426 (4.37%)** | +| boxedAccountUnsized2 | 1,270 | - | +| boxedAccountUnsizedInit4 | 19,438 | 🔴 **+880 (4.74%)** | +| boxedAccountUnsized4 | 2,132 | - | +| boxedAccountUnsizedInit8 | 37,917 | 🔴 **+1,732 (4.79%)** | +| boxedAccountUnsized8 | 3,881 | - | +| boxedInterfaceAccountMint1 | 1,351 | - | +| boxedInterfaceAccountMint2 | 2,123 | - | +| boxedInterfaceAccountMint4 | 3,656 | - | +| boxedInterfaceAccountMint8 | 6,738 | - | +| boxedInterfaceAccountToken1 | 2,011 | - | +| boxedInterfaceAccountToken2 | 3,431 | - | +| boxedInterfaceAccountToken4 | 6,260 | - | +| boxedInterfaceAccountToken8 | 11,934 | - | +| interfaceAccountMint1 | 1,476 | - | +| interfaceAccountMint2 | 2,489 | - | +| interfaceAccountMint4 | 4,511 | - | +| interfaceAccountMint8 | 8,550 | - | +| interfaceAccountToken1 | 2,111 | - | +| interfaceAccountToken2 | 3,729 | - | +| interfaceAccountToken4 | 6,955 | - | +| interface1 | 769 | - | +| interface2 | 912 | - | +| interface4 | 1,189 | - | +| interface8 | 1,748 | - | +| program1 | 779 | - | +| program2 | 920 | - | +| program4 | 1,193 | - | +| program8 | 1,744 | - | +| signer1 | 774 | - | +| signer2 | 1,064 | - | +| signer4 | 1,637 | - | +| signer8 | 2,788 | - | +| systemAccount1 | 796 | - | +| systemAccount2 | 1,096 | - | +| systemAccount4 | 1,689 | - | +| systemAccount8 | 2,880 | - | +| uncheckedAccount1 | 783 | - | +| uncheckedAccount2 | 1,056 | - | +| uncheckedAccount4 | 1,594 | - | +| uncheckedAccount8 | 2,679 | - | ### Notable changes diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 65517278b3..3e7389a371 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1305,60 +1305,60 @@ "solanaVersion": "2.1.0", "result": { "binarySize": { - "bench": 1041928 + "bench": 1089928 }, "computeUnits": { "accountInfo1": 571, "accountInfo2": 895, "accountInfo4": 1553, "accountInfo8": 2923, - "accountEmptyInit1": 5083, + "accountEmptyInit1": 5323, "accountEmpty1": 645, - "accountEmptyInit2": 9301, + "accountEmptyInit2": 9720, "accountEmpty2": 1007, - "accountEmptyInit4": 17764, + "accountEmptyInit4": 18562, "accountEmpty4": 1724, - "accountEmptyInit8": 34723, + "accountEmptyInit8": 36524, "accountEmpty8": 3163, - "accountSizedInit1": 5192, + "accountSizedInit1": 5432, "accountSized1": 693, - "accountSizedInit2": 9489, + "accountSizedInit2": 9912, "accountSized2": 1075, - "accountSizedInit4": 18170, + "accountSizedInit4": 19032, "accountSized4": 1848, - "accountSizedInit8": 35433, + "accountSizedInit8": 37282, "accountSized8": 3387, - "accountUnsizedInit1": 5305, + "accountUnsizedInit1": 5546, "accountUnsized1": 746, - "accountUnsizedInit2": 9759, + "accountUnsizedInit2": 10184, "accountUnsized2": 1163, - "accountUnsizedInit4": 18603, + "accountUnsizedInit4": 19397, "accountUnsized4": 2002, - "accountUnsizedInit8": 35993, + "accountUnsizedInit8": 37830, "accountUnsized8": 3673, - "boxedAccountEmptyInit1": 5175, + "boxedAccountEmptyInit1": 5416, "boxedAccountEmpty1": 734, - "boxedAccountEmptyInit2": 9414, + "boxedAccountEmptyInit2": 9840, "boxedAccountEmpty2": 1116, - "boxedAccountEmptyInit4": 17918, + "boxedAccountEmptyInit4": 18682, "boxedAccountEmpty4": 1872, - "boxedAccountEmptyInit8": 34953, + "boxedAccountEmptyInit8": 36497, "boxedAccountEmpty8": 3401, - "boxedAccountSizedInit1": 5271, + "boxedAccountSizedInit1": 5512, "boxedAccountSized1": 783, - "boxedAccountSizedInit2": 9583, + "boxedAccountSizedInit2": 10009, "boxedAccountSized2": 1190, - "boxedAccountSizedInit4": 18230, + "boxedAccountSizedInit4": 19098, "boxedAccountSized4": 1996, - "boxedAccountSizedInit8": 35553, + "boxedAccountSizedInit8": 37173, "boxedAccountSized8": 3628, - "boxedAccountUnsizedInit1": 5371, + "boxedAccountUnsizedInit1": 5612, "boxedAccountUnsized1": 836, - "boxedAccountUnsizedInit2": 9759, + "boxedAccountUnsizedInit2": 10185, "boxedAccountUnsized2": 1270, - "boxedAccountUnsizedInit4": 18558, + "boxedAccountUnsizedInit4": 19438, "boxedAccountUnsized4": 2132, - "boxedAccountUnsizedInit8": 36185, + "boxedAccountUnsizedInit8": 37917, "boxedAccountUnsized8": 3881, "boxedInterfaceAccountMint1": 1351, "boxedInterfaceAccountMint2": 2123, From 62b76d0bf16f1b2ee0d29f11891b244edbbf6cf2 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 20:42:47 +0530 Subject: [PATCH 06/39] feat: exclude UncheckedAccounts from duplicate mutable account checks --- lang/syn/src/codegen/accounts/try_accounts.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index 38b05cc08e..e25c24a1fd 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -210,12 +210,17 @@ fn is_init(af: &AccountField) -> bool { // Generates duplicate mutable account validation logic fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::TokenStream { // Find all mutable account fields that don't have dup constraint + // Exclude UncheckedAccount types as they are unchecked by design let check_required_fields: Vec<_> = accs .fields .iter() .filter_map(|af| match af { AccountField::Field(f) if f.constraints.is_mutable() && !f.constraints.is_dup() => { - Some(f) + // Exclude UncheckedAccount types from duplicate checks + match &f.ty { + crate::Ty::UncheckedAccount => None, + _ => Some(f), + } } _ => None, }) From 4b3b85c70ddb65aa0f253b7f43ea9b2c6091d501 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 20:47:37 +0530 Subject: [PATCH 07/39] feat(tests): add duplicate-mutable-accounts to test scripts --- tests/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/package.json b/tests/package.json index 41c258ceb9..7de67496ff 100644 --- a/tests/package.json +++ b/tests/package.json @@ -50,7 +50,8 @@ "cpi-returns", "multiple-suites", "multiple-suites-run-single", - "bpf-upgradeable-state" + "bpf-upgradeable-state", + "duplicate-mutable-accounts" ], "dependencies": { "@project-serum/common": "^0.0.1-beta.3", From da22fa8f0f3d99f05e162872c8c4e017eb745ac6 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 21:03:09 +0530 Subject: [PATCH 08/39] feat: enhance duplicate mutable account checks for optional fields --- lang/syn/src/codegen/accounts/try_accounts.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index e25c24a1fd..e57584987f 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -236,7 +236,11 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke .iter() .map(|f| { let name = &f.ident; - quote! { #name.key() } + if f.is_optional { + quote! { #name.as_ref().map(|f| f.key()) } + } else { + quote! { Some(#name.key()) } + } }) .collect(); @@ -250,10 +254,12 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke { let mut __mutable_accounts = std::collections::BTreeSet::new(); #( - if !__mutable_accounts.insert(#field_keys) { - return Err(anchor_lang::error::Error::from( - anchor_lang::error::ErrorCode::ConstraintDuplicateMutableAccount - ).with_account_name(#field_name_strs)); + if let Some(key) = #field_keys { + if !__mutable_accounts.insert(key) { + return Err(anchor_lang::error::Error::from( + anchor_lang::error::ErrorCode::ConstraintDuplicateMutableAccount + ).with_account_name(#field_name_strs)); + } } )* } From 0ee61f86cdb0e4eb17a4097a7fe7118167874d62 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 21:11:06 +0530 Subject: [PATCH 09/39] chore(bench): update --- bench/COMPUTE_UNITS.md | 2 +- tests/bench/bench.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 68a87703ae..b5759dc4c4 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -52,7 +52,7 @@ Solana version: 2.1.0 | boxedAccountEmpty2 | 1,116 | - | | boxedAccountEmptyInit4 | 18,682 | 🔴 **+764 (4.26%)** | | boxedAccountEmpty4 | 1,872 | - | -| boxedAccountEmptyInit8 | 36,497 | 🔴 **+1,544 (4.42%)** | +| boxedAccountEmptyInit8 | 36,893 | 🔴 **+1,940 (5.55%)** | | boxedAccountEmpty8 | 3,401 | - | | boxedAccountSizedInit1 | 5,512 | 🔴 **+241 (4.57%)** | | boxedAccountSized1 | 783 | - | diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 3e7389a371..16c9841efd 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1342,7 +1342,7 @@ "boxedAccountEmpty2": 1116, "boxedAccountEmptyInit4": 18682, "boxedAccountEmpty4": 1872, - "boxedAccountEmptyInit8": 36497, + "boxedAccountEmptyInit8": 36893, "boxedAccountEmpty8": 3401, "boxedAccountSizedInit1": 5512, "boxedAccountSized1": 783, From a6f6c572de5adaca778fd8ec1889c4d57f2bc69c Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 21:14:12 +0530 Subject: [PATCH 10/39] fix: update program IDs --- tests/duplicate-mutable-accounts/Anchor.toml | 2 +- .../programs/duplicate-mutable-accounts/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/duplicate-mutable-accounts/Anchor.toml b/tests/duplicate-mutable-accounts/Anchor.toml index c839ab54b0..7bae6d45b8 100644 --- a/tests/duplicate-mutable-accounts/Anchor.toml +++ b/tests/duplicate-mutable-accounts/Anchor.toml @@ -3,7 +3,7 @@ cluster = "localnet" wallet = "~/.config/solana/id.json" [programs.localnet] -declare_id = "4D6rvpR7TSPwmFottLGa5gpzMcJ76kN8bimQHV9rogjH" +declare_id = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" [scripts] test = "yarn run ts-mocha -t 1000000 tests/*.ts" diff --git a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs index 4c21601f49..b915f2b89e 100644 --- a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs +++ b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs @@ -1,7 +1,7 @@ use anchor_lang::prelude::*; // Intentionally different program id than the one defined in Anchor.toml. -declare_id!("4D6rvpR7TSPwmFottLGa5gpzMcJ76kN8bimQHV9rogjH"); +declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); #[program] pub mod duplicate_mutable_accounts { From 4035b0e67a222eaac5fd5726c35dc58a3b55e8a2 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 21:14:34 +0530 Subject: [PATCH 11/39] feat: allow duplicate accounts in realloc2 ix --- tests/realloc/programs/realloc/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/realloc/programs/realloc/src/lib.rs b/tests/realloc/programs/realloc/src/lib.rs index 3ac5eb5dc2..500d2c2380 100644 --- a/tests/realloc/programs/realloc/src/lib.rs +++ b/tests/realloc/programs/realloc/src/lib.rs @@ -93,6 +93,7 @@ pub struct Realloc2<'info> { realloc = Sample::space((len + 10) as usize), realloc::payer = authority, realloc::zero = false, + dup, // Allow duplicate accounts )] pub sample2: Account<'info, Sample>, From c65be84984a53e325e20e189da5a7bc32cb691c3 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 21:32:47 +0530 Subject: [PATCH 12/39] chore(bench): update --- bench/BINARY_SIZE.md | 2 +- bench/COMPUTE_UNITS.md | 34 +++++++++++++++++----------------- tests/bench/bench.json | 36 ++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index 852400310a..59c397daee 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,089,928 | 🔴 **+48,000 (4.61%)** | +| bench | 1,091,904 | 🔴 **+49,976 (4.80%)** | ### Notable changes diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index b5759dc4c4..009c7f6555 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -22,53 +22,53 @@ Solana version: 2.1.0 | accountInfo2 | 895 | - | | accountInfo4 | 1,553 | - | | accountInfo8 | 2,923 | - | -| accountEmptyInit1 | 5,323 | 🔴 **+240 (4.72%)** | +| accountEmptyInit1 | 5,260 | 🔴 **+177 (3.48%)** | | accountEmpty1 | 645 | - | -| accountEmptyInit2 | 9,720 | 🔴 **+419 (4.50%)** | +| accountEmptyInit2 | 9,724 | 🔴 **+423 (4.55%)** | | accountEmpty2 | 1,007 | - | -| accountEmptyInit4 | 18,562 | 🔴 **+798 (4.49%)** | +| accountEmptyInit4 | 18,629 | 🔴 **+865 (4.87%)** | | accountEmpty4 | 1,724 | - | -| accountEmptyInit8 | 36,524 | 🔴 **+1,801 (5.19%)** | +| accountEmptyInit8 | 36,519 | 🔴 **+1,796 (5.17%)** | | accountEmpty8 | 3,163 | - | | accountSizedInit1 | 5,432 | 🔴 **+240 (4.62%)** | | accountSized1 | 693 | - | | accountSizedInit2 | 9,912 | 🔴 **+423 (4.46%)** | | accountSized2 | 1,075 | - | -| accountSizedInit4 | 19,032 | 🔴 **+862 (4.74%)** | +| accountSizedInit4 | 18,936 | 🔴 **+766 (4.22%)** | | accountSized4 | 1,848 | - | -| accountSizedInit8 | 37,282 | 🔴 **+1,849 (5.22%)** | +| accountSizedInit8 | 37,294 | 🔴 **+1,861 (5.25%)** | | accountSized8 | 3,387 | - | | accountUnsizedInit1 | 5,546 | 🔴 **+241 (4.54%)** | | accountUnsized1 | 746 | - | -| accountUnsizedInit2 | 10,184 | 🔴 **+425 (4.35%)** | +| accountUnsizedInit2 | 10,180 | 🔴 **+421 (4.31%)** | | accountUnsized2 | 1,163 | - | -| accountUnsizedInit4 | 19,397 | 🔴 **+794 (4.27%)** | +| accountUnsizedInit4 | 19,301 | 🔴 **+698 (3.75%)** | | accountUnsized4 | 2,002 | - | -| accountUnsizedInit8 | 37,830 | 🔴 **+1,837 (5.10%)** | +| accountUnsizedInit8 | 37,682 | 🔴 **+1,689 (4.69%)** | | accountUnsized8 | 3,673 | - | | boxedAccountEmptyInit1 | 5,416 | 🔴 **+241 (4.66%)** | | boxedAccountEmpty1 | 734 | - | | boxedAccountEmptyInit2 | 9,840 | 🔴 **+426 (4.53%)** | | boxedAccountEmpty2 | 1,116 | - | -| boxedAccountEmptyInit4 | 18,682 | 🔴 **+764 (4.26%)** | +| boxedAccountEmptyInit4 | 18,798 | 🔴 **+880 (4.91%)** | | boxedAccountEmpty4 | 1,872 | - | -| boxedAccountEmptyInit8 | 36,893 | 🔴 **+1,940 (5.55%)** | +| boxedAccountEmptyInit8 | 36,861 | 🔴 **+1,908 (5.46%)** | | boxedAccountEmpty8 | 3,401 | - | | boxedAccountSizedInit1 | 5,512 | 🔴 **+241 (4.57%)** | | boxedAccountSized1 | 783 | - | -| boxedAccountSizedInit2 | 10,009 | 🔴 **+426 (4.45%)** | +| boxedAccountSizedInit2 | 10,005 | 🔴 **+422 (4.40%)** | | boxedAccountSized2 | 1,190 | - | -| boxedAccountSizedInit4 | 19,098 | 🔴 **+868 (4.76%)** | +| boxedAccountSizedInit4 | 19,102 | 🔴 **+872 (4.78%)** | | boxedAccountSized4 | 1,996 | - | -| boxedAccountSizedInit8 | 37,173 | 🔴 **+1,620 (4.56%)** | +| boxedAccountSizedInit8 | 37,521 | 🔴 **+1,968 (5.54%)** | | boxedAccountSized8 | 3,628 | - | | boxedAccountUnsizedInit1 | 5,612 | 🔴 **+241 (4.49%)** | | boxedAccountUnsized1 | 836 | - | -| boxedAccountUnsizedInit2 | 10,185 | 🔴 **+426 (4.37%)** | +| boxedAccountUnsizedInit2 | 10,181 | 🔴 **+422 (4.32%)** | | boxedAccountUnsized2 | 1,270 | - | -| boxedAccountUnsizedInit4 | 19,438 | 🔴 **+880 (4.74%)** | +| boxedAccountUnsizedInit4 | 19,434 | 🔴 **+876 (4.72%)** | | boxedAccountUnsized4 | 2,132 | - | -| boxedAccountUnsizedInit8 | 37,917 | 🔴 **+1,732 (4.79%)** | +| boxedAccountUnsizedInit8 | 37,781 | 🔴 **+1,596 (4.41%)** | | boxedAccountUnsized8 | 3,881 | - | | boxedInterfaceAccountMint1 | 1,351 | - | | boxedInterfaceAccountMint2 | 2,123 | - | diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 16c9841efd..f5335ec7c2 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1305,60 +1305,60 @@ "solanaVersion": "2.1.0", "result": { "binarySize": { - "bench": 1089928 + "bench": 1091904 }, "computeUnits": { "accountInfo1": 571, "accountInfo2": 895, "accountInfo4": 1553, "accountInfo8": 2923, - "accountEmptyInit1": 5323, + "accountEmptyInit1": 5260, "accountEmpty1": 645, - "accountEmptyInit2": 9720, + "accountEmptyInit2": 9724, "accountEmpty2": 1007, - "accountEmptyInit4": 18562, + "accountEmptyInit4": 18629, "accountEmpty4": 1724, - "accountEmptyInit8": 36524, + "accountEmptyInit8": 36519, "accountEmpty8": 3163, "accountSizedInit1": 5432, "accountSized1": 693, "accountSizedInit2": 9912, "accountSized2": 1075, - "accountSizedInit4": 19032, + "accountSizedInit4": 18936, "accountSized4": 1848, - "accountSizedInit8": 37282, + "accountSizedInit8": 37294, "accountSized8": 3387, "accountUnsizedInit1": 5546, "accountUnsized1": 746, - "accountUnsizedInit2": 10184, + "accountUnsizedInit2": 10180, "accountUnsized2": 1163, - "accountUnsizedInit4": 19397, + "accountUnsizedInit4": 19301, "accountUnsized4": 2002, - "accountUnsizedInit8": 37830, + "accountUnsizedInit8": 37682, "accountUnsized8": 3673, "boxedAccountEmptyInit1": 5416, "boxedAccountEmpty1": 734, "boxedAccountEmptyInit2": 9840, "boxedAccountEmpty2": 1116, - "boxedAccountEmptyInit4": 18682, + "boxedAccountEmptyInit4": 18798, "boxedAccountEmpty4": 1872, - "boxedAccountEmptyInit8": 36893, + "boxedAccountEmptyInit8": 36861, "boxedAccountEmpty8": 3401, "boxedAccountSizedInit1": 5512, "boxedAccountSized1": 783, - "boxedAccountSizedInit2": 10009, + "boxedAccountSizedInit2": 10005, "boxedAccountSized2": 1190, - "boxedAccountSizedInit4": 19098, + "boxedAccountSizedInit4": 19102, "boxedAccountSized4": 1996, - "boxedAccountSizedInit8": 37173, + "boxedAccountSizedInit8": 37521, "boxedAccountSized8": 3628, "boxedAccountUnsizedInit1": 5612, "boxedAccountUnsized1": 836, - "boxedAccountUnsizedInit2": 10185, + "boxedAccountUnsizedInit2": 10181, "boxedAccountUnsized2": 1270, - "boxedAccountUnsizedInit4": 19438, + "boxedAccountUnsizedInit4": 19434, "boxedAccountUnsized4": 2132, - "boxedAccountUnsizedInit8": 37917, + "boxedAccountUnsizedInit8": 37781, "boxedAccountUnsized8": 3881, "boxedInterfaceAccountMint1": 1351, "boxedInterfaceAccountMint2": 2123, From d55c2ef07486e93f680b9d2de27a1df94b43d4a1 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 28 Aug 2025 21:45:29 +0530 Subject: [PATCH 13/39] chore(bench): update --- bench/COMPUTE_UNITS.md | 2 +- tests/bench/bench.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 009c7f6555..1b38aa0d65 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -22,7 +22,7 @@ Solana version: 2.1.0 | accountInfo2 | 895 | - | | accountInfo4 | 1,553 | - | | accountInfo8 | 2,923 | - | -| accountEmptyInit1 | 5,260 | 🔴 **+177 (3.48%)** | +| accountEmptyInit1 | 5,323 | 🔴 **+240 (4.72%)** | | accountEmpty1 | 645 | - | | accountEmptyInit2 | 9,724 | 🔴 **+423 (4.55%)** | | accountEmpty2 | 1,007 | - | diff --git a/tests/bench/bench.json b/tests/bench/bench.json index f5335ec7c2..2ebf126c26 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1312,7 +1312,7 @@ "accountInfo2": 895, "accountInfo4": 1553, "accountInfo8": 2923, - "accountEmptyInit1": 5260, + "accountEmptyInit1": 5323, "accountEmpty1": 645, "accountEmptyInit2": 9724, "accountEmpty2": 1007, From 5c228f57a8e995c5361438fdb0425b941c0b63db Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 29 Aug 2025 15:02:47 +0530 Subject: [PATCH 14/39] feat(tests): allow duplicate accounts in misc tests --- tests/misc/programs/misc-optional/src/context.rs | 4 ++-- tests/misc/programs/misc/src/context.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/misc/programs/misc-optional/src/context.rs b/tests/misc/programs/misc-optional/src/context.rs index 1a06393a95..fcbd761b58 100644 --- a/tests/misc/programs/misc-optional/src/context.rs +++ b/tests/misc/programs/misc-optional/src/context.rs @@ -749,7 +749,7 @@ pub struct InitManyAssociatedTokenAccounts<'info> { pub struct TestMultipleZeroConstraint<'info> { #[account(zero)] pub one: Option>, - #[account(zero)] + #[account(zero, dup)] // Allow duplicate accounts to test the error pub two: Option>, } @@ -757,7 +757,7 @@ pub struct TestMultipleZeroConstraint<'info> { pub struct TestInitAndZero<'info> { #[account(init, payer = payer, space = Data::DISCRIMINATOR.len() + Data::LEN)] pub init: Option>, - #[account(zero)] + #[account(zero, dup)] // Allow duplicate accounts to test the error pub zero: Option>, #[account(mut)] pub payer: Option>, diff --git a/tests/misc/programs/misc/src/context.rs b/tests/misc/programs/misc/src/context.rs index d19c84c562..7fb3571409 100644 --- a/tests/misc/programs/misc/src/context.rs +++ b/tests/misc/programs/misc/src/context.rs @@ -821,7 +821,7 @@ pub struct Empty {} pub struct TestMultipleZeroConstraint<'info> { #[account(zero)] pub one: Account<'info, Data>, - #[account(zero)] + #[account(zero, dup)] // Allow duplicate accounts to test the error pub two: Account<'info, Data>, } @@ -829,7 +829,7 @@ pub struct TestMultipleZeroConstraint<'info> { pub struct TestInitAndZero<'info> { #[account(init, payer = payer, space = Data::DISCRIMINATOR.len() + Data::LEN)] pub init: Account<'info, Data>, - #[account(zero)] + #[account(zero, dup)] // Allow duplicate accounts to test the error pub zero: Account<'info, Data>, #[account(mut)] pub payer: Signer<'info>, From 8dd5c8daa256a3a20b88dc5f876e47f8ebe11d4e Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 29 Aug 2025 15:11:00 +0530 Subject: [PATCH 15/39] fix(bench):update --- bench/COMPUTE_UNITS.md | 26 +++++++++++++------------- tests/bench/bench.json | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 1b38aa0d65..86805f3fb1 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -26,33 +26,33 @@ Solana version: 2.1.0 | accountEmpty1 | 645 | - | | accountEmptyInit2 | 9,724 | 🔴 **+423 (4.55%)** | | accountEmpty2 | 1,007 | - | -| accountEmptyInit4 | 18,629 | 🔴 **+865 (4.87%)** | +| accountEmptyInit4 | 18,558 | 🔴 **+794 (4.47%)** | | accountEmpty4 | 1,724 | - | -| accountEmptyInit8 | 36,519 | 🔴 **+1,796 (5.17%)** | +| accountEmptyInit8 | 36,239 | 🔴 **+1,516 (4.37%)** | | accountEmpty8 | 3,163 | - | | accountSizedInit1 | 5,432 | 🔴 **+240 (4.62%)** | | accountSized1 | 693 | - | -| accountSizedInit2 | 9,912 | 🔴 **+423 (4.46%)** | +| accountSizedInit2 | 9,908 | 🔴 **+419 (4.42%)** | | accountSized2 | 1,075 | - | -| accountSizedInit4 | 18,936 | 🔴 **+766 (4.22%)** | +| accountSizedInit4 | 19,036 | 🔴 **+866 (4.77%)** | | accountSized4 | 1,848 | - | -| accountSizedInit8 | 37,294 | 🔴 **+1,861 (5.25%)** | +| accountSizedInit8 | 37,238 | 🔴 **+1,805 (5.09%)** | | accountSized8 | 3,387 | - | | accountUnsizedInit1 | 5,546 | 🔴 **+241 (4.54%)** | | accountUnsized1 | 746 | - | | accountUnsizedInit2 | 10,180 | 🔴 **+421 (4.31%)** | | accountUnsized2 | 1,163 | - | -| accountUnsizedInit4 | 19,301 | 🔴 **+698 (3.75%)** | +| accountUnsizedInit4 | 19,476 | 🔴 **+873 (4.69%)** | | accountUnsized4 | 2,002 | - | -| accountUnsizedInit8 | 37,682 | 🔴 **+1,689 (4.69%)** | +| accountUnsizedInit8 | 37,758 | 🔴 **+1,765 (4.90%)** | | accountUnsized8 | 3,673 | - | | boxedAccountEmptyInit1 | 5,416 | 🔴 **+241 (4.66%)** | | boxedAccountEmpty1 | 734 | - | | boxedAccountEmptyInit2 | 9,840 | 🔴 **+426 (4.53%)** | | boxedAccountEmpty2 | 1,116 | - | -| boxedAccountEmptyInit4 | 18,798 | 🔴 **+880 (4.91%)** | +| boxedAccountEmptyInit4 | 18,794 | 🔴 **+876 (4.89%)** | | boxedAccountEmpty4 | 1,872 | - | -| boxedAccountEmptyInit8 | 36,861 | 🔴 **+1,908 (5.46%)** | +| boxedAccountEmptyInit8 | 37,037 | 🔴 **+2,084 (5.96%)** | | boxedAccountEmpty8 | 3,401 | - | | boxedAccountSizedInit1 | 5,512 | 🔴 **+241 (4.57%)** | | boxedAccountSized1 | 783 | - | @@ -60,15 +60,15 @@ Solana version: 2.1.0 | boxedAccountSized2 | 1,190 | - | | boxedAccountSizedInit4 | 19,102 | 🔴 **+872 (4.78%)** | | boxedAccountSized4 | 1,996 | - | -| boxedAccountSizedInit8 | 37,521 | 🔴 **+1,968 (5.54%)** | +| boxedAccountSizedInit8 | 37,397 | 🔴 **+1,844 (5.19%)** | | boxedAccountSized8 | 3,628 | - | | boxedAccountUnsizedInit1 | 5,612 | 🔴 **+241 (4.49%)** | | boxedAccountUnsized1 | 836 | - | -| boxedAccountUnsizedInit2 | 10,181 | 🔴 **+422 (4.32%)** | +| boxedAccountUnsizedInit2 | 10,185 | 🔴 **+426 (4.37%)** | | boxedAccountUnsized2 | 1,270 | - | -| boxedAccountUnsizedInit4 | 19,434 | 🔴 **+876 (4.72%)** | +| boxedAccountUnsizedInit4 | 19,359 | 🔴 **+801 (4.32%)** | | boxedAccountUnsized4 | 2,132 | - | -| boxedAccountUnsizedInit8 | 37,781 | 🔴 **+1,596 (4.41%)** | +| boxedAccountUnsizedInit8 | 37,805 | 🔴 **+1,620 (4.48%)** | | boxedAccountUnsized8 | 3,881 | - | | boxedInterfaceAccountMint1 | 1,351 | - | | boxedInterfaceAccountMint2 | 2,123 | - | diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 2ebf126c26..e8cfebbb9b 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1316,33 +1316,33 @@ "accountEmpty1": 645, "accountEmptyInit2": 9724, "accountEmpty2": 1007, - "accountEmptyInit4": 18629, + "accountEmptyInit4": 18558, "accountEmpty4": 1724, - "accountEmptyInit8": 36519, + "accountEmptyInit8": 36239, "accountEmpty8": 3163, "accountSizedInit1": 5432, "accountSized1": 693, - "accountSizedInit2": 9912, + "accountSizedInit2": 9908, "accountSized2": 1075, - "accountSizedInit4": 18936, + "accountSizedInit4": 19036, "accountSized4": 1848, - "accountSizedInit8": 37294, + "accountSizedInit8": 37238, "accountSized8": 3387, "accountUnsizedInit1": 5546, "accountUnsized1": 746, "accountUnsizedInit2": 10180, "accountUnsized2": 1163, - "accountUnsizedInit4": 19301, + "accountUnsizedInit4": 19476, "accountUnsized4": 2002, - "accountUnsizedInit8": 37682, + "accountUnsizedInit8": 37758, "accountUnsized8": 3673, "boxedAccountEmptyInit1": 5416, "boxedAccountEmpty1": 734, "boxedAccountEmptyInit2": 9840, "boxedAccountEmpty2": 1116, - "boxedAccountEmptyInit4": 18798, + "boxedAccountEmptyInit4": 18794, "boxedAccountEmpty4": 1872, - "boxedAccountEmptyInit8": 36861, + "boxedAccountEmptyInit8": 37037, "boxedAccountEmpty8": 3401, "boxedAccountSizedInit1": 5512, "boxedAccountSized1": 783, @@ -1350,15 +1350,15 @@ "boxedAccountSized2": 1190, "boxedAccountSizedInit4": 19102, "boxedAccountSized4": 1996, - "boxedAccountSizedInit8": 37521, + "boxedAccountSizedInit8": 37397, "boxedAccountSized8": 3628, "boxedAccountUnsizedInit1": 5612, "boxedAccountUnsized1": 836, - "boxedAccountUnsizedInit2": 10181, + "boxedAccountUnsizedInit2": 10185, "boxedAccountUnsized2": 1270, - "boxedAccountUnsizedInit4": 19434, + "boxedAccountUnsizedInit4": 19359, "boxedAccountUnsized4": 2132, - "boxedAccountUnsizedInit8": 37781, + "boxedAccountUnsizedInit8": 37805, "boxedAccountUnsized8": 3881, "boxedInterfaceAccountMint1": 1351, "boxedInterfaceAccountMint2": 2123, From a42335ac9387cb2ffd6fdfc798eef5d7db9c63b0 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 29 Aug 2025 16:07:40 +0530 Subject: [PATCH 16/39] fix: update program ID for duplicate mutable accounts --- .../programs/duplicate-mutable-accounts/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs index b915f2b89e..4c21601f49 100644 --- a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs +++ b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs @@ -1,7 +1,7 @@ use anchor_lang::prelude::*; // Intentionally different program id than the one defined in Anchor.toml. -declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); +declare_id!("4D6rvpR7TSPwmFottLGa5gpzMcJ76kN8bimQHV9rogjH"); #[program] pub mod duplicate_mutable_accounts { From 5237b78cc3345b4166a0c643a9b103a774acc76f Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 29 Aug 2025 16:10:01 +0530 Subject: [PATCH 17/39] fix: update program ID --- tests/duplicate-mutable-accounts/Anchor.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/duplicate-mutable-accounts/Anchor.toml b/tests/duplicate-mutable-accounts/Anchor.toml index 7bae6d45b8..6cf3d81575 100644 --- a/tests/duplicate-mutable-accounts/Anchor.toml +++ b/tests/duplicate-mutable-accounts/Anchor.toml @@ -3,7 +3,7 @@ cluster = "localnet" wallet = "~/.config/solana/id.json" [programs.localnet] -declare_id = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" +duplicate_mutable_accounts = "4D6rvpR7TSPwmFottLGa5gpzMcJ76kN8bimQHV9rogjH" [scripts] test = "yarn run ts-mocha -t 1000000 tests/*.ts" From 4a1503ee353892a348fd7ca291813f8af489ca8a Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 29 Aug 2025 17:02:41 +0530 Subject: [PATCH 18/39] fix(bench): update --- bench/COMPUTE_UNITS.md | 2 +- tests/bench/bench.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 86805f3fb1..c5c38d6a12 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -22,7 +22,7 @@ Solana version: 2.1.0 | accountInfo2 | 895 | - | | accountInfo4 | 1,553 | - | | accountInfo8 | 2,923 | - | -| accountEmptyInit1 | 5,323 | 🔴 **+240 (4.72%)** | +| accountEmptyInit1 | 5,260 | 🔴 **+177 (3.48%)** | | accountEmpty1 | 645 | - | | accountEmptyInit2 | 9,724 | 🔴 **+423 (4.55%)** | | accountEmpty2 | 1,007 | - | diff --git a/tests/bench/bench.json b/tests/bench/bench.json index e8cfebbb9b..ad6cc1642d 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1312,7 +1312,7 @@ "accountInfo2": 895, "accountInfo4": 1553, "accountInfo8": 2923, - "accountEmptyInit1": 5323, + "accountEmptyInit1": 5260, "accountEmpty1": 645, "accountEmptyInit2": 9724, "accountEmpty2": 1007, From 6389a61d6ea5d8d98da131d0bc1543ce023323d6 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 29 Aug 2025 19:37:02 +0530 Subject: [PATCH 19/39] chore(docs): Updated docs and CHANGELOG.md --- CHANGELOG.md | 1 + .../docs/references/account-constraints.mdx | 27 +++++++++++++++++++ lang/derive/accounts/src/lib.rs | 16 +++++++++++ 3 files changed, 44 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1dbb0a9d6..076b70993e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Replace `solana-program` crate with smaller crates ([#3819](https://github.com/solana-foundation/anchor/pull/3819)). - cli: Replace `anchor verify` to use `solana-verify` under the hood, adding automatic installation via AVM, local path support, and future-proof argument passing ([#3768](https://github.com/solana-foundation/anchor/pull/3768)). - cli: Make `anchor deploy` to upload the IDL to the cluster by default unless `--no-idl` is passed ([#3863](https://github.com/solana-foundation/anchor/pull/3863)). +- lang: Disallow duplicate mutable accounts by default. But allows duplicate mutable accounts in instruction contexts using `dup` constraint ([#3899](https://github.com/solana-foundation/anchor/pull/3899)). ### Fixes diff --git a/docs/content/docs/references/account-constraints.mdx b/docs/content/docs/references/account-constraints.mdx index 5f12ca4b9b..ee8890240f 100644 --- a/docs/content/docs/references/account-constraints.mdx +++ b/docs/content/docs/references/account-constraints.mdx @@ -38,6 +38,33 @@ Examples: [Github](https://github.com/solana-developers/anchor-examples/tree/mai #[account(mut @ )] ``` +### `#[account(dup)]` + +Description: By default, Anchor will prevents duplicate mutable accounts to avoid potential security issues and unintended behavior. +The `dup` constraint explicitly allows this for cases where it's intentional and safe. + +**Note**: This constraint only applies to mutable accounts (`mut`). Readonly accounts naturally allow duplicates without requiring the `dup` constraint. + +```rust title="attribute" +#[account(mut, dup)] +#[account(mut, dup @ )] +``` + +```rust title="snippet" +#[derive(Accounts)] +pub struct AllowsDuplicateMutable<'info> { + #[account(mut)] + pub account1: Account<'info, Counter>, + // This account can be the same as account1 + #[account(mut, dup)] + pub account2: Account<'info, Counter>, +} + +pub fn allows_duplicate_mutable(ctx: Context) -> Result<()> { + Ok(()) +} +``` + ### `#[account(init)]` Description: Creates the account via a CPI to the system program and initializes diff --git a/lang/derive/accounts/src/lib.rs b/lang/derive/accounts/src/lib.rs index 7cfb19479b..1c379b913d 100644 --- a/lang/derive/accounts/src/lib.rs +++ b/lang/derive/accounts/src/lib.rs @@ -90,6 +90,22 @@ use syn::parse_macro_input; /// /// /// +/// #[account(dup)]

+/// +/// +/// Allows the same mutable account to be passed multiple times within the same instruction context.
+/// By default, Anchor will prevents duplicate mutable accounts to avoid potential security issues and unintended behavior.
+/// The dup constraint explicitly allows this for cases where it's intentional and safe.
+/// This constraint only applies to mutable accounts (mut). Readonly accounts naturally allow duplicates without requiring the dup constraint.
+/// Example: +///

+/// #[account(mut)]
+/// pub account1: Account<'info, Counter>,
+///                 
+/// +/// +/// +/// /// #[account(init, payer = <target_account>, space = <num_bytes>)] /// /// From bd203674aa837ac0dead49ac1daee8d7f25e1e3e Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Tue, 16 Sep 2025 12:04:11 +0530 Subject: [PATCH 20/39] refactor: ignore init accounts --- lang/syn/src/codegen/accounts/try_accounts.rs | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index e57584987f..dacf182e7f 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -209,16 +209,14 @@ fn is_init(af: &AccountField) -> bool { // Generates duplicate mutable account validation logic fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::TokenStream { - // Find all mutable account fields that don't have dup constraint - // Exclude UncheckedAccount types as they are unchecked by design - let check_required_fields: Vec<_> = accs + // Collect all mutable account fields without `dup` constraint, excluding UncheckedAccount & init accounts. + let candidates: Vec<_> = accs .fields .iter() .filter_map(|af| match af { - AccountField::Field(f) if f.constraints.is_mutable() && !f.constraints.is_dup() => { - // Exclude UncheckedAccount types from duplicate checks + AccountField::Field(f) if f.constraints.is_mutable() && !f.constraints.is_dup() && f.constraints.init.is_none() => { match &f.ty { - crate::Ty::UncheckedAccount => None, + crate::Ty::UncheckedAccount => None, // unchecked by design _ => Some(f), } } @@ -226,13 +224,13 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke }) .collect(); - if check_required_fields.len() <= 1 { - // If there's 0 or 1 fields to check, no duplicates possible + if candidates.len() <= 1 { + // 0 or 1 -> no duplicates possible return quote! {}; } - // Generate validation code using BTreeSet like realloc pattern - let field_keys: Vec<_> = check_required_fields + // Generate validation code using BTreeSet + let field_keys: Vec<_> = candidates .iter() .map(|f| { let name = &f.ident; @@ -244,17 +242,18 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke }) .collect(); - let field_name_strs: Vec<_> = check_required_fields + let field_name_strs: Vec<_> = candidates .iter() .map(|f| f.ident.to_string()) .collect(); quote! { - // Duplicate mutable account validation - using pattern similar to realloc + // Duplicate mutable account validation - using BTreeSet for efficiency { let mut __mutable_accounts = std::collections::BTreeSet::new(); #( if let Some(key) = #field_keys { + // Check for duplicates and insert the key and account name if !__mutable_accounts.insert(key) { return Err(anchor_lang::error::Error::from( anchor_lang::error::ErrorCode::ConstraintDuplicateMutableAccount @@ -264,4 +263,4 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke )* } } -} +} \ No newline at end of file From e5fd85531ae52cad75ae550cd167b4ee8ebec925 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Tue, 16 Sep 2025 12:14:44 +0530 Subject: [PATCH 21/39] fix(bench): update --- bench/BINARY_SIZE.md | 2 +- bench/COMPUTE_UNITS.md | 178 ++++++++++++++++++++--------------------- tests/bench/bench.json | 50 ++++++------ 3 files changed, 115 insertions(+), 115 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index 59c397daee..047f54dead 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,091,904 | 🔴 **+49,976 (4.80%)** | +| bench | 1,058,168 | 🔴 **+16,240 (1.56%)** | ### Notable changes diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index c5c38d6a12..b48c5286df 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -16,95 +16,95 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.1.0 -| Instruction | Compute Units | - | -| --------------------------- | ------------- | --------------------- | -| accountInfo1 | 571 | - | -| accountInfo2 | 895 | - | -| accountInfo4 | 1,553 | - | -| accountInfo8 | 2,923 | - | -| accountEmptyInit1 | 5,260 | 🔴 **+177 (3.48%)** | -| accountEmpty1 | 645 | - | -| accountEmptyInit2 | 9,724 | 🔴 **+423 (4.55%)** | -| accountEmpty2 | 1,007 | - | -| accountEmptyInit4 | 18,558 | 🔴 **+794 (4.47%)** | -| accountEmpty4 | 1,724 | - | -| accountEmptyInit8 | 36,239 | 🔴 **+1,516 (4.37%)** | -| accountEmpty8 | 3,163 | - | -| accountSizedInit1 | 5,432 | 🔴 **+240 (4.62%)** | -| accountSized1 | 693 | - | -| accountSizedInit2 | 9,908 | 🔴 **+419 (4.42%)** | -| accountSized2 | 1,075 | - | -| accountSizedInit4 | 19,036 | 🔴 **+866 (4.77%)** | -| accountSized4 | 1,848 | - | -| accountSizedInit8 | 37,238 | 🔴 **+1,805 (5.09%)** | -| accountSized8 | 3,387 | - | -| accountUnsizedInit1 | 5,546 | 🔴 **+241 (4.54%)** | -| accountUnsized1 | 746 | - | -| accountUnsizedInit2 | 10,180 | 🔴 **+421 (4.31%)** | -| accountUnsized2 | 1,163 | - | -| accountUnsizedInit4 | 19,476 | 🔴 **+873 (4.69%)** | -| accountUnsized4 | 2,002 | - | -| accountUnsizedInit8 | 37,758 | 🔴 **+1,765 (4.90%)** | -| accountUnsized8 | 3,673 | - | -| boxedAccountEmptyInit1 | 5,416 | 🔴 **+241 (4.66%)** | -| boxedAccountEmpty1 | 734 | - | -| boxedAccountEmptyInit2 | 9,840 | 🔴 **+426 (4.53%)** | -| boxedAccountEmpty2 | 1,116 | - | -| boxedAccountEmptyInit4 | 18,794 | 🔴 **+876 (4.89%)** | -| boxedAccountEmpty4 | 1,872 | - | -| boxedAccountEmptyInit8 | 37,037 | 🔴 **+2,084 (5.96%)** | -| boxedAccountEmpty8 | 3,401 | - | -| boxedAccountSizedInit1 | 5,512 | 🔴 **+241 (4.57%)** | -| boxedAccountSized1 | 783 | - | -| boxedAccountSizedInit2 | 10,005 | 🔴 **+422 (4.40%)** | -| boxedAccountSized2 | 1,190 | - | -| boxedAccountSizedInit4 | 19,102 | 🔴 **+872 (4.78%)** | -| boxedAccountSized4 | 1,996 | - | -| boxedAccountSizedInit8 | 37,397 | 🔴 **+1,844 (5.19%)** | -| boxedAccountSized8 | 3,628 | - | -| boxedAccountUnsizedInit1 | 5,612 | 🔴 **+241 (4.49%)** | -| boxedAccountUnsized1 | 836 | - | -| boxedAccountUnsizedInit2 | 10,185 | 🔴 **+426 (4.37%)** | -| boxedAccountUnsized2 | 1,270 | - | -| boxedAccountUnsizedInit4 | 19,359 | 🔴 **+801 (4.32%)** | -| boxedAccountUnsized4 | 2,132 | - | -| boxedAccountUnsizedInit8 | 37,805 | 🔴 **+1,620 (4.48%)** | -| boxedAccountUnsized8 | 3,881 | - | -| boxedInterfaceAccountMint1 | 1,351 | - | -| boxedInterfaceAccountMint2 | 2,123 | - | -| boxedInterfaceAccountMint4 | 3,656 | - | -| boxedInterfaceAccountMint8 | 6,738 | - | -| boxedInterfaceAccountToken1 | 2,011 | - | -| boxedInterfaceAccountToken2 | 3,431 | - | -| boxedInterfaceAccountToken4 | 6,260 | - | -| boxedInterfaceAccountToken8 | 11,934 | - | -| interfaceAccountMint1 | 1,476 | - | -| interfaceAccountMint2 | 2,489 | - | -| interfaceAccountMint4 | 4,511 | - | -| interfaceAccountMint8 | 8,550 | - | -| interfaceAccountToken1 | 2,111 | - | -| interfaceAccountToken2 | 3,729 | - | -| interfaceAccountToken4 | 6,955 | - | -| interface1 | 769 | - | -| interface2 | 912 | - | -| interface4 | 1,189 | - | -| interface8 | 1,748 | - | -| program1 | 779 | - | -| program2 | 920 | - | -| program4 | 1,193 | - | -| program8 | 1,744 | - | -| signer1 | 774 | - | -| signer2 | 1,064 | - | -| signer4 | 1,637 | - | -| signer8 | 2,788 | - | -| systemAccount1 | 796 | - | -| systemAccount2 | 1,096 | - | -| systemAccount4 | 1,689 | - | -| systemAccount8 | 2,880 | - | -| uncheckedAccount1 | 783 | - | -| uncheckedAccount2 | 1,056 | - | -| uncheckedAccount4 | 1,594 | - | -| uncheckedAccount8 | 2,679 | - | +| Instruction | Compute Units | - | +| --------------------------- | ------------- | ------------------ | +| accountInfo1 | 571 | - | +| accountInfo2 | 895 | - | +| accountInfo4 | 1,553 | - | +| accountInfo8 | 2,923 | - | +| accountEmptyInit1 | 5,079 | 🟢 **-4 (0.08%)** | +| accountEmpty1 | 645 | - | +| accountEmptyInit2 | 9,293 | 🟢 **-8 (0.09%)** | +| accountEmpty2 | 1,007 | - | +| accountEmptyInit4 | 17,748 | 🟢 **-16 (0.09%)** | +| accountEmpty4 | 1,724 | - | +| accountEmptyInit8 | 34,691 | 🟢 **-32 (0.09%)** | +| accountEmpty8 | 3,163 | - | +| accountSizedInit1 | 5,188 | 🟢 **-4 (0.08%)** | +| accountSized1 | 693 | - | +| accountSizedInit2 | 9,481 | 🟢 **-8 (0.08%)** | +| accountSized2 | 1,075 | - | +| accountSizedInit4 | 18,154 | 🟢 **-16 (0.09%)** | +| accountSized4 | 1,848 | - | +| accountSizedInit8 | 35,401 | 🟢 **-32 (0.09%)** | +| accountSized8 | 3,387 | - | +| accountUnsizedInit1 | 5,301 | 🟢 **-4 (0.08%)** | +| accountUnsized1 | 746 | - | +| accountUnsizedInit2 | 9,751 | 🟢 **-8 (0.08%)** | +| accountUnsized2 | 1,163 | - | +| accountUnsizedInit4 | 18,587 | 🟢 **-16 (0.09%)** | +| accountUnsized4 | 2,002 | - | +| accountUnsizedInit8 | 35,961 | 🟢 **-32 (0.09%)** | +| accountUnsized8 | 3,673 | - | +| boxedAccountEmptyInit1 | 5,171 | 🟢 **-4 (0.08%)** | +| boxedAccountEmpty1 | 734 | - | +| boxedAccountEmptyInit2 | 9,406 | 🟢 **-8 (0.08%)** | +| boxedAccountEmpty2 | 1,116 | - | +| boxedAccountEmptyInit4 | 17,902 | 🟢 **-16 (0.09%)** | +| boxedAccountEmpty4 | 1,872 | - | +| boxedAccountEmptyInit8 | 34,921 | 🟢 **-32 (0.09%)** | +| boxedAccountEmpty8 | 3,401 | - | +| boxedAccountSizedInit1 | 5,267 | 🟢 **-4 (0.08%)** | +| boxedAccountSized1 | 783 | - | +| boxedAccountSizedInit2 | 9,575 | 🟢 **-8 (0.08%)** | +| boxedAccountSized2 | 1,190 | - | +| boxedAccountSizedInit4 | 18,214 | 🟢 **-16 (0.09%)** | +| boxedAccountSized4 | 1,996 | - | +| boxedAccountSizedInit8 | 35,521 | 🟢 **-32 (0.09%)** | +| boxedAccountSized8 | 3,628 | - | +| boxedAccountUnsizedInit1 | 5,367 | 🟢 **-4 (0.07%)** | +| boxedAccountUnsized1 | 836 | - | +| boxedAccountUnsizedInit2 | 9,751 | 🟢 **-8 (0.08%)** | +| boxedAccountUnsized2 | 1,270 | - | +| boxedAccountUnsizedInit4 | 18,542 | 🟢 **-16 (0.09%)** | +| boxedAccountUnsized4 | 2,132 | - | +| boxedAccountUnsizedInit8 | 36,153 | 🟢 **-32 (0.09%)** | +| boxedAccountUnsized8 | 3,881 | - | +| boxedInterfaceAccountMint1 | 1,351 | - | +| boxedInterfaceAccountMint2 | 2,123 | - | +| boxedInterfaceAccountMint4 | 3,656 | - | +| boxedInterfaceAccountMint8 | 6,738 | - | +| boxedInterfaceAccountToken1 | 2,011 | - | +| boxedInterfaceAccountToken2 | 3,431 | - | +| boxedInterfaceAccountToken4 | 6,260 | - | +| boxedInterfaceAccountToken8 | 11,934 | - | +| interfaceAccountMint1 | 1,476 | - | +| interfaceAccountMint2 | 2,489 | - | +| interfaceAccountMint4 | 4,511 | - | +| interfaceAccountMint8 | 8,550 | - | +| interfaceAccountToken1 | 2,111 | - | +| interfaceAccountToken2 | 3,729 | - | +| interfaceAccountToken4 | 6,955 | - | +| interface1 | 769 | - | +| interface2 | 912 | - | +| interface4 | 1,189 | - | +| interface8 | 1,748 | - | +| program1 | 779 | - | +| program2 | 920 | - | +| program4 | 1,193 | - | +| program8 | 1,744 | - | +| signer1 | 774 | - | +| signer2 | 1,064 | - | +| signer4 | 1,637 | - | +| signer8 | 2,788 | - | +| systemAccount1 | 796 | - | +| systemAccount2 | 1,096 | - | +| systemAccount4 | 1,689 | - | +| systemAccount8 | 2,880 | - | +| uncheckedAccount1 | 783 | - | +| uncheckedAccount2 | 1,056 | - | +| uncheckedAccount4 | 1,594 | - | +| uncheckedAccount8 | 2,679 | - | ### Notable changes diff --git a/tests/bench/bench.json b/tests/bench/bench.json index ad6cc1642d..660c233bde 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1305,60 +1305,60 @@ "solanaVersion": "2.1.0", "result": { "binarySize": { - "bench": 1091904 + "bench": 1058168 }, "computeUnits": { "accountInfo1": 571, "accountInfo2": 895, "accountInfo4": 1553, "accountInfo8": 2923, - "accountEmptyInit1": 5260, + "accountEmptyInit1": 5079, "accountEmpty1": 645, - "accountEmptyInit2": 9724, + "accountEmptyInit2": 9293, "accountEmpty2": 1007, - "accountEmptyInit4": 18558, + "accountEmptyInit4": 17748, "accountEmpty4": 1724, - "accountEmptyInit8": 36239, + "accountEmptyInit8": 34691, "accountEmpty8": 3163, - "accountSizedInit1": 5432, + "accountSizedInit1": 5188, "accountSized1": 693, - "accountSizedInit2": 9908, + "accountSizedInit2": 9481, "accountSized2": 1075, - "accountSizedInit4": 19036, + "accountSizedInit4": 18154, "accountSized4": 1848, - "accountSizedInit8": 37238, + "accountSizedInit8": 35401, "accountSized8": 3387, - "accountUnsizedInit1": 5546, + "accountUnsizedInit1": 5301, "accountUnsized1": 746, - "accountUnsizedInit2": 10180, + "accountUnsizedInit2": 9751, "accountUnsized2": 1163, - "accountUnsizedInit4": 19476, + "accountUnsizedInit4": 18587, "accountUnsized4": 2002, - "accountUnsizedInit8": 37758, + "accountUnsizedInit8": 35961, "accountUnsized8": 3673, - "boxedAccountEmptyInit1": 5416, + "boxedAccountEmptyInit1": 5171, "boxedAccountEmpty1": 734, - "boxedAccountEmptyInit2": 9840, + "boxedAccountEmptyInit2": 9406, "boxedAccountEmpty2": 1116, - "boxedAccountEmptyInit4": 18794, + "boxedAccountEmptyInit4": 17902, "boxedAccountEmpty4": 1872, - "boxedAccountEmptyInit8": 37037, + "boxedAccountEmptyInit8": 34921, "boxedAccountEmpty8": 3401, - "boxedAccountSizedInit1": 5512, + "boxedAccountSizedInit1": 5267, "boxedAccountSized1": 783, - "boxedAccountSizedInit2": 10005, + "boxedAccountSizedInit2": 9575, "boxedAccountSized2": 1190, - "boxedAccountSizedInit4": 19102, + "boxedAccountSizedInit4": 18214, "boxedAccountSized4": 1996, - "boxedAccountSizedInit8": 37397, + "boxedAccountSizedInit8": 35521, "boxedAccountSized8": 3628, - "boxedAccountUnsizedInit1": 5612, + "boxedAccountUnsizedInit1": 5367, "boxedAccountUnsized1": 836, - "boxedAccountUnsizedInit2": 10185, + "boxedAccountUnsizedInit2": 9751, "boxedAccountUnsized2": 1270, - "boxedAccountUnsizedInit4": 19359, + "boxedAccountUnsizedInit4": 18542, "boxedAccountUnsized4": 2132, - "boxedAccountUnsizedInit8": 37805, + "boxedAccountUnsizedInit8": 36153, "boxedAccountUnsized8": 3881, "boxedInterfaceAccountMint1": 1351, "boxedInterfaceAccountMint2": 2123, From bb5a597d0ee87043a8c674898f452b50bef50faf Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Tue, 16 Sep 2025 12:25:23 +0530 Subject: [PATCH 22/39] chore: formating --- lang/syn/src/codegen/accounts/try_accounts.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index dacf182e7f..769f5e53ef 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -214,7 +214,11 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke .fields .iter() .filter_map(|af| match af { - AccountField::Field(f) if f.constraints.is_mutable() && !f.constraints.is_dup() && f.constraints.init.is_none() => { + AccountField::Field(f) + if f.constraints.is_mutable() + && !f.constraints.is_dup() + && f.constraints.init.is_none() => + { match &f.ty { crate::Ty::UncheckedAccount => None, // unchecked by design _ => Some(f), @@ -242,10 +246,7 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke }) .collect(); - let field_name_strs: Vec<_> = candidates - .iter() - .map(|f| f.ident.to_string()) - .collect(); + let field_name_strs: Vec<_> = candidates.iter().map(|f| f.ident.to_string()).collect(); quote! { // Duplicate mutable account validation - using BTreeSet for efficiency @@ -263,4 +264,4 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke )* } } -} \ No newline at end of file +} From 6c3535bbdd0dda3ef43b4e6ce1f1b124c3d353ce Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Tue, 16 Sep 2025 12:57:33 +0530 Subject: [PATCH 23/39] refactor: optimize duplicate mutable checks generation --- lang/syn/src/codegen/accounts/try_accounts.rs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index 769f5e53ef..c584a61750 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -234,19 +234,21 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke } // Generate validation code using BTreeSet - let field_keys: Vec<_> = candidates - .iter() - .map(|f| { - let name = &f.ident; - if f.is_optional { - quote! { #name.as_ref().map(|f| f.key()) } - } else { - quote! { Some(#name.key()) } - } - }) - .collect(); + let mut field_keys = Vec::with_capacity(candidates.len()); + let mut field_name_strs = Vec::with_capacity(candidates.len()); - let field_name_strs: Vec<_> = candidates.iter().map(|f| f.ident.to_string()).collect(); + for f in candidates.iter() { + let name = &f.ident; + + if f.is_optional { + field_keys.push(quote! { #name.as_ref().map(|f| f.key()) }); + } else { + field_keys.push(quote! { Some(#name.key()) }); + } + + // Use stringify! to avoid runtime allocation + field_name_strs.push(quote! { stringify!(#name) }); + } quote! { // Duplicate mutable account validation - using BTreeSet for efficiency From 3110653f6d5a39bce963b118a3d9f5ca978ad031 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Tue, 16 Sep 2025 18:47:33 +0530 Subject: [PATCH 24/39] refactor: replace BTreeSet with HashSet --- lang/syn/src/codegen/accounts/try_accounts.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index c584a61750..b99cfd0543 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -251,9 +251,9 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke } quote! { - // Duplicate mutable account validation - using BTreeSet for efficiency + // Duplicate mutable account validation - using HashSet { - let mut __mutable_accounts = std::collections::BTreeSet::new(); + let mut __mutable_accounts = std::collections::HashSet::new(); #( if let Some(key) = #field_keys { // Check for duplicates and insert the key and account name From 8e61e4a6260434e9b6caab093bf1ca0adb6d9317 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 23 Oct 2025 09:18:38 +0530 Subject: [PATCH 25/39] (chore): Update benchmarks --- bench/BINARY_SIZE.md | 6 +++--- tests/bench/bench.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index f975b13418..c930252349 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -16,9 +16,9 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Program | Binary Size | - | -| ------- | ----------- | ----------------------- | -| bench | 1,024,096 | 🟢 **-102,744 (9.12%)** | +| Program | Binary Size | - | +| ------- | ----------- | ---------------------- | +| bench | 1,037,080 | 🟢 **-89,760 (7.97%)** | ### Notable changes diff --git a/tests/bench/bench.json b/tests/bench/bench.json index cbebb7849f..c9c64ce964 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1677,7 +1677,7 @@ "solanaVersion": "2.3.0", "result": { "binarySize": { - "bench": 1024096 + "bench": 1037080 }, "computeUnits": { "accountInfo1": 685, From 9bebf805739af318747e62368b0ea560345a6a9c Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 23 Oct 2025 11:15:42 +0530 Subject: [PATCH 26/39] test(events): use confirmOptions for transaction handling --- tests/events/tests/events.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/events/tests/events.ts b/tests/events/tests/events.ts index 7cd2333a78..b7f82da79d 100644 --- a/tests/events/tests/events.ts +++ b/tests/events/tests/events.ts @@ -8,6 +8,13 @@ describe("Events", () => { anchor.setProvider(anchor.AnchorProvider.env()); const program = anchor.workspace.Events as anchor.Program; + const confirmOptions = { + commitment: "confirmed" as const, + preflightCommitment: "confirmed" as const, + skipPreflight: true, + maxRetries: 3, + }; + type Event = anchor.IdlEvents; const getEvent = async ( eventName: E, @@ -48,11 +55,17 @@ describe("Events", () => { describe("CPI event", () => { it("Works without accounts being specified", async () => { const tx = await program.methods.testEventCpi().transaction(); - const config = { commitment: "confirmed" } as const; - const txHash = await program.provider.sendAndConfirm(tx, [], config); + const txHash = await program.provider.sendAndConfirm( + tx, + [], + confirmOptions + ); const txResult = await program.provider.connection.getTransaction( txHash, - config + { + ...confirmOptions, + maxSupportedTransactionVersion: 0, + } ); const ixData = anchor.utils.bytes.bs58.decode( From 5f5267684ee1dbe6af9d6797b24ad51da36c3da0 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Sat, 25 Oct 2025 10:55:59 +0530 Subject: [PATCH 27/39] chore: Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 458249c351..f72c38483f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ The minor version will be incremented upon a breaking change and the patch versi ### Breaking +- lang: Disallow duplicate mutable accounts by default. But allows duplicate mutable accounts in instruction contexts using `dup` constraint ([#3946](https://github.com/solana-foundation/anchor/pull/3946)). + ## [0.32.1] - 2025-10-09 ### Features @@ -37,7 +39,6 @@ The minor version will be incremented upon a breaking change and the patch versi - cli: Replace `anchor verify` to use `solana-verify` under the hood, adding automatic installation via AVM, local path support, and future-proof argument passing ([#3768](https://github.com/solana-foundation/anchor/pull/3768)). - lang: Replace `solana-program` crate with smaller crates ([#3819](https://github.com/solana-foundation/anchor/pull/3819)). - cli: Make `anchor deploy` to upload the IDL to the cluster by default unless `--no-idl` is passed ([#3863](https://github.com/solana-foundation/anchor/pull/3863)). -- lang: Disallow duplicate mutable accounts by default. But allows duplicate mutable accounts in instruction contexts using `dup` constraint ([#3946](https://github.com/solana-foundation/anchor/pull/3946)). - lang: Add generic program validation support to `Program` type allowing `Program<'info>` for executable-only validation ([#3878](https://github.com/solana-foundation/anchor/pull/3878)). - lang: Use `solana-invoke` instead of `solana_cpi::invoke` ([#3900](https://github.com/solana-foundation/anchor/pull/3900)). - client: remove `solana-client` from `anchor-client` and `cli` ([#3877](https://github.com/solana-foundation/anchor/pull/3877)). From 8fa5a374da8eea173406c3bc5773543893612d62 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 30 Oct 2025 15:54:41 +0530 Subject: [PATCH 28/39] feat(lang): Added checks for duplicate mutable accounts in `remaining_accounts` to prevent validation bypass. --- lang/syn/src/codegen/accounts/try_accounts.rs | 37 ++++++++- .../duplicate-mutable-accounts/src/lib.rs | 26 ++++++- .../tests/duplicate-mutable-accounts.ts | 77 ++++++++++++++++++- 3 files changed, 133 insertions(+), 7 deletions(-) diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index bc0963c9d3..e83e3cf779 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -238,12 +238,27 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke }) .collect(); - if candidates.len() <= 1 { - // 0 or 1 -> no duplicates possible - return quote! {}; + if candidates.is_empty() { + // No declared mutable accounts, but still need to check remaining_accounts + return quote! { + // Duplicate mutable account validation for remaining_accounts only + { + let mut __mutable_accounts = std::collections::HashSet::new(); + + for __remaining_account in __accounts.iter() { + if __remaining_account.is_writable { + if !__mutable_accounts.insert(*__remaining_account.key) { + return Err(anchor_lang::error::Error::from( + anchor_lang::error::ErrorCode::ConstraintDuplicateMutableAccount + ) + .with_account_name(format!("{} (remaining_accounts)", __remaining_account.key))); + } + } + } + } + }; } - // Generate validation code using BTreeSet let mut field_keys = Vec::with_capacity(candidates.len()); let mut field_name_strs = Vec::with_capacity(candidates.len()); @@ -264,6 +279,8 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke // Duplicate mutable account validation - using HashSet { let mut __mutable_accounts = std::collections::HashSet::new(); + + // First, check declared mutable accounts for duplicates among themselves #( if let Some(key) = #field_keys { // Check for duplicates and insert the key and account name @@ -274,6 +291,18 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke } } )* + + // This prevents duplicates from being passed via remaining_accounts + for __remaining_account in __accounts.iter() { + if __remaining_account.is_writable { + if !__mutable_accounts.insert(*__remaining_account.key) { + return Err(anchor_lang::error::Error::from( + anchor_lang::error::ErrorCode::ConstraintDuplicateMutableAccount + ) + .with_account_name(format!("{} (remaining_accounts)", __remaining_account.key))); + } + } + } } } } diff --git a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs index 4c21601f49..2615378d1a 100644 --- a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs +++ b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs @@ -32,6 +32,22 @@ pub mod duplicate_mutable_accounts { pub fn allows_duplicate_readonly(_ctx: Context) -> Result<()> { Ok(()) } + + // Test that remaining_accounts are accessible and can be used + pub fn use_remaining_accounts(ctx: Context) -> Result<()> { + ctx.accounts.account1.count += 1; + + msg!( + "Processing {} remaining accounts", + ctx.remaining_accounts.len() + ); + for (i, account_info) in ctx.remaining_accounts.iter().enumerate() { + if account_info.is_writable { + msg!("Remaining account {} is writable", account_info.key); + } + } + Ok(()) + } } #[account] @@ -48,7 +64,6 @@ pub struct Initialize<'info> { pub system_program: Program<'info, System>, } -// No extra accounts here, because tests only pass account1 and account2. #[derive(Accounts)] pub struct FailsDuplicateMutable<'info> { #[account(mut)] @@ -57,7 +72,7 @@ pub struct FailsDuplicateMutable<'info> { pub account2: Account<'info, Counter>, } -// Allow the same mutable account to be supplied twice. +// Allow the same mutable account to be supplied twice via the `dup` constraint. #[derive(Accounts)] pub struct AllowsDuplicateMutable<'info> { #[account(mut)] @@ -72,3 +87,10 @@ pub struct AllowsDuplicateReadonly<'info> { pub account1: Account<'info, Counter>, pub account2: Account<'info, Counter>, } + +// Test using remaining_accounts +#[derive(Accounts)] +pub struct UseRemainingAccounts<'info> { + #[account(mut)] + pub account1: Account<'info, Counter>, +} diff --git a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts index 057b67f689..10bc256639 100644 --- a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts +++ b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts @@ -78,7 +78,7 @@ describe("duplicate-mutable-accounts", () => { } }); - it("Should succeed with duplicate mutable accounts", async () => { + it("Should succeed with duplicate mutable accounts when using dup constraint", async () => { // This instruction MUST have `#[account(mut, dup)]` on at least one account await program.methods .allowsDuplicateMutable() @@ -89,4 +89,79 @@ describe("duplicate-mutable-accounts", () => { .rpc(); assert.ok(true); }); + + it("Should allow duplicate readonly accounts", async () => { + // Readonly accounts can be duplicated without any constraint + await program.methods + .allowsDuplicateReadonly() + .accounts({ + account1: dataAccount1.publicKey, + account2: dataAccount1.publicKey, // same account, both readonly + }) + .rpc(); + assert.ok(true, "Readonly duplicates are allowed"); + }); + + it("Should block duplicate in remainingAccounts", async () => { + try { + await program.methods + .failsDuplicateMutable() + .accounts({ + account1: dataAccount1.publicKey, + account2: dataAccount2.publicKey, // Different account + }) + .remainingAccounts([ + { + pubkey: dataAccount1.publicKey, // duplicate via remainingAccounts + isWritable: true, + isSigner: false, + }, + ]) + .rpc(); + + assert.fail("Should have been blocked - remainingAccounts bypass failed"); + } catch (e) { + // Should be blocked with framework-level security fix + assert.ok( + e.message.includes("ConstraintDuplicateMutableAccount") || + e.message.includes("duplicate") || + e.message.includes("2040"), + "Successfully blocked with framework-level validation" + ); + console.log("✓ Duplicate blocked by Anchor framework:", e.message); + } + }); + + it("Should allow using remaining_accounts without duplicates", async () => { + // Get initial counts + const beforeAccount1 = await program.account.counter.fetch( + dataAccount1.publicKey + ); + + // Call with valid remaining accounts (no duplicates) + await program.methods + .useRemainingAccounts() + .accounts({ + account1: dataAccount1.publicKey, + }) + .remainingAccounts([ + { + pubkey: dataAccount2.publicKey, + isWritable: true, + isSigner: false, + }, + ]) + .rpc(); + + // Verify account was incremented + const afterAccount1 = await program.account.counter.fetch( + dataAccount1.publicKey + ); + + assert.equal( + afterAccount1.count.toNumber(), + beforeAccount1.count.toNumber() + 1, + "Account1 should be incremented" + ); + }); }); From 779727005ab08077ac4003b4f77f4142877872c9 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 30 Oct 2025 16:09:45 +0530 Subject: [PATCH 29/39] feat(tests): Add nested duplicate account test to prevent mutable account conflicts --- .../duplicate-mutable-accounts/src/lib.rs | 23 ++++++++++++++- .../tests/duplicate-mutable-accounts.ts | 29 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs index 2615378d1a..246adb7df5 100644 --- a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs +++ b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs @@ -33,6 +33,14 @@ pub mod duplicate_mutable_accounts { Ok(()) } + // Test nested account structures + pub fn nested_duplicate(ctx: Context) -> Result<()> { + // Both wrappers contain mutable counters + ctx.accounts.wrapper1.counter.count += 1; + ctx.accounts.wrapper2.counter.count += 1; + Ok(()) + } + // Test that remaining_accounts are accessible and can be used pub fn use_remaining_accounts(ctx: Context) -> Result<()> { ctx.accounts.account1.count += 1; @@ -41,7 +49,7 @@ pub mod duplicate_mutable_accounts { "Processing {} remaining accounts", ctx.remaining_accounts.len() ); - for (i, account_info) in ctx.remaining_accounts.iter().enumerate() { + for account_info in ctx.remaining_accounts.iter() { if account_info.is_writable { msg!("Remaining account {} is writable", account_info.key); } @@ -88,6 +96,19 @@ pub struct AllowsDuplicateReadonly<'info> { pub account2: Account<'info, Counter>, } +// Nested account structures +#[derive(Accounts)] +pub struct CounterWrapper<'info> { + #[account(mut)] + pub counter: Account<'info, Counter>, +} + +#[derive(Accounts)] +pub struct NestedDuplicate<'info> { + pub wrapper1: CounterWrapper<'info>, + pub wrapper2: CounterWrapper<'info>, +} + // Test using remaining_accounts #[derive(Accounts)] pub struct UseRemainingAccounts<'info> { diff --git a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts index 10bc256639..3182569717 100644 --- a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts +++ b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts @@ -102,6 +102,34 @@ describe("duplicate-mutable-accounts", () => { assert.ok(true, "Readonly duplicates are allowed"); }); + it("Should block nested duplicate accounts", async () => { + try { + await program.methods + .nestedDuplicate() + .accounts({ + wrapper1: { + counter: dataAccount1.publicKey, + }, + wrapper2: { + counter: dataAccount1.publicKey, // Same counter in both wrappers! + }, + }) + .rpc(); + + assert.fail( + "Nested structures with duplicate accounts should be blocked" + ); + } catch (e) { + // Should be blocked with the fix + assert.ok( + e.message.includes("ConstraintDuplicateMutableAccount") || + e.message.includes("duplicate") || + e.message.includes("2040"), + "Nested duplicate correctly blocked" + ); + } + }); + it("Should block duplicate in remainingAccounts", async () => { try { await program.methods @@ -128,7 +156,6 @@ describe("duplicate-mutable-accounts", () => { e.message.includes("2040"), "Successfully blocked with framework-level validation" ); - console.log("✓ Duplicate blocked by Anchor framework:", e.message); } }); From bbff6e93a80057e5ef560d63b22b8d77cdae7bf3 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Thu, 30 Oct 2025 17:56:26 +0530 Subject: [PATCH 30/39] chore(bench): Update benchmarks --- bench/BINARY_SIZE.md | 6 +- bench/COMPUTE_UNITS.md | 184 ++++++++++++++++++++--------------------- tests/bench/bench.json | 124 +++++++++++++-------------- 3 files changed, 157 insertions(+), 157 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index c930252349..5680534afc 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -16,9 +16,9 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Program | Binary Size | - | -| ------- | ----------- | ---------------------- | -| bench | 1,037,080 | 🟢 **-89,760 (7.97%)** | +| Program | Binary Size | - | +| ------- | ----------- | --------------------- | +| bench | 1,117,184 | 🟢 **-9,656 (0.86%)** | ### Notable changes diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index e796228b98..8ea5f679a8 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -16,95 +16,95 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Instruction | Compute Units | - | -| --------------------------- | ------------- | ------------------- | -| accountInfo1 | 685 | - | -| accountInfo2 | 1,053 | - | -| accountInfo4 | 1,750 | - | -| accountInfo8 | 3,135 | - | -| accountEmptyInit1 | 4,915 | - | -| accountEmpty1 | 774 | - | -| accountEmptyInit2 | 8,793 | - | -| accountEmpty2 | 1,174 | - | -| accountEmptyInit4 | 16,495 | 🟢 **-253 (1.51%)** | -| accountEmpty4 | 1,962 | - | -| accountEmptyInit8 | 31,997 | 🟢 **-360 (1.11%)** | -| accountEmpty8 | 3,548 | - | -| accountSizedInit1 | 5,019 | - | -| accountSized1 | 822 | - | -| accountSizedInit2 | 8,981 | - | -| accountSized2 | 1,240 | - | -| accountSizedInit4 | 16,850 | 🟢 **-304 (1.77%)** | -| accountSized4 | 2,082 | - | -| accountSizedInit8 | 32,653 | 🟢 **-360 (1.09%)** | -| accountSized8 | 3,762 | - | -| accountUnsizedInit1 | 5,127 | - | -| accountUnsized1 | 874 | - | -| accountUnsizedInit2 | 9,131 | 🟢 **-120 (1.30%)** | -| accountUnsized2 | 1,326 | - | -| accountUnsizedInit4 | 17,198 | 🟢 **-180 (1.04%)** | -| accountUnsized4 | 2,231 | - | -| accountUnsizedInit8 | 33,324 | 🟢 **-637 (1.88%)** | -| accountUnsized8 | 4,035 | - | -| boxedAccountEmptyInit1 | 5,007 | - | -| boxedAccountEmpty1 | 864 | - | -| boxedAccountEmptyInit2 | 8,906 | - | -| boxedAccountEmpty2 | 1,286 | - | -| boxedAccountEmptyInit4 | 16,648 | 🟢 **-254 (1.50%)** | -| boxedAccountEmpty4 | 2,115 | - | -| boxedAccountEmptyInit8 | 32,231 | 🟢 **-360 (1.10%)** | -| boxedAccountEmpty8 | 3,801 | - | -| boxedAccountSizedInit1 | 5,103 | - | -| boxedAccountSized1 | 912 | - | -| boxedAccountSizedInit2 | 9,075 | - | -| boxedAccountSized2 | 1,355 | - | -| boxedAccountSizedInit4 | 16,960 | 🟢 **-254 (1.48%)** | -| boxedAccountSized4 | 2,231 | - | -| boxedAccountSizedInit8 | 32,831 | 🟢 **-690 (2.06%)** | -| boxedAccountSized8 | 4,007 | - | -| boxedAccountUnsizedInit1 | 5,202 | - | -| boxedAccountUnsized1 | 964 | - | -| boxedAccountUnsizedInit2 | 9,251 | - | -| boxedAccountUnsized2 | 1,434 | - | -| boxedAccountUnsizedInit4 | 17,284 | 🟢 **-258 (1.47%)** | -| boxedAccountUnsized4 | 2,367 | - | -| boxedAccountUnsizedInit8 | 33,455 | 🟢 **-698 (2.04%)** | -| boxedAccountUnsized8 | 4,257 | - | -| boxedInterfaceAccountMint1 | 1,110 | - | -| boxedInterfaceAccountMint2 | 1,534 | - | -| boxedInterfaceAccountMint4 | 2,370 | - | -| boxedInterfaceAccountMint8 | 4,064 | - | -| boxedInterfaceAccountToken1 | 1,246 | - | -| boxedInterfaceAccountToken2 | 1,794 | - | -| boxedInterfaceAccountToken4 | 2,878 | - | -| boxedInterfaceAccountToken8 | 5,068 | - | -| interfaceAccountMint1 | 1,126 | - | -| interfaceAccountMint2 | 1,562 | - | -| interfaceAccountMint4 | 2,432 | - | -| interfaceAccountMint8 | 4,163 | - | -| interfaceAccountToken1 | 1,268 | - | -| interfaceAccountToken2 | 1,849 | - | -| interfaceAccountToken4 | 2,997 | - | -| interface1 | 878 | - | -| interface2 | 1,023 | - | -| interface4 | 1,301 | - | -| interface8 | 1,867 | - | -| program1 | 890 | - | -| program2 | 1,035 | - | -| program4 | 1,313 | - | -| program8 | 1,879 | - | -| signer1 | 874 | - | -| signer2 | 1,173 | - | -| signer4 | 1,759 | - | -| signer8 | 2,941 | - | -| systemAccount1 | 911 | - | -| systemAccount2 | 1,235 | - | -| systemAccount4 | 1,871 | - | -| systemAccount8 | 3,153 | - | -| uncheckedAccount1 | 882 | - | -| uncheckedAccount2 | 1,162 | - | -| uncheckedAccount4 | 1,716 | - | -| uncheckedAccount8 | 2,833 | - | +| Instruction | Compute Units | - | +| --------------------------- | ------------- | -------------------- | +| accountInfo1 | 723 | 🔴 **+38 (5.55%)** | +| accountInfo2 | 1,099 | 🔴 **+46 (4.37%)** | +| accountInfo4 | 1,796 | 🔴 **+46 (2.63%)** | +| accountInfo8 | 3,186 | 🔴 **+51 (1.63%)** | +| accountEmptyInit1 | 5,447 | 🔴 **+532 (10.82%)** | +| accountEmpty1 | 790 | 🔴 **+16 (2.07%)** | +| accountEmptyInit2 | 9,326 | 🔴 **+533 (6.06%)** | +| accountEmpty2 | 1,187 | 🔴 **+13 (1.11%)** | +| accountEmptyInit4 | 17,074 | 🔴 **+326 (1.95%)** | +| accountEmpty4 | 1,962 | - | +| accountEmptyInit8 | 32,601 | 🔴 **+244 (0.75%)** | +| accountEmpty8 | 3,548 | - | +| accountSizedInit1 | 5,551 | 🔴 **+532 (10.60%)** | +| accountSized1 | 836 | 🔴 **+14 (1.70%)** | +| accountSizedInit2 | 9,510 | 🔴 **+529 (5.89%)** | +| accountSized2 | 1,259 | 🔴 **+19 (1.53%)** | +| accountSizedInit4 | 17,428 | 🔴 **+274 (1.60%)** | +| accountSized4 | 2,082 | - | +| accountSizedInit8 | 33,251 | 🔴 **+238 (0.72%)** | +| accountSized8 | 3,762 | - | +| accountUnsizedInit1 | 5,661 | 🔴 **+534 (10.42%)** | +| accountUnsized1 | 894 | 🔴 **+20 (2.29%)** | +| accountUnsizedInit2 | 9,709 | 🔴 **+458 (4.95%)** | +| accountUnsized2 | 1,347 | 🔴 **+21 (1.58%)** | +| accountUnsizedInit4 | 17,797 | 🔴 **+419 (2.41%)** | +| accountUnsized4 | 2,231 | - | +| accountUnsizedInit8 | 33,922 | 🟢 **-39 (0.11%)** | +| accountUnsized8 | 4,035 | - | +| boxedAccountEmptyInit1 | 5,539 | 🔴 **+532 (10.63%)** | +| boxedAccountEmpty1 | 881 | 🔴 **+17 (1.97%)** | +| boxedAccountEmptyInit2 | 9,438 | 🔴 **+532 (5.97%)** | +| boxedAccountEmpty2 | 1,300 | 🔴 **+14 (1.09%)** | +| boxedAccountEmptyInit4 | 17,227 | 🔴 **+325 (1.92%)** | +| boxedAccountEmpty4 | 2,115 | - | +| boxedAccountEmptyInit8 | 32,830 | 🔴 **+239 (0.73%)** | +| boxedAccountEmpty8 | 3,801 | - | +| boxedAccountSizedInit1 | 5,635 | 🔴 **+532 (10.43%)** | +| boxedAccountSized1 | 929 | 🔴 **+17 (1.86%)** | +| boxedAccountSizedInit2 | 9,606 | 🔴 **+531 (5.85%)** | +| boxedAccountSized2 | 1,370 | 🔴 **+15 (1.11%)** | +| boxedAccountSizedInit4 | 17,539 | 🔴 **+325 (1.89%)** | +| boxedAccountSized4 | 2,231 | - | +| boxedAccountSizedInit8 | 33,430 | 🟢 **-91 (0.27%)** | +| boxedAccountSized8 | 4,007 | - | +| boxedAccountUnsizedInit1 | 5,734 | 🔴 **+532 (10.23%)** | +| boxedAccountUnsized1 | 981 | 🔴 **+17 (1.76%)** | +| boxedAccountUnsizedInit2 | 9,780 | 🔴 **+529 (5.72%)** | +| boxedAccountUnsized2 | 1,450 | 🔴 **+16 (1.12%)** | +| boxedAccountUnsizedInit4 | 17,883 | 🔴 **+341 (1.94%)** | +| boxedAccountUnsized4 | 2,367 | - | +| boxedAccountUnsizedInit8 | 34,054 | 🟢 **-99 (0.29%)** | +| boxedAccountUnsized8 | 4,257 | - | +| boxedInterfaceAccountMint1 | 1,127 | 🔴 **+17 (1.53%)** | +| boxedInterfaceAccountMint2 | 1,534 | - | +| boxedInterfaceAccountMint4 | 2,370 | - | +| boxedInterfaceAccountMint8 | 4,064 | - | +| boxedInterfaceAccountToken1 | 1,263 | 🔴 **+17 (1.36%)** | +| boxedInterfaceAccountToken2 | 1,794 | - | +| boxedInterfaceAccountToken4 | 2,878 | - | +| boxedInterfaceAccountToken8 | 5,068 | - | +| interfaceAccountMint1 | 1,163 | 🔴 **+37 (3.29%)** | +| interfaceAccountMint2 | 1,600 | 🔴 **+38 (2.43%)** | +| interfaceAccountMint4 | 2,468 | 🔴 **+36 (1.48%)** | +| interfaceAccountMint8 | 4,163 | - | +| interfaceAccountToken1 | 1,315 | 🔴 **+47 (3.71%)** | +| interfaceAccountToken2 | 1,892 | 🔴 **+43 (2.33%)** | +| interfaceAccountToken4 | 3,040 | 🔴 **+43 (1.43%)** | +| interface1 | 894 | 🔴 **+16 (1.82%)** | +| interface2 | 1,036 | 🔴 **+13 (1.27%)** | +| interface4 | 1,318 | 🔴 **+17 (1.31%)** | +| interface8 | 1,867 | - | +| program1 | 914 | 🔴 **+24 (2.70%)** | +| program2 | 1,064 | 🔴 **+29 (2.80%)** | +| program4 | 1,362 | 🔴 **+49 (3.73%)** | +| program8 | 1,943 | 🔴 **+64 (3.41%)** | +| signer1 | 890 | 🔴 **+16 (1.83%)** | +| signer2 | 1,186 | 🔴 **+13 (1.11%)** | +| signer4 | 1,759 | - | +| signer8 | 2,941 | - | +| systemAccount1 | 927 | 🔴 **+16 (1.76%)** | +| systemAccount2 | 1,248 | 🔴 **+13 (1.05%)** | +| systemAccount4 | 1,871 | - | +| systemAccount8 | 3,153 | - | +| uncheckedAccount1 | 896 | 🔴 **+14 (1.59%)** | +| uncheckedAccount2 | 1,179 | 🔴 **+17 (1.46%)** | +| uncheckedAccount4 | 1,737 | 🔴 **+21 (1.22%)** | +| uncheckedAccount8 | 2,833 | - | ### Notable changes @@ -188,9 +188,9 @@ Solana version: 2.3.0 | interface4 | 1,301 | 🔴 **+112 (9.42%)** | | interface8 | 1,867 | 🔴 **+119 (6.81%)** | | program1 | 890 | 🔴 **+111 (14.25%)** | -| program2 | 1,035 | 🔴 **+115 (12.50%)** | -| program4 | 1,313 | 🔴 **+120 (10.06%)** | -| program8 | 1,879 | 🔴 **+135 (7.74%)** | +| program2 | 1,035 | 🔴 **+101 (10.81%)** | +| program4 | 1,313 | 🔴 **+92 (7.53%)** | +| program8 | 1,879 | 🔴 **+79 (4.39%)** | | signer1 | 874 | 🔴 **+100 (12.92%)** | | signer2 | 1,173 | 🔴 **+109 (10.24%)** | | signer4 | 1,759 | 🔴 **+122 (7.45%)** | diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 08ba5bd675..de47aaf92d 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1677,95 +1677,95 @@ "solanaVersion": "2.3.0", "result": { "binarySize": { - "bench": 1037080 + "bench": 1117184 }, "computeUnits": { - "accountInfo1": 685, - "accountInfo2": 1053, - "accountInfo4": 1750, - "accountInfo8": 3135, - "accountEmptyInit1": 4915, - "accountEmpty1": 774, - "accountEmptyInit2": 8793, - "accountEmpty2": 1174, - "accountEmptyInit4": 16495, + "accountInfo1": 723, + "accountInfo2": 1099, + "accountInfo4": 1796, + "accountInfo8": 3186, + "accountEmptyInit1": 5447, + "accountEmpty1": 790, + "accountEmptyInit2": 9326, + "accountEmpty2": 1187, + "accountEmptyInit4": 17074, "accountEmpty4": 1962, - "accountEmptyInit8": 31997, + "accountEmptyInit8": 32601, "accountEmpty8": 3548, - "accountSizedInit1": 5019, - "accountSized1": 822, - "accountSizedInit2": 8981, - "accountSized2": 1240, - "accountSizedInit4": 16850, + "accountSizedInit1": 5551, + "accountSized1": 836, + "accountSizedInit2": 9510, + "accountSized2": 1259, + "accountSizedInit4": 17428, "accountSized4": 2082, - "accountSizedInit8": 32653, + "accountSizedInit8": 33251, "accountSized8": 3762, - "accountUnsizedInit1": 5127, - "accountUnsized1": 874, - "accountUnsizedInit2": 9131, - "accountUnsized2": 1326, - "accountUnsizedInit4": 17198, + "accountUnsizedInit1": 5661, + "accountUnsized1": 894, + "accountUnsizedInit2": 9709, + "accountUnsized2": 1347, + "accountUnsizedInit4": 17797, "accountUnsized4": 2231, - "accountUnsizedInit8": 33324, + "accountUnsizedInit8": 33922, "accountUnsized8": 4035, - "boxedAccountEmptyInit1": 5007, - "boxedAccountEmpty1": 864, - "boxedAccountEmptyInit2": 8906, - "boxedAccountEmpty2": 1286, - "boxedAccountEmptyInit4": 16648, + "boxedAccountEmptyInit1": 5539, + "boxedAccountEmpty1": 881, + "boxedAccountEmptyInit2": 9438, + "boxedAccountEmpty2": 1300, + "boxedAccountEmptyInit4": 17227, "boxedAccountEmpty4": 2115, - "boxedAccountEmptyInit8": 32231, + "boxedAccountEmptyInit8": 32830, "boxedAccountEmpty8": 3801, - "boxedAccountSizedInit1": 5103, - "boxedAccountSized1": 912, - "boxedAccountSizedInit2": 9075, - "boxedAccountSized2": 1355, - "boxedAccountSizedInit4": 16960, + "boxedAccountSizedInit1": 5635, + "boxedAccountSized1": 929, + "boxedAccountSizedInit2": 9606, + "boxedAccountSized2": 1370, + "boxedAccountSizedInit4": 17539, "boxedAccountSized4": 2231, - "boxedAccountSizedInit8": 32831, + "boxedAccountSizedInit8": 33430, "boxedAccountSized8": 4007, - "boxedAccountUnsizedInit1": 5202, - "boxedAccountUnsized1": 964, - "boxedAccountUnsizedInit2": 9251, - "boxedAccountUnsized2": 1434, - "boxedAccountUnsizedInit4": 17284, + "boxedAccountUnsizedInit1": 5734, + "boxedAccountUnsized1": 981, + "boxedAccountUnsizedInit2": 9780, + "boxedAccountUnsized2": 1450, + "boxedAccountUnsizedInit4": 17883, "boxedAccountUnsized4": 2367, - "boxedAccountUnsizedInit8": 33455, + "boxedAccountUnsizedInit8": 34054, "boxedAccountUnsized8": 4257, - "boxedInterfaceAccountMint1": 1110, + "boxedInterfaceAccountMint1": 1127, "boxedInterfaceAccountMint2": 1534, "boxedInterfaceAccountMint4": 2370, "boxedInterfaceAccountMint8": 4064, - "boxedInterfaceAccountToken1": 1246, + "boxedInterfaceAccountToken1": 1263, "boxedInterfaceAccountToken2": 1794, "boxedInterfaceAccountToken4": 2878, "boxedInterfaceAccountToken8": 5068, - "interfaceAccountMint1": 1126, - "interfaceAccountMint2": 1562, - "interfaceAccountMint4": 2432, + "interfaceAccountMint1": 1163, + "interfaceAccountMint2": 1600, + "interfaceAccountMint4": 2468, "interfaceAccountMint8": 4163, - "interfaceAccountToken1": 1268, - "interfaceAccountToken2": 1849, - "interfaceAccountToken4": 2997, - "interface1": 878, - "interface2": 1023, - "interface4": 1301, + "interfaceAccountToken1": 1315, + "interfaceAccountToken2": 1892, + "interfaceAccountToken4": 3040, + "interface1": 894, + "interface2": 1036, + "interface4": 1318, "interface8": 1867, - "program1": 890, - "program2": 1051, - "program4": 1345, + "program1": 914, + "program2": 1064, + "program4": 1362, "program8": 1943, - "signer1": 874, - "signer2": 1173, + "signer1": 890, + "signer2": 1186, "signer4": 1759, "signer8": 2941, - "systemAccount1": 911, - "systemAccount2": 1235, + "systemAccount1": 927, + "systemAccount2": 1248, "systemAccount4": 1871, "systemAccount8": 3153, - "uncheckedAccount1": 882, - "uncheckedAccount2": 1162, - "uncheckedAccount4": 1716, + "uncheckedAccount1": 896, + "uncheckedAccount2": 1179, + "uncheckedAccount4": 1737, "uncheckedAccount8": 2833 }, "stackMemory": { From 74f1898e01948fae9823fb2e5844a8290c0f2e41 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 31 Oct 2025 15:20:16 +0530 Subject: [PATCH 31/39] fix(lang): Exclude Signer accounts from duplicate mutable checks in account validation --- lang/syn/src/codegen/accounts/try_accounts.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index e83e3cf779..cc3c95b44c 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -219,7 +219,7 @@ fn is_init(af: &AccountField) -> bool { // Generates duplicate mutable account validation logic fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::TokenStream { - // Collect all mutable account fields without `dup` constraint, excluding UncheckedAccount & init accounts. + // Collect all mutable account fields without `dup` constraint, excluding UncheckedAccount, Signer, and init accounts. let candidates: Vec<_> = accs .fields .iter() @@ -231,6 +231,7 @@ fn generate_duplicate_mutable_checks(accs: &AccountsStruct) -> proc_macro2::Toke { match &f.ty { crate::Ty::UncheckedAccount => None, // unchecked by design + crate::Ty::Signer => None, // signers are excluded as they're typically payers _ => Some(f), } } From 2ab93ce521f237d59ecbf74d18fb7c99acd7f0e2 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 31 Oct 2025 15:20:31 +0530 Subject: [PATCH 32/39] feat(tests): Add test to initialize multiple accounts with the same payer --- .../duplicate-mutable-accounts/src/lib.rs | 23 +++++++++++ .../tests/duplicate-mutable-accounts.ts | 40 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs index 246adb7df5..eaa1725221 100644 --- a/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs +++ b/tests/duplicate-mutable-accounts/programs/duplicate-mutable-accounts/src/lib.rs @@ -56,6 +56,17 @@ pub mod duplicate_mutable_accounts { } Ok(()) } + + // Test initializing multiple accounts with the same payer + pub fn init_multiple_with_same_payer( + ctx: Context, + initial1: u64, + initial2: u64, + ) -> Result<()> { + ctx.accounts.data_account1.count = initial1; + ctx.accounts.data_account2.count = initial2; + Ok(()) + } } #[account] @@ -115,3 +126,15 @@ pub struct UseRemainingAccounts<'info> { #[account(mut)] pub account1: Account<'info, Counter>, } + +// Test initializing multiple accounts with the same payer +#[derive(Accounts)] +pub struct InitMultipleWithSamePayer<'info> { + #[account(init, payer = user, space = 8 + 8)] + pub data_account1: Account<'info, Counter>, + #[account(init, payer = user, space = 8 + 8)] + pub data_account2: Account<'info, Counter>, + #[account(mut)] + pub user: Signer<'info>, + pub system_program: Program<'info, System>, +} diff --git a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts index 3182569717..4fdc5f5702 100644 --- a/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts +++ b/tests/duplicate-mutable-accounts/tests/duplicate-mutable-accounts.ts @@ -191,4 +191,44 @@ describe("duplicate-mutable-accounts", () => { "Account1 should be incremented" ); }); + + it("Should allow initializing multiple accounts with the same payer", async () => { + // Create two new keypairs for the accounts to be initialized + const newAccount1 = anchor.web3.Keypair.generate(); + const newAccount2 = anchor.web3.Keypair.generate(); + + // Initialize both accounts using the same payer + // This should succeed because: + // 1. The payer is a Signer, which is excluded from duplicate checks + // 2. The accounts being initialized are different (newAccount1 vs newAccount2) + await program.methods + .initMultipleWithSamePayer(new anchor.BN(500), new anchor.BN(600)) + .accounts({ + dataAccount1: newAccount1.publicKey, + dataAccount2: newAccount2.publicKey, + user: user_wallet.publicKey, + systemProgram: anchor.web3.SystemProgram.programId, + }) + .signers([user_wallet, newAccount1, newAccount2]) + .rpc(); + + // Verify both accounts were created with correct values + const account1Data = await program.account.counter.fetch( + newAccount1.publicKey + ); + const account2Data = await program.account.counter.fetch( + newAccount2.publicKey + ); + + assert.equal( + account1Data.count.toNumber(), + 500, + "First account should have count 500" + ); + assert.equal( + account2Data.count.toNumber(), + 600, + "Second account should have count 600" + ); + }); }); From 10da01a9018d2ec44e5ec4cfed95dc262748fdfb Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 31 Oct 2025 16:02:46 +0530 Subject: [PATCH 33/39] chore(bench): Update --- bench/COMPUTE_UNITS.md | 178 ++++++++++++++++++++--------------------- tests/bench/bench.json | 48 +++++------ 2 files changed, 113 insertions(+), 113 deletions(-) diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 8ea5f679a8..41cdcb7ef1 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -16,95 +16,95 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Instruction | Compute Units | - | -| --------------------------- | ------------- | -------------------- | -| accountInfo1 | 723 | 🔴 **+38 (5.55%)** | -| accountInfo2 | 1,099 | 🔴 **+46 (4.37%)** | -| accountInfo4 | 1,796 | 🔴 **+46 (2.63%)** | -| accountInfo8 | 3,186 | 🔴 **+51 (1.63%)** | -| accountEmptyInit1 | 5,447 | 🔴 **+532 (10.82%)** | -| accountEmpty1 | 790 | 🔴 **+16 (2.07%)** | -| accountEmptyInit2 | 9,326 | 🔴 **+533 (6.06%)** | -| accountEmpty2 | 1,187 | 🔴 **+13 (1.11%)** | -| accountEmptyInit4 | 17,074 | 🔴 **+326 (1.95%)** | -| accountEmpty4 | 1,962 | - | -| accountEmptyInit8 | 32,601 | 🔴 **+244 (0.75%)** | -| accountEmpty8 | 3,548 | - | -| accountSizedInit1 | 5,551 | 🔴 **+532 (10.60%)** | -| accountSized1 | 836 | 🔴 **+14 (1.70%)** | -| accountSizedInit2 | 9,510 | 🔴 **+529 (5.89%)** | -| accountSized2 | 1,259 | 🔴 **+19 (1.53%)** | -| accountSizedInit4 | 17,428 | 🔴 **+274 (1.60%)** | -| accountSized4 | 2,082 | - | -| accountSizedInit8 | 33,251 | 🔴 **+238 (0.72%)** | -| accountSized8 | 3,762 | - | -| accountUnsizedInit1 | 5,661 | 🔴 **+534 (10.42%)** | -| accountUnsized1 | 894 | 🔴 **+20 (2.29%)** | -| accountUnsizedInit2 | 9,709 | 🔴 **+458 (4.95%)** | -| accountUnsized2 | 1,347 | 🔴 **+21 (1.58%)** | -| accountUnsizedInit4 | 17,797 | 🔴 **+419 (2.41%)** | -| accountUnsized4 | 2,231 | - | -| accountUnsizedInit8 | 33,922 | 🟢 **-39 (0.11%)** | -| accountUnsized8 | 4,035 | - | -| boxedAccountEmptyInit1 | 5,539 | 🔴 **+532 (10.63%)** | -| boxedAccountEmpty1 | 881 | 🔴 **+17 (1.97%)** | -| boxedAccountEmptyInit2 | 9,438 | 🔴 **+532 (5.97%)** | -| boxedAccountEmpty2 | 1,300 | 🔴 **+14 (1.09%)** | -| boxedAccountEmptyInit4 | 17,227 | 🔴 **+325 (1.92%)** | -| boxedAccountEmpty4 | 2,115 | - | -| boxedAccountEmptyInit8 | 32,830 | 🔴 **+239 (0.73%)** | -| boxedAccountEmpty8 | 3,801 | - | -| boxedAccountSizedInit1 | 5,635 | 🔴 **+532 (10.43%)** | -| boxedAccountSized1 | 929 | 🔴 **+17 (1.86%)** | -| boxedAccountSizedInit2 | 9,606 | 🔴 **+531 (5.85%)** | -| boxedAccountSized2 | 1,370 | 🔴 **+15 (1.11%)** | -| boxedAccountSizedInit4 | 17,539 | 🔴 **+325 (1.89%)** | -| boxedAccountSized4 | 2,231 | - | -| boxedAccountSizedInit8 | 33,430 | 🟢 **-91 (0.27%)** | -| boxedAccountSized8 | 4,007 | - | -| boxedAccountUnsizedInit1 | 5,734 | 🔴 **+532 (10.23%)** | -| boxedAccountUnsized1 | 981 | 🔴 **+17 (1.76%)** | -| boxedAccountUnsizedInit2 | 9,780 | 🔴 **+529 (5.72%)** | -| boxedAccountUnsized2 | 1,450 | 🔴 **+16 (1.12%)** | -| boxedAccountUnsizedInit4 | 17,883 | 🔴 **+341 (1.94%)** | -| boxedAccountUnsized4 | 2,367 | - | -| boxedAccountUnsizedInit8 | 34,054 | 🟢 **-99 (0.29%)** | -| boxedAccountUnsized8 | 4,257 | - | -| boxedInterfaceAccountMint1 | 1,127 | 🔴 **+17 (1.53%)** | -| boxedInterfaceAccountMint2 | 1,534 | - | -| boxedInterfaceAccountMint4 | 2,370 | - | -| boxedInterfaceAccountMint8 | 4,064 | - | -| boxedInterfaceAccountToken1 | 1,263 | 🔴 **+17 (1.36%)** | -| boxedInterfaceAccountToken2 | 1,794 | - | -| boxedInterfaceAccountToken4 | 2,878 | - | -| boxedInterfaceAccountToken8 | 5,068 | - | -| interfaceAccountMint1 | 1,163 | 🔴 **+37 (3.29%)** | -| interfaceAccountMint2 | 1,600 | 🔴 **+38 (2.43%)** | -| interfaceAccountMint4 | 2,468 | 🔴 **+36 (1.48%)** | -| interfaceAccountMint8 | 4,163 | - | -| interfaceAccountToken1 | 1,315 | 🔴 **+47 (3.71%)** | -| interfaceAccountToken2 | 1,892 | 🔴 **+43 (2.33%)** | -| interfaceAccountToken4 | 3,040 | 🔴 **+43 (1.43%)** | -| interface1 | 894 | 🔴 **+16 (1.82%)** | -| interface2 | 1,036 | 🔴 **+13 (1.27%)** | -| interface4 | 1,318 | 🔴 **+17 (1.31%)** | -| interface8 | 1,867 | - | -| program1 | 914 | 🔴 **+24 (2.70%)** | -| program2 | 1,064 | 🔴 **+29 (2.80%)** | -| program4 | 1,362 | 🔴 **+49 (3.73%)** | -| program8 | 1,943 | 🔴 **+64 (3.41%)** | -| signer1 | 890 | 🔴 **+16 (1.83%)** | -| signer2 | 1,186 | 🔴 **+13 (1.11%)** | -| signer4 | 1,759 | - | -| signer8 | 2,941 | - | -| systemAccount1 | 927 | 🔴 **+16 (1.76%)** | -| systemAccount2 | 1,248 | 🔴 **+13 (1.05%)** | -| systemAccount4 | 1,871 | - | -| systemAccount8 | 3,153 | - | -| uncheckedAccount1 | 896 | 🔴 **+14 (1.59%)** | -| uncheckedAccount2 | 1,179 | 🔴 **+17 (1.46%)** | -| uncheckedAccount4 | 1,737 | 🔴 **+21 (1.22%)** | -| uncheckedAccount8 | 2,833 | - | +| Instruction | Compute Units | - | +| --------------------------- | ------------- | ------------------- | +| accountInfo1 | 723 | 🔴 **+38 (5.55%)** | +| accountInfo2 | 1,099 | 🔴 **+46 (4.37%)** | +| accountInfo4 | 1,796 | 🔴 **+46 (2.63%)** | +| accountInfo8 | 3,186 | 🔴 **+51 (1.63%)** | +| accountEmptyInit1 | 4,895 | 🟢 **-20 (0.41%)** | +| accountEmpty1 | 790 | 🔴 **+16 (2.07%)** | +| accountEmptyInit2 | 8,774 | 🟢 **-19 (0.22%)** | +| accountEmpty2 | 1,187 | 🔴 **+13 (1.11%)** | +| accountEmptyInit4 | 16,522 | 🟢 **-226 (1.35%)** | +| accountEmpty4 | 1,962 | - | +| accountEmptyInit8 | 32,029 | 🟢 **-328 (1.01%)** | +| accountEmpty8 | 3,548 | - | +| accountSizedInit1 | 4,999 | 🟢 **-20 (0.40%)** | +| accountSized1 | 836 | 🔴 **+14 (1.70%)** | +| accountSizedInit2 | 8,958 | 🟢 **-23 (0.26%)** | +| accountSized2 | 1,259 | 🔴 **+19 (1.53%)** | +| accountSizedInit4 | 16,876 | 🟢 **-278 (1.62%)** | +| accountSized4 | 2,082 | - | +| accountSizedInit8 | 32,680 | 🟢 **-333 (1.01%)** | +| accountSized8 | 3,762 | - | +| accountUnsizedInit1 | 5,109 | 🟢 **-18 (0.35%)** | +| accountUnsized1 | 894 | 🔴 **+20 (2.29%)** | +| accountUnsizedInit2 | 9,159 | 🟢 **-92 (0.99%)** | +| accountUnsized2 | 1,347 | 🔴 **+21 (1.58%)** | +| accountUnsizedInit4 | 17,224 | 🟢 **-154 (0.89%)** | +| accountUnsized4 | 2,231 | - | +| accountUnsizedInit8 | 33,370 | 🟢 **-591 (1.74%)** | +| accountUnsized8 | 4,035 | - | +| boxedAccountEmptyInit1 | 4,987 | 🟢 **-20 (0.40%)** | +| boxedAccountEmpty1 | 881 | 🔴 **+17 (1.97%)** | +| boxedAccountEmptyInit2 | 8,887 | 🟢 **-19 (0.21%)** | +| boxedAccountEmpty2 | 1,300 | 🔴 **+14 (1.09%)** | +| boxedAccountEmptyInit4 | 16,675 | 🟢 **-227 (1.34%)** | +| boxedAccountEmpty4 | 2,115 | - | +| boxedAccountEmptyInit8 | 32,258 | 🟢 **-333 (1.02%)** | +| boxedAccountEmpty8 | 3,801 | - | +| boxedAccountSizedInit1 | 5,083 | 🟢 **-20 (0.39%)** | +| boxedAccountSized1 | 929 | 🔴 **+17 (1.86%)** | +| boxedAccountSizedInit2 | 9,055 | 🟢 **-20 (0.22%)** | +| boxedAccountSized2 | 1,370 | 🔴 **+15 (1.11%)** | +| boxedAccountSizedInit4 | 16,987 | 🟢 **-227 (1.32%)** | +| boxedAccountSized4 | 2,231 | - | +| boxedAccountSizedInit8 | 32,858 | 🟢 **-663 (1.98%)** | +| boxedAccountSized8 | 4,007 | - | +| boxedAccountUnsizedInit1 | 5,182 | 🟢 **-20 (0.38%)** | +| boxedAccountUnsized1 | 981 | 🔴 **+17 (1.76%)** | +| boxedAccountUnsizedInit2 | 9,229 | 🟢 **-22 (0.24%)** | +| boxedAccountUnsized2 | 1,450 | 🔴 **+16 (1.12%)** | +| boxedAccountUnsizedInit4 | 17,311 | 🟢 **-231 (1.32%)** | +| boxedAccountUnsized4 | 2,367 | - | +| boxedAccountUnsizedInit8 | 33,502 | 🟢 **-651 (1.91%)** | +| boxedAccountUnsized8 | 4,257 | - | +| boxedInterfaceAccountMint1 | 1,127 | 🔴 **+17 (1.53%)** | +| boxedInterfaceAccountMint2 | 1,534 | - | +| boxedInterfaceAccountMint4 | 2,370 | - | +| boxedInterfaceAccountMint8 | 4,064 | - | +| boxedInterfaceAccountToken1 | 1,263 | 🔴 **+17 (1.36%)** | +| boxedInterfaceAccountToken2 | 1,794 | - | +| boxedInterfaceAccountToken4 | 2,878 | - | +| boxedInterfaceAccountToken8 | 5,068 | - | +| interfaceAccountMint1 | 1,163 | 🔴 **+37 (3.29%)** | +| interfaceAccountMint2 | 1,600 | 🔴 **+38 (2.43%)** | +| interfaceAccountMint4 | 2,468 | 🔴 **+36 (1.48%)** | +| interfaceAccountMint8 | 4,163 | - | +| interfaceAccountToken1 | 1,315 | 🔴 **+47 (3.71%)** | +| interfaceAccountToken2 | 1,892 | 🔴 **+43 (2.33%)** | +| interfaceAccountToken4 | 3,040 | 🔴 **+43 (1.43%)** | +| interface1 | 894 | 🔴 **+16 (1.82%)** | +| interface2 | 1,036 | 🔴 **+13 (1.27%)** | +| interface4 | 1,318 | 🔴 **+17 (1.31%)** | +| interface8 | 1,867 | - | +| program1 | 914 | 🔴 **+24 (2.70%)** | +| program2 | 1,064 | 🔴 **+29 (2.80%)** | +| program4 | 1,362 | 🔴 **+49 (3.73%)** | +| program8 | 1,943 | 🔴 **+64 (3.41%)** | +| signer1 | 890 | 🔴 **+16 (1.83%)** | +| signer2 | 1,186 | 🔴 **+13 (1.11%)** | +| signer4 | 1,759 | - | +| signer8 | 2,941 | - | +| systemAccount1 | 927 | 🔴 **+16 (1.76%)** | +| systemAccount2 | 1,248 | 🔴 **+13 (1.05%)** | +| systemAccount4 | 1,871 | - | +| systemAccount8 | 3,153 | - | +| uncheckedAccount1 | 896 | 🔴 **+14 (1.59%)** | +| uncheckedAccount2 | 1,179 | 🔴 **+17 (1.46%)** | +| uncheckedAccount4 | 1,737 | 🔴 **+21 (1.22%)** | +| uncheckedAccount8 | 2,833 | - | ### Notable changes diff --git a/tests/bench/bench.json b/tests/bench/bench.json index de47aaf92d..66f3d1142f 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1684,53 +1684,53 @@ "accountInfo2": 1099, "accountInfo4": 1796, "accountInfo8": 3186, - "accountEmptyInit1": 5447, + "accountEmptyInit1": 4895, "accountEmpty1": 790, - "accountEmptyInit2": 9326, + "accountEmptyInit2": 8774, "accountEmpty2": 1187, - "accountEmptyInit4": 17074, + "accountEmptyInit4": 16522, "accountEmpty4": 1962, - "accountEmptyInit8": 32601, + "accountEmptyInit8": 32029, "accountEmpty8": 3548, - "accountSizedInit1": 5551, + "accountSizedInit1": 4999, "accountSized1": 836, - "accountSizedInit2": 9510, + "accountSizedInit2": 8958, "accountSized2": 1259, - "accountSizedInit4": 17428, + "accountSizedInit4": 16876, "accountSized4": 2082, - "accountSizedInit8": 33251, + "accountSizedInit8": 32680, "accountSized8": 3762, - "accountUnsizedInit1": 5661, + "accountUnsizedInit1": 5109, "accountUnsized1": 894, - "accountUnsizedInit2": 9709, + "accountUnsizedInit2": 9159, "accountUnsized2": 1347, - "accountUnsizedInit4": 17797, + "accountUnsizedInit4": 17224, "accountUnsized4": 2231, - "accountUnsizedInit8": 33922, + "accountUnsizedInit8": 33370, "accountUnsized8": 4035, - "boxedAccountEmptyInit1": 5539, + "boxedAccountEmptyInit1": 4987, "boxedAccountEmpty1": 881, - "boxedAccountEmptyInit2": 9438, + "boxedAccountEmptyInit2": 8887, "boxedAccountEmpty2": 1300, - "boxedAccountEmptyInit4": 17227, + "boxedAccountEmptyInit4": 16675, "boxedAccountEmpty4": 2115, - "boxedAccountEmptyInit8": 32830, + "boxedAccountEmptyInit8": 32258, "boxedAccountEmpty8": 3801, - "boxedAccountSizedInit1": 5635, + "boxedAccountSizedInit1": 5083, "boxedAccountSized1": 929, - "boxedAccountSizedInit2": 9606, + "boxedAccountSizedInit2": 9055, "boxedAccountSized2": 1370, - "boxedAccountSizedInit4": 17539, + "boxedAccountSizedInit4": 16987, "boxedAccountSized4": 2231, - "boxedAccountSizedInit8": 33430, + "boxedAccountSizedInit8": 32858, "boxedAccountSized8": 4007, - "boxedAccountUnsizedInit1": 5734, + "boxedAccountUnsizedInit1": 5182, "boxedAccountUnsized1": 981, - "boxedAccountUnsizedInit2": 9780, + "boxedAccountUnsizedInit2": 9229, "boxedAccountUnsized2": 1450, - "boxedAccountUnsizedInit4": 17883, + "boxedAccountUnsizedInit4": 17311, "boxedAccountUnsized4": 2367, - "boxedAccountUnsizedInit8": 34054, + "boxedAccountUnsizedInit8": 33502, "boxedAccountUnsized8": 4257, "boxedInterfaceAccountMint1": 1127, "boxedInterfaceAccountMint2": 1534, From 21b34611f389ae62a4444a9107bcd92b86bc691e Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 21 Nov 2025 19:52:10 +0530 Subject: [PATCH 34/39] fix: package.json --- tests/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/package.json b/tests/package.json index dcc205624c..7571a236b2 100644 --- a/tests/package.json +++ b/tests/package.json @@ -52,7 +52,7 @@ "multiple-suites", "multiple-suites-run-single", "bpf-upgradeable-state", - "duplicate-mutable-accounts" + "duplicate-mutable-accounts", "signature-verification" ], "dependencies": { From a196525ced7805fb2e3949548cffcdb9f742363b Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 21 Nov 2025 20:02:19 +0530 Subject: [PATCH 35/39] refactor: remove unused confirmOptions from event tests --- tests/events/tests/events.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/events/tests/events.ts b/tests/events/tests/events.ts index bb76f266c1..141d5a3dcd 100644 --- a/tests/events/tests/events.ts +++ b/tests/events/tests/events.ts @@ -14,13 +14,6 @@ describe("Events", () => { maxRetries: 3, }; - const confirmOptions = { - commitment: "confirmed" as const, - preflightCommitment: "confirmed" as const, - skipPreflight: true, - maxRetries: 3, - }; - type Event = anchor.IdlEvents; const getEvent = async ( eventName: E, From 11c7e475533f2304d5a2978cae4b8584699e5207 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 21 Nov 2025 20:06:50 +0530 Subject: [PATCH 36/39] chore: update benchmarks --- bench/BINARY_SIZE.md | 6 +- bench/COMPUTE_UNITS.md | 178 ++++++++++++++++++++--------------------- tests/bench/bench.json | 164 ++++++++++++++++++------------------- 3 files changed, 174 insertions(+), 174 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index 5680534afc..634fedf04e 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -16,9 +16,9 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Program | Binary Size | - | -| ------- | ----------- | --------------------- | -| bench | 1,117,184 | 🟢 **-9,656 (0.86%)** | +| Program | Binary Size | - | +| ------- | ----------- | ---------------------- | +| bench | 1,078,616 | 🟢 **-48,224 (4.28%)** | ### Notable changes diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 41cdcb7ef1..5769dbd81b 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -16,95 +16,95 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Instruction | Compute Units | - | -| --------------------------- | ------------- | ------------------- | -| accountInfo1 | 723 | 🔴 **+38 (5.55%)** | -| accountInfo2 | 1,099 | 🔴 **+46 (4.37%)** | -| accountInfo4 | 1,796 | 🔴 **+46 (2.63%)** | -| accountInfo8 | 3,186 | 🔴 **+51 (1.63%)** | -| accountEmptyInit1 | 4,895 | 🟢 **-20 (0.41%)** | -| accountEmpty1 | 790 | 🔴 **+16 (2.07%)** | -| accountEmptyInit2 | 8,774 | 🟢 **-19 (0.22%)** | -| accountEmpty2 | 1,187 | 🔴 **+13 (1.11%)** | -| accountEmptyInit4 | 16,522 | 🟢 **-226 (1.35%)** | -| accountEmpty4 | 1,962 | - | -| accountEmptyInit8 | 32,029 | 🟢 **-328 (1.01%)** | -| accountEmpty8 | 3,548 | - | -| accountSizedInit1 | 4,999 | 🟢 **-20 (0.40%)** | -| accountSized1 | 836 | 🔴 **+14 (1.70%)** | -| accountSizedInit2 | 8,958 | 🟢 **-23 (0.26%)** | -| accountSized2 | 1,259 | 🔴 **+19 (1.53%)** | -| accountSizedInit4 | 16,876 | 🟢 **-278 (1.62%)** | -| accountSized4 | 2,082 | - | -| accountSizedInit8 | 32,680 | 🟢 **-333 (1.01%)** | -| accountSized8 | 3,762 | - | -| accountUnsizedInit1 | 5,109 | 🟢 **-18 (0.35%)** | -| accountUnsized1 | 894 | 🔴 **+20 (2.29%)** | -| accountUnsizedInit2 | 9,159 | 🟢 **-92 (0.99%)** | -| accountUnsized2 | 1,347 | 🔴 **+21 (1.58%)** | -| accountUnsizedInit4 | 17,224 | 🟢 **-154 (0.89%)** | -| accountUnsized4 | 2,231 | - | -| accountUnsizedInit8 | 33,370 | 🟢 **-591 (1.74%)** | -| accountUnsized8 | 4,035 | - | -| boxedAccountEmptyInit1 | 4,987 | 🟢 **-20 (0.40%)** | -| boxedAccountEmpty1 | 881 | 🔴 **+17 (1.97%)** | -| boxedAccountEmptyInit2 | 8,887 | 🟢 **-19 (0.21%)** | -| boxedAccountEmpty2 | 1,300 | 🔴 **+14 (1.09%)** | -| boxedAccountEmptyInit4 | 16,675 | 🟢 **-227 (1.34%)** | -| boxedAccountEmpty4 | 2,115 | - | -| boxedAccountEmptyInit8 | 32,258 | 🟢 **-333 (1.02%)** | -| boxedAccountEmpty8 | 3,801 | - | -| boxedAccountSizedInit1 | 5,083 | 🟢 **-20 (0.39%)** | -| boxedAccountSized1 | 929 | 🔴 **+17 (1.86%)** | -| boxedAccountSizedInit2 | 9,055 | 🟢 **-20 (0.22%)** | -| boxedAccountSized2 | 1,370 | 🔴 **+15 (1.11%)** | -| boxedAccountSizedInit4 | 16,987 | 🟢 **-227 (1.32%)** | -| boxedAccountSized4 | 2,231 | - | -| boxedAccountSizedInit8 | 32,858 | 🟢 **-663 (1.98%)** | -| boxedAccountSized8 | 4,007 | - | -| boxedAccountUnsizedInit1 | 5,182 | 🟢 **-20 (0.38%)** | -| boxedAccountUnsized1 | 981 | 🔴 **+17 (1.76%)** | -| boxedAccountUnsizedInit2 | 9,229 | 🟢 **-22 (0.24%)** | -| boxedAccountUnsized2 | 1,450 | 🔴 **+16 (1.12%)** | -| boxedAccountUnsizedInit4 | 17,311 | 🟢 **-231 (1.32%)** | -| boxedAccountUnsized4 | 2,367 | - | -| boxedAccountUnsizedInit8 | 33,502 | 🟢 **-651 (1.91%)** | -| boxedAccountUnsized8 | 4,257 | - | -| boxedInterfaceAccountMint1 | 1,127 | 🔴 **+17 (1.53%)** | -| boxedInterfaceAccountMint2 | 1,534 | - | -| boxedInterfaceAccountMint4 | 2,370 | - | -| boxedInterfaceAccountMint8 | 4,064 | - | -| boxedInterfaceAccountToken1 | 1,263 | 🔴 **+17 (1.36%)** | -| boxedInterfaceAccountToken2 | 1,794 | - | -| boxedInterfaceAccountToken4 | 2,878 | - | -| boxedInterfaceAccountToken8 | 5,068 | - | -| interfaceAccountMint1 | 1,163 | 🔴 **+37 (3.29%)** | -| interfaceAccountMint2 | 1,600 | 🔴 **+38 (2.43%)** | -| interfaceAccountMint4 | 2,468 | 🔴 **+36 (1.48%)** | -| interfaceAccountMint8 | 4,163 | - | -| interfaceAccountToken1 | 1,315 | 🔴 **+47 (3.71%)** | -| interfaceAccountToken2 | 1,892 | 🔴 **+43 (2.33%)** | -| interfaceAccountToken4 | 3,040 | 🔴 **+43 (1.43%)** | -| interface1 | 894 | 🔴 **+16 (1.82%)** | -| interface2 | 1,036 | 🔴 **+13 (1.27%)** | -| interface4 | 1,318 | 🔴 **+17 (1.31%)** | -| interface8 | 1,867 | - | -| program1 | 914 | 🔴 **+24 (2.70%)** | -| program2 | 1,064 | 🔴 **+29 (2.80%)** | -| program4 | 1,362 | 🔴 **+49 (3.73%)** | -| program8 | 1,943 | 🔴 **+64 (3.41%)** | -| signer1 | 890 | 🔴 **+16 (1.83%)** | -| signer2 | 1,186 | 🔴 **+13 (1.11%)** | -| signer4 | 1,759 | - | -| signer8 | 2,941 | - | -| systemAccount1 | 927 | 🔴 **+16 (1.76%)** | -| systemAccount2 | 1,248 | 🔴 **+13 (1.05%)** | -| systemAccount4 | 1,871 | - | -| systemAccount8 | 3,153 | - | -| uncheckedAccount1 | 896 | 🔴 **+14 (1.59%)** | -| uncheckedAccount2 | 1,179 | 🔴 **+17 (1.46%)** | -| uncheckedAccount4 | 1,737 | 🔴 **+21 (1.22%)** | -| uncheckedAccount8 | 2,833 | - | +| Instruction | Compute Units | - | +| --------------------------- | ------------- | --------------------- | +| accountInfo1 | 713 | 🔴 **+28 (4.09%)** | +| accountInfo2 | 1,099 | 🔴 **+46 (4.37%)** | +| accountInfo4 | 1,796 | 🔴 **+46 (2.63%)** | +| accountInfo8 | 3,230 | 🔴 **+95 (3.03%)** | +| accountEmptyInit1 | 4,767 | 🟢 **-148 (3.01%)** | +| accountEmpty1 | 746 | 🟢 **-28 (3.62%)** | +| accountEmptyInit2 | 8,534 | 🟢 **-259 (2.95%)** | +| accountEmpty2 | 1,120 | 🟢 **-54 (4.60%)** | +| accountEmptyInit4 | 16,056 | 🟢 **-692 (4.13%)** | +| accountEmpty4 | 1,867 | 🟢 **-95 (4.84%)** | +| accountEmptyInit8 | 31,111 | 🟢 **-1,246 (3.85%)** | +| accountEmpty8 | 3,361 | 🟢 **-187 (5.27%)** | +| accountSizedInit1 | 4,867 | 🟢 **-152 (3.03%)** | +| accountSized1 | 791 | 🟢 **-31 (3.77%)** | +| accountSizedInit2 | 8,711 | 🟢 **-270 (3.01%)** | +| accountSized2 | 1,190 | 🟢 **-50 (4.03%)** | +| accountSizedInit4 | 16,394 | 🟢 **-760 (4.43%)** | +| accountSized4 | 1,983 | 🟢 **-99 (4.76%)** | +| accountSizedInit8 | 31,730 | 🟢 **-1,283 (3.89%)** | +| accountSized8 | 3,564 | 🟢 **-198 (5.26%)** | +| accountUnsizedInit1 | 4,978 | 🟢 **-149 (2.91%)** | +| accountUnsized1 | 847 | 🟢 **-27 (3.09%)** | +| accountUnsizedInit2 | 8,913 | 🟢 **-338 (3.65%)** | +| accountUnsized2 | 1,275 | 🟢 **-51 (3.85%)** | +| accountUnsizedInit4 | 16,746 | 🟢 **-632 (3.64%)** | +| accountUnsized4 | 2,128 | 🟢 **-103 (4.62%)** | +| accountUnsizedInit8 | 32,428 | 🟢 **-1,533 (4.51%)** | +| accountUnsized8 | 3,831 | 🟢 **-204 (5.06%)** | +| boxedAccountEmptyInit1 | 4,859 | 🟢 **-148 (2.96%)** | +| boxedAccountEmpty1 | 837 | 🟢 **-27 (3.13%)** | +| boxedAccountEmptyInit2 | 8,647 | 🟢 **-259 (2.91%)** | +| boxedAccountEmpty2 | 1,232 | 🟢 **-54 (4.20%)** | +| boxedAccountEmptyInit4 | 16,209 | 🟢 **-693 (4.10%)** | +| boxedAccountEmpty4 | 2,020 | 🟢 **-95 (4.49%)** | +| boxedAccountEmptyInit8 | 31,340 | 🟢 **-1,251 (3.84%)** | +| boxedAccountEmpty8 | 3,613 | 🟢 **-188 (4.95%)** | +| boxedAccountSizedInit1 | 4,953 | 🟢 **-150 (2.94%)** | +| boxedAccountSized1 | 884 | 🟢 **-28 (3.07%)** | +| boxedAccountSizedInit2 | 8,811 | 🟢 **-264 (2.91%)** | +| boxedAccountSized2 | 1,300 | 🟢 **-55 (4.06%)** | +| boxedAccountSizedInit4 | 16,513 | 🟢 **-701 (4.07%)** | +| boxedAccountSized4 | 2,132 | 🟢 **-99 (4.44%)** | +| boxedAccountSizedInit8 | 31,924 | 🟢 **-1,597 (4.76%)** | +| boxedAccountSized8 | 3,812 | 🟢 **-195 (4.87%)** | +| boxedAccountUnsizedInit1 | 5,052 | 🟢 **-150 (2.88%)** | +| boxedAccountUnsized1 | 934 | 🟢 **-30 (3.11%)** | +| boxedAccountUnsizedInit2 | 8,985 | 🟢 **-266 (2.88%)** | +| boxedAccountUnsized2 | 1,378 | 🟢 **-56 (3.91%)** | +| boxedAccountUnsizedInit4 | 16,837 | 🟢 **-705 (4.02%)** | +| boxedAccountUnsized4 | 2,264 | 🟢 **-103 (4.35%)** | +| boxedAccountUnsizedInit8 | 32,568 | 🟢 **-1,585 (4.64%)** | +| boxedAccountUnsized8 | 4,053 | 🟢 **-204 (4.79%)** | +| boxedInterfaceAccountMint1 | 1,084 | 🟢 **-26 (2.34%)** | +| boxedInterfaceAccountMint2 | 1,485 | 🟢 **-49 (3.19%)** | +| boxedInterfaceAccountMint4 | 2,283 | 🟢 **-87 (3.67%)** | +| boxedInterfaceAccountMint8 | 3,898 | 🟢 **-166 (4.08%)** | +| boxedInterfaceAccountToken1 | 1,222 | 🟢 **-24 (1.93%)** | +| boxedInterfaceAccountToken2 | 1,749 | 🟢 **-45 (2.51%)** | +| boxedInterfaceAccountToken4 | 2,799 | 🟢 **-79 (2.74%)** | +| boxedInterfaceAccountToken8 | 4,918 | 🟢 **-150 (2.96%)** | +| interfaceAccountMint1 | 1,120 | 🟢 **-6 (0.53%)** | +| interfaceAccountMint2 | 1,536 | 🟢 **-26 (1.66%)** | +| interfaceAccountMint4 | 2,363 | 🟢 **-69 (2.84%)** | +| interfaceAccountMint8 | 4,014 | 🟢 **-149 (3.58%)** | +| interfaceAccountToken1 | 1,274 | 🔴 **+6 (0.47%)** | +| interfaceAccountToken2 | 1,832 | 🟢 **-17 (0.92%)** | +| interfaceAccountToken4 | 2,943 | 🟢 **-54 (1.80%)** | +| interface1 | 872 | 🟢 **-6 (0.68%)** | +| interface2 | 1,015 | 🟢 **-8 (0.78%)** | +| interface4 | 1,300 | 🟢 **-1 (0.08%)** | +| interface8 | 1,867 | - | +| program1 | 888 | 🟢 **-2 (0.22%)** | +| program2 | 1,035 | - | +| program4 | 1,328 | 🔴 **+15 (1.14%)** | +| program8 | 1,914 | 🔴 **+35 (1.86%)** | +| signer1 | 878 | 🔴 **+4 (0.46%)** | +| signer2 | 1,186 | 🔴 **+13 (1.11%)** | +| signer4 | 1,792 | 🔴 **+33 (1.88%)** | +| signer8 | 3,010 | 🔴 **+69 (2.35%)** | +| systemAccount1 | 900 | 🟢 **-11 (1.21%)** | +| systemAccount2 | 1,215 | 🟢 **-20 (1.62%)** | +| systemAccount4 | 1,844 | 🟢 **-27 (1.44%)** | +| systemAccount8 | 3,102 | 🟢 **-51 (1.62%)** | +| uncheckedAccount1 | 884 | 🔴 **+2 (0.23%)** | +| uncheckedAccount2 | 1,179 | 🔴 **+17 (1.46%)** | +| uncheckedAccount4 | 1,737 | 🔴 **+21 (1.22%)** | +| uncheckedAccount8 | 2,892 | 🔴 **+59 (2.08%)** | ### Notable changes diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 8f0dd75443..9ddfcdf7f2 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1677,96 +1677,96 @@ "solanaVersion": "2.3.0", "result": { "binarySize": { - "bench": 1117184 + "bench": 1078616 }, "computeUnits": { - "accountInfo1": 723, + "accountInfo1": 713, "accountInfo2": 1099, "accountInfo4": 1796, - "accountInfo8": 3186, - "accountEmptyInit1": 4895, - "accountEmpty1": 790, - "accountEmptyInit2": 8774, - "accountEmpty2": 1187, - "accountEmptyInit4": 16522, - "accountEmpty4": 1962, - "accountEmptyInit8": 32029, - "accountEmpty8": 3548, - "accountSizedInit1": 4999, - "accountSized1": 836, - "accountSizedInit2": 8958, - "accountSized2": 1259, - "accountSizedInit4": 16876, - "accountSized4": 2082, - "accountSizedInit8": 32680, - "accountSized8": 3762, - "accountUnsizedInit1": 5109, - "accountUnsized1": 894, - "accountUnsizedInit2": 9159, - "accountUnsized2": 1347, - "accountUnsizedInit4": 17224, - "accountUnsized4": 2231, - "accountUnsizedInit8": 33370, - "accountUnsized8": 4035, - "boxedAccountEmptyInit1": 4987, - "boxedAccountEmpty1": 881, - "boxedAccountEmptyInit2": 8887, - "boxedAccountEmpty2": 1300, - "boxedAccountEmptyInit4": 16675, - "boxedAccountEmpty4": 2115, - "boxedAccountEmptyInit8": 32258, - "boxedAccountEmpty8": 3801, - "boxedAccountSizedInit1": 5083, - "boxedAccountSized1": 929, - "boxedAccountSizedInit2": 9055, - "boxedAccountSized2": 1370, - "boxedAccountSizedInit4": 16987, - "boxedAccountSized4": 2231, - "boxedAccountSizedInit8": 32858, - "boxedAccountSized8": 4007, - "boxedAccountUnsizedInit1": 5182, - "boxedAccountUnsized1": 981, - "boxedAccountUnsizedInit2": 9229, - "boxedAccountUnsized2": 1450, - "boxedAccountUnsizedInit4": 17311, - "boxedAccountUnsized4": 2367, - "boxedAccountUnsizedInit8": 33502, - "boxedAccountUnsized8": 4257, - "boxedInterfaceAccountMint1": 1127, - "boxedInterfaceAccountMint2": 1534, - "boxedInterfaceAccountMint4": 2370, - "boxedInterfaceAccountMint8": 4064, - "boxedInterfaceAccountToken1": 1263, - "boxedInterfaceAccountToken2": 1794, - "boxedInterfaceAccountToken4": 2878, - "boxedInterfaceAccountToken8": 5068, - "interfaceAccountMint1": 1163, - "interfaceAccountMint2": 1600, - "interfaceAccountMint4": 2468, - "interfaceAccountMint8": 4163, - "interfaceAccountToken1": 1315, - "interfaceAccountToken2": 1892, - "interfaceAccountToken4": 3040, - "interface1": 894, - "interface2": 1036, - "interface4": 1318, + "accountInfo8": 3230, + "accountEmptyInit1": 4767, + "accountEmpty1": 746, + "accountEmptyInit2": 8534, + "accountEmpty2": 1120, + "accountEmptyInit4": 16056, + "accountEmpty4": 1867, + "accountEmptyInit8": 31111, + "accountEmpty8": 3361, + "accountSizedInit1": 4867, + "accountSized1": 791, + "accountSizedInit2": 8711, + "accountSized2": 1190, + "accountSizedInit4": 16394, + "accountSized4": 1983, + "accountSizedInit8": 31730, + "accountSized8": 3564, + "accountUnsizedInit1": 4978, + "accountUnsized1": 847, + "accountUnsizedInit2": 8913, + "accountUnsized2": 1275, + "accountUnsizedInit4": 16746, + "accountUnsized4": 2128, + "accountUnsizedInit8": 32428, + "accountUnsized8": 3831, + "boxedAccountEmptyInit1": 4859, + "boxedAccountEmpty1": 837, + "boxedAccountEmptyInit2": 8647, + "boxedAccountEmpty2": 1232, + "boxedAccountEmptyInit4": 16209, + "boxedAccountEmpty4": 2020, + "boxedAccountEmptyInit8": 31340, + "boxedAccountEmpty8": 3613, + "boxedAccountSizedInit1": 4953, + "boxedAccountSized1": 884, + "boxedAccountSizedInit2": 8811, + "boxedAccountSized2": 1300, + "boxedAccountSizedInit4": 16513, + "boxedAccountSized4": 2132, + "boxedAccountSizedInit8": 31924, + "boxedAccountSized8": 3812, + "boxedAccountUnsizedInit1": 5052, + "boxedAccountUnsized1": 934, + "boxedAccountUnsizedInit2": 8985, + "boxedAccountUnsized2": 1378, + "boxedAccountUnsizedInit4": 16837, + "boxedAccountUnsized4": 2264, + "boxedAccountUnsizedInit8": 32568, + "boxedAccountUnsized8": 4053, + "boxedInterfaceAccountMint1": 1084, + "boxedInterfaceAccountMint2": 1485, + "boxedInterfaceAccountMint4": 2283, + "boxedInterfaceAccountMint8": 3898, + "boxedInterfaceAccountToken1": 1222, + "boxedInterfaceAccountToken2": 1749, + "boxedInterfaceAccountToken4": 2799, + "boxedInterfaceAccountToken8": 4918, + "interfaceAccountMint1": 1120, + "interfaceAccountMint2": 1536, + "interfaceAccountMint4": 2363, + "interfaceAccountMint8": 4014, + "interfaceAccountToken1": 1274, + "interfaceAccountToken2": 1832, + "interfaceAccountToken4": 2943, + "interface1": 872, + "interface2": 1015, + "interface4": 1300, "interface8": 1867, - "program1": 914, - "program2": 1064, - "program4": 1362, - "program8": 1943, - "signer1": 890, + "program1": 888, + "program2": 1035, + "program4": 1328, + "program8": 1914, + "signer1": 878, "signer2": 1186, - "signer4": 1759, - "signer8": 2941, - "systemAccount1": 927, - "systemAccount2": 1248, - "systemAccount4": 1871, - "systemAccount8": 3153, - "uncheckedAccount1": 896, + "signer4": 1792, + "signer8": 3010, + "systemAccount1": 900, + "systemAccount2": 1215, + "systemAccount4": 1844, + "systemAccount8": 3102, + "uncheckedAccount1": 884, "uncheckedAccount2": 1179, "uncheckedAccount4": 1737, - "uncheckedAccount8": 2833 + "uncheckedAccount8": 2892 }, "stackMemory": { "account_info1": 46, From 0557e757cbc9d0b37c8f33da5a3e1f6f6f8c8fdc Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Fri, 21 Nov 2025 20:48:15 +0530 Subject: [PATCH 37/39] chore: update benchmarks --- bench/BINARY_SIZE.md | 2 +- bench/COMPUTE_UNITS.md | 178 ++++++++++++++++++++--------------------- tests/bench/bench.json | 162 ++++++++++++++++++------------------- 3 files changed, 171 insertions(+), 171 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index 634fedf04e..67e42482c8 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -18,7 +18,7 @@ Solana version: 2.3.0 | Program | Binary Size | - | | ------- | ----------- | ---------------------- | -| bench | 1,078,616 | 🟢 **-48,224 (4.28%)** | +| bench | 1,110,968 | 🟢 **-15,872 (1.41%)** | ### Notable changes diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 5769dbd81b..c845f3b3b9 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -16,95 +16,95 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Instruction | Compute Units | - | -| --------------------------- | ------------- | --------------------- | -| accountInfo1 | 713 | 🔴 **+28 (4.09%)** | -| accountInfo2 | 1,099 | 🔴 **+46 (4.37%)** | -| accountInfo4 | 1,796 | 🔴 **+46 (2.63%)** | -| accountInfo8 | 3,230 | 🔴 **+95 (3.03%)** | -| accountEmptyInit1 | 4,767 | 🟢 **-148 (3.01%)** | -| accountEmpty1 | 746 | 🟢 **-28 (3.62%)** | -| accountEmptyInit2 | 8,534 | 🟢 **-259 (2.95%)** | -| accountEmpty2 | 1,120 | 🟢 **-54 (4.60%)** | -| accountEmptyInit4 | 16,056 | 🟢 **-692 (4.13%)** | -| accountEmpty4 | 1,867 | 🟢 **-95 (4.84%)** | -| accountEmptyInit8 | 31,111 | 🟢 **-1,246 (3.85%)** | -| accountEmpty8 | 3,361 | 🟢 **-187 (5.27%)** | -| accountSizedInit1 | 4,867 | 🟢 **-152 (3.03%)** | -| accountSized1 | 791 | 🟢 **-31 (3.77%)** | -| accountSizedInit2 | 8,711 | 🟢 **-270 (3.01%)** | -| accountSized2 | 1,190 | 🟢 **-50 (4.03%)** | -| accountSizedInit4 | 16,394 | 🟢 **-760 (4.43%)** | -| accountSized4 | 1,983 | 🟢 **-99 (4.76%)** | -| accountSizedInit8 | 31,730 | 🟢 **-1,283 (3.89%)** | -| accountSized8 | 3,564 | 🟢 **-198 (5.26%)** | -| accountUnsizedInit1 | 4,978 | 🟢 **-149 (2.91%)** | -| accountUnsized1 | 847 | 🟢 **-27 (3.09%)** | -| accountUnsizedInit2 | 8,913 | 🟢 **-338 (3.65%)** | -| accountUnsized2 | 1,275 | 🟢 **-51 (3.85%)** | -| accountUnsizedInit4 | 16,746 | 🟢 **-632 (3.64%)** | -| accountUnsized4 | 2,128 | 🟢 **-103 (4.62%)** | -| accountUnsizedInit8 | 32,428 | 🟢 **-1,533 (4.51%)** | -| accountUnsized8 | 3,831 | 🟢 **-204 (5.06%)** | -| boxedAccountEmptyInit1 | 4,859 | 🟢 **-148 (2.96%)** | -| boxedAccountEmpty1 | 837 | 🟢 **-27 (3.13%)** | -| boxedAccountEmptyInit2 | 8,647 | 🟢 **-259 (2.91%)** | -| boxedAccountEmpty2 | 1,232 | 🟢 **-54 (4.20%)** | -| boxedAccountEmptyInit4 | 16,209 | 🟢 **-693 (4.10%)** | -| boxedAccountEmpty4 | 2,020 | 🟢 **-95 (4.49%)** | -| boxedAccountEmptyInit8 | 31,340 | 🟢 **-1,251 (3.84%)** | -| boxedAccountEmpty8 | 3,613 | 🟢 **-188 (4.95%)** | -| boxedAccountSizedInit1 | 4,953 | 🟢 **-150 (2.94%)** | -| boxedAccountSized1 | 884 | 🟢 **-28 (3.07%)** | -| boxedAccountSizedInit2 | 8,811 | 🟢 **-264 (2.91%)** | -| boxedAccountSized2 | 1,300 | 🟢 **-55 (4.06%)** | -| boxedAccountSizedInit4 | 16,513 | 🟢 **-701 (4.07%)** | -| boxedAccountSized4 | 2,132 | 🟢 **-99 (4.44%)** | -| boxedAccountSizedInit8 | 31,924 | 🟢 **-1,597 (4.76%)** | -| boxedAccountSized8 | 3,812 | 🟢 **-195 (4.87%)** | -| boxedAccountUnsizedInit1 | 5,052 | 🟢 **-150 (2.88%)** | -| boxedAccountUnsized1 | 934 | 🟢 **-30 (3.11%)** | -| boxedAccountUnsizedInit2 | 8,985 | 🟢 **-266 (2.88%)** | -| boxedAccountUnsized2 | 1,378 | 🟢 **-56 (3.91%)** | -| boxedAccountUnsizedInit4 | 16,837 | 🟢 **-705 (4.02%)** | -| boxedAccountUnsized4 | 2,264 | 🟢 **-103 (4.35%)** | -| boxedAccountUnsizedInit8 | 32,568 | 🟢 **-1,585 (4.64%)** | -| boxedAccountUnsized8 | 4,053 | 🟢 **-204 (4.79%)** | -| boxedInterfaceAccountMint1 | 1,084 | 🟢 **-26 (2.34%)** | -| boxedInterfaceAccountMint2 | 1,485 | 🟢 **-49 (3.19%)** | -| boxedInterfaceAccountMint4 | 2,283 | 🟢 **-87 (3.67%)** | -| boxedInterfaceAccountMint8 | 3,898 | 🟢 **-166 (4.08%)** | -| boxedInterfaceAccountToken1 | 1,222 | 🟢 **-24 (1.93%)** | -| boxedInterfaceAccountToken2 | 1,749 | 🟢 **-45 (2.51%)** | -| boxedInterfaceAccountToken4 | 2,799 | 🟢 **-79 (2.74%)** | -| boxedInterfaceAccountToken8 | 4,918 | 🟢 **-150 (2.96%)** | -| interfaceAccountMint1 | 1,120 | 🟢 **-6 (0.53%)** | -| interfaceAccountMint2 | 1,536 | 🟢 **-26 (1.66%)** | -| interfaceAccountMint4 | 2,363 | 🟢 **-69 (2.84%)** | -| interfaceAccountMint8 | 4,014 | 🟢 **-149 (3.58%)** | -| interfaceAccountToken1 | 1,274 | 🔴 **+6 (0.47%)** | -| interfaceAccountToken2 | 1,832 | 🟢 **-17 (0.92%)** | -| interfaceAccountToken4 | 2,943 | 🟢 **-54 (1.80%)** | -| interface1 | 872 | 🟢 **-6 (0.68%)** | -| interface2 | 1,015 | 🟢 **-8 (0.78%)** | -| interface4 | 1,300 | 🟢 **-1 (0.08%)** | -| interface8 | 1,867 | - | -| program1 | 888 | 🟢 **-2 (0.22%)** | -| program2 | 1,035 | - | -| program4 | 1,328 | 🔴 **+15 (1.14%)** | -| program8 | 1,914 | 🔴 **+35 (1.86%)** | -| signer1 | 878 | 🔴 **+4 (0.46%)** | -| signer2 | 1,186 | 🔴 **+13 (1.11%)** | -| signer4 | 1,792 | 🔴 **+33 (1.88%)** | -| signer8 | 3,010 | 🔴 **+69 (2.35%)** | -| systemAccount1 | 900 | 🟢 **-11 (1.21%)** | -| systemAccount2 | 1,215 | 🟢 **-20 (1.62%)** | -| systemAccount4 | 1,844 | 🟢 **-27 (1.44%)** | -| systemAccount8 | 3,102 | 🟢 **-51 (1.62%)** | -| uncheckedAccount1 | 884 | 🔴 **+2 (0.23%)** | -| uncheckedAccount2 | 1,179 | 🔴 **+17 (1.46%)** | -| uncheckedAccount4 | 1,737 | 🔴 **+21 (1.22%)** | -| uncheckedAccount8 | 2,892 | 🔴 **+59 (2.08%)** | +| Instruction | Compute Units | - | +| --------------------------- | ------------- | ------------------- | +| accountInfo1 | 723 | 🔴 **+38 (5.55%)** | +| accountInfo2 | 1,099 | 🔴 **+46 (4.37%)** | +| accountInfo4 | 1,796 | 🔴 **+46 (2.63%)** | +| accountInfo8 | 3,186 | 🔴 **+51 (1.63%)** | +| accountEmptyInit1 | 4,895 | 🟢 **-20 (0.41%)** | +| accountEmpty1 | 790 | 🔴 **+16 (2.07%)** | +| accountEmptyInit2 | 8,774 | 🟢 **-19 (0.22%)** | +| accountEmpty2 | 1,187 | 🔴 **+13 (1.11%)** | +| accountEmptyInit4 | 16,522 | 🟢 **-226 (1.35%)** | +| accountEmpty4 | 1,979 | 🔴 **+17 (0.87%)** | +| accountEmptyInit8 | 32,029 | 🟢 **-328 (1.01%)** | +| accountEmpty8 | 3,565 | 🔴 **+17 (0.48%)** | +| accountSizedInit1 | 4,999 | 🟢 **-20 (0.40%)** | +| accountSized1 | 836 | 🔴 **+14 (1.70%)** | +| accountSizedInit2 | 8,958 | 🟢 **-23 (0.26%)** | +| accountSized2 | 1,259 | 🔴 **+19 (1.53%)** | +| accountSizedInit4 | 16,876 | 🟢 **-278 (1.62%)** | +| accountSized4 | 2,101 | 🔴 **+19 (0.91%)** | +| accountSizedInit8 | 32,680 | 🟢 **-333 (1.01%)** | +| accountSized8 | 3,779 | 🔴 **+17 (0.45%)** | +| accountUnsizedInit1 | 5,109 | 🟢 **-18 (0.35%)** | +| accountUnsized1 | 894 | 🔴 **+20 (2.29%)** | +| accountUnsizedInit2 | 9,159 | 🟢 **-92 (0.99%)** | +| accountUnsized2 | 1,347 | 🔴 **+21 (1.58%)** | +| accountUnsizedInit4 | 17,224 | 🟢 **-154 (0.89%)** | +| accountUnsized4 | 2,251 | 🔴 **+20 (0.90%)** | +| accountUnsizedInit8 | 33,370 | 🟢 **-591 (1.74%)** | +| accountUnsized8 | 4,054 | 🔴 **+19 (0.47%)** | +| boxedAccountEmptyInit1 | 4,987 | 🟢 **-20 (0.40%)** | +| boxedAccountEmpty1 | 881 | 🔴 **+17 (1.97%)** | +| boxedAccountEmptyInit2 | 8,887 | 🟢 **-19 (0.21%)** | +| boxedAccountEmpty2 | 1,300 | 🔴 **+14 (1.09%)** | +| boxedAccountEmptyInit4 | 16,675 | 🟢 **-227 (1.34%)** | +| boxedAccountEmpty4 | 2,132 | 🔴 **+17 (0.80%)** | +| boxedAccountEmptyInit8 | 32,258 | 🟢 **-333 (1.02%)** | +| boxedAccountEmpty8 | 3,818 | 🔴 **+17 (0.45%)** | +| boxedAccountSizedInit1 | 5,083 | 🟢 **-20 (0.39%)** | +| boxedAccountSized1 | 929 | 🔴 **+17 (1.86%)** | +| boxedAccountSizedInit2 | 9,055 | 🟢 **-20 (0.22%)** | +| boxedAccountSized2 | 1,370 | 🔴 **+15 (1.11%)** | +| boxedAccountSizedInit4 | 16,987 | 🟢 **-227 (1.32%)** | +| boxedAccountSized4 | 2,248 | 🔴 **+17 (0.76%)** | +| boxedAccountSizedInit8 | 32,858 | 🟢 **-663 (1.98%)** | +| boxedAccountSized8 | 4,026 | 🔴 **+19 (0.47%)** | +| boxedAccountUnsizedInit1 | 5,182 | 🟢 **-20 (0.38%)** | +| boxedAccountUnsized1 | 981 | 🔴 **+17 (1.76%)** | +| boxedAccountUnsizedInit2 | 9,229 | 🟢 **-22 (0.24%)** | +| boxedAccountUnsized2 | 1,450 | 🔴 **+16 (1.12%)** | +| boxedAccountUnsizedInit4 | 17,311 | 🟢 **-231 (1.32%)** | +| boxedAccountUnsized4 | 2,384 | 🔴 **+17 (0.72%)** | +| boxedAccountUnsizedInit8 | 33,502 | 🟢 **-651 (1.91%)** | +| boxedAccountUnsized8 | 4,274 | 🔴 **+17 (0.40%)** | +| boxedInterfaceAccountMint1 | 1,129 | 🔴 **+19 (1.71%)** | +| boxedInterfaceAccountMint2 | 1,553 | 🔴 **+19 (1.24%)** | +| boxedInterfaceAccountMint4 | 2,393 | 🔴 **+23 (0.97%)** | +| boxedInterfaceAccountMint8 | 4,097 | 🔴 **+33 (0.81%)** | +| boxedInterfaceAccountToken1 | 1,265 | 🔴 **+19 (1.52%)** | +| boxedInterfaceAccountToken2 | 1,813 | 🔴 **+19 (1.06%)** | +| boxedInterfaceAccountToken4 | 2,901 | 🔴 **+23 (0.80%)** | +| boxedInterfaceAccountToken8 | 5,101 | 🔴 **+33 (0.65%)** | +| interfaceAccountMint1 | 1,165 | 🔴 **+39 (3.46%)** | +| interfaceAccountMint2 | 1,604 | 🔴 **+42 (2.69%)** | +| interfaceAccountMint4 | 2,476 | 🔴 **+44 (1.81%)** | +| interfaceAccountMint8 | 4,216 | 🔴 **+53 (1.27%)** | +| interfaceAccountToken1 | 1,317 | 🔴 **+49 (3.86%)** | +| interfaceAccountToken2 | 1,896 | 🔴 **+47 (2.54%)** | +| interfaceAccountToken4 | 3,048 | 🔴 **+51 (1.70%)** | +| interface1 | 894 | 🔴 **+16 (1.82%)** | +| interface2 | 1,036 | 🔴 **+13 (1.27%)** | +| interface4 | 1,318 | 🔴 **+17 (1.31%)** | +| interface8 | 1,867 | - | +| program1 | 914 | 🔴 **+24 (2.70%)** | +| program2 | 1,064 | 🔴 **+29 (2.80%)** | +| program4 | 1,362 | 🔴 **+49 (3.73%)** | +| program8 | 1,960 | 🔴 **+81 (4.31%)** | +| signer1 | 890 | 🔴 **+16 (1.83%)** | +| signer2 | 1,186 | 🔴 **+13 (1.11%)** | +| signer4 | 1,792 | 🔴 **+33 (1.88%)** | +| signer8 | 2,958 | 🔴 **+17 (0.58%)** | +| systemAccount1 | 927 | 🔴 **+16 (1.76%)** | +| systemAccount2 | 1,248 | 🔴 **+13 (1.05%)** | +| systemAccount4 | 1,888 | 🔴 **+17 (0.91%)** | +| systemAccount8 | 3,170 | 🔴 **+17 (0.54%)** | +| uncheckedAccount1 | 896 | 🔴 **+14 (1.59%)** | +| uncheckedAccount2 | 1,179 | 🔴 **+17 (1.46%)** | +| uncheckedAccount4 | 1,737 | 🔴 **+21 (1.22%)** | +| uncheckedAccount8 | 2,851 | 🔴 **+18 (0.64%)** | ### Notable changes diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 9ddfcdf7f2..bf56913fbb 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1677,96 +1677,96 @@ "solanaVersion": "2.3.0", "result": { "binarySize": { - "bench": 1078616 + "bench": 1110968 }, "computeUnits": { - "accountInfo1": 713, + "accountInfo1": 723, "accountInfo2": 1099, "accountInfo4": 1796, - "accountInfo8": 3230, - "accountEmptyInit1": 4767, - "accountEmpty1": 746, - "accountEmptyInit2": 8534, - "accountEmpty2": 1120, - "accountEmptyInit4": 16056, - "accountEmpty4": 1867, - "accountEmptyInit8": 31111, - "accountEmpty8": 3361, - "accountSizedInit1": 4867, - "accountSized1": 791, - "accountSizedInit2": 8711, - "accountSized2": 1190, - "accountSizedInit4": 16394, - "accountSized4": 1983, - "accountSizedInit8": 31730, - "accountSized8": 3564, - "accountUnsizedInit1": 4978, - "accountUnsized1": 847, - "accountUnsizedInit2": 8913, - "accountUnsized2": 1275, - "accountUnsizedInit4": 16746, - "accountUnsized4": 2128, - "accountUnsizedInit8": 32428, - "accountUnsized8": 3831, - "boxedAccountEmptyInit1": 4859, - "boxedAccountEmpty1": 837, - "boxedAccountEmptyInit2": 8647, - "boxedAccountEmpty2": 1232, - "boxedAccountEmptyInit4": 16209, - "boxedAccountEmpty4": 2020, - "boxedAccountEmptyInit8": 31340, - "boxedAccountEmpty8": 3613, - "boxedAccountSizedInit1": 4953, - "boxedAccountSized1": 884, - "boxedAccountSizedInit2": 8811, - "boxedAccountSized2": 1300, - "boxedAccountSizedInit4": 16513, - "boxedAccountSized4": 2132, - "boxedAccountSizedInit8": 31924, - "boxedAccountSized8": 3812, - "boxedAccountUnsizedInit1": 5052, - "boxedAccountUnsized1": 934, - "boxedAccountUnsizedInit2": 8985, - "boxedAccountUnsized2": 1378, - "boxedAccountUnsizedInit4": 16837, - "boxedAccountUnsized4": 2264, - "boxedAccountUnsizedInit8": 32568, - "boxedAccountUnsized8": 4053, - "boxedInterfaceAccountMint1": 1084, - "boxedInterfaceAccountMint2": 1485, - "boxedInterfaceAccountMint4": 2283, - "boxedInterfaceAccountMint8": 3898, - "boxedInterfaceAccountToken1": 1222, - "boxedInterfaceAccountToken2": 1749, - "boxedInterfaceAccountToken4": 2799, - "boxedInterfaceAccountToken8": 4918, - "interfaceAccountMint1": 1120, - "interfaceAccountMint2": 1536, - "interfaceAccountMint4": 2363, - "interfaceAccountMint8": 4014, - "interfaceAccountToken1": 1274, - "interfaceAccountToken2": 1832, - "interfaceAccountToken4": 2943, - "interface1": 872, - "interface2": 1015, - "interface4": 1300, + "accountInfo8": 3186, + "accountEmptyInit1": 4895, + "accountEmpty1": 790, + "accountEmptyInit2": 8774, + "accountEmpty2": 1187, + "accountEmptyInit4": 16522, + "accountEmpty4": 1979, + "accountEmptyInit8": 32029, + "accountEmpty8": 3565, + "accountSizedInit1": 4999, + "accountSized1": 836, + "accountSizedInit2": 8958, + "accountSized2": 1259, + "accountSizedInit4": 16876, + "accountSized4": 2101, + "accountSizedInit8": 32680, + "accountSized8": 3779, + "accountUnsizedInit1": 5109, + "accountUnsized1": 894, + "accountUnsizedInit2": 9159, + "accountUnsized2": 1347, + "accountUnsizedInit4": 17224, + "accountUnsized4": 2251, + "accountUnsizedInit8": 33370, + "accountUnsized8": 4054, + "boxedAccountEmptyInit1": 4987, + "boxedAccountEmpty1": 881, + "boxedAccountEmptyInit2": 8887, + "boxedAccountEmpty2": 1300, + "boxedAccountEmptyInit4": 16675, + "boxedAccountEmpty4": 2132, + "boxedAccountEmptyInit8": 32258, + "boxedAccountEmpty8": 3818, + "boxedAccountSizedInit1": 5083, + "boxedAccountSized1": 929, + "boxedAccountSizedInit2": 9055, + "boxedAccountSized2": 1370, + "boxedAccountSizedInit4": 16987, + "boxedAccountSized4": 2248, + "boxedAccountSizedInit8": 32858, + "boxedAccountSized8": 4026, + "boxedAccountUnsizedInit1": 5182, + "boxedAccountUnsized1": 981, + "boxedAccountUnsizedInit2": 9229, + "boxedAccountUnsized2": 1450, + "boxedAccountUnsizedInit4": 17311, + "boxedAccountUnsized4": 2384, + "boxedAccountUnsizedInit8": 33502, + "boxedAccountUnsized8": 4274, + "boxedInterfaceAccountMint1": 1129, + "boxedInterfaceAccountMint2": 1553, + "boxedInterfaceAccountMint4": 2393, + "boxedInterfaceAccountMint8": 4097, + "boxedInterfaceAccountToken1": 1265, + "boxedInterfaceAccountToken2": 1813, + "boxedInterfaceAccountToken4": 2901, + "boxedInterfaceAccountToken8": 5101, + "interfaceAccountMint1": 1165, + "interfaceAccountMint2": 1604, + "interfaceAccountMint4": 2476, + "interfaceAccountMint8": 4216, + "interfaceAccountToken1": 1317, + "interfaceAccountToken2": 1896, + "interfaceAccountToken4": 3048, + "interface1": 894, + "interface2": 1036, + "interface4": 1318, "interface8": 1867, - "program1": 888, - "program2": 1035, - "program4": 1328, - "program8": 1914, - "signer1": 878, + "program1": 914, + "program2": 1064, + "program4": 1362, + "program8": 1960, + "signer1": 890, "signer2": 1186, "signer4": 1792, - "signer8": 3010, - "systemAccount1": 900, - "systemAccount2": 1215, - "systemAccount4": 1844, - "systemAccount8": 3102, - "uncheckedAccount1": 884, + "signer8": 2958, + "systemAccount1": 927, + "systemAccount2": 1248, + "systemAccount4": 1888, + "systemAccount8": 3170, + "uncheckedAccount1": 896, "uncheckedAccount2": 1179, "uncheckedAccount4": 1737, - "uncheckedAccount8": 2892 + "uncheckedAccount8": 2851 }, "stackMemory": { "account_info1": 46, From aea833c251e8d0d6d6c5a124ca01feb33d75f4fa Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Tue, 25 Nov 2025 11:46:55 +0530 Subject: [PATCH 38/39] Update benchmarks --- bench/BINARY_SIZE.md | 32 ++-- bench/COMPUTE_UNITS.md | 414 ++++++++++++++++++++--------------------- tests/bench/bench.json | 60 +++--- 3 files changed, 253 insertions(+), 253 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index a61c119f9c..67f1aaa013 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -16,9 +16,9 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Program | Binary Size | - | -| ------- | ----------- | ------------------------ | -| bench | 966,096 | 🟢 **-160,744 (14.27%)** | +| Program | Binary Size | - | +| ------- | ----------- | ---------------------- | +| bench | 1,046,072 | 🟢 **-80,768 (7.17%)** | ### Notable changes @@ -28,8 +28,8 @@ Solana version: 2.3.0 Solana version: 2.3.0 -| Program | Binary Size | - | -| ------- | ----------- | ----------------------- | +| Program | Binary Size | - | +| ------- | ----------- | ------------------------ | | bench | 1,126,840 | 🔴 **+181,272 (19.17%)** | ### Notable changes @@ -42,8 +42,8 @@ Solana version: 2.3.0 Solana version: 2.1.0 -| Program | Binary Size | - | -| ------- | ----------- | --------------------- | +| Program | Binary Size | - | +| ------- | ----------- | ---------------------- | | bench | 945,568 | 🟢 **-96,360 (9.25%)** | ### Notable changes @@ -66,8 +66,8 @@ Solana version: 2.1.0 Solana version: 2.1.0 -| Program | Binary Size | - | -| ------- | ----------- | ----------------------- | +| Program | Binary Size | - | +| ------- | ----------- | ------------------------ | | bench | 1,041,928 | 🔴 **+250,920 (31.72%)** | ### Notable changes @@ -93,8 +93,8 @@ Solana version: 1.18.17 Solana version: 1.18.8 -| Program | Binary Size | - | -| ------- | ----------- | --------------------- | +| Program | Binary Size | - | +| ------- | ----------- | ---------------------- | | bench | 791,008 | 🔴 **+47,952 (6.45%)** | ### Notable changes @@ -107,8 +107,8 @@ Solana version: 1.18.8 Solana version: 1.17.0 -| Program | Binary Size | +/- | -| ------- | ----------- | ----------------------- | +| Program | Binary Size | +/- | +| ------- | ----------- | ------------------------ | | bench | 743,056 | 🟢 **-417,904 (36.00%)** | ### Notable changes @@ -123,8 +123,8 @@ Solana version: 1.17.0 Solana version: 1.16.0 -| Program | Binary Size | +/- | -| ------- | ----------- | --------------------- | +| Program | Binary Size | +/- | +| ------- | ----------- | ---------------------- | | bench | 1,160,960 | 🔴 **+23,272 (2.05%)** | ### Notable changes @@ -141,4 +141,4 @@ Solana version: 1.14.16 | ------- | ----------- | --- | | bench | 1,137,688 | N/A | ---- \ No newline at end of file +--- diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 4ce92f285d..ce768631e8 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -18,38 +18,38 @@ Solana version: 2.3.0 | Instruction | Compute Units | - | | --------------------------- | ------------- | ------------------- | -| accountInfo1 | 685 | - | -| accountInfo2 | 1,053 | - | -| accountInfo4 | 1,750 | - | -| accountInfo8 | 3,135 | - | +| accountInfo1 | 723 | 🔴 **+38 (5.55%)** | +| accountInfo2 | 1,099 | 🔴 **+46 (4.37%)** | +| accountInfo4 | 1,796 | 🔴 **+46 (2.63%)** | +| accountInfo8 | 3,186 | 🔴 **+51 (1.63%)** | | accountEmptyInit1 | 4,915 | - | -| accountEmpty1 | 774 | - | +| accountEmpty1 | 790 | 🔴 **+16 (2.07%)** | | accountEmptyInit2 | 8,793 | - | -| accountEmpty2 | 1,174 | - | +| accountEmpty2 | 1,187 | 🔴 **+13 (1.11%)** | | accountEmptyInit4 | 16,495 | 🟢 **-253 (1.51%)** | | accountEmpty4 | 1,962 | - | | accountEmptyInit8 | 31,997 | 🟢 **-360 (1.11%)** | | accountEmpty8 | 3,548 | - | | accountSizedInit1 | 5,019 | - | -| accountSized1 | 813 | 🟢 **-9 (1.09%)** | +| accountSized1 | 827 | 🔴 **+5 (0.61%)** | | accountSizedInit2 | 8,981 | - | -| accountSized2 | 1,222 | 🟢 **-18 (1.45%)** | +| accountSized2 | 1,241 | 🔴 **+1 (0.08%)** | | accountSizedInit4 | 16,850 | 🟢 **-304 (1.77%)** | | accountSized4 | 2,046 | 🟢 **-36 (1.73%)** | | accountSizedInit8 | 32,653 | 🟢 **-360 (1.09%)** | | accountSized8 | 3,690 | 🟢 **-72 (1.91%)** | | accountUnsizedInit1 | 5,127 | - | -| accountUnsized1 | 853 | 🟢 **-21 (2.40%)** | +| accountUnsized1 | 873 | 🟢 **-1 (0.11%)** | | accountUnsizedInit2 | 9,131 | 🟢 **-120 (1.30%)** | -| accountUnsized2 | 1,284 | 🟢 **-42 (3.17%)** | +| accountUnsized2 | 1,305 | 🟢 **-21 (1.58%)** | | accountUnsizedInit4 | 17,198 | 🟢 **-180 (1.04%)** | | accountUnsized4 | 2,147 | 🟢 **-84 (3.77%)** | | accountUnsizedInit8 | 33,324 | 🟢 **-637 (1.88%)** | | accountUnsized8 | 3,867 | 🟢 **-168 (4.16%)** | | boxedAccountEmptyInit1 | 5,007 | - | -| boxedAccountEmpty1 | 864 | - | +| boxedAccountEmpty1 | 881 | 🔴 **+17 (1.97%)** | | boxedAccountEmptyInit2 | 8,906 | - | -| boxedAccountEmpty2 | 1,286 | - | +| boxedAccountEmpty2 | 1,300 | 🔴 **+14 (1.09%)** | | boxedAccountEmptyInit4 | 16,648 | 🟢 **-254 (1.50%)** | | boxedAccountEmpty4 | 2,115 | - | | boxedAccountEmptyInit8 | 32,231 | 🟢 **-360 (1.10%)** | @@ -57,37 +57,37 @@ Solana version: 2.3.0 | boxedAccountSizedInit1 | 5,103 | - | | boxedAccountSized1 | 912 | - | | boxedAccountSizedInit2 | 9,075 | - | -| boxedAccountSized2 | 1,337 | 🟢 **-18 (1.33%)** | +| boxedAccountSized2 | 1,352 | 🟢 **-3 (0.22%)** | | boxedAccountSizedInit4 | 16,960 | 🟢 **-254 (1.48%)** | | boxedAccountSized4 | 2,195 | 🟢 **-36 (1.61%)** | | boxedAccountSizedInit8 | 32,831 | 🟢 **-690 (2.06%)** | | boxedAccountSized8 | 3,935 | 🟢 **-72 (1.80%)** | | boxedAccountUnsizedInit1 | 5,202 | - | -| boxedAccountUnsized1 | 943 | 🟢 **-21 (2.18%)** | +| boxedAccountUnsized1 | 960 | 🟢 **-4 (0.41%)** | | boxedAccountUnsizedInit2 | 9,251 | - | -| boxedAccountUnsized2 | 1,392 | 🟢 **-42 (2.93%)** | +| boxedAccountUnsized2 | 1,408 | 🟢 **-26 (1.81%)** | | boxedAccountUnsizedInit4 | 17,284 | 🟢 **-258 (1.47%)** | | boxedAccountUnsized4 | 2,283 | 🟢 **-84 (3.55%)** | | boxedAccountUnsizedInit8 | 33,455 | 🟢 **-698 (2.04%)** | | boxedAccountUnsized8 | 4,089 | 🟢 **-168 (3.95%)** | -| boxedInterfaceAccountMint1 | 1,110 | - | -| boxedInterfaceAccountMint2 | 1,534 | - | +| boxedInterfaceAccountMint1 | 1,129 | 🔴 **+19 (1.71%)** | +| boxedInterfaceAccountMint2 | 1,553 | 🔴 **+19 (1.24%)** | | boxedInterfaceAccountMint4 | 2,370 | - | | boxedInterfaceAccountMint8 | 4,064 | - | -| boxedInterfaceAccountToken1 | 1,246 | - | -| boxedInterfaceAccountToken2 | 1,794 | - | +| boxedInterfaceAccountToken1 | 1,265 | 🔴 **+19 (1.52%)** | +| boxedInterfaceAccountToken2 | 1,813 | 🔴 **+19 (1.06%)** | | boxedInterfaceAccountToken4 | 2,878 | - | | boxedInterfaceAccountToken8 | 5,068 | - | -| interfaceAccountMint1 | 1,126 | - | -| interfaceAccountMint2 | 1,562 | - | -| interfaceAccountMint4 | 2,432 | - | -| interfaceAccountMint8 | 4,163 | - | -| interfaceAccountToken1 | 1,268 | - | -| interfaceAccountToken2 | 1,849 | - | -| interfaceAccountToken4 | 2,997 | - | -| interface1 | 878 | - | -| interface2 | 1,023 | - | -| interface4 | 1,301 | - | +| interfaceAccountMint1 | 1,165 | 🔴 **+39 (3.46%)** | +| interfaceAccountMint2 | 1,604 | 🔴 **+42 (2.69%)** | +| interfaceAccountMint4 | 2,476 | 🔴 **+44 (1.81%)** | +| interfaceAccountMint8 | 4,216 | 🔴 **+53 (1.27%)** | +| interfaceAccountToken1 | 1,317 | 🔴 **+49 (3.86%)** | +| interfaceAccountToken2 | 1,896 | 🔴 **+47 (2.54%)** | +| interfaceAccountToken4 | 3,048 | 🔴 **+51 (1.70%)** | +| interface1 | 894 | 🔴 **+16 (1.82%)** | +| interface2 | 1,036 | 🔴 **+13 (1.27%)** | +| interface4 | 1,318 | 🔴 **+17 (1.31%)** | | interface8 | 1,867 | - | | program1 | 914 | 🔴 **+24 (2.70%)** | | program2 | 1,064 | 🔴 **+29 (2.80%)** | @@ -114,95 +114,95 @@ Solana version: 2.3.0 Solana version: 2.3.0 -| Instruction | Compute Units | - | -|------------------------------|---------------|------------------------| -| accountInfo1 | 685 | 🔴 **+114 (19.96%)** | -| accountInfo2 | 1,053 | 🔴 **+158 (17.65%)** | -| accountInfo4 | 1,750 | 🔴 **+197 (12.69%)** | -| accountInfo8 | 3,135 | 🔴 **+212 (7.25%)** | -| accountEmptyInit1 | 4,915 | 🔴 **+131 (2.74%)** | -| accountEmpty1 | 774 | 🔴 **+129 (20.00%)** | -| accountEmptyInit2 | 8,793 | 🔴 **+124 (1.43%)** | -| accountEmpty2 | 1,174 | 🔴 **+167 (16.58%)** | -| accountEmptyInit4 | 16,748 | 🔴 **+248 (1.50%)** | -| accountEmpty4 | 1,962 | 🔴 **+238 (13.81%)** | -| accountEmptyInit8 | 32,357 | 🔴 **+26 (0.08%)** | -| accountEmpty8 | 3,548 | 🔴 **+385 (12.17%)** | -| accountSizedInit1 | 5,019 | 🔴 **+126 (2.58%)** | -| accountSized1 | 822 | 🔴 **+129 (18.61%)** | -| accountSizedInit2 | 8,981 | 🔴 **+124 (1.40%)** | -| accountSized2 | 1,240 | 🔴 **+165 (15.35%)** | -| accountSizedInit4 | 17,154 | 🔴 **+248 (1.47%)** | -| accountSized4 | 2,082 | 🔴 **+234 (12.66%)** | -| accountSizedInit8 | 33,013 | 🟢 **-28 (0.08%)** | -| accountSized8 | 3,762 | 🔴 **+375 (11.07%)** | -| accountUnsizedInit1 | 5,127 | 🔴 **+121 (2.42%)** | -| accountUnsized1 | 874 | 🔴 **+128 (17.16%)** | -| accountUnsizedInit2 | 9,251 | 🔴 **+124 (1.36%)** | -| accountUnsized2 | 1,326 | 🔴 **+163 (14.02%)** | -| accountUnsizedInit4 | 17,378 | 🟢 **-29 (0.17%)** | -| accountUnsized4 | 2,231 | 🔴 **+229 (11.44%)** | -| accountUnsizedInit8 | 33,961 | 🔴 **+496 (1.48%)** | -| accountUnsized8 | 4,035 | 🔴 **+362 (9.86%)** | -| boxedAccountEmptyInit1 | 5,007 | 🔴 **+131 (2.69%)** | -| boxedAccountEmpty1 | 864 | 🔴 **+130 (17.71%)** | -| boxedAccountEmptyInit2 | 8,906 | 🔴 **+123 (1.40%)** | -| boxedAccountEmpty2 | 1,286 | 🔴 **+170 (15.23%)** | -| boxedAccountEmptyInit4 | 16,902 | 🔴 **+247 (1.48%)** | -| boxedAccountEmpty4 | 2,115 | 🔴 **+243 (12.98%)** | -| boxedAccountEmptyInit8 | 32,591 | 🔴 **+30 (0.09%)** | -| boxedAccountEmpty8 | 3,801 | 🔴 **+400 (11.76%)** | -| boxedAccountSizedInit1 | 5,103 | 🔴 **+131 (2.63%)** | -| boxedAccountSized1 | 912 | 🔴 **+129 (16.48%)** | -| boxedAccountSizedInit2 | 9,075 | 🔴 **+123 (1.37%)** | -| boxedAccountSized2 | 1,355 | 🔴 **+165 (13.87%)** | -| boxedAccountSizedInit4 | 17,214 | 🔴 **+247 (1.46%)** | -| boxedAccountSized4 | 2,231 | 🔴 **+235 (11.77%)** | -| boxedAccountSizedInit8 | 33,521 | 🔴 **+360 (1.09%)** | -| boxedAccountSized8 | 4,007 | 🔴 **+379 (10.45%)** | -| boxedAccountUnsizedInit1 | 5,202 | 🔴 **+130 (2.56%)** | -| boxedAccountUnsized1 | 964 | 🔴 **+128 (15.31%)** | -| boxedAccountUnsizedInit2 | 9,251 | 🔴 **+123 (1.35%)** | -| boxedAccountUnsized2 | 1,434 | 🔴 **+164 (12.91%)** | -| boxedAccountUnsizedInit4 | 17,542 | 🔴 **+247 (1.43%)** | -| boxedAccountUnsized4 | 2,367 | 🔴 **+235 (11.02%)** | -| boxedAccountUnsizedInit8 | 34,153 | 🔴 **+360 (1.07%)** | -| boxedAccountUnsized8 | 4,257 | 🔴 **+376 (9.69%)** | -| boxedInterfaceAccountMint1 | 1,110 | 🟢 **-241 (17.84%)** | -| boxedInterfaceAccountMint2 | 1,534 | 🟢 **-589 (27.74%)** | -| boxedInterfaceAccountMint4 | 2,370 | 🟢 **-1,286 (35.18%)** | -| boxedInterfaceAccountMint8 | 4,064 | 🟢 **-2,674 (39.69%)** | -| boxedInterfaceAccountToken1 | 1,246 | 🟢 **-765 (38.04%)** | -| boxedInterfaceAccountToken2 | 1,794 | 🟢 **-1,637 (47.71%)** | -| boxedInterfaceAccountToken4 | 2,878 | 🟢 **-3,382 (54.03%)** | -| boxedInterfaceAccountToken8 | 5,068 | 🟢 **-6,866 (57.53%)** | -| interfaceAccountMint1 | 1,126 | 🟢 **-350 (23.71%)** | -| interfaceAccountMint2 | 1,562 | 🟢 **-927 (37.24%)** | -| interfaceAccountMint4 | 2,432 | 🟢 **-2,079 (46.09%)** | -| interfaceAccountMint8 | 4,163 | 🟢 **-4,387 (51.31%)** | -| interfaceAccountToken1 | 1,268 | 🟢 **-843 (39.93%)** | -| interfaceAccountToken2 | 1,849 | 🟢 **-1,880 (50.42%)** | -| interfaceAccountToken4 | 2,997 | 🟢 **-3,958 (56.91%)** | -| interface1 | 878 | 🔴 **+109 (14.17%)** | -| interface2 | 1,023 | 🔴 **+111 (12.17%)** | -| interface4 | 1,301 | 🔴 **+112 (9.42%)** | -| interface8 | 1,867 | 🔴 **+119 (6.81%)** | -| program1 | 890 | 🔴 **+111 (14.25%)** | -| program2 | 1,035 | 🔴 **+115 (12.50%)** | -| program4 | 1,313 | 🔴 **+120 (10.06%)** | -| program8 | 1,879 | 🔴 **+135 (7.74%)** | -| signer1 | 874 | 🔴 **+100 (12.92%)** | -| signer2 | 1,173 | 🔴 **+109 (10.24%)** | -| signer4 | 1,759 | 🔴 **+122 (7.45%)** | -| signer8 | 2,941 | 🔴 **+153 (5.49%)** | -| systemAccount1 | 911 | 🔴 **+115 (14.45%)** | -| systemAccount2 | 1,235 | 🔴 **+139 (12.68%)** | -| systemAccount4 | 1,871 | 🔴 **+182 (10.78%)** | -| systemAccount8 | 3,153 | 🔴 **+273 (9.48%)** | -| uncheckedAccount1 | 882 | 🔴 **+99 (12.64%)** | -| uncheckedAccount2 | 1,162 | 🔴 **+106 (10.04%)** | -| uncheckedAccount4 | 1,716 | 🔴 **+122 (7.65%)** | -| uncheckedAccount8 | 2,833 | 🔴 **+154 (5.75%)** | +| Instruction | Compute Units | - | +| --------------------------- | ------------- | ---------------------- | +| accountInfo1 | 685 | 🔴 **+114 (19.96%)** | +| accountInfo2 | 1,053 | 🔴 **+158 (17.65%)** | +| accountInfo4 | 1,750 | 🔴 **+197 (12.69%)** | +| accountInfo8 | 3,135 | 🔴 **+212 (7.25%)** | +| accountEmptyInit1 | 4,915 | 🔴 **+131 (2.74%)** | +| accountEmpty1 | 774 | 🔴 **+129 (20.00%)** | +| accountEmptyInit2 | 8,793 | 🔴 **+124 (1.43%)** | +| accountEmpty2 | 1,174 | 🔴 **+167 (16.58%)** | +| accountEmptyInit4 | 16,748 | 🔴 **+248 (1.50%)** | +| accountEmpty4 | 1,962 | 🔴 **+238 (13.81%)** | +| accountEmptyInit8 | 32,357 | 🔴 **+26 (0.08%)** | +| accountEmpty8 | 3,548 | 🔴 **+385 (12.17%)** | +| accountSizedInit1 | 5,019 | 🔴 **+126 (2.58%)** | +| accountSized1 | 822 | 🔴 **+129 (18.61%)** | +| accountSizedInit2 | 8,981 | 🔴 **+124 (1.40%)** | +| accountSized2 | 1,240 | 🔴 **+165 (15.35%)** | +| accountSizedInit4 | 17,154 | 🔴 **+248 (1.47%)** | +| accountSized4 | 2,082 | 🔴 **+234 (12.66%)** | +| accountSizedInit8 | 33,013 | 🟢 **-28 (0.08%)** | +| accountSized8 | 3,762 | 🔴 **+375 (11.07%)** | +| accountUnsizedInit1 | 5,127 | 🔴 **+121 (2.42%)** | +| accountUnsized1 | 874 | 🔴 **+128 (17.16%)** | +| accountUnsizedInit2 | 9,251 | 🔴 **+124 (1.36%)** | +| accountUnsized2 | 1,326 | 🔴 **+163 (14.02%)** | +| accountUnsizedInit4 | 17,378 | 🟢 **-29 (0.17%)** | +| accountUnsized4 | 2,231 | 🔴 **+229 (11.44%)** | +| accountUnsizedInit8 | 33,961 | 🔴 **+496 (1.48%)** | +| accountUnsized8 | 4,035 | 🔴 **+362 (9.86%)** | +| boxedAccountEmptyInit1 | 5,007 | 🔴 **+131 (2.69%)** | +| boxedAccountEmpty1 | 864 | 🔴 **+130 (17.71%)** | +| boxedAccountEmptyInit2 | 8,906 | 🔴 **+123 (1.40%)** | +| boxedAccountEmpty2 | 1,286 | 🔴 **+170 (15.23%)** | +| boxedAccountEmptyInit4 | 16,902 | 🔴 **+247 (1.48%)** | +| boxedAccountEmpty4 | 2,115 | 🔴 **+243 (12.98%)** | +| boxedAccountEmptyInit8 | 32,591 | 🔴 **+30 (0.09%)** | +| boxedAccountEmpty8 | 3,801 | 🔴 **+400 (11.76%)** | +| boxedAccountSizedInit1 | 5,103 | 🔴 **+131 (2.63%)** | +| boxedAccountSized1 | 912 | 🔴 **+129 (16.48%)** | +| boxedAccountSizedInit2 | 9,075 | 🔴 **+123 (1.37%)** | +| boxedAccountSized2 | 1,355 | 🔴 **+165 (13.87%)** | +| boxedAccountSizedInit4 | 17,214 | 🔴 **+247 (1.46%)** | +| boxedAccountSized4 | 2,231 | 🔴 **+235 (11.77%)** | +| boxedAccountSizedInit8 | 33,521 | 🔴 **+360 (1.09%)** | +| boxedAccountSized8 | 4,007 | 🔴 **+379 (10.45%)** | +| boxedAccountUnsizedInit1 | 5,202 | 🔴 **+130 (2.56%)** | +| boxedAccountUnsized1 | 964 | 🔴 **+128 (15.31%)** | +| boxedAccountUnsizedInit2 | 9,251 | 🔴 **+123 (1.35%)** | +| boxedAccountUnsized2 | 1,434 | 🔴 **+164 (12.91%)** | +| boxedAccountUnsizedInit4 | 17,542 | 🔴 **+247 (1.43%)** | +| boxedAccountUnsized4 | 2,367 | 🔴 **+235 (11.02%)** | +| boxedAccountUnsizedInit8 | 34,153 | 🔴 **+360 (1.07%)** | +| boxedAccountUnsized8 | 4,257 | 🔴 **+376 (9.69%)** | +| boxedInterfaceAccountMint1 | 1,110 | 🟢 **-241 (17.84%)** | +| boxedInterfaceAccountMint2 | 1,534 | 🟢 **-589 (27.74%)** | +| boxedInterfaceAccountMint4 | 2,370 | 🟢 **-1,286 (35.18%)** | +| boxedInterfaceAccountMint8 | 4,064 | 🟢 **-2,674 (39.69%)** | +| boxedInterfaceAccountToken1 | 1,246 | 🟢 **-765 (38.04%)** | +| boxedInterfaceAccountToken2 | 1,794 | 🟢 **-1,637 (47.71%)** | +| boxedInterfaceAccountToken4 | 2,878 | 🟢 **-3,382 (54.03%)** | +| boxedInterfaceAccountToken8 | 5,068 | 🟢 **-6,866 (57.53%)** | +| interfaceAccountMint1 | 1,126 | 🟢 **-350 (23.71%)** | +| interfaceAccountMint2 | 1,562 | 🟢 **-927 (37.24%)** | +| interfaceAccountMint4 | 2,432 | 🟢 **-2,079 (46.09%)** | +| interfaceAccountMint8 | 4,163 | 🟢 **-4,387 (51.31%)** | +| interfaceAccountToken1 | 1,268 | 🟢 **-843 (39.93%)** | +| interfaceAccountToken2 | 1,849 | 🟢 **-1,880 (50.42%)** | +| interfaceAccountToken4 | 2,997 | 🟢 **-3,958 (56.91%)** | +| interface1 | 878 | 🔴 **+109 (14.17%)** | +| interface2 | 1,023 | 🔴 **+111 (12.17%)** | +| interface4 | 1,301 | 🔴 **+112 (9.42%)** | +| interface8 | 1,867 | 🔴 **+119 (6.81%)** | +| program1 | 890 | 🔴 **+111 (14.25%)** | +| program2 | 1,035 | 🔴 **+101 (10.81%)** | +| program4 | 1,313 | 🔴 **+92 (7.53%)** | +| program8 | 1,879 | 🔴 **+79 (4.39%)** | +| signer1 | 874 | 🔴 **+100 (12.92%)** | +| signer2 | 1,173 | 🔴 **+109 (10.24%)** | +| signer4 | 1,759 | 🔴 **+122 (7.45%)** | +| signer8 | 2,941 | 🔴 **+153 (5.49%)** | +| systemAccount1 | 911 | 🔴 **+115 (14.45%)** | +| systemAccount2 | 1,235 | 🔴 **+139 (12.68%)** | +| systemAccount4 | 1,871 | 🔴 **+182 (10.78%)** | +| systemAccount8 | 3,153 | 🔴 **+273 (9.48%)** | +| uncheckedAccount1 | 882 | 🔴 **+99 (12.64%)** | +| uncheckedAccount2 | 1,162 | 🔴 **+106 (10.04%)** | +| uncheckedAccount4 | 1,716 | 🔴 **+122 (7.65%)** | +| uncheckedAccount8 | 2,833 | 🔴 **+154 (5.75%)** | ### Notable changes @@ -212,95 +212,95 @@ Solana version: 2.3.0 Solana version: 2.1.0 -| Instruction | Compute Units | - | -|------------------------------|---------------|-----------------------| -| accountInfo1 | 571 | - | -| accountInfo2 | 895 | - | -| accountInfo4 | 1,553 | - | -| accountInfo8 | 2,923 | - | -| accountEmptyInit1 | 4,784 | 🟢 **-299 (5.88%)** | -| accountEmpty1 | 645 | - | -| accountEmptyInit2 | 8,669 | 🟢 **-632 (6.79%)** | -| accountEmpty2 | 1,007 | - | -| accountEmptyInit4 | 16,500 | 🟢 **-1,264 (7.12%)** | -| accountEmpty4 | 1,724 | - | -| accountEmptyInit8 | 32,331 | 🟢 **-2,392 (6.89%)** | -| accountEmpty8 | 3,163 | - | -| accountSizedInit1 | 4,893 | 🟢 **-299 (5.76%)** | -| accountSized1 | 693 | - | -| accountSizedInit2 | 8,857 | 🟢 **-632 (6.66%)** | -| accountSized2 | 1,075 | - | -| accountSizedInit4 | 16,906 | 🟢 **-1,264 (6.96%)** | -| accountSized4 | 1,848 | - | -| accountSizedInit8 | 33,041 | 🟢 **-2,392 (6.75%)** | -| accountSized8 | 3,387 | - | -| accountUnsizedInit1 | 5,006 | 🟢 **-299 (5.64%)** | -| accountUnsized1 | 746 | - | -| accountUnsizedInit2 | 9,127 | 🟢 **-632 (6.48%)** | -| accountUnsized2 | 1,163 | - | -| accountUnsizedInit4 | 17,407 | 🟢 **-1,196 (6.43%)** | -| accountUnsized4 | 2,002 | - | -| accountUnsizedInit8 | 33,465 | 🟢 **-2,528 (7.02%)** | -| accountUnsized8 | 3,673 | - | -| boxedAccountEmptyInit1 | 4,876 | 🟢 **-299 (5.78%)** | -| boxedAccountEmpty1 | 734 | - | -| boxedAccountEmptyInit2 | 8,783 | 🟢 **-631 (6.70%)** | -| boxedAccountEmpty2 | 1,116 | - | -| boxedAccountEmptyInit4 | 16,655 | 🟢 **-1,263 (7.05%)** | -| boxedAccountEmpty4 | 1,872 | - | -| boxedAccountEmptyInit8 | 32,561 | 🟢 **-2,392 (6.84%)** | -| boxedAccountEmpty8 | 3,401 | - | -| boxedAccountSizedInit1 | 4,972 | 🟢 **-299 (5.67%)** | -| boxedAccountSized1 | 783 | - | -| boxedAccountSizedInit2 | 8,952 | 🟢 **-631 (6.58%)** | -| boxedAccountSized2 | 1,190 | - | -| boxedAccountSizedInit4 | 16,967 | 🟢 **-1,263 (6.93%)** | -| boxedAccountSized4 | 1,996 | - | -| boxedAccountSizedInit8 | 33,161 | 🟢 **-2,392 (6.73%)** | -| boxedAccountSized8 | 3,628 | - | -| boxedAccountUnsizedInit1 | 5,072 | 🟢 **-299 (5.57%)** | -| boxedAccountUnsized1 | 836 | - | -| boxedAccountUnsizedInit2 | 9,128 | 🟢 **-631 (6.47%)** | -| boxedAccountUnsized2 | 1,270 | - | -| boxedAccountUnsizedInit4 | 17,295 | 🟢 **-1,263 (6.81%)** | -| boxedAccountUnsized4 | 2,132 | - | -| boxedAccountUnsizedInit8 | 33,793 | 🟢 **-2,392 (6.61%)** | -| boxedAccountUnsized8 | 3,881 | - | -| boxedInterfaceAccountMint1 | 1,351 | - | -| boxedInterfaceAccountMint2 | 2,123 | - | -| boxedInterfaceAccountMint4 | 3,656 | - | -| boxedInterfaceAccountMint8 | 6,738 | - | -| boxedInterfaceAccountToken1 | 2,011 | - | -| boxedInterfaceAccountToken2 | 3,431 | - | -| boxedInterfaceAccountToken4 | 6,260 | - | -| boxedInterfaceAccountToken8 | 11,934 | - | -| interfaceAccountMint1 | 1,476 | - | -| interfaceAccountMint2 | 2,489 | - | -| interfaceAccountMint4 | 4,511 | - | -| interfaceAccountMint8 | 8,550 | - | -| interfaceAccountToken1 | 2,111 | - | -| interfaceAccountToken2 | 3,729 | - | -| interfaceAccountToken4 | 6,955 | - | -| interface1 | 769 | - | -| interface2 | 912 | - | -| interface4 | 1,189 | - | -| interface8 | 1,748 | - | -| program1 | 779 | - | -| program2 | 934 | 🔴 **+14 (1.52%)** | -| program4 | 1,221 | 🔴 **+28 (2.35%)** | -| program8 | 1,800 | 🔴 **+56 (3.21%)** | -| signer1 | 774 | - | -| signer2 | 1,064 | - | -| signer4 | 1,637 | - | -| signer8 | 2,788 | - | -| systemAccount1 | 796 | - | -| systemAccount2 | 1,096 | - | -| systemAccount4 | 1,689 | - | -| systemAccount8 | 2,880 | - | -| uncheckedAccount1 | 783 | - | -| uncheckedAccount2 | 1,056 | - | -| uncheckedAccount4 | 1,594 | - | -| uncheckedAccount8 | 2,679 | - | +| Instruction | Compute Units | - | +| --------------------------- | ------------- | --------------------- | +| accountInfo1 | 571 | - | +| accountInfo2 | 895 | - | +| accountInfo4 | 1,553 | - | +| accountInfo8 | 2,923 | - | +| accountEmptyInit1 | 4,784 | 🟢 **-299 (5.88%)** | +| accountEmpty1 | 645 | - | +| accountEmptyInit2 | 8,669 | 🟢 **-632 (6.79%)** | +| accountEmpty2 | 1,007 | - | +| accountEmptyInit4 | 16,500 | 🟢 **-1,264 (7.12%)** | +| accountEmpty4 | 1,724 | - | +| accountEmptyInit8 | 32,331 | 🟢 **-2,392 (6.89%)** | +| accountEmpty8 | 3,163 | - | +| accountSizedInit1 | 4,893 | 🟢 **-299 (5.76%)** | +| accountSized1 | 693 | - | +| accountSizedInit2 | 8,857 | 🟢 **-632 (6.66%)** | +| accountSized2 | 1,075 | - | +| accountSizedInit4 | 16,906 | 🟢 **-1,264 (6.96%)** | +| accountSized4 | 1,848 | - | +| accountSizedInit8 | 33,041 | 🟢 **-2,392 (6.75%)** | +| accountSized8 | 3,387 | - | +| accountUnsizedInit1 | 5,006 | 🟢 **-299 (5.64%)** | +| accountUnsized1 | 746 | - | +| accountUnsizedInit2 | 9,127 | 🟢 **-632 (6.48%)** | +| accountUnsized2 | 1,163 | - | +| accountUnsizedInit4 | 17,407 | 🟢 **-1,196 (6.43%)** | +| accountUnsized4 | 2,002 | - | +| accountUnsizedInit8 | 33,465 | 🟢 **-2,528 (7.02%)** | +| accountUnsized8 | 3,673 | - | +| boxedAccountEmptyInit1 | 4,876 | 🟢 **-299 (5.78%)** | +| boxedAccountEmpty1 | 734 | - | +| boxedAccountEmptyInit2 | 8,783 | 🟢 **-631 (6.70%)** | +| boxedAccountEmpty2 | 1,116 | - | +| boxedAccountEmptyInit4 | 16,655 | 🟢 **-1,263 (7.05%)** | +| boxedAccountEmpty4 | 1,872 | - | +| boxedAccountEmptyInit8 | 32,561 | 🟢 **-2,392 (6.84%)** | +| boxedAccountEmpty8 | 3,401 | - | +| boxedAccountSizedInit1 | 4,972 | 🟢 **-299 (5.67%)** | +| boxedAccountSized1 | 783 | - | +| boxedAccountSizedInit2 | 8,952 | 🟢 **-631 (6.58%)** | +| boxedAccountSized2 | 1,190 | - | +| boxedAccountSizedInit4 | 16,967 | 🟢 **-1,263 (6.93%)** | +| boxedAccountSized4 | 1,996 | - | +| boxedAccountSizedInit8 | 33,161 | 🟢 **-2,392 (6.73%)** | +| boxedAccountSized8 | 3,628 | - | +| boxedAccountUnsizedInit1 | 5,072 | 🟢 **-299 (5.57%)** | +| boxedAccountUnsized1 | 836 | - | +| boxedAccountUnsizedInit2 | 9,128 | 🟢 **-631 (6.47%)** | +| boxedAccountUnsized2 | 1,270 | - | +| boxedAccountUnsizedInit4 | 17,295 | 🟢 **-1,263 (6.81%)** | +| boxedAccountUnsized4 | 2,132 | - | +| boxedAccountUnsizedInit8 | 33,793 | 🟢 **-2,392 (6.61%)** | +| boxedAccountUnsized8 | 3,881 | - | +| boxedInterfaceAccountMint1 | 1,351 | - | +| boxedInterfaceAccountMint2 | 2,123 | - | +| boxedInterfaceAccountMint4 | 3,656 | - | +| boxedInterfaceAccountMint8 | 6,738 | - | +| boxedInterfaceAccountToken1 | 2,011 | - | +| boxedInterfaceAccountToken2 | 3,431 | - | +| boxedInterfaceAccountToken4 | 6,260 | - | +| boxedInterfaceAccountToken8 | 11,934 | - | +| interfaceAccountMint1 | 1,476 | - | +| interfaceAccountMint2 | 2,489 | - | +| interfaceAccountMint4 | 4,511 | - | +| interfaceAccountMint8 | 8,550 | - | +| interfaceAccountToken1 | 2,111 | - | +| interfaceAccountToken2 | 3,729 | - | +| interfaceAccountToken4 | 6,955 | - | +| interface1 | 769 | - | +| interface2 | 912 | - | +| interface4 | 1,189 | - | +| interface8 | 1,748 | - | +| program1 | 779 | - | +| program2 | 934 | 🔴 **+14 (1.52%)** | +| program4 | 1,221 | 🔴 **+28 (2.35%)** | +| program8 | 1,800 | 🔴 **+56 (3.21%)** | +| signer1 | 774 | - | +| signer2 | 1,064 | - | +| signer4 | 1,637 | - | +| signer8 | 2,788 | - | +| systemAccount1 | 796 | - | +| systemAccount2 | 1,096 | - | +| systemAccount4 | 1,689 | - | +| systemAccount8 | 2,880 | - | +| uncheckedAccount1 | 783 | - | +| uncheckedAccount2 | 1,056 | - | +| uncheckedAccount4 | 1,594 | - | +| uncheckedAccount8 | 2,679 | - | ### Notable changes diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 726ca29eee..af641df266 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1677,41 +1677,41 @@ "solanaVersion": "2.3.0", "result": { "binarySize": { - "bench": 966096 + "bench": 1046072 }, "computeUnits": { - "accountInfo1": 685, - "accountInfo2": 1053, - "accountInfo4": 1750, - "accountInfo8": 3135, + "accountInfo1": 723, + "accountInfo2": 1099, + "accountInfo4": 1796, + "accountInfo8": 3186, "accountEmptyInit1": 4915, - "accountEmpty1": 774, + "accountEmpty1": 790, "accountEmptyInit2": 8793, - "accountEmpty2": 1174, + "accountEmpty2": 1187, "accountEmptyInit4": 16495, "accountEmpty4": 1962, "accountEmptyInit8": 31997, "accountEmpty8": 3548, "accountSizedInit1": 5019, - "accountSized1": 813, + "accountSized1": 827, "accountSizedInit2": 8981, - "accountSized2": 1222, + "accountSized2": 1241, "accountSizedInit4": 16850, "accountSized4": 2046, "accountSizedInit8": 32653, "accountSized8": 3690, "accountUnsizedInit1": 5127, - "accountUnsized1": 853, + "accountUnsized1": 873, "accountUnsizedInit2": 9131, - "accountUnsized2": 1284, + "accountUnsized2": 1305, "accountUnsizedInit4": 17198, "accountUnsized4": 2147, "accountUnsizedInit8": 33324, "accountUnsized8": 3867, "boxedAccountEmptyInit1": 5007, - "boxedAccountEmpty1": 864, + "boxedAccountEmpty1": 881, "boxedAccountEmptyInit2": 8906, - "boxedAccountEmpty2": 1286, + "boxedAccountEmpty2": 1300, "boxedAccountEmptyInit4": 16648, "boxedAccountEmpty4": 2115, "boxedAccountEmptyInit8": 32231, @@ -1719,37 +1719,37 @@ "boxedAccountSizedInit1": 5103, "boxedAccountSized1": 912, "boxedAccountSizedInit2": 9075, - "boxedAccountSized2": 1337, + "boxedAccountSized2": 1352, "boxedAccountSizedInit4": 16960, "boxedAccountSized4": 2195, "boxedAccountSizedInit8": 32831, "boxedAccountSized8": 3935, "boxedAccountUnsizedInit1": 5202, - "boxedAccountUnsized1": 943, + "boxedAccountUnsized1": 960, "boxedAccountUnsizedInit2": 9251, - "boxedAccountUnsized2": 1392, + "boxedAccountUnsized2": 1408, "boxedAccountUnsizedInit4": 17284, "boxedAccountUnsized4": 2283, "boxedAccountUnsizedInit8": 33455, "boxedAccountUnsized8": 4089, - "boxedInterfaceAccountMint1": 1110, - "boxedInterfaceAccountMint2": 1534, + "boxedInterfaceAccountMint1": 1129, + "boxedInterfaceAccountMint2": 1553, "boxedInterfaceAccountMint4": 2370, "boxedInterfaceAccountMint8": 4064, - "boxedInterfaceAccountToken1": 1246, - "boxedInterfaceAccountToken2": 1794, + "boxedInterfaceAccountToken1": 1265, + "boxedInterfaceAccountToken2": 1813, "boxedInterfaceAccountToken4": 2878, "boxedInterfaceAccountToken8": 5068, - "interfaceAccountMint1": 1126, - "interfaceAccountMint2": 1562, - "interfaceAccountMint4": 2432, - "interfaceAccountMint8": 4163, - "interfaceAccountToken1": 1268, - "interfaceAccountToken2": 1849, - "interfaceAccountToken4": 2997, - "interface1": 878, - "interface2": 1023, - "interface4": 1301, + "interfaceAccountMint1": 1165, + "interfaceAccountMint2": 1604, + "interfaceAccountMint4": 2476, + "interfaceAccountMint8": 4216, + "interfaceAccountToken1": 1317, + "interfaceAccountToken2": 1896, + "interfaceAccountToken4": 3048, + "interface1": 894, + "interface2": 1036, + "interface4": 1318, "interface8": 1867, "program1": 914, "program2": 1064, From 6f0944f04771a1513e2fae9a22a26aec300c78d2 Mon Sep 17 00:00:00 2001 From: swaroop-osec Date: Sat, 29 Nov 2025 09:05:03 +0530 Subject: [PATCH 39/39] chore: Update benchmarks --- bench/BINARY_SIZE.md | 6 +-- bench/COMPUTE_UNITS.md | 114 +++++++++++++++++++-------------------- bench/STACK_MEMORY.md | 91 ++++++++++++++++++++++++++++++- tests/bench/bench.json | 118 ++++++++++++++++++++--------------------- 4 files changed, 208 insertions(+), 121 deletions(-) diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index 5ea8ca8681..320b5ad865 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -16,9 +16,9 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Program | Binary Size | - | -| ------- | ----------- | ------------------------ | -| bench | 932,424 | 🟢 **-194,416 (17.25%)** | +| Program | Binary Size | - | +| ------- | ----------- | ----------------------- | +| bench | 1,015,624 | 🟢 **-111,216 (9.87%)** | ### Notable changes diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 5d3134b461..00bf4fb2b3 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -18,93 +18,93 @@ Solana version: 2.3.0 | Instruction | Compute Units | - | | --------------------------- | ------------- | --------------------- | -| accountInfo1 | 702 | 🔴 **+17 (2.48%)** | -| accountInfo2 | 1,124 | 🔴 **+71 (6.74%)** | -| accountInfo4 | 1,921 | 🔴 **+171 (9.77%)** | -| accountInfo8 | 3,480 | 🔴 **+345 (11.00%)** | +| accountInfo1 | 760 | 🔴 **+75 (10.95%)** | +| accountInfo2 | 1,180 | 🔴 **+127 (12.06%)** | +| accountInfo4 | 1,952 | 🔴 **+202 (11.54%)** | +| accountInfo8 | 3,530 | 🔴 **+395 (12.60%)** | | accountEmptyInit1 | 4,770 | 🟢 **-145 (2.95%)** | -| accountEmpty1 | 738 | 🟢 **-36 (4.65%)** | +| accountEmpty1 | 773 | 🟢 **-1 (0.13%)** | | accountEmptyInit2 | 8,487 | 🟢 **-306 (3.48%)** | -| accountEmpty2 | 1,138 | 🟢 **-36 (3.07%)** | +| accountEmpty2 | 1,173 | 🟢 **-1 (0.09%)** | | accountEmptyInit4 | 15,915 | 🟢 **-833 (4.97%)** | -| accountEmpty4 | 1,923 | 🟢 **-39 (1.99%)** | +| accountEmpty4 | 1,960 | 🟢 **-2 (0.10%)** | | accountEmptyInit8 | 30,779 | 🟢 **-1,578 (4.88%)** | -| accountEmpty8 | 3,500 | 🟢 **-48 (1.35%)** | +| accountEmpty8 | 3,539 | 🟢 **-9 (0.25%)** | | accountSizedInit1 | 4,864 | 🟢 **-155 (3.09%)** | -| accountSized1 | 786 | 🟢 **-36 (4.38%)** | +| accountSized1 | 820 | 🟢 **-2 (0.24%)** | | accountSizedInit2 | 8,654 | 🟢 **-327 (3.64%)** | -| accountSized2 | 1,198 | 🟢 **-42 (3.39%)** | +| accountSized2 | 1,236 | 🟢 **-4 (0.32%)** | | accountSizedInit4 | 16,236 | 🟢 **-918 (5.35%)** | -| accountSized4 | 2,031 | 🟢 **-51 (2.45%)** | +| accountSized4 | 2,070 | 🟢 **-12 (0.58%)** | | accountSizedInit8 | 31,363 | 🟢 **-1,650 (5.00%)** | -| accountSized8 | 3,694 | 🟢 **-68 (1.81%)** | +| accountSized8 | 3,731 | 🟢 **-31 (0.82%)** | | accountUnsizedInit1 | 4,967 | 🟢 **-160 (3.12%)** | -| accountUnsized1 | 814 | 🟢 **-60 (6.86%)** | +| accountUnsized1 | 854 | 🟢 **-20 (2.29%)** | | accountUnsizedInit2 | 8,841 | 🟢 **-410 (4.43%)** | -| accountUnsized2 | 1,240 | 🟢 **-86 (6.49%)** | +| accountUnsized2 | 1,281 | 🟢 **-45 (3.39%)** | | accountUnsizedInit4 | 16,559 | 🟢 **-819 (4.71%)** | -| accountUnsized4 | 2,093 | 🟢 **-138 (6.19%)** | +| accountUnsized4 | 2,134 | 🟢 **-97 (4.35%)** | | accountUnsizedInit8 | 31,985 | 🟢 **-1,976 (5.82%)** | -| accountUnsized8 | 3,797 | 🟢 **-238 (5.90%)** | +| accountUnsized8 | 3,837 | 🟢 **-198 (4.91%)** | | boxedAccountEmptyInit1 | 4,864 | 🟢 **-143 (2.86%)** | -| boxedAccountEmpty1 | 831 | 🟢 **-33 (3.82%)** | +| boxedAccountEmpty1 | 864 | - | | boxedAccountEmptyInit2 | 8,604 | 🟢 **-302 (3.39%)** | -| boxedAccountEmpty2 | 1,253 | 🟢 **-33 (2.57%)** | +| boxedAccountEmpty2 | 1,285 | 🟢 **-1 (0.08%)** | | boxedAccountEmptyInit4 | 16,075 | 🟢 **-827 (4.89%)** | -| boxedAccountEmpty4 | 2,077 | 🟢 **-38 (1.80%)** | +| boxedAccountEmpty4 | 2,112 | 🟢 **-3 (0.14%)** | | boxedAccountEmptyInit8 | 31,026 | 🟢 **-1,565 (4.80%)** | | boxedAccountEmpty8 | 3,797 | 🟢 **-4 (0.11%)** | | boxedAccountSizedInit1 | 4,952 | 🟢 **-151 (2.96%)** | -| boxedAccountSized1 | 877 | 🟢 **-35 (3.84%)** | +| boxedAccountSized1 | 913 | 🔴 **+1 (0.11%)** | | boxedAccountSizedInit2 | 8,756 | 🟢 **-319 (3.52%)** | -| boxedAccountSized2 | 1,318 | 🟢 **-37 (2.73%)** | +| boxedAccountSized2 | 1,351 | 🟢 **-4 (0.30%)** | | boxedAccountSizedInit4 | 16,355 | 🟢 **-859 (4.99%)** | -| boxedAccountSized4 | 2,185 | 🟢 **-46 (2.06%)** | +| boxedAccountSized4 | 2,218 | 🟢 **-13 (0.58%)** | | boxedAccountSizedInit8 | 31,562 | 🟢 **-1,959 (5.84%)** | | boxedAccountSized8 | 3,984 | 🟢 **-23 (0.57%)** | | boxedAccountUnsizedInit1 | 5,044 | 🟢 **-158 (3.04%)** | -| boxedAccountUnsized1 | 907 | 🟢 **-57 (5.91%)** | +| boxedAccountUnsized1 | 943 | 🟢 **-21 (2.18%)** | | boxedAccountUnsizedInit2 | 8,916 | 🟢 **-335 (3.62%)** | -| boxedAccountUnsized2 | 1,352 | 🟢 **-82 (5.72%)** | +| boxedAccountUnsized2 | 1,386 | 🟢 **-48 (3.35%)** | | boxedAccountUnsizedInit4 | 16,651 | 🟢 **-891 (5.08%)** | -| boxedAccountUnsized4 | 2,234 | 🟢 **-133 (5.62%)** | +| boxedAccountUnsized4 | 2,270 | 🟢 **-97 (4.10%)** | | boxedAccountUnsizedInit8 | 32,130 | 🟢 **-2,023 (5.92%)** | | boxedAccountUnsized8 | 4,063 | 🟢 **-194 (4.56%)** | -| boxedInterfaceAccountMint1 | 1,092 | 🟢 **-18 (1.62%)** | -| boxedInterfaceAccountMint2 | 1,490 | 🟢 **-44 (2.87%)** | -| boxedInterfaceAccountMint4 | 2,276 | 🟢 **-94 (3.97%)** | +| boxedInterfaceAccountMint1 | 1,128 | 🔴 **+18 (1.62%)** | +| boxedInterfaceAccountMint2 | 1,523 | 🟢 **-11 (0.72%)** | +| boxedInterfaceAccountMint4 | 2,307 | 🟢 **-63 (2.66%)** | | boxedInterfaceAccountMint8 | 3,907 | 🟢 **-157 (3.86%)** | -| boxedInterfaceAccountToken1 | 1,219 | 🟢 **-27 (2.17%)** | -| boxedInterfaceAccountToken2 | 1,732 | 🟢 **-62 (3.46%)** | -| boxedInterfaceAccountToken4 | 2,748 | 🟢 **-130 (4.52%)** | +| boxedInterfaceAccountToken1 | 1,255 | 🔴 **+9 (0.72%)** | +| boxedInterfaceAccountToken2 | 1,765 | 🟢 **-29 (1.62%)** | +| boxedInterfaceAccountToken4 | 2,779 | 🟢 **-99 (3.44%)** | | boxedInterfaceAccountToken8 | 4,839 | 🟢 **-229 (4.52%)** | -| interfaceAccountMint1 | 1,107 | 🟢 **-19 (1.69%)** | -| interfaceAccountMint2 | 1,494 | 🟢 **-68 (4.35%)** | -| interfaceAccountMint4 | 2,276 | 🟢 **-156 (6.41%)** | +| interfaceAccountMint1 | 1,145 | 🔴 **+19 (1.69%)** | +| interfaceAccountMint2 | 1,533 | 🟢 **-29 (1.86%)** | +| interfaceAccountMint4 | 2,313 | 🟢 **-119 (4.89%)** | | interfaceAccountMint8 | 3,835 | 🟢 **-328 (7.88%)** | -| interfaceAccountToken1 | 1,239 | 🟢 **-29 (2.29%)** | -| interfaceAccountToken2 | 1,753 | 🟢 **-96 (5.19%)** | -| interfaceAccountToken4 | 2,783 | 🟢 **-214 (7.14%)** | -| interface1 | 883 | 🔴 **+5 (0.57%)** | -| interface2 | 1,029 | 🔴 **+6 (0.59%)** | -| interface4 | 1,308 | 🔴 **+7 (0.54%)** | -| interface8 | 1,887 | 🔴 **+20 (1.07%)** | -| program1 | 899 | 🔴 **+9 (1.01%)** | -| program2 | 1,049 | 🔴 **+14 (1.35%)** | -| program4 | 1,336 | 🔴 **+23 (1.75%)** | -| program8 | 1,917 | 🔴 **+38 (2.02%)** | -| signer1 | 888 | 🔴 **+14 (1.60%)** | -| signer2 | 1,244 | 🔴 **+71 (6.05%)** | -| signer4 | 1,904 | 🔴 **+145 (8.24%)** | -| signer8 | 3,293 | 🔴 **+352 (11.97%)** | -| systemAccount1 | 910 | 🟢 **-1 (0.11%)** | -| systemAccount2 | 1,269 | 🔴 **+34 (2.75%)** | -| systemAccount4 | 1,972 | 🔴 **+101 (5.40%)** | -| systemAccount8 | 3,385 | 🔴 **+232 (7.36%)** | -| uncheckedAccount1 | 896 | 🔴 **+14 (1.59%)** | -| uncheckedAccount2 | 1,233 | 🔴 **+71 (6.11%)** | -| uncheckedAccount4 | 1,861 | 🔴 **+145 (8.45%)** | -| uncheckedAccount8 | 3,171 | 🔴 **+338 (11.93%)** | +| interfaceAccountToken1 | 1,279 | 🔴 **+11 (0.87%)** | +| interfaceAccountToken2 | 1,792 | 🟢 **-57 (3.08%)** | +| interfaceAccountToken4 | 2,825 | 🟢 **-172 (5.74%)** | +| interface1 | 918 | 🔴 **+40 (4.56%)** | +| interface2 | 1,064 | 🔴 **+41 (4.01%)** | +| interface4 | 1,345 | 🔴 **+44 (3.38%)** | +| interface8 | 1,912 | 🔴 **+45 (2.41%)** | +| program1 | 934 | 🔴 **+44 (4.94%)** | +| program2 | 1,084 | 🔴 **+49 (4.73%)** | +| program4 | 1,373 | 🔴 **+60 (4.57%)** | +| program8 | 1,956 | 🔴 **+77 (4.10%)** | +| signer1 | 923 | 🔴 **+49 (5.61%)** | +| signer2 | 1,272 | 🔴 **+99 (8.44%)** | +| signer4 | 1,957 | 🔴 **+198 (11.26%)** | +| signer8 | 3,332 | 🔴 **+391 (13.29%)** | +| systemAccount1 | 945 | 🔴 **+34 (3.73%)** | +| systemAccount2 | 1,304 | 🔴 **+69 (5.59%)** | +| systemAccount4 | 2,009 | 🔴 **+138 (7.38%)** | +| systemAccount8 | 3,424 | 🔴 **+271 (8.59%)** | +| uncheckedAccount1 | 931 | 🔴 **+49 (5.56%)** | +| uncheckedAccount2 | 1,263 | 🔴 **+101 (8.69%)** | +| uncheckedAccount4 | 1,911 | 🔴 **+195 (11.36%)** | +| uncheckedAccount8 | 3,207 | 🔴 **+374 (13.20%)** | ### Notable changes diff --git a/bench/STACK_MEMORY.md b/bench/STACK_MEMORY.md index 96acf23cce..1ec4c55dcb 100644 --- a/bench/STACK_MEMORY.md +++ b/bench/STACK_MEMORY.md @@ -16,8 +16,95 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 2.3.0 -| Instruction | Stack Memory | - | -| ----------- | ------------ | --- | +| Instruction | Stack Memory | - | +| ------------------------------ | ------------ | ------------------- | +| account_info1 | 46 | - | +| account_info2 | 88 | - | +| account_info4 | 88 | - | +| account_info8 | 88 | - | +| account_empty_init1 | 88 | - | +| account_empty_init2 | 88 | - | +| account_empty_init4 | 88 | - | +| account_empty_init8 | 88 | - | +| account_empty1 | 88 | - | +| account_empty2 | 88 | - | +| account_empty4 | 88 | - | +| account_empty8 | 88 | - | +| account_sized_init1 | 88 | - | +| account_sized_init2 | 88 | - | +| account_sized_init4 | 88 | - | +| account_sized_init8 | 88 | - | +| account_sized1 | 88 | - | +| account_sized2 | 88 | - | +| account_sized4 | 88 | - | +| account_sized8 | 88 | - | +| account_unsized_init1 | 88 | - | +| account_unsized_init2 | 88 | - | +| account_unsized_init4 | 88 | - | +| account_unsized_init8 | 88 | - | +| account_unsized1 | 88 | - | +| account_unsized2 | 88 | - | +| account_unsized4 | 88 | - | +| account_unsized8 | 88 | - | +| boxed_account_empty_init1 | 88 | - | +| boxed_account_empty_init2 | 88 | - | +| boxed_account_empty_init4 | 88 | - | +| boxed_account_empty_init8 | 88 | - | +| boxed_account_empty1 | 88 | - | +| boxed_account_empty2 | 88 | - | +| boxed_account_empty4 | 88 | - | +| boxed_account_empty8 | 96 | 🔴 **+8 (9.09%)** | +| boxed_account_sized_init1 | 88 | - | +| boxed_account_sized_init2 | 88 | - | +| boxed_account_sized_init4 | 88 | - | +| boxed_account_sized_init8 | 88 | - | +| boxed_account_sized1 | 88 | - | +| boxed_account_sized2 | 88 | - | +| boxed_account_sized4 | 88 | - | +| boxed_account_sized8 | 96 | 🔴 **+8 (9.09%)** | +| boxed_account_unsized_init1 | 88 | - | +| boxed_account_unsized_init2 | 88 | - | +| boxed_account_unsized_init4 | 88 | - | +| boxed_account_unsized_init8 | 88 | - | +| boxed_account_unsized1 | 88 | - | +| boxed_account_unsized2 | 88 | - | +| boxed_account_unsized4 | 88 | - | +| boxed_account_unsized8 | 96 | 🔴 **+8 (9.09%)** | +| boxed_interface_account_mint1 | 88 | - | +| boxed_interface_account_mint2 | 88 | - | +| boxed_interface_account_mint4 | 88 | - | +| boxed_interface_account_mint8 | 96 | 🔴 **+8 (9.09%)** | +| boxed_interface_account_token1 | 88 | - | +| boxed_interface_account_token2 | 88 | - | +| boxed_interface_account_token4 | 88 | - | +| boxed_interface_account_token8 | 96 | 🔴 **+8 (9.09%)** | +| interface_account_mint1 | 88 | - | +| interface_account_mint2 | 88 | - | +| interface_account_mint4 | 88 | - | +| interface_account_mint8 | 88 | - | +| interface_account_token1 | 104 | 🔴 **+24 (30.00%)** | +| interface_account_token2 | 104 | 🔴 **+24 (30.00%)** | +| interface_account_token4 | 104 | 🔴 **+24 (30.00%)** | +| interface1 | 88 | - | +| interface2 | 88 | - | +| interface4 | 88 | - | +| interface8 | 88 | - | +| program1 | 88 | - | +| program2 | 88 | - | +| program4 | 88 | - | +| program8 | 88 | - | +| signer1 | 88 | - | +| signer2 | 88 | - | +| signer4 | 88 | - | +| signer8 | 88 | - | +| system_account1 | 88 | - | +| system_account2 | 88 | - | +| system_account4 | 88 | - | +| system_account8 | 88 | - | +| unchecked_account1 | 88 | - | +| unchecked_account2 | 88 | - | +| unchecked_account4 | 88 | - | +| unchecked_account8 | 88 | - | ### Notable changes diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 6f30f0136b..6b4fb34bf1 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -1677,96 +1677,96 @@ "solanaVersion": "2.3.0", "result": { "binarySize": { - "bench": 932424 + "bench": 1015624 }, "computeUnits": { - "accountInfo1": 702, - "accountInfo2": 1124, - "accountInfo4": 1921, - "accountInfo8": 3480, + "accountInfo1": 760, + "accountInfo2": 1180, + "accountInfo4": 1952, + "accountInfo8": 3530, "accountEmptyInit1": 4770, - "accountEmpty1": 738, + "accountEmpty1": 773, "accountEmptyInit2": 8487, - "accountEmpty2": 1138, + "accountEmpty2": 1173, "accountEmptyInit4": 15915, - "accountEmpty4": 1923, + "accountEmpty4": 1960, "accountEmptyInit8": 30779, - "accountEmpty8": 3500, + "accountEmpty8": 3539, "accountSizedInit1": 4864, - "accountSized1": 786, + "accountSized1": 820, "accountSizedInit2": 8654, - "accountSized2": 1198, + "accountSized2": 1236, "accountSizedInit4": 16236, - "accountSized4": 2031, + "accountSized4": 2070, "accountSizedInit8": 31363, - "accountSized8": 3694, + "accountSized8": 3731, "accountUnsizedInit1": 4967, - "accountUnsized1": 814, + "accountUnsized1": 854, "accountUnsizedInit2": 8841, - "accountUnsized2": 1240, + "accountUnsized2": 1281, "accountUnsizedInit4": 16559, - "accountUnsized4": 2093, + "accountUnsized4": 2134, "accountUnsizedInit8": 31985, - "accountUnsized8": 3797, + "accountUnsized8": 3837, "boxedAccountEmptyInit1": 4864, - "boxedAccountEmpty1": 831, + "boxedAccountEmpty1": 864, "boxedAccountEmptyInit2": 8604, - "boxedAccountEmpty2": 1253, + "boxedAccountEmpty2": 1285, "boxedAccountEmptyInit4": 16075, - "boxedAccountEmpty4": 2077, + "boxedAccountEmpty4": 2112, "boxedAccountEmptyInit8": 31026, "boxedAccountEmpty8": 3797, "boxedAccountSizedInit1": 4952, - "boxedAccountSized1": 877, + "boxedAccountSized1": 913, "boxedAccountSizedInit2": 8756, - "boxedAccountSized2": 1318, + "boxedAccountSized2": 1351, "boxedAccountSizedInit4": 16355, - "boxedAccountSized4": 2185, + "boxedAccountSized4": 2218, "boxedAccountSizedInit8": 31562, "boxedAccountSized8": 3984, "boxedAccountUnsizedInit1": 5044, - "boxedAccountUnsized1": 907, + "boxedAccountUnsized1": 943, "boxedAccountUnsizedInit2": 8916, - "boxedAccountUnsized2": 1352, + "boxedAccountUnsized2": 1386, "boxedAccountUnsizedInit4": 16651, - "boxedAccountUnsized4": 2234, + "boxedAccountUnsized4": 2270, "boxedAccountUnsizedInit8": 32130, "boxedAccountUnsized8": 4063, - "boxedInterfaceAccountMint1": 1092, - "boxedInterfaceAccountMint2": 1490, - "boxedInterfaceAccountMint4": 2276, + "boxedInterfaceAccountMint1": 1128, + "boxedInterfaceAccountMint2": 1523, + "boxedInterfaceAccountMint4": 2307, "boxedInterfaceAccountMint8": 3907, - "boxedInterfaceAccountToken1": 1219, - "boxedInterfaceAccountToken2": 1732, - "boxedInterfaceAccountToken4": 2748, + "boxedInterfaceAccountToken1": 1255, + "boxedInterfaceAccountToken2": 1765, + "boxedInterfaceAccountToken4": 2779, "boxedInterfaceAccountToken8": 4839, - "interfaceAccountMint1": 1107, - "interfaceAccountMint2": 1494, - "interfaceAccountMint4": 2276, + "interfaceAccountMint1": 1145, + "interfaceAccountMint2": 1533, + "interfaceAccountMint4": 2313, "interfaceAccountMint8": 3835, - "interfaceAccountToken1": 1239, - "interfaceAccountToken2": 1753, - "interfaceAccountToken4": 2783, - "interface1": 883, - "interface2": 1029, - "interface4": 1308, - "interface8": 1887, - "program1": 899, - "program2": 1049, - "program4": 1336, - "program8": 1917, - "signer1": 888, - "signer2": 1244, - "signer4": 1904, - "signer8": 3293, - "systemAccount1": 910, - "systemAccount2": 1269, - "systemAccount4": 1972, - "systemAccount8": 3385, - "uncheckedAccount1": 896, - "uncheckedAccount2": 1233, - "uncheckedAccount4": 1861, - "uncheckedAccount8": 3171 + "interfaceAccountToken1": 1279, + "interfaceAccountToken2": 1792, + "interfaceAccountToken4": 2825, + "interface1": 918, + "interface2": 1064, + "interface4": 1345, + "interface8": 1912, + "program1": 934, + "program2": 1084, + "program4": 1373, + "program8": 1956, + "signer1": 923, + "signer2": 1272, + "signer4": 1957, + "signer8": 3332, + "systemAccount1": 945, + "systemAccount2": 1304, + "systemAccount4": 2009, + "systemAccount8": 3424, + "uncheckedAccount1": 931, + "uncheckedAccount2": 1263, + "uncheckedAccount4": 1911, + "uncheckedAccount8": 3207 }, "stackMemory": { "account_info1": 46, @@ -1859,4 +1859,4 @@ } } } -} +} \ No newline at end of file