Don't repack if not needed (#355)
This commit is contained in:
parent
64a9e151e0
commit
815cca3cb8
|
@ -69,19 +69,13 @@ impl State {
|
|||
pub fn token_account_deserialize(
|
||||
info: &AccountInfo,
|
||||
) -> Result<spl_token::state::Account, Error> {
|
||||
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, Error> {
|
||||
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();
|
||||
|
||||
|
|
|
@ -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())
|
||||
/// 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<T: Pack>(input: &[u8]) -> Result<T, ProgramError> {
|
||||
if input.len() < T::LEN {
|
||||
println!("ilen {:?} tlen {:?}", input.len(), T::LEN);
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
Ok(T::unpack_from_slice(input)?)
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
|
|
Loading…
Reference in New Issue