Selaa lähdekoodia

lang: Avoid temporary `Vec`s when serializing objects with discriminators and set default capacity to 256 bytes (#2691)

Michal Nazarewicz 1 vuosi sitten
vanhempi
sitoutus
250fa8cdc5
5 muutettua tiedostoa jossa 18 lisäystä ja 17 poistoa
  1. 1 0
      CHANGELOG.md
  2. 3 2
      cli/src/lib.rs
  3. 7 9
      lang/attribute/event/src/lib.rs
  4. 4 3
      lang/src/lib.rs
  5. 3 3
      lang/syn/src/codegen/program/cpi.rs

+ 1 - 0
CHANGELOG.md

@@ -26,6 +26,7 @@ The minor version will be incremented upon a breaking change and the patch versi
 - cli: Fix commit based `anchor_version` override ([#2704](https://github.com/coral-xyz/anchor/pull/2704)).
 - spl: Fix compilation with `shmem` feature enabled ([#2722](https://github.com/coral-xyz/anchor/pull/2722)).
 - cli: Localhost default test validator address changes from `localhost` to `127.0.0.1`, NodeJS 17 IP resolution changes for IPv6 ([#2725](https://github.com/coral-xyz/anchor/pull/2725)).
+- lang: Eliminate temporary Vec allocations when serialising objects with discriminant ([#2691](https://github.com/coral-xyz/anchor/pull/2691)).
 
 ### Breaking
 

+ 3 - 2
cli/src/lib.rs

@@ -3844,8 +3844,9 @@ fn serialize_idl(idl: &Idl) -> Result<Vec<u8>> {
 }
 
 fn serialize_idl_ix(ix_inner: anchor_lang::idl::IdlInstruction) -> Result<Vec<u8>> {
-    let mut data = anchor_lang::idl::IDL_IX_TAG.to_le_bytes().to_vec();
-    data.append(&mut ix_inner.try_to_vec()?);
+    let mut data = Vec::with_capacity(256);
+    data.extend_from_slice(&anchor_lang::idl::IDL_IX_TAG.to_le_bytes());
+    ix_inner.serialize(&mut data)?;
     Ok(data)
 }
 

+ 7 - 9
lang/attribute/event/src/lib.rs

@@ -21,12 +21,9 @@ pub fn event(
     let event_name = &event_strct.ident;
 
     let discriminator: proc_macro2::TokenStream = {
-        let discriminator_preimage = format!("event:{event_name}");
-        let mut discriminator = [0u8; 8];
-        discriminator.copy_from_slice(
-            &anchor_syn::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8],
-        );
-        format!("{discriminator:?}").parse().unwrap()
+        let discriminator_preimage = format!("event:{event_name}").into_bytes();
+        let discriminator = anchor_syn::hash::hash(&discriminator_preimage);
+        format!("{:?}", &discriminator.0[..8]).parse().unwrap()
     };
 
     let ret = quote! {
@@ -35,9 +32,10 @@ pub fn event(
 
         impl anchor_lang::Event for #event_name {
             fn data(&self) -> Vec<u8> {
-                let mut d = #discriminator.to_vec();
-                d.append(&mut self.try_to_vec().unwrap());
-                d
+                let mut data = Vec::with_capacity(256);
+                data.extend_from_slice(&#discriminator);
+                self.serialize(&mut data).unwrap();
+                data
             }
         }
 

+ 4 - 3
lang/src/lib.rs

@@ -266,9 +266,10 @@ pub trait ZeroCopy: Discriminator + Copy + Clone + Zeroable + Pod {}
 /// to an instruction.
 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
+        let mut data = Vec::with_capacity(256);
+        data.extend_from_slice(&Self::discriminator());
+        self.serialize(&mut data).unwrap();
+        data
     }
 }
 

+ 3 - 3
lang/syn/src/codegen/program/cpi.rs

@@ -34,10 +34,10 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
                     ) -> #method_ret {
                         let ix = {
                             let ix = instruction::#ix_variant;
-                            let mut ix_data = AnchorSerialize::try_to_vec(&ix)
+                            let mut data = Vec::with_capacity(256);
+                            data.extend_from_slice(&#sighash_tts);
+                            AnchorSerialize::serialize(&ix, &mut data)
                                 .map_err(|_| anchor_lang::error::ErrorCode::InstructionDidNotSerialize)?;
-                            let mut data = #sighash_tts.to_vec();
-                            data.append(&mut ix_data);
                             let accounts = ctx.to_account_metas(None);
                             anchor_lang::solana_program::instruction::Instruction {
                                 program_id: ctx.program.key(),