Skip to content

Commit

Permalink
lang: Support empty seeds constraint token (coral-xyz#853)
Browse files Browse the repository at this point in the history
  • Loading branch information
cqfd authored Oct 9, 2021
1 parent d5fe928 commit d774b45
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 7 deletions.
25 changes: 18 additions & 7 deletions lang/syn/src/codegen/accounts/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,24 +287,27 @@ fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_ma
if let Some(pair) = s.pop() {
s.push_value(pair.into_value());
}
let maybe_seeds_plus_comma = (!s.is_empty()).then(|| {
quote! { #s, }
});
let inner = match c.bump.as_ref() {
// Bump target not given. Use the canonical bump.
None => {
quote! {
[
#s,
#maybe_seeds_plus_comma
&[
Pubkey::find_program_address(
&[#s],
program_id,
).1
]
][..]
]
}
}
// Bump target given. Use it.
Some(b) => quote! {
[#s, &[#b]]
[#maybe_seeds_plus_comma &[#b][..]]
},
};
quote! {
Expand All @@ -317,7 +320,12 @@ fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_ma

fn generate_constraint_seeds(f: &Field, c: &ConstraintSeedsGroup) -> proc_macro2::TokenStream {
let name = &f.ident;
let s = &c.seeds;
let s = &mut c.seeds.clone();
// If the seeds came with a trailing comma, we need to chop it off
// before we interpolate them below.
if let Some(pair) = s.pop() {
s.push_value(pair.into_value());
}

// If the bump is provided with init *and target*, then force it to be the
// canonical bump.
Expand All @@ -336,25 +344,28 @@ fn generate_constraint_seeds(f: &Field, c: &ConstraintSeedsGroup) -> proc_macro2
}
}
} else {
let maybe_seeds_plus_comma = (!s.is_empty()).then(|| {
quote! { #s, }
});
let seeds = match c.bump.as_ref() {
// Bump target not given. Find it.
None => {
quote! {
[
#s,
#maybe_seeds_plus_comma
&[
Pubkey::find_program_address(
&[#s],
program_id,
).1
]
][..]
]
}
}
// Bump target given. Use it.
Some(b) => {
quote! {
[#s, &[#b]]
[#maybe_seeds_plus_comma &[#b][..]]
}
}
};
Expand Down
14 changes: 14 additions & 0 deletions tests/misc/programs/misc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,17 @@ pub struct TestFetchAll<'info> {
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct TestInitWithEmptySeeds<'info> {
#[account(init, seeds = [], bump, payer = authority, space = 8 + size_of::<Data>())]
pub pda: Account<'info, Data>,
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct TestEmptySeedsConstraint<'info> {
#[account(seeds = [], bump)]
pub pda: AccountInfo<'info>,
}
8 changes: 8 additions & 0 deletions tests/misc/programs/misc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,12 @@ pub mod misc {
ctx.accounts.data.filterable = filterable;
Ok(())
}

pub fn test_init_with_empty_seeds(ctx: Context<TestInitWithEmptySeeds>) -> ProgramResult {
Ok(())
}

pub fn test_empty_seeds_constraint(ctx: Context<TestEmptySeedsConstraint>) -> ProgramResult {
Ok(())
}
}
30 changes: 30 additions & 0 deletions tests/misc/tests/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -770,4 +770,34 @@ describe("misc", () => {
// results in 1 account.
assert.equal(allAccountsFilteredByProgramFilters2.length, 1);
});

it("Can use pdas with empty seeds", async () => {
const [pda, bump] = await PublicKey.findProgramAddress([], program.programId);

await program.rpc.testInitWithEmptySeeds({
accounts: {
pda: pda,
authority: program.provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId
}
});
await program.rpc.testEmptySeedsConstraint({
accounts: {
pda: pda
}
});

const [pda2, bump2] = await PublicKey.findProgramAddress(["non-empty"], program.programId);
await assert.rejects(
program.rpc.testEmptySeedsConstraint({
accounts: {
pda: pda2
}
}),
(err) => {
assert.equal(err.code, 146);
return true;
}
);
});
});

0 comments on commit d774b45

Please sign in to comment.