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))
|
- 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)).
|
- 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)).
|
- 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
|
## [0.25.0] - 2022-07-05
|
||||||
|
|
||||||
|
|
|
@ -139,9 +139,7 @@ pub fn account(
|
||||||
|
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_gen anchor_lang::Discriminator for #account_name #type_gen #where_clause {
|
impl #impl_gen anchor_lang::Discriminator for #account_name #type_gen #where_clause {
|
||||||
fn discriminator() -> [u8; 8] {
|
const DISCRIMINATOR: [u8; 8] = #discriminator;
|
||||||
#discriminator
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This trait is useful for clients deserializing accounts.
|
// This trait is useful for clients deserializing accounts.
|
||||||
|
@ -211,9 +209,7 @@ pub fn account(
|
||||||
|
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_gen anchor_lang::Discriminator for #account_name #type_gen #where_clause {
|
impl #impl_gen anchor_lang::Discriminator for #account_name #type_gen #where_clause {
|
||||||
fn discriminator() -> [u8; 8] {
|
const DISCRIMINATOR: [u8; 8] = #discriminator;
|
||||||
#discriminator
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#owner_impl
|
#owner_impl
|
||||||
|
|
|
@ -40,9 +40,7 @@ pub fn event(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl anchor_lang::Discriminator for #event_name {
|
impl anchor_lang::Discriminator for #event_name {
|
||||||
fn discriminator() -> [u8; 8] {
|
const DISCRIMINATOR: [u8; 8] = #discriminator;
|
||||||
#discriminator
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,8 +182,12 @@ pub trait ZeroCopy: Discriminator + Copy + Clone + Zeroable + Pod {}
|
||||||
/// `Sha256(<namespace>:<method_name>)[..8] || BorshSerialize(args)`.
|
/// `Sha256(<namespace>:<method_name>)[..8] || BorshSerialize(args)`.
|
||||||
/// `args` is a borsh serialized struct of named fields for each argument given
|
/// `args` is a borsh serialized struct of named fields for each argument given
|
||||||
/// to an instruction.
|
/// to an instruction.
|
||||||
pub trait InstructionData: AnchorSerialize {
|
pub trait InstructionData: Discriminator + AnchorSerialize {
|
||||||
fn data(&self) -> Vec<u8>;
|
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.
|
/// 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.
|
/// 8 byte unique identifier for a type.
|
||||||
pub trait Discriminator {
|
pub trait Discriminator {
|
||||||
fn discriminator() -> [u8; 8];
|
const DISCRIMINATOR: [u8; 8];
|
||||||
|
fn discriminator() -> [u8; 8] {
|
||||||
|
Self::DISCRIMINATOR
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bump seed for program derived addresses.
|
/// Bump seed for program derived addresses.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::codegen::program::common::*;
|
use crate::codegen::program::common::*;
|
||||||
use crate::Program;
|
use crate::Program;
|
||||||
|
use heck::CamelCase;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
pub fn generate(program: &Program) -> proc_macro2::TokenStream {
|
pub fn generate(program: &Program) -> proc_macro2::TokenStream {
|
||||||
|
@ -35,14 +36,25 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
|
||||||
methods
|
methods
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ix: &crate::StateIx| {
|
.map(|ix: &crate::StateIx| {
|
||||||
let name = &ix.raw_method.sig.ident.to_string();
|
|
||||||
let ix_method_name: proc_macro2::TokenStream =
|
let ix_method_name: proc_macro2::TokenStream =
|
||||||
{ format!("__{}", name).parse().unwrap() };
|
format!("__{}", ix.raw_method.sig.ident).parse().expect(
|
||||||
let sighash_arr = sighash(SIGHASH_STATE_NAMESPACE, name);
|
"Failed to parse ix method name with `__` as `TokenStream`",
|
||||||
let sighash_tts: proc_macro2::TokenStream =
|
);
|
||||||
format!("{:?}", sighash_arr).parse().unwrap();
|
|
||||||
|
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! {
|
quote! {
|
||||||
#sighash_tts => {
|
instruction::state::#ix_name_camel::DISCRIMINATOR => {
|
||||||
__private::__state::#ix_method_name(
|
__private::__state::#ix_method_name(
|
||||||
program_id,
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
|
@ -99,11 +111,15 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ix| {
|
.map(|ix| {
|
||||||
let ix_method_name = &ix.raw_method.sig.ident;
|
let ix_method_name = &ix.raw_method.sig.ident;
|
||||||
let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, &ix_method_name.to_string());
|
let ix_name_camel: proc_macro2::TokenStream = ix_method_name
|
||||||
let sighash_tts: proc_macro2::TokenStream =
|
.to_string()
|
||||||
format!("{:?}", sighash_arr).parse().unwrap();
|
.as_str()
|
||||||
|
.to_camel_case()
|
||||||
|
.parse()
|
||||||
|
.expect("Failed to parse ix method name in camel as `TokenStream`");
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#sighash_tts => {
|
instruction::#ix_name_camel::DISCRIMINATOR => {
|
||||||
__private::__global::#ix_method_name(
|
__private::__global::#ix_method_name(
|
||||||
program_id,
|
program_id,
|
||||||
accounts,
|
accounts,
|
||||||
|
@ -162,6 +178,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use anchor_lang::Discriminator;
|
||||||
match sighash {
|
match sighash {
|
||||||
#ctor_state_dispatch_arm
|
#ctor_state_dispatch_arm
|
||||||
#(#state_dispatch_arms)*
|
#(#state_dispatch_arms)*
|
||||||
|
|
|
@ -39,11 +39,13 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
|
||||||
/// constructor.
|
/// constructor.
|
||||||
#strct
|
#strct
|
||||||
|
|
||||||
impl anchor_lang::InstructionData for New {
|
impl anchor_lang::Discriminator for New {
|
||||||
fn data(&self) -> Vec<u8> {
|
const DISCRIMINATOR: [u8; 8] = #sighash_tts;
|
||||||
let mut d = #sighash_tts.to_vec();
|
}
|
||||||
d.append(&mut self.try_to_vec().expect("Should always serialize"));
|
impl anchor_lang::InstructionData for New {}
|
||||||
d
|
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 =
|
let sighash_tts: proc_macro2::TokenStream =
|
||||||
format!("{:?}", sighash_arr).parse().unwrap();
|
format!("{:?}", sighash_arr).parse().unwrap();
|
||||||
quote! {
|
quote! {
|
||||||
impl anchor_lang::InstructionData for #ix_name_camel {
|
impl anchor_lang::Discriminator for #ix_name_camel {
|
||||||
fn data(&self) -> Vec<u8> {
|
const DISCRIMINATOR: [u8; 8] = #sighash_tts;
|
||||||
let mut d = #sighash_tts.to_vec();
|
}
|
||||||
d.append(&mut self.try_to_vec().expect("Should always serialize"));
|
impl anchor_lang::InstructionData for #ix_name_camel {}
|
||||||
d
|
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 =
|
let sighash_tts: proc_macro2::TokenStream =
|
||||||
format!("{:?}", sighash_arr).parse().unwrap();
|
format!("{:?}", sighash_arr).parse().unwrap();
|
||||||
quote! {
|
quote! {
|
||||||
impl anchor_lang::InstructionData for #ix_name_camel {
|
impl anchor_lang::Discriminator for #ix_name_camel {
|
||||||
fn data(&self) -> Vec<u8> {
|
const DISCRIMINATOR: [u8; 8] = #sighash_tts;
|
||||||
let mut d = #sighash_tts.to_vec();
|
}
|
||||||
d.append(&mut self.try_to_vec().expect("Should always serialize"));
|
impl anchor_lang::InstructionData for #ix_name_camel {}
|
||||||
d
|
impl anchor_lang::Owner for #ix_name_camel {
|
||||||
|
fn owner() -> Pubkey {
|
||||||
|
ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue