diff --git a/token-swap/program/src/processor.rs b/token-swap/program/src/processor.rs index bb8d5bfa..64a09378 100644 --- a/token-swap/program/src/processor.rs +++ b/token-swap/program/src/processor.rs @@ -69,19 +69,13 @@ impl State { pub fn token_account_deserialize( info: &AccountInfo, ) -> Result { - spl_token::state::Account::unpack_from_slice(&info.data.borrow_mut()) + spl_token::state::Account::unpack(&info.data.borrow_mut()) .map_err(|_| Error::ExpectedAccount) - // Ok(*spl_token::state::unpack(&mut info.data.borrow_mut()) - // .map_err(|_| Error::ExpectedAccount)?) } /// Deserializes a spl_token `Mint`. pub fn mint_deserialize(info: &AccountInfo) -> Result { - spl_token::state::Mint::unpack_from_slice(&info.data.borrow_mut()) - .map_err(|_| Error::ExpectedAccount) - - // Ok(*spl_token::state::unpack(&mut info.data.borrow_mut()) - // .map_err(|_| Error::ExpectedToken)?) + spl_token::state::Mint::unpack(&info.data.borrow_mut()).map_err(|_| Error::ExpectedAccount) } /// Calculates the authority id by generating a program address. @@ -523,7 +517,7 @@ mod tests { account::Account, account_info::create_is_signer_account_infos, instruction::Instruction, }; use spl_token::{ - instruction::{initialize_account, initialize_mint}, + instruction::{initialize_account, initialize_mint, mint_to}, processor::Processor as SplProcessor, state::{Account as SplAccount, Mint as SplMint}, }; @@ -575,24 +569,26 @@ mod tests { .unwrap(); let mut authority_account = Account::default(); do_process_instruction( - initialize_mint( + initialize_mint(&program_id, &token_key, authority_key, None, 2).unwrap(), + vec![&mut token_account, &mut authority_account], + ) + .unwrap(); + + do_process_instruction( + mint_to( &program_id, &token_key, - Some(&account_key), - Some(&authority_key), + &account_key, + authority_key, + &[], amount, - 2, ) .unwrap(), - if amount == 0 { - vec![&mut token_account, &mut authority_account] - } else { - vec![ - &mut token_account, - &mut account_account, - &mut authority_account, - ] - }, + vec![ + &mut token_account, + &mut account_account, + &mut authority_account, + ], ) .unwrap(); diff --git a/token/program/src/pack.rs b/token/program/src/pack.rs index bf6a205e..26504203 100644 --- a/token/program/src/pack.rs +++ b/token/program/src/pack.rs @@ -21,6 +21,28 @@ pub trait Pack: Sealed { #[doc(hidden)] fn unpack_from_slice(src: &[u8]) -> Result; + /// Unpack from slice and check if initialized + fn unpack(input: &[u8]) -> Result + 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 { + 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, 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, { - 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(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(input: &[u8]) -> Result { - let value: T = unpack_unchecked(input)?; - if value.is_initialized() { - Ok(value) - } else { - Err(TokenError::UninitializedState.into()) + /// 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(()) } } - -fn unpack_unchecked(input: &[u8]) -> Result { - if input.len() < T::LEN { - println!("ilen {:?} tlen {:?}", input.len(), T::LEN); - return Err(ProgramError::InvalidAccountData); - } - Ok(T::unpack_from_slice(input)?) -} diff --git a/token/program/src/processor.rs b/token/program/src/processor.rs index 41373e11..9ab174e5 100644 --- a/token/program/src/processor.rs +++ b/token/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::::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(())