From 5e1c2bb34d1c4ac08791cc9e448fa61e7a0dfd79 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 1 Oct 2020 11:02:31 +0200 Subject: [PATCH] token-swap: Use sdk version of Pack (#554) * token-swap: Use sdk version of Pack * Update to get_packed_len per review --- token-swap/program/src/error.rs | 3 -- token-swap/program/src/processor.rs | 12 ++++---- token-swap/program/src/state.rs | 45 +++++++++++++---------------- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/token-swap/program/src/error.rs b/token-swap/program/src/error.rs index 5761456e..59c4d3e3 100644 --- a/token-swap/program/src/error.rs +++ b/token-swap/program/src/error.rs @@ -34,9 +34,6 @@ pub enum SwapError { /// The provided token account has a delegate. #[error("Token account has a delegate")] InvalidDelegate, - /// The swap info is invalid. - #[error("Swap info invalid")] - InvalidSwapInfo, /// The input token is invalid for swap. #[error("InvalidInput")] InvalidInput, diff --git a/token-swap/program/src/processor.rs b/token-swap/program/src/processor.rs index 531fecac..52acc413 100644 --- a/token-swap/program/src/processor.rs +++ b/token-swap/program/src/processor.rs @@ -220,7 +220,7 @@ impl Processor { fee_numerator, fee_denominator, }; - obj.pack(&mut swap_info.data.borrow_mut()); + SwapInfo::pack(obj, &mut swap_info.data.borrow_mut())?; Ok(()) } @@ -549,7 +549,6 @@ impl PrintProgramError for SwapError { SwapError::InvalidSupply => info!("Error: Pool token mint has a non-zero supply"), SwapError::RepeatedMint => info!("Error: Swap input token accounts have the same mint"), SwapError::InvalidDelegate => info!("Error: Token account has a delegate"), - SwapError::InvalidSwapInfo => info!("Error: Swap info invalid"), SwapError::InvalidInput => info!("Error: InvalidInput"), SwapError::IncorrectSwapAccount => { info!("Error: Address of the provided swap token account is incorrect") @@ -585,7 +584,6 @@ mod tests { processor::Processor as SplProcessor, state::{Account as SplAccount, Mint as SplMint}, }; - use std::mem::size_of; struct SwapAccountInfo { nonce: u8, @@ -617,7 +615,7 @@ mod tests { token_b_amount: u64, ) -> Self { let swap_key = pubkey_rand(); - let swap_account = Account::new(0, size_of::(), &SWAP_PROGRAM_ID); + let swap_account = Account::new(0, SwapInfo::get_packed_len(), &SWAP_PROGRAM_ID); let (authority_key, nonce) = Pubkey::find_program_address(&[&swap_key.to_bytes()[..]], &SWAP_PROGRAM_ID); @@ -1516,7 +1514,7 @@ mod tests { mut pool_account, ) = accounts.setup_token_accounts(&user_key, &depositor_key, deposit_a, deposit_b, 0); assert_eq!( - Err(SwapError::InvalidSwapInfo.into()), + Err(ProgramError::UninitializedAccount), accounts.deposit( &depositor_key, &token_a_key, @@ -1960,7 +1958,7 @@ mod tests { mut pool_account, ) = accounts.setup_token_accounts(&user_key, &withdrawer_key, initial_a, initial_b, 0); assert_eq!( - Err(SwapError::InvalidSwapInfo.into()), + Err(ProgramError::UninitializedAccount), accounts.withdraw( &withdrawer_key, &pool_key, @@ -2399,7 +2397,7 @@ mod tests { _pool_account, ) = accounts.setup_token_accounts(&user_key, &swapper_key, initial_a, initial_b, 0); assert_eq!( - Err(SwapError::InvalidSwapInfo.into()), + Err(ProgramError::UninitializedAccount), accounts.swap( &swapper_key, &token_a_key, diff --git a/token-swap/program/src/state.rs b/token-swap/program/src/state.rs index 33caca24..ae2cd553 100644 --- a/token-swap/program/src/state.rs +++ b/token-swap/program/src/state.rs @@ -1,8 +1,11 @@ //! State transition types -use crate::error::SwapError; use arrayref::{array_mut_ref, array_ref, array_refs, mut_array_refs}; -use solana_sdk::{program_error::ProgramError, pubkey::Pubkey}; +use solana_sdk::{ + program_error::ProgramError, + program_pack::{IsInitialized, Pack, Sealed}, + pubkey::Pubkey, +}; /// Program states. #[repr(C)] @@ -30,26 +33,19 @@ pub struct SwapInfo { pub fee_denominator: u64, } -impl SwapInfo { - /// Helper function to get the more efficient packed size of the struct - const fn get_packed_len() -> usize { - 114 +impl Sealed for SwapInfo {} +impl IsInitialized for SwapInfo { + fn is_initialized(&self) -> bool { + self.is_initialized } +} - /// Unpacks a byte buffer into a [SwapInfo](struct.SwapInfo.html) and checks - /// that it is initialized. - pub fn unpack(input: &[u8]) -> Result { - let value = Self::unpack_unchecked(input)?; - if value.is_initialized { - Ok(value) - } else { - Err(SwapError::InvalidSwapInfo.into()) - } - } +impl Pack for SwapInfo { + const LEN: usize = 114; /// Unpacks a byte buffer into a [SwapInfo](struct.SwapInfo.html). - pub fn unpack_unchecked(input: &[u8]) -> Result { - let input = array_ref![input, 0, SwapInfo::get_packed_len()]; + fn unpack_from_slice(input: &[u8]) -> Result { + let input = array_ref![input, 0, 114]; #[allow(clippy::ptr_offset_with_cast)] let (is_initialized, nonce, token_a, token_b, pool_mint, fee_numerator, fee_denominator) = array_refs![input, 1, 1, 32, 32, 32, 8, 8]; @@ -68,9 +64,8 @@ impl SwapInfo { }) } - /// Packs [SwapInfo](struct.SwapInfo.html) into a byte buffer. - pub fn pack(&self, output: &mut [u8]) { - let output = array_mut_ref![output, 0, SwapInfo::get_packed_len()]; + fn pack_into_slice(&self, output: &mut [u8]) { + let output = array_mut_ref![output, 0, 114]; let (is_initialized, nonce, token_a, token_b, pool_mint, fee_numerator, fee_denominator) = mut_array_refs![output, 1, 1, 32, 32, 32, 8, 8]; is_initialized[0] = self.is_initialized as u8; @@ -109,8 +104,8 @@ mod tests { fee_denominator, }; - let mut packed = [0u8; SwapInfo::get_packed_len()]; - swap_info.pack(&mut packed); + let mut packed = [0u8; SwapInfo::LEN]; + SwapInfo::pack(swap_info, &mut packed).unwrap(); let unpacked = SwapInfo::unpack(&packed).unwrap(); assert_eq!(swap_info, unpacked); @@ -127,11 +122,11 @@ mod tests { let unpacked = SwapInfo::unpack(&packed).unwrap(); assert_eq!(swap_info, unpacked); - let packed = [0u8; SwapInfo::get_packed_len()]; + let packed = [0u8; SwapInfo::LEN]; let swap_info: SwapInfo = Default::default(); let unpack_unchecked = SwapInfo::unpack_unchecked(&packed).unwrap(); assert_eq!(unpack_unchecked, swap_info); let err = SwapInfo::unpack(&packed).unwrap_err(); - assert_eq!(err, SwapError::InvalidSwapInfo.into()); + assert_eq!(err, ProgramError::UninitializedAccount); } }