Skip to content

Commit

Permalink
lang: Add executable account constraint (#140)
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante committed Apr 3, 2021
1 parent 7f2ef23 commit d6d41ee
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ incremented for features.
* lang, client, ts: Add event emission and subscriptions ([#89](https://github.com/project-serum/anchor/pull/89)).
* lang/account: Allow namespacing account discriminators ([#128](https://github.com/project-serum/anchor/pull/128)).
* cli: TypeScript migrations ([#132](https://github.com/project-serum/anchor/pull/132)).
* lang: Add `#[account(executable)]` attribute ([#140](https://github.com/project-serum/anchor/pull/140)).

## Breaking Changes

Expand Down
10 changes: 10 additions & 0 deletions examples/misc/programs/misc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ pub mod misc {
ctx.accounts.data.idata = idata;
Ok(())
}

pub fn test_executable(ctx: Context<TestExecutable>) -> ProgramResult {
Ok(())
}
}

#[derive(Accounts)]
Expand All @@ -39,6 +43,12 @@ pub struct Initialize<'info> {
rent: Sysvar<'info, Rent>,
}

#[derive(Accounts)]
pub struct TestExecutable<'info> {
#[account(executable)]
program: AccountInfo<'info>,
}

#[account]
pub struct Data {
udata: u128,
Expand Down
21 changes: 21 additions & 0 deletions examples/misc/tests/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,25 @@ describe("misc", () => {
let accInfo = await anchor.getProvider().connection.getAccountInfo(pid);
assert.ok(accInfo.executable);
});

it("Can use the executable attribtue", async () => {
await program.rpc.testExecutable({
accounts: {
program: program.programId,
},
});

await assert.rejects(
async () => {
await program.rpc.testExecutable({
accounts: {
program: program.provider.wallet.publicKey,
},
});
},
(err) => {
return true;
}
);
});
});
17 changes: 15 additions & 2 deletions lang/syn/src/codegen/accounts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
AccountField, AccountsStruct, CompositeField, Constraint, ConstraintBelongsTo,
ConstraintLiteral, ConstraintOwner, ConstraintRentExempt, ConstraintSeeds, ConstraintSigner,
Field, Ty,
ConstraintExecutable, ConstraintLiteral, ConstraintOwner, ConstraintRentExempt,
ConstraintSeeds, ConstraintSigner, Field, Ty,
};
use heck::SnakeCase;
use quote::quote;
Expand Down Expand Up @@ -305,6 +305,7 @@ pub fn generate_field_constraint(f: &Field, c: &Constraint) -> proc_macro2::Toke
Constraint::Owner(c) => generate_constraint_owner(f, c),
Constraint::RentExempt(c) => generate_constraint_rent_exempt(f, c),
Constraint::Seeds(c) => generate_constraint_seeds(f, c),
Constraint::Executable(c) => generate_constraint_executable(f, c),
}
}

Expand Down Expand Up @@ -411,3 +412,15 @@ pub fn generate_constraint_seeds(f: &Field, c: &ConstraintSeeds) -> proc_macro2:
}
}
}

pub fn generate_constraint_executable(
f: &Field,
_c: &ConstraintExecutable,
) -> proc_macro2::TokenStream {
let name = &f.ident;
quote! {
if !#name.to_account_info().executable {
return Err(anchor_lang::solana_program::program_error::ProgramError::Custom(5)) // todo
}
}
}
4 changes: 4 additions & 0 deletions lang/syn/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ pub enum Constraint {
Owner(ConstraintOwner),
RentExempt(ConstraintRentExempt),
Seeds(ConstraintSeeds),
Executable(ConstraintExecutable),
}

#[derive(Debug)]
Expand Down Expand Up @@ -303,6 +304,9 @@ pub struct ConstraintSeeds {
pub seeds: proc_macro2::Group,
}

#[derive(Debug)]
pub struct ConstraintExecutable {}

#[derive(Debug)]
pub struct Error {
pub name: String,
Expand Down
8 changes: 6 additions & 2 deletions lang/syn/src/parser/accounts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::{
AccountField, AccountsStruct, CompositeField, Constraint, ConstraintBelongsTo,
ConstraintLiteral, ConstraintOwner, ConstraintRentExempt, ConstraintSeeds, ConstraintSigner,
CpiAccountTy, Field, ProgramAccountTy, ProgramStateTy, SysvarTy, Ty,
ConstraintExecutable, ConstraintLiteral, ConstraintOwner, ConstraintRentExempt,
ConstraintSeeds, ConstraintSigner, CpiAccountTy, Field, ProgramAccountTy, ProgramStateTy,
SysvarTy, Ty,
};

pub fn parse(strct: &syn::ItemStruct) -> AccountsStruct {
Expand Down Expand Up @@ -270,6 +271,9 @@ fn parse_constraints(anchor: &syn::Attribute) -> (Vec<Constraint>, bool, bool, b
}
};
}
"executable" => {
constraints.push(Constraint::Executable(ConstraintExecutable {}));
}
_ => {
panic!("invalid syntax");
}
Expand Down

0 comments on commit d6d41ee

Please sign in to comment.