diff --git a/CHANGELOG.md b/CHANGELOG.md index 1737e4a90c..9610e4374b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ incremented for features. * lang: Put `init_if_needed` behind a feature flag to decrease wrong usage ([#1258](https://github.com/project-serum/anchor/pull/1258)). * lang: rename `loader_account` module to `account_loader` module ([#1279](https://github.com/project-serum/anchor/pull/1279)) * lang: The `Accounts` trait's `try_accounts` method now has an additional `bumps: &mut BTreeMap` argument, which accumulates bump seeds ([#1367](https://github.com/project-serum/anchor/pull/1367)). +* lang: Providing `bump = ` targets with `init` will now error. On `init` only, it is required to use `bump` without a target and access the seed inside function handlers via `ctx.bumps.get("` target to minimize compute units used ([#1380](https://github.com/project-serum/anchor/pull/1380)). * ts: `Coder` is now an interface and the existing class has been renamed to `BorshCoder`. This change allows the generation of Anchor clients for non anchor programs ([#1259](https://github.com/project-serum/anchor/pull/1259/files)). * cli: [[test.clone]] key in Anchor.toml is renamed to [[test.validator.clone]] ([#1366](https://github.com/project-serum/anchor/pull/1366)). diff --git a/lang/syn/src/parser/accounts/constraints.rs b/lang/syn/src/parser/accounts/constraints.rs index ed2500ed15..533d5053fc 100644 --- a/lang/syn/src/parser/accounts/constraints.rs +++ b/lang/syn/src/parser/accounts/constraints.rs @@ -414,6 +414,16 @@ impl<'ty> ConstraintGroupBuilder<'ty> { self.signer .replace(Context::new(i.span(), ConstraintSigner { error: None })); } + + // Assert a bump target is not given on init. + if let Some(b) = &self.bump { + if b.bump.is_some() { + return Err(ParseError::new( + b.span(), + "bump targets should not be provided with init. Please use bump without a target." + )); + } + } } // Zero. diff --git a/tests/cfo/programs/cfo/src/lib.rs b/tests/cfo/programs/cfo/src/lib.rs index 53ed6cb440..079b3f089a 100644 --- a/tests/cfo/programs/cfo/src/lib.rs +++ b/tests/cfo/programs/cfo/src/lib.rs @@ -322,14 +322,14 @@ pub struct CreateOfficer<'info> { #[account( init, seeds = [dex_program.key.as_ref()], - bump = bumps.bump, + bump, payer = authority, )] officer: Box>, #[account( init, seeds = [b"token", officer.key().as_ref(), srm_mint.key().as_ref()], - bump = bumps.srm, + bump, payer = authority, token::mint = srm_mint, token::authority = officer, @@ -338,7 +338,7 @@ pub struct CreateOfficer<'info> { #[account( init, seeds = [b"token", officer.key().as_ref(), usdc_mint.key().as_ref()], - bump = bumps.usdc, + bump, payer = authority, token::mint = usdc_mint, token::authority = officer, @@ -347,7 +347,7 @@ pub struct CreateOfficer<'info> { #[account( init, seeds = [b"stake", officer.key().as_ref()], - bump = bumps.stake, + bump, payer = authority, token::mint = srm_mint, token::authority = officer, @@ -356,7 +356,7 @@ pub struct CreateOfficer<'info> { #[account( init, seeds = [b"treasury", officer.key().as_ref()], - bump = bumps.treasury, + bump, payer = authority, token::mint = srm_mint, token::authority = officer, @@ -390,7 +390,7 @@ pub struct AuthorizeMarket<'info> { init, payer = payer, seeds = [b"market-auth", officer.key().as_ref(), market.key.as_ref()], - bump = bump, + bump, )] market_auth: Account<'info, MarketAuth>, payer: Signer<'info>, @@ -416,7 +416,7 @@ pub struct CreateOfficerToken<'info> { #[account( init, seeds = [b"token", officer.key().as_ref(), mint.key().as_ref()], - bump = bump, + bump, token::mint = mint, token::authority = officer, payer = payer, @@ -437,7 +437,7 @@ pub struct CreateOfficerOpenOrders<'info> { #[account( init, seeds = [b"open-orders", officer.key().as_ref(), market.key.as_ref()], - bump = bump, + bump, space = 12 + size_of::(), payer = payer, owner = dex::ID, diff --git a/tests/chat/programs/chat/src/lib.rs b/tests/chat/programs/chat/src/lib.rs index bb6a897ef3..40fac7f89c 100644 --- a/tests/chat/programs/chat/src/lib.rs +++ b/tests/chat/programs/chat/src/lib.rs @@ -1,7 +1,7 @@ //! A simple chat program using a ring buffer to store messages. -use anchor_lang::prelude::*; use anchor_lang::accounts::loader::Loader; +use anchor_lang::prelude::*; declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); @@ -9,10 +9,10 @@ declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); pub mod chat { use super::*; - pub fn create_user(ctx: Context, name: String, bump: u8) -> Result<()> { + pub fn create_user(ctx: Context, name: String) -> Result<()> { ctx.accounts.user.name = name; ctx.accounts.user.authority = *ctx.accounts.authority.key; - ctx.accounts.user.bump = bump; + ctx.accounts.user.bump = *ctx.bumps.get("user").unwrap(); Ok(()) } pub fn create_chat_room(ctx: Context, name: String) -> Result<()> { @@ -39,12 +39,12 @@ pub mod chat { } #[derive(Accounts)] -#[instruction(name: String, bump: u8)] +#[instruction(name: String)] pub struct CreateUser<'info> { #[account( init, seeds = [authority.key().as_ref()], - bump = bump, + bump, payer = authority, space = 320, )] diff --git a/tests/chat/tests/chat.js b/tests/chat/tests/chat.js index c858aa1fee..65e80af9f0 100644 --- a/tests/chat/tests/chat.js +++ b/tests/chat/tests/chat.js @@ -38,7 +38,7 @@ describe("chat", () => { [authority.toBuffer()], program.programId ); - await program.rpc.createUser("My User", bump, { + await program.rpc.createUser("My User", { accounts: { user, authority, diff --git a/tests/ido-pool/programs/ido-pool/src/lib.rs b/tests/ido-pool/programs/ido-pool/src/lib.rs index b5a164d24f..e49fe0f251 100644 --- a/tests/ido-pool/programs/ido-pool/src/lib.rs +++ b/tests/ido-pool/programs/ido-pool/src/lib.rs @@ -19,7 +19,7 @@ pub mod ido_pool { pub fn initialize_pool( ctx: Context, ido_name: String, - bumps: PoolBumps, + _bumps: PoolBumps, // No longer used. num_ido_tokens: u64, ido_times: IdoTimes, ) -> ProgramResult { @@ -32,7 +32,12 @@ pub mod ido_pool { name_data[..name_bytes.len()].copy_from_slice(name_bytes); ido_account.ido_name = name_data; - ido_account.bumps = bumps; + ido_account.bumps = PoolBumps { + ido_account: *ctx.bumps.get("ido_account").unwrap(), + redeemable_mint: *ctx.bumps.get("redeemable_mint").unwrap(), + pool_watermelon: *ctx.bumps.get("pool_watermelon").unwrap(), + pool_usdc: *ctx.bumps.get("pool_usdc").unwrap(), + }; ido_account.ido_authority = ctx.accounts.ido_authority.key(); ido_account.usdc_mint = ctx.accounts.usdc_mint.key(); @@ -289,7 +294,7 @@ pub struct InitializePool<'info> { // IDO Accounts #[account(init, seeds = [ido_name.as_bytes()], - bump = bumps.ido_account, + bump, payer = ido_authority)] pub ido_account: Box>, // TODO Confirm USDC mint address on mainnet or leave open as an option for other stables @@ -299,7 +304,7 @@ pub struct InitializePool<'info> { mint::decimals = DECIMALS, mint::authority = ido_account, seeds = [ido_name.as_bytes(), b"redeemable_mint".as_ref()], - bump = bumps.redeemable_mint, + bump, payer = ido_authority)] pub redeemable_mint: Box>, #[account(constraint = watermelon_mint.key() == ido_authority_watermelon.mint)] @@ -308,14 +313,14 @@ pub struct InitializePool<'info> { token::mint = watermelon_mint, token::authority = ido_account, seeds = [ido_name.as_bytes(), b"pool_watermelon"], - bump = bumps.pool_watermelon, + bump, payer = ido_authority)] pub pool_watermelon: Box>, #[account(init, token::mint = usdc_mint, token::authority = ido_account, seeds = [ido_name.as_bytes(), b"pool_usdc"], - bump = bumps.pool_usdc, + bump, payer = ido_authority)] pub pool_usdc: Box>, // Programs and Sysvars diff --git a/tests/misc/programs/misc/src/context.rs b/tests/misc/programs/misc/src/context.rs index 64ec51d5b2..e27ec8c880 100644 --- a/tests/misc/programs/misc/src/context.rs +++ b/tests/misc/programs/misc/src/context.rs @@ -1,19 +1,18 @@ use crate::account::*; -use anchor_lang::prelude::*; -use anchor_lang::accounts::loader::Loader; use anchor_lang::accounts::cpi_state::CpiState; +use anchor_lang::accounts::loader::Loader; +use anchor_lang::prelude::*; use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token::{Mint, Token, TokenAccount}; use misc2::misc2::MyState as Misc2State; use std::mem::size_of; #[derive(Accounts)] -#[instruction(token_bump: u8, mint_bump: u8)] pub struct TestTokenSeedsInit<'info> { #[account( init, seeds = [b"my-mint-seed".as_ref()], - bump = mint_bump, + bump, payer = authority, mint::decimals = 6, mint::authority = authority, @@ -22,7 +21,7 @@ pub struct TestTokenSeedsInit<'info> { #[account( init, seeds = [b"my-token-seed".as_ref(),], - bump = token_bump, + bump, payer = authority, token::mint = mint, token::authority = authority, @@ -79,7 +78,7 @@ pub struct TestPdaInit<'info> { #[account( init, seeds = [b"my-seed", domain.as_bytes(), foo.key.as_ref(), &seed], - bump = bump, + bump, payer = my_payer, )] pub my_pda: Account<'info, DataU16>, @@ -89,12 +88,11 @@ pub struct TestPdaInit<'info> { } #[derive(Accounts)] -#[instruction(bump: u8)] pub struct TestPdaInitZeroCopy<'info> { #[account( init, seeds = [b"my-seed".as_ref()], - bump = bump, + bump, payer = my_payer, )] pub my_pda: Loader<'info, DataZeroCopy>, @@ -367,7 +365,7 @@ pub struct InitDecreaseLamports<'info> { pub data: AccountInfo<'info>, #[account(mut)] pub user: Signer<'info>, - pub system_program: Program<'info, System> + pub system_program: Program<'info, System>, } #[derive(Accounts)] @@ -376,7 +374,7 @@ pub struct InitIfNeededChecksRentExemption<'info> { pub data: AccountInfo<'info>, #[account(mut)] pub user: Signer<'info>, - pub system_program: Program<'info, System> + pub system_program: Program<'info, System>, } #[derive(Accounts)] diff --git a/tests/misc/programs/misc/src/lib.rs b/tests/misc/programs/misc/src/lib.rs index 9b7df57aec..0f5e31f6f8 100644 --- a/tests/misc/programs/misc/src/lib.rs +++ b/tests/misc/programs/misc/src/lib.rs @@ -121,10 +121,10 @@ pub mod misc { Ok(()) } - pub fn test_pda_init_zero_copy(ctx: Context, bump: u8) -> ProgramResult { + pub fn test_pda_init_zero_copy(ctx: Context) -> ProgramResult { let mut acc = ctx.accounts.my_pda.load_init()?; acc.data = 9; - acc.bump = bump; + acc.bump = *ctx.bumps.get("my_pda").unwrap(); Ok(()) } @@ -134,11 +134,7 @@ pub mod misc { Ok(()) } - pub fn test_token_seeds_init( - _ctx: Context, - _token_bump: u8, - _mint_bump: u8, - ) -> ProgramResult { + pub fn test_token_seeds_init(_ctx: Context) -> ProgramResult { Ok(()) } @@ -264,15 +260,17 @@ pub mod misc { **ctx.accounts.user.try_borrow_mut_lamports()? += 1; Ok(()) } - - pub fn init_if_needed_checks_rent_exemption(_ctx: Context) -> ProgramResult { + + pub fn init_if_needed_checks_rent_exemption( + _ctx: Context, + ) -> ProgramResult { Ok(()) } - + pub fn test_program_id_constraint( _ctx: Context, _bump: u8, - _second_bump: u8 + _second_bump: u8, ) -> ProgramResult { Ok(()) } diff --git a/tests/misc/tests/misc.js b/tests/misc/tests/misc.js index 96bf281e2c..fc1b7983d6 100644 --- a/tests/misc/tests/misc.js +++ b/tests/misc/tests/misc.js @@ -307,7 +307,7 @@ describe("misc", () => { [Buffer.from(anchor.utils.bytes.utf8.encode("my-seed"))], program.programId ); - await program.rpc.testPdaInitZeroCopy(nonce, { + await program.rpc.testPdaInitZeroCopy({ accounts: { myPda, myPayer: program.provider.wallet.publicKey, @@ -347,7 +347,7 @@ describe("misc", () => { [Buffer.from(anchor.utils.bytes.utf8.encode("my-token-seed"))], program.programId ); - await program.rpc.testTokenSeedsInit(token_bump, mint_bump, { + await program.rpc.testTokenSeedsInit({ accounts: { myPda, mint, diff --git a/ts/src/utils/features.ts b/ts/src/utils/features.ts index 9fd8c8a374..246b2b99aa 100644 --- a/ts/src/utils/features.ts +++ b/ts/src/utils/features.ts @@ -1,4 +1,4 @@ -const _AVAILABLE_FEATURES = new Set(["anchor-deprecated-state"]); +const _AVAILABLE_FEATURES = new Set(["anchor-deprecated-state", "debug-logs"]); const _FEATURES = new Map();