Browse Source

Don't repack if not needed (#355)

Jack May 5 years ago
parent
commit
057519a286
2 changed files with 62 additions and 66 deletions
  1. 34 28
      program/src/pack.rs
  2. 28 38
      program/src/processor.rs

+ 34 - 28
program/src/pack.rs

@@ -21,6 +21,28 @@ pub trait Pack: Sealed {
     #[doc(hidden)]
     fn unpack_from_slice(src: &[u8]) -> Result<Self, ProgramError>;
 
+    /// Unpack from slice and check if initialized
+    fn unpack(input: &[u8]) -> Result<Self, ProgramError>
+    where
+        Self: IsInitialized,
+    {
+        let value = Self::unpack_unchecked(input)?;
+        if value.is_initialized() {
+            Ok(value)
+        } else {
+            Err(TokenError::UninitializedState.into())
+        }
+    }
+
+    /// Unpack from slice without checking if initialized
+    fn unpack_unchecked(input: &[u8]) -> Result<Self, ProgramError> {
+        if input.len() < Self::LEN {
+            println!("ilen {:?} tlen {:?}", input.len(), Self::LEN);
+            return Err(ProgramError::InvalidAccountData);
+        }
+        Ok(Self::unpack_from_slice(input)?)
+    }
+
     /// Borrow `Self` from `input` for the duration of the call to `f`, but first check that `Self`
     /// is initialized
     #[inline(never)]
@@ -29,9 +51,9 @@ pub trait Pack: Sealed {
         F: FnMut(&mut Self) -> Result<U, ProgramError>,
         Self: IsInitialized,
     {
-        let mut t = unpack(input)?;
+        let mut t = Self::unpack(input)?;
         let u = f(&mut t)?;
-        pack(t, input)?;
+        Self::pack(t, input)?;
         Ok(u)
     }
 
@@ -42,35 +64,19 @@ pub trait Pack: Sealed {
     where
         F: FnMut(&mut Self) -> Result<U, ProgramError>,
     {
-        let mut t = unpack_unchecked(input)?;
+        let mut t = Self::unpack_unchecked(input)?;
         let u = f(&mut t)?;
-        pack(t, input)?;
+        Self::pack(t, input)?;
         Ok(u)
     }
-}
-
-fn pack<T: Pack>(src: T, dst: &mut [u8]) -> Result<(), ProgramError> {
-    if dst.len() < T::LEN {
-        println!("dlen {:?} tlen {:?}", dst.len(), T::LEN);
-        return Err(ProgramError::InvalidAccountData);
-    }
-    src.pack_into_slice(dst);
-    Ok(())
-}
-
-fn unpack<T: Pack + IsInitialized>(input: &[u8]) -> Result<T, ProgramError> {
-    let value: T = unpack_unchecked(input)?;
-    if value.is_initialized() {
-        Ok(value)
-    } else {
-        Err(TokenError::UninitializedState.into())
-    }
-}
 
-fn unpack_unchecked<T: Pack>(input: &[u8]) -> Result<T, ProgramError> {
-    if input.len() < T::LEN {
-        println!("ilen {:?} tlen {:?}", input.len(), T::LEN);
-        return Err(ProgramError::InvalidAccountData);
+    /// Pack into slice
+    fn pack(src: Self, dst: &mut [u8]) -> Result<(), ProgramError> {
+        if dst.len() < Self::LEN {
+            println!("dlen {:?} tlen {:?}", dst.len(), Self::LEN);
+            return Err(ProgramError::InvalidAccountData);
+        }
+        src.pack_into_slice(dst);
+        Ok(())
     }
-    Ok(T::unpack_from_slice(input)?)
 }

+ 28 - 38
program/src/processor.rs

@@ -75,8 +75,7 @@ impl Processor {
             }
 
             if *mint_info.key != crate::native_mint::id() {
-                let mut mint_info_data = mint_info.data.borrow_mut();
-                Mint::unpack_mut(&mut mint_info_data, &mut |_| Ok(()))
+                let _ = Mint::unpack(&mint_info.data.borrow_mut())
                     .map_err(|_| Into::<ProgramError>::into(TokenError::InvalidMint))?;
             }
 
@@ -177,18 +176,15 @@ impl Processor {
                     return Err(TokenError::AccountFrozen.into());
                 }
 
-                if let Some((mint_account_info, expected_decimals)) = expected_mint_info {
-                    if source_account.mint != *mint_account_info.key {
+                if let Some((mint_info, expected_decimals)) = expected_mint_info {
+                    if source_account.mint != *mint_info.key {
                         return Err(TokenError::MintMismatch.into());
                     }
 
-                    let mut mint_info_data = mint_account_info.data.borrow_mut();
-                    Mint::unpack_mut(&mut mint_info_data, &mut |mint: &mut Mint| {
-                        if expected_decimals != mint.decimals {
-                            return Err(TokenError::MintDecimalsMismatch.into());
-                        }
-                        Ok(())
-                    })?;
+                    let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
+                    if expected_decimals != mint.decimals {
+                        return Err(TokenError::MintDecimalsMismatch.into());
+                    }
                 }
 
                 match source_account.delegate {
@@ -268,18 +264,15 @@ impl Processor {
                 return Err(TokenError::AccountFrozen.into());
             }
 
-            if let Some((mint_account_info, expected_decimals)) = expected_mint_info {
-                if source_account.mint != *mint_account_info.key {
+            if let Some((mint_info, expected_decimals)) = expected_mint_info {
+                if source_account.mint != *mint_info.key {
                     return Err(TokenError::MintMismatch.into());
                 }
 
-                let mut mint_info_data = mint_account_info.data.borrow_mut();
-                Mint::unpack_mut(&mut mint_info_data, &mut |mint: &mut Mint| {
-                    if expected_decimals != mint.decimals {
-                        return Err(TokenError::MintDecimalsMismatch.into());
-                    }
-                    Ok(())
-                })?;
+                let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
+                if expected_decimals != mint.decimals {
+                    return Err(TokenError::MintDecimalsMismatch.into());
+                }
             }
 
             Self::validate_owner(
@@ -442,8 +435,8 @@ impl Processor {
                 return Err(TokenError::MintMismatch.into());
             }
 
-            let mut mint_info_data = mint_info.data.borrow_mut();
-            Mint::unpack_mut(&mut mint_info_data, &mut |mint: &mut Mint| {
+            let mut mint_data = mint_info.data.borrow_mut();
+            Mint::unpack_mut(&mut mint_data, &mut |mint: &mut Mint| {
                 if let Some(expected_decimals) = expected_decimals {
                     if expected_decimals != mint.decimals {
                         return Err(TokenError::MintDecimalsMismatch.into());
@@ -612,19 +605,16 @@ impl Processor {
                 return Err(TokenError::InvalidState.into());
             }
 
-            let mut mint_data = mint_info.data.borrow_mut();
-            Mint::unpack_mut(
-                &mut mint_data,
-                &mut |mint: &mut Mint| match mint.freeze_authority {
-                    COption::Some(authority) => Self::validate_owner(
-                        program_id,
-                        &authority,
-                        authority_info,
-                        account_info_iter.as_slice(),
-                    ),
-                    COption::None => Err(TokenError::MintCannotFreeze.into()),
-                },
-            )?;
+            let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
+            match mint.freeze_authority {
+                COption::Some(authority) => Self::validate_owner(
+                    program_id,
+                    &authority,
+                    authority_info,
+                    account_info_iter.as_slice(),
+                ),
+                COption::None => Err(TokenError::MintCannotFreeze.into()),
+            }?;
 
             source_account.state = if freeze {
                 AccountState::Frozen
@@ -1497,7 +1487,7 @@ mod tests {
             vec![&mut mint_account, &mut account_account, &mut owner_account],
         )
         .unwrap();
-        Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |_| Ok(())).unwrap();
+        let _ = Mint::unpack(&mut mint_account.data).unwrap();
         Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
             assert_eq!(account.amount, 42);
             Ok(())
@@ -1522,7 +1512,7 @@ mod tests {
             )
         );
 
-        Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |_| Ok(())).unwrap();
+        let _ = Mint::unpack(&mut mint_account.data).unwrap();
         Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
             assert_eq!(account.amount, 42);
             Ok(())
@@ -1544,7 +1534,7 @@ mod tests {
             vec![&mut mint_account, &mut account_account, &mut owner_account],
         )
         .unwrap();
-        Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |_| Ok(())).unwrap();
+        let _ = Mint::unpack(&mut mint_account.data).unwrap();
         Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
             assert_eq!(account.amount, 84);
             Ok(())