Skip to content

Commit

Permalink
lang: Add Owner & Discriminator implementation for ix structures
Browse files Browse the repository at this point in the history
lang: Add into `Discriminator` trait constant `DISCRIMINATOR`

So that during match instructions or other entities there is no explicit instruction call of `discriminator()`

lang: Add `Owner` impl to instructions
  • Loading branch information
cyphersnake committed Nov 23, 2022
1 parent 52b32d2 commit 0b64d30
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- ts: SPL coders have been removed from the main Anchor package. ([#2155](https://github.com/coral-xyz/anchor/pull/2155))
- lang: Remove `rent` from constraints ([#2265](https://github.com/coral-xyz/anchor/pull/2265)).
- spl: Remove `rent` from `associated_token::Create` ([#2265](https://github.com/coral-xyz/anchor/pull/2265)).
- lang: Add `Discriminator` and `Owner` trait implementation for structures representing instructions ([#1997](https://github.com/coral-xyz/anchor/pull/1997))

## [0.25.0] - 2022-07-05

Expand Down
8 changes: 2 additions & 6 deletions lang/attribute/account/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,7 @@ pub fn account(

#[automatically_derived]
impl #impl_gen anchor_lang::Discriminator for #account_name #type_gen #where_clause {
fn discriminator() -> [u8; 8] {
#discriminator
}
const DISCRIMINATOR: [u8; 8] = #discriminator;
}

// This trait is useful for clients deserializing accounts.
Expand Down Expand Up @@ -211,9 +209,7 @@ pub fn account(

#[automatically_derived]
impl #impl_gen anchor_lang::Discriminator for #account_name #type_gen #where_clause {
fn discriminator() -> [u8; 8] {
#discriminator
}
const DISCRIMINATOR: [u8; 8] = #discriminator;
}

#owner_impl
Expand Down
4 changes: 1 addition & 3 deletions lang/attribute/event/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ pub fn event(
}

impl anchor_lang::Discriminator for #event_name {
fn discriminator() -> [u8; 8] {
#discriminator
}
const DISCRIMINATOR: [u8; 8] = #discriminator;
}
})
}
Expand Down
13 changes: 10 additions & 3 deletions lang/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,12 @@ pub trait ZeroCopy: Discriminator + Copy + Clone + Zeroable + Pod {}
/// `Sha256(<namespace>:<method_name>)[..8] || BorshSerialize(args)`.
/// `args` is a borsh serialized struct of named fields for each argument given
/// to an instruction.
pub trait InstructionData: AnchorSerialize {
fn data(&self) -> Vec<u8>;
pub trait InstructionData: Discriminator + AnchorSerialize {
fn data(&self) -> Vec<u8> {
let mut d = Self::discriminator().to_vec();
d.append(&mut self.try_to_vec().expect("Should always serialize"));
d
}
}

/// An event that can be emitted via a Solana log. See [`emit!`](crate::prelude::emit) for an example.
Expand All @@ -201,7 +205,10 @@ pub trait EventData: AnchorSerialize + Discriminator {

/// 8 byte unique identifier for a type.
pub trait Discriminator {
fn discriminator() -> [u8; 8];
const DISCRIMINATOR: [u8; 8];
fn discriminator() -> [u8; 8] {
Self::DISCRIMINATOR
}
}

/// Bump seed for program derived addresses.
Expand Down
37 changes: 27 additions & 10 deletions lang/syn/src/codegen/program/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::codegen::program::common::*;
use crate::Program;
use heck::CamelCase;
use quote::quote;

pub fn generate(program: &Program) -> proc_macro2::TokenStream {
Expand Down Expand Up @@ -35,14 +36,25 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
methods
.iter()
.map(|ix: &crate::StateIx| {
let name = &ix.raw_method.sig.ident.to_string();
let ix_method_name: proc_macro2::TokenStream =
{ format!("__{}", name).parse().unwrap() };
let sighash_arr = sighash(SIGHASH_STATE_NAMESPACE, name);
let sighash_tts: proc_macro2::TokenStream =
format!("{:?}", sighash_arr).parse().unwrap();
format!("__{}", ix.raw_method.sig.ident).parse().expect(
"Failed to parse ix method name with `__` as `TokenStream`",
);

let ix_name_camel: proc_macro2::TokenStream = ix
.raw_method
.sig
.ident
.to_string()
.as_str()
.to_camel_case()
.parse()
.expect(
"Failed to parse state ix method name in camel as `TokenStream`",
);

quote! {
#sighash_tts => {
instruction::state::#ix_name_camel::DISCRIMINATOR => {
__private::__state::#ix_method_name(
program_id,
accounts,
Expand Down Expand Up @@ -99,11 +111,15 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
.iter()
.map(|ix| {
let ix_method_name = &ix.raw_method.sig.ident;
let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, &ix_method_name.to_string());
let sighash_tts: proc_macro2::TokenStream =
format!("{:?}", sighash_arr).parse().unwrap();
let ix_name_camel: proc_macro2::TokenStream = ix_method_name
.to_string()
.as_str()
.to_camel_case()
.parse()
.expect("Failed to parse ix method name in camel as `TokenStream`");

quote! {
#sighash_tts => {
instruction::#ix_name_camel::DISCRIMINATOR => {
__private::__global::#ix_method_name(
program_id,
accounts,
Expand Down Expand Up @@ -162,6 +178,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
}
}

use anchor_lang::Discriminator;
match sighash {
#ctor_state_dispatch_arm
#(#state_dispatch_arms)*
Expand Down
36 changes: 21 additions & 15 deletions lang/syn/src/codegen/program/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
/// constructor.
#strct

impl anchor_lang::InstructionData for New {
fn data(&self) -> Vec<u8> {
let mut d = #sighash_tts.to_vec();
d.append(&mut self.try_to_vec().expect("Should always serialize"));
d
impl anchor_lang::Discriminator for New {
const DISCRIMINATOR: [u8; 8] = #sighash_tts;
}
impl anchor_lang::InstructionData for New {}
impl anchor_lang::Owner for New {
fn owner() -> Pubkey {
ID
}
}
}
Expand Down Expand Up @@ -82,11 +84,13 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
let sighash_tts: proc_macro2::TokenStream =
format!("{:?}", sighash_arr).parse().unwrap();
quote! {
impl anchor_lang::InstructionData for #ix_name_camel {
fn data(&self) -> Vec<u8> {
let mut d = #sighash_tts.to_vec();
d.append(&mut self.try_to_vec().expect("Should always serialize"));
d
impl anchor_lang::Discriminator for #ix_name_camel {
const DISCRIMINATOR: [u8; 8] = #sighash_tts;
}
impl anchor_lang::InstructionData for #ix_name_camel {}
impl anchor_lang::Owner for #ix_name_camel {
fn owner() -> Pubkey {
ID
}
}
}
Expand Down Expand Up @@ -138,11 +142,13 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
let sighash_tts: proc_macro2::TokenStream =
format!("{:?}", sighash_arr).parse().unwrap();
quote! {
impl anchor_lang::InstructionData for #ix_name_camel {
fn data(&self) -> Vec<u8> {
let mut d = #sighash_tts.to_vec();
d.append(&mut self.try_to_vec().expect("Should always serialize"));
d
impl anchor_lang::Discriminator for #ix_name_camel {
const DISCRIMINATOR: [u8; 8] = #sighash_tts;
}
impl anchor_lang::InstructionData for #ix_name_camel {}
impl anchor_lang::Owner for #ix_name_camel {
fn owner() -> Pubkey {
ID
}
}
}
Expand Down

0 comments on commit 0b64d30

Please sign in to comment.