lang: Add `Owner` & `Discriminator` implementation for ix structures (#2085)
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 Co-authored-by: Mikhail Gorbachev <m.gorbachev@joinsprouttherapy.com>
This commit is contained in:
parent
686c97e45b
commit
a73bd728fb
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
@ -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
|
||||
|
|
|
@ -40,9 +40,7 @@ pub fn event(
|
|||
}
|
||||
|
||||
impl anchor_lang::Discriminator for #event_name {
|
||||
fn discriminator() -> [u8; 8] {
|
||||
#discriminator
|
||||
}
|
||||
const DISCRIMINATOR: [u8; 8] = #discriminator;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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)*
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue