diff --git a/lang/src/lib.rs b/lang/src/lib.rs index 52d0f3ced1..68003af4ca 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -181,8 +181,12 @@ pub trait ZeroCopy: Discriminator + Copy + Clone + Zeroable + Pod {} /// `Sha256(::)[..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; +pub trait InstructionData: Discriminator + AnchorSerialize { + fn data(&self) -> Vec { + 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. diff --git a/lang/syn/src/codegen/program/instruction.rs b/lang/syn/src/codegen/program/instruction.rs index 9191d05d70..c6a3c00af1 100644 --- a/lang/syn/src/codegen/program/instruction.rs +++ b/lang/syn/src/codegen/program/instruction.rs @@ -39,13 +39,12 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { /// constructor. #strct - impl anchor_lang::InstructionData for New { - fn data(&self) -> Vec { - 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 { + fn discriminator() -> [u8; 8] { + #sighash_tts } } + impl anchor_lang::InstructionData for $ix_name_camel {} } } }; @@ -82,13 +81,12 @@ 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 { - 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 { + fn discriminator() -> [u8; 8] { + #sighash_tts } } + impl anchor_lang::InstructionData for $ix_name_camel {} } }; @@ -138,13 +136,12 @@ 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 { - 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 { + fn discriminator() -> [u8; 8] { + #sighash_tts } } + impl anchor_lang::InstructionData for $ix_name_camel {} } }; // If no args, output a "unit" variant instead of a struct variant.