Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 815cca3

Browse files
authored
Don't repack if not needed (#355)
1 parent 64a9e15 commit 815cca3

File tree

3 files changed

+80
-88
lines changed

3 files changed

+80
-88
lines changed

token-swap/program/src/processor.rs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,13 @@ impl State {
6969
pub fn token_account_deserialize(
7070
info: &AccountInfo,
7171
) -> Result<spl_token::state::Account, Error> {
72-
spl_token::state::Account::unpack_from_slice(&info.data.borrow_mut())
72+
spl_token::state::Account::unpack(&info.data.borrow_mut())
7373
.map_err(|_| Error::ExpectedAccount)
74-
// Ok(*spl_token::state::unpack(&mut info.data.borrow_mut())
75-
// .map_err(|_| Error::ExpectedAccount)?)
7674
}
7775

7876
/// Deserializes a spl_token `Mint`.
7977
pub fn mint_deserialize(info: &AccountInfo) -> Result<spl_token::state::Mint, Error> {
80-
spl_token::state::Mint::unpack_from_slice(&info.data.borrow_mut())
81-
.map_err(|_| Error::ExpectedAccount)
82-
83-
// Ok(*spl_token::state::unpack(&mut info.data.borrow_mut())
84-
// .map_err(|_| Error::ExpectedToken)?)
78+
spl_token::state::Mint::unpack(&info.data.borrow_mut()).map_err(|_| Error::ExpectedAccount)
8579
}
8680

8781
/// Calculates the authority id by generating a program address.
@@ -523,7 +517,7 @@ mod tests {
523517
account::Account, account_info::create_is_signer_account_infos, instruction::Instruction,
524518
};
525519
use spl_token::{
526-
instruction::{initialize_account, initialize_mint},
520+
instruction::{initialize_account, initialize_mint, mint_to},
527521
processor::Processor as SplProcessor,
528522
state::{Account as SplAccount, Mint as SplMint},
529523
};
@@ -575,24 +569,26 @@ mod tests {
575569
.unwrap();
576570
let mut authority_account = Account::default();
577571
do_process_instruction(
578-
initialize_mint(
572+
initialize_mint(&program_id, &token_key, authority_key, None, 2).unwrap(),
573+
vec![&mut token_account, &mut authority_account],
574+
)
575+
.unwrap();
576+
577+
do_process_instruction(
578+
mint_to(
579579
&program_id,
580580
&token_key,
581-
Some(&account_key),
582-
Some(&authority_key),
581+
&account_key,
582+
authority_key,
583+
&[],
583584
amount,
584-
2,
585585
)
586586
.unwrap(),
587-
if amount == 0 {
588-
vec![&mut token_account, &mut authority_account]
589-
} else {
590-
vec![
591-
&mut token_account,
592-
&mut account_account,
593-
&mut authority_account,
594-
]
595-
},
587+
vec![
588+
&mut token_account,
589+
&mut account_account,
590+
&mut authority_account,
591+
],
596592
)
597593
.unwrap();
598594

token/program/src/pack.rs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,28 @@ pub trait Pack: Sealed {
2121
#[doc(hidden)]
2222
fn unpack_from_slice(src: &[u8]) -> Result<Self, ProgramError>;
2323

24+
/// Unpack from slice and check if initialized
25+
fn unpack(input: &[u8]) -> Result<Self, ProgramError>
26+
where
27+
Self: IsInitialized,
28+
{
29+
let value = Self::unpack_unchecked(input)?;
30+
if value.is_initialized() {
31+
Ok(value)
32+
} else {
33+
Err(TokenError::UninitializedState.into())
34+
}
35+
}
36+
37+
/// Unpack from slice without checking if initialized
38+
fn unpack_unchecked(input: &[u8]) -> Result<Self, ProgramError> {
39+
if input.len() < Self::LEN {
40+
println!("ilen {:?} tlen {:?}", input.len(), Self::LEN);
41+
return Err(ProgramError::InvalidAccountData);
42+
}
43+
Ok(Self::unpack_from_slice(input)?)
44+
}
45+
2446
/// Borrow `Self` from `input` for the duration of the call to `f`, but first check that `Self`
2547
/// is initialized
2648
#[inline(never)]
@@ -29,9 +51,9 @@ pub trait Pack: Sealed {
2951
F: FnMut(&mut Self) -> Result<U, ProgramError>,
3052
Self: IsInitialized,
3153
{
32-
let mut t = unpack(input)?;
54+
let mut t = Self::unpack(input)?;
3355
let u = f(&mut t)?;
34-
pack(t, input)?;
56+
Self::pack(t, input)?;
3557
Ok(u)
3658
}
3759

@@ -42,35 +64,19 @@ pub trait Pack: Sealed {
4264
where
4365
F: FnMut(&mut Self) -> Result<U, ProgramError>,
4466
{
45-
let mut t = unpack_unchecked(input)?;
67+
let mut t = Self::unpack_unchecked(input)?;
4668
let u = f(&mut t)?;
47-
pack(t, input)?;
69+
Self::pack(t, input)?;
4870
Ok(u)
4971
}
50-
}
51-
52-
fn pack<T: Pack>(src: T, dst: &mut [u8]) -> Result<(), ProgramError> {
53-
if dst.len() < T::LEN {
54-
println!("dlen {:?} tlen {:?}", dst.len(), T::LEN);
55-
return Err(ProgramError::InvalidAccountData);
56-
}
57-
src.pack_into_slice(dst);
58-
Ok(())
59-
}
60-
61-
fn unpack<T: Pack + IsInitialized>(input: &[u8]) -> Result<T, ProgramError> {
62-
let value: T = unpack_unchecked(input)?;
63-
if value.is_initialized() {
64-
Ok(value)
65-
} else {
66-
Err(TokenError::UninitializedState.into())
67-
}
68-
}
6972

70-
fn unpack_unchecked<T: Pack>(input: &[u8]) -> Result<T, ProgramError> {
71-
if input.len() < T::LEN {
72-
println!("ilen {:?} tlen {:?}", input.len(), T::LEN);
73-
return Err(ProgramError::InvalidAccountData);
73+
/// Pack into slice
74+
fn pack(src: Self, dst: &mut [u8]) -> Result<(), ProgramError> {
75+
if dst.len() < Self::LEN {
76+
println!("dlen {:?} tlen {:?}", dst.len(), Self::LEN);
77+
return Err(ProgramError::InvalidAccountData);
78+
}
79+
src.pack_into_slice(dst);
80+
Ok(())
7481
}
75-
Ok(T::unpack_from_slice(input)?)
7682
}

token/program/src/processor.rs

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ impl Processor {
7575
}
7676

7777
if *mint_info.key != crate::native_mint::id() {
78-
let mut mint_info_data = mint_info.data.borrow_mut();
79-
Mint::unpack_mut(&mut mint_info_data, &mut |_| Ok(()))
78+
let _ = Mint::unpack(&mint_info.data.borrow_mut())
8079
.map_err(|_| Into::<ProgramError>::into(TokenError::InvalidMint))?;
8180
}
8281

@@ -177,18 +176,15 @@ impl Processor {
177176
return Err(TokenError::AccountFrozen.into());
178177
}
179178

180-
if let Some((mint_account_info, expected_decimals)) = expected_mint_info {
181-
if source_account.mint != *mint_account_info.key {
179+
if let Some((mint_info, expected_decimals)) = expected_mint_info {
180+
if source_account.mint != *mint_info.key {
182181
return Err(TokenError::MintMismatch.into());
183182
}
184183

185-
let mut mint_info_data = mint_account_info.data.borrow_mut();
186-
Mint::unpack_mut(&mut mint_info_data, &mut |mint: &mut Mint| {
187-
if expected_decimals != mint.decimals {
188-
return Err(TokenError::MintDecimalsMismatch.into());
189-
}
190-
Ok(())
191-
})?;
184+
let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
185+
if expected_decimals != mint.decimals {
186+
return Err(TokenError::MintDecimalsMismatch.into());
187+
}
192188
}
193189

194190
match source_account.delegate {
@@ -268,18 +264,15 @@ impl Processor {
268264
return Err(TokenError::AccountFrozen.into());
269265
}
270266

271-
if let Some((mint_account_info, expected_decimals)) = expected_mint_info {
272-
if source_account.mint != *mint_account_info.key {
267+
if let Some((mint_info, expected_decimals)) = expected_mint_info {
268+
if source_account.mint != *mint_info.key {
273269
return Err(TokenError::MintMismatch.into());
274270
}
275271

276-
let mut mint_info_data = mint_account_info.data.borrow_mut();
277-
Mint::unpack_mut(&mut mint_info_data, &mut |mint: &mut Mint| {
278-
if expected_decimals != mint.decimals {
279-
return Err(TokenError::MintDecimalsMismatch.into());
280-
}
281-
Ok(())
282-
})?;
272+
let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
273+
if expected_decimals != mint.decimals {
274+
return Err(TokenError::MintDecimalsMismatch.into());
275+
}
283276
}
284277

285278
Self::validate_owner(
@@ -442,8 +435,8 @@ impl Processor {
442435
return Err(TokenError::MintMismatch.into());
443436
}
444437

445-
let mut mint_info_data = mint_info.data.borrow_mut();
446-
Mint::unpack_mut(&mut mint_info_data, &mut |mint: &mut Mint| {
438+
let mut mint_data = mint_info.data.borrow_mut();
439+
Mint::unpack_mut(&mut mint_data, &mut |mint: &mut Mint| {
447440
if let Some(expected_decimals) = expected_decimals {
448441
if expected_decimals != mint.decimals {
449442
return Err(TokenError::MintDecimalsMismatch.into());
@@ -612,19 +605,16 @@ impl Processor {
612605
return Err(TokenError::InvalidState.into());
613606
}
614607

615-
let mut mint_data = mint_info.data.borrow_mut();
616-
Mint::unpack_mut(
617-
&mut mint_data,
618-
&mut |mint: &mut Mint| match mint.freeze_authority {
619-
COption::Some(authority) => Self::validate_owner(
620-
program_id,
621-
&authority,
622-
authority_info,
623-
account_info_iter.as_slice(),
624-
),
625-
COption::None => Err(TokenError::MintCannotFreeze.into()),
626-
},
627-
)?;
608+
let mint = Mint::unpack(&mint_info.data.borrow_mut())?;
609+
match mint.freeze_authority {
610+
COption::Some(authority) => Self::validate_owner(
611+
program_id,
612+
&authority,
613+
authority_info,
614+
account_info_iter.as_slice(),
615+
),
616+
COption::None => Err(TokenError::MintCannotFreeze.into()),
617+
}?;
628618

629619
source_account.state = if freeze {
630620
AccountState::Frozen
@@ -1497,7 +1487,7 @@ mod tests {
14971487
vec![&mut mint_account, &mut account_account, &mut owner_account],
14981488
)
14991489
.unwrap();
1500-
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |_| Ok(())).unwrap();
1490+
let _ = Mint::unpack(&mut mint_account.data).unwrap();
15011491
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
15021492
assert_eq!(account.amount, 42);
15031493
Ok(())
@@ -1522,7 +1512,7 @@ mod tests {
15221512
)
15231513
);
15241514

1525-
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |_| Ok(())).unwrap();
1515+
let _ = Mint::unpack(&mut mint_account.data).unwrap();
15261516
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
15271517
assert_eq!(account.amount, 42);
15281518
Ok(())
@@ -1544,7 +1534,7 @@ mod tests {
15441534
vec![&mut mint_account, &mut account_account, &mut owner_account],
15451535
)
15461536
.unwrap();
1547-
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |_| Ok(())).unwrap();
1537+
let _ = Mint::unpack(&mut mint_account.data).unwrap();
15481538
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
15491539
assert_eq!(account.amount, 84);
15501540
Ok(())

0 commit comments

Comments
 (0)