Remove Pack mutable unpack methods (#443)

* Remove Pack::unpack_mut

* Remove Pack::unpack_unchecked_mut
This commit is contained in:
Tyera Eulberg 2020-09-14 15:08:14 -06:00 committed by GitHub
parent cf50a55586
commit e7a876f280
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 263 additions and 459 deletions

View File

@ -47,33 +47,6 @@ pub trait Pack: Sealed {
Ok(Self::unpack_from_slice(input)?) 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)]
fn unpack_mut<F, U>(input: &mut [u8], f: &mut F) -> Result<U, ProgramError>
where
F: FnMut(&mut Self) -> Result<U, ProgramError>,
Self: IsInitialized,
{
let mut t = Self::unpack(input)?;
let u = f(&mut t)?;
Self::pack(t, input)?;
Ok(u)
}
/// Borrow `Self` from `input` for the duration of the call to `f`, without checking that
/// `Self` has been initialized
#[inline(never)]
fn unpack_unchecked_mut<F, U>(input: &mut [u8], f: &mut F) -> Result<U, ProgramError>
where
F: FnMut(&mut Self) -> Result<U, ProgramError>,
{
let mut t = Self::unpack_unchecked(input)?;
let u = f(&mut t)?;
Self::pack(t, input)?;
Ok(u)
}
/// Pack into slice /// Pack into slice
fn pack(src: Self, dst: &mut [u8]) -> Result<(), ProgramError> { fn pack(src: Self, dst: &mut [u8]) -> Result<(), ProgramError> {
if dst.len() != Self::LEN { if dst.len() != Self::LEN {

View File

@ -35,8 +35,7 @@ impl Processor {
let mint_data_len = mint_info.data_len(); let mint_data_len = mint_info.data_len();
let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?; let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?;
let mut mint_data = mint_info.data.borrow_mut(); let mut mint = Mint::unpack_unchecked(&mint_info.data.borrow())?;
Mint::unpack_unchecked_mut(&mut mint_data, &mut |mint: &mut Mint| {
if mint.is_initialized { if mint.is_initialized {
return Err(TokenError::AlreadyInUse.into()); return Err(TokenError::AlreadyInUse.into());
} }
@ -50,8 +49,9 @@ impl Processor {
mint.is_initialized = true; mint.is_initialized = true;
mint.freeze_authority = freeze_authority; mint.freeze_authority = freeze_authority;
Mint::pack(mint, &mut mint_info.data.borrow_mut())?;
Ok(()) Ok(())
})
} }
/// Processes an [InitializeAccount](enum.TokenInstruction.html) instruction. /// Processes an [InitializeAccount](enum.TokenInstruction.html) instruction.
@ -63,8 +63,7 @@ impl Processor {
let new_account_info_data_len = new_account_info.data_len(); let new_account_info_data_len = new_account_info.data_len();
let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?; let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?;
let mut new_account_data = new_account_info.data.borrow_mut(); let mut account = Account::unpack_unchecked(&new_account_info.data.borrow())?;
Account::unpack_unchecked_mut(&mut new_account_data, &mut |account: &mut Account| {
if account.is_initialized() { if account.is_initialized() {
return Err(TokenError::AlreadyInUse.into()); return Err(TokenError::AlreadyInUse.into());
} }
@ -95,8 +94,9 @@ impl Processor {
account.amount = 0; account.amount = 0;
}; };
Account::pack(account, &mut new_account_info.data.borrow_mut())?;
Ok(()) Ok(())
})
} }
/// Processes a [InitializeMultisig](enum.TokenInstruction.html) instruction. /// Processes a [InitializeMultisig](enum.TokenInstruction.html) instruction.
@ -106,10 +106,7 @@ impl Processor {
let multisig_info_data_len = multisig_info.data_len(); let multisig_info_data_len = multisig_info.data_len();
let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?; let rent = &Rent::from_account_info(next_account_info(account_info_iter)?)?;
let mut multisig_account_data = multisig_info.data.borrow_mut(); let mut multisig = Multisig::unpack_unchecked(&multisig_info.data.borrow())?;
Multisig::unpack_unchecked_mut(
&mut multisig_account_data,
&mut |multisig: &mut Multisig| {
if multisig.is_initialized { if multisig.is_initialized {
return Err(TokenError::AlreadyInUse.into()); return Err(TokenError::AlreadyInUse.into());
} }
@ -132,9 +129,9 @@ impl Processor {
} }
multisig.is_initialized = true; multisig.is_initialized = true;
Multisig::pack(multisig, &mut multisig_info.data.borrow_mut())?;
Ok(()) Ok(())
},
)
} }
/// Processes a [Transfer](enum.TokenInstruction.html) instruction. /// Processes a [Transfer](enum.TokenInstruction.html) instruction.
@ -715,8 +712,7 @@ impl Processor {
if program_id == owner_account_info.owner if program_id == owner_account_info.owner
&& owner_account_info.data_len() == Multisig::get_packed_len() && owner_account_info.data_len() == Multisig::get_packed_len()
{ {
let mut owner_data = owner_account_info.data.borrow_mut(); let multisig = Multisig::unpack(&owner_account_info.data.borrow())?;
Multisig::unpack_mut(&mut owner_data, &mut |multisig: &mut Multisig| {
let mut num_signers = 0; let mut num_signers = 0;
for signer in signers.iter() { for signer in signers.iter() {
if multisig.signers[0..multisig.n as usize].contains(signer.key) { if multisig.signers[0..multisig.n as usize].contains(signer.key) {
@ -729,8 +725,7 @@ impl Processor {
if num_signers < multisig.m { if num_signers < multisig.m {
return Err(ProgramError::MissingRequiredSignature); return Err(ProgramError::MissingRequiredSignature);
} }
Ok(()) return Ok(());
})?;
} else if !owner_account_info.is_signer { } else if !owner_account_info.is_signer {
return Err(ProgramError::MissingRequiredSignature); return Err(ProgramError::MissingRequiredSignature);
} }
@ -1011,11 +1006,8 @@ mod tests {
vec![&mut mint2_account, &mut rent_sysvar], vec![&mut mint2_account, &mut rent_sysvar],
) )
.unwrap(); .unwrap();
Mint::unpack_unchecked_mut(&mut mint2_account.data, &mut |mint: &mut Mint| { let mint = Mint::unpack_unchecked(&mint2_account.data).unwrap();
assert_eq!(mint.freeze_authority, COption::Some(owner_key)); assert_eq!(mint.freeze_authority, COption::Some(owner_key));
Ok(())
})
.unwrap();
} }
#[test] #[test]
@ -1223,17 +1215,12 @@ mod tests {
.unwrap(); .unwrap();
// source-delegate transfer // source-delegate transfer
Account::unpack_unchecked_mut( let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
&mut account1_info.data.borrow_mut(),
&mut |account: &mut Account| {
account.amount = 1000; account.amount = 1000;
account.delegated_amount = 1000; account.delegated_amount = 1000;
account.delegate = COption::Some(account1_key); account.delegate = COption::Some(account1_key);
account.owner = owner_key; account.owner = owner_key;
Ok(()) Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
},
)
.unwrap();
do_process_instruction_dups( do_process_instruction_dups(
transfer( transfer(
@ -1499,11 +1486,9 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut mismatch_account.data, &mut |account: &mut Account| { let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
account.mint = mint2_key; account.mint = mint2_key;
Ok(()) Account::pack(account, &mut mismatch_account.data).unwrap();
})
.unwrap();
// mint to account // mint to account
do_process_instruction( do_process_instruction(
@ -1729,11 +1714,8 @@ mod tests {
) )
.unwrap() .unwrap()
} }
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, 1000); assert_eq!(account.amount, 1000);
Ok(())
})
.unwrap();
// insufficient funds // insufficient funds
assert_eq!( assert_eq!(
@ -1890,9 +1872,9 @@ mod tests {
vec![&mut mint_account, &mut rent_sysvar], vec![&mut mint_account, &mut rent_sysvar],
) )
.unwrap(); .unwrap();
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |mint: &mut Mint| { let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
assert_eq!( assert_eq!(
*mint, mint,
Mint { Mint {
mint_authority: COption::Some(owner_key), mint_authority: COption::Some(owner_key),
supply: 0, supply: 0,
@ -1901,9 +1883,6 @@ mod tests {
freeze_authority: COption::None, freeze_authority: COption::None,
} }
); );
Ok(())
})
.unwrap();
// create account // create account
do_process_instruction( do_process_instruction(
@ -1924,11 +1903,8 @@ mod tests {
) )
.unwrap(); .unwrap();
let _ = Mint::unpack(&mut mint_account.data).unwrap(); let _ = Mint::unpack(&mut mint_account.data).unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, 42); assert_eq!(account.amount, 42);
Ok(())
})
.unwrap();
// mint to 2, with incorrect decimals // mint to 2, with incorrect decimals
assert_eq!( assert_eq!(
@ -1949,11 +1925,8 @@ mod tests {
); );
let _ = Mint::unpack(&mut mint_account.data).unwrap(); let _ = Mint::unpack(&mut mint_account.data).unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, 42); assert_eq!(account.amount, 42);
Ok(())
})
.unwrap();
// mint to 2 // mint to 2
do_process_instruction( do_process_instruction(
@ -1971,11 +1944,8 @@ mod tests {
) )
.unwrap(); .unwrap();
let _ = Mint::unpack(&mut mint_account.data).unwrap(); let _ = Mint::unpack(&mut mint_account.data).unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, 84); assert_eq!(account.amount, 84);
Ok(())
})
.unwrap();
} }
#[test] #[test]
@ -2478,14 +2448,9 @@ mod tests {
.unwrap(); .unwrap();
// set close_authority when currently self // set close_authority when currently self
Account::unpack_unchecked_mut( let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
&mut account1_info.data.borrow_mut(),
&mut |account: &mut Account| {
account.close_authority = COption::Some(account1_key); account.close_authority = COption::Some(account1_key);
Ok(()) Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
},
)
.unwrap();
do_process_instruction_dups( do_process_instruction_dups(
set_authority( set_authority(
@ -2896,11 +2861,9 @@ mod tests {
.unwrap(); .unwrap();
// mint_to when mint_authority is account owner // mint_to when mint_authority is account owner
Mint::unpack_unchecked_mut(&mut mint_info.data.borrow_mut(), &mut |mint: &mut Mint| { let mut mint = Mint::unpack_unchecked(&mint_info.data.borrow()).unwrap();
mint.mint_authority = COption::Some(account1_key); mint.mint_authority = COption::Some(account1_key);
Ok(()) Mint::pack(mint, &mut mint_info.data.borrow_mut()).unwrap();
})
.unwrap();
do_process_instruction_dups( do_process_instruction_dups(
mint_to( mint_to(
&program_id, &program_id,
@ -3036,11 +2999,9 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut mismatch_account.data, &mut |account: &mut Account| { let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
account.mint = mint2_key; account.mint = mint2_key;
Ok(()) Account::pack(account, &mut mismatch_account.data).unwrap();
})
.unwrap();
// mint to // mint to
do_process_instruction( do_process_instruction(
@ -3049,16 +3010,10 @@ mod tests {
) )
.unwrap(); .unwrap();
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |mint: &mut Mint| { let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
assert_eq!(mint.supply, 42); assert_eq!(mint.supply, 42);
Ok(()) let account = Account::unpack_unchecked(&account_account.data).unwrap();
})
.unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
assert_eq!(account.amount, 42); assert_eq!(account.amount, 42);
Ok(())
})
.unwrap();
// mint to another account to test supply accumulation // mint to another account to test supply accumulation
do_process_instruction( do_process_instruction(
@ -3067,16 +3022,10 @@ mod tests {
) )
.unwrap(); .unwrap();
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |mint: &mut Mint| { let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
assert_eq!(mint.supply, 84); assert_eq!(mint.supply, 84);
Ok(()) let account = Account::unpack_unchecked(&account2_account.data).unwrap();
})
.unwrap();
Account::unpack_unchecked_mut(&mut account2_account.data, &mut |account: &mut Account| {
assert_eq!(account.amount, 42); assert_eq!(account.amount, 42);
Ok(())
})
.unwrap();
// missing signer // missing signer
let mut instruction = let mut instruction =
@ -3248,14 +3197,9 @@ mod tests {
vec![mint_info.clone(), account1_info.clone(), owner_info.clone()], vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut( let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
&mut account1_info.data.borrow_mut(),
&mut |account: &mut Account| {
account.owner = mint_key; account.owner = mint_key;
Ok(()) Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
},
)
.unwrap();
do_process_instruction_dups( do_process_instruction_dups(
burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(), burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(),
vec![account1_info.clone(), mint_info.clone(), mint_info.clone()], vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
@ -3284,16 +3228,11 @@ mod tests {
vec![mint_info.clone(), account1_info.clone(), owner_info.clone()], vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut( let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
&mut account1_info.data.borrow_mut(),
&mut |account: &mut Account| {
account.delegated_amount = 1000; account.delegated_amount = 1000;
account.delegate = COption::Some(account1_key); account.delegate = COption::Some(account1_key);
account.owner = owner_key; account.owner = owner_key;
Ok(()) Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
},
)
.unwrap();
do_process_instruction_dups( do_process_instruction_dups(
burn( burn(
&program_id, &program_id,
@ -3338,16 +3277,11 @@ mod tests {
vec![mint_info.clone(), account1_info.clone(), owner_info.clone()], vec![mint_info.clone(), account1_info.clone(), owner_info.clone()],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut( let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
&mut account1_info.data.borrow_mut(),
&mut |account: &mut Account| {
account.delegated_amount = 1000; account.delegated_amount = 1000;
account.delegate = COption::Some(mint_key); account.delegate = COption::Some(mint_key);
account.owner = owner_key; account.owner = owner_key;
Ok(()) Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
},
)
.unwrap();
do_process_instruction_dups( do_process_instruction_dups(
burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(), burn(&program_id, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(),
vec![account1_info.clone(), mint_info.clone(), mint_info.clone()], vec![account1_info.clone(), mint_info.clone(), mint_info.clone()],
@ -3464,11 +3398,9 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut mismatch_account.data, &mut |account: &mut Account| { let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap();
account.mint = mint2_key; account.mint = mint2_key;
Ok(()) Account::pack(account, &mut mismatch_account.data).unwrap();
})
.unwrap();
// mint to account // mint to account
do_process_instruction( do_process_instruction(
@ -3534,17 +3466,10 @@ mod tests {
) )
.unwrap(); .unwrap();
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |mint: &mut Mint| { let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
assert_eq!(mint.supply, 1000 - 42); assert_eq!(mint.supply, 1000 - 42);
let account = Account::unpack_unchecked(&account_account.data).unwrap();
Ok(())
})
.unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
assert_eq!(account.amount, 1000 - 42); assert_eq!(account.amount, 1000 - 42);
Ok(())
})
.unwrap();
// insufficient funds // insufficient funds
assert_eq!( assert_eq!(
@ -3611,16 +3536,10 @@ mod tests {
.unwrap(); .unwrap();
// match // match
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |mint: &mut Mint| { let mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
assert_eq!(mint.supply, 1000 - 42 - 84); assert_eq!(mint.supply, 1000 - 42 - 84);
Ok(()) let account = Account::unpack_unchecked(&account_account.data).unwrap();
})
.unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| {
assert_eq!(account.amount, 1000 - 42 - 84); assert_eq!(account.amount, 1000 - 42 - 84);
Ok(())
})
.unwrap();
// insufficient funds approved via delegate // insufficient funds approved via delegate
assert_eq!( assert_eq!(
@ -4076,14 +3995,12 @@ mod tests {
} }
let mut lamports = 0; let mut lamports = 0;
let mut data = vec![0; Multisig::get_packed_len()]; let mut data = vec![0; Multisig::get_packed_len()];
Multisig::unpack_unchecked_mut(&mut data, &mut |multisig: &mut Multisig| { let mut multisig = Multisig::unpack_unchecked(&data).unwrap();
multisig.m = MAX_SIGNERS as u8; multisig.m = MAX_SIGNERS as u8;
multisig.n = MAX_SIGNERS as u8; multisig.n = MAX_SIGNERS as u8;
multisig.signers = signer_keys; multisig.signers = signer_keys;
multisig.is_initialized = true; multisig.is_initialized = true;
Ok(()) Multisig::pack(multisig, &mut data).unwrap();
})
.unwrap();
let owner_account_info = AccountInfo::new( let owner_account_info = AccountInfo::new(
&owner_key, &owner_key,
false, false,
@ -4100,24 +4017,20 @@ mod tests {
// 1 of 11 // 1 of 11
{ {
let mut data_ref_mut = owner_account_info.data.borrow_mut(); let mut multisig =
Multisig::unpack_unchecked_mut(&mut data_ref_mut, &mut |multisig: &mut Multisig| { Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
multisig.m = 1; multisig.m = 1;
Ok(()) Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
})
.unwrap();
} }
Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap(); Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
// 2:1 // 2:1
{ {
let mut data_ref_mut = owner_account_info.data.borrow_mut(); let mut multisig =
Multisig::unpack_unchecked_mut(&mut data_ref_mut, &mut |multisig: &mut Multisig| { Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
multisig.m = 2; multisig.m = 2;
multisig.n = 1; multisig.n = 1;
Ok(()) Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
})
.unwrap();
} }
assert_eq!( assert_eq!(
Err(ProgramError::MissingRequiredSignature), Err(ProgramError::MissingRequiredSignature),
@ -4126,25 +4039,21 @@ mod tests {
// 0:11 // 0:11
{ {
let mut data_ref_mut = owner_account_info.data.borrow_mut(); let mut multisig =
Multisig::unpack_unchecked_mut(&mut data_ref_mut, &mut |multisig: &mut Multisig| { Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
multisig.m = 0; multisig.m = 0;
multisig.n = 11; multisig.n = 11;
Ok(()) Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
})
.unwrap();
} }
Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap(); Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers).unwrap();
// 2:11 but 0 provided // 2:11 but 0 provided
{ {
let mut data_ref_mut = owner_account_info.data.borrow_mut(); let mut multisig =
Multisig::unpack_unchecked_mut(&mut data_ref_mut, &mut |multisig: &mut Multisig| { Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
multisig.m = 2; multisig.m = 2;
multisig.n = 11; multisig.n = 11;
Ok(()) Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
})
.unwrap();
} }
assert_eq!( assert_eq!(
Err(ProgramError::MissingRequiredSignature), Err(ProgramError::MissingRequiredSignature),
@ -4152,13 +4061,11 @@ mod tests {
); );
// 2:11 but 1 provided // 2:11 but 1 provided
{ {
let mut data_ref_mut = owner_account_info.data.borrow_mut(); let mut multisig =
Multisig::unpack_unchecked_mut(&mut data_ref_mut, &mut |multisig: &mut Multisig| { Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
multisig.m = 2; multisig.m = 2;
multisig.n = 11; multisig.n = 11;
Ok(()) Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
})
.unwrap();
} }
assert_eq!( assert_eq!(
Err(ProgramError::MissingRequiredSignature), Err(ProgramError::MissingRequiredSignature),
@ -4167,26 +4074,22 @@ mod tests {
// 2:11, 2 from middle provided // 2:11, 2 from middle provided
{ {
let mut data_ref_mut = owner_account_info.data.borrow_mut(); let mut multisig =
Multisig::unpack_unchecked_mut(&mut data_ref_mut, &mut |multisig: &mut Multisig| { Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
multisig.m = 2; multisig.m = 2;
multisig.n = 11; multisig.n = 11;
Ok(()) Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
})
.unwrap();
} }
Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers[5..7]) Processor::validate_owner(&program_id, &owner_key, &owner_account_info, &signers[5..7])
.unwrap(); .unwrap();
// 11:11, one is not a signer // 11:11, one is not a signer
{ {
let mut data_ref_mut = owner_account_info.data.borrow_mut(); let mut multisig =
Multisig::unpack_unchecked_mut(&mut data_ref_mut, &mut |multisig: &mut Multisig| { Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap();
multisig.m = 2; // TODO 11? multisig.m = 2; // TODO 11?
multisig.n = 11; multisig.n = 11;
Ok(()) Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap();
})
.unwrap();
} }
signers[5].is_signer = false; signers[5].is_signer = false;
assert_eq!( assert_eq!(
@ -4260,15 +4163,10 @@ mod tests {
.unwrap(); .unwrap();
// source-close-authority close // source-close-authority close
Account::unpack_unchecked_mut( let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
&mut account1_info.data.borrow_mut(),
&mut |account: &mut Account| {
account.close_authority = COption::Some(account1_key); account.close_authority = COption::Some(account1_key);
account.owner = owner_key; account.owner = owner_key;
Ok(()) Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
},
)
.unwrap();
do_process_instruction_dups( do_process_instruction_dups(
close_account( close_account(
&program_id, &program_id,
@ -4356,11 +4254,8 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, 42); assert_eq!(account.amount, 42);
Ok(())
})
.unwrap();
// initialize native account // initialize native account
do_process_instruction( do_process_instruction(
@ -4379,12 +4274,9 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account2_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account2_account.data).unwrap();
assert!(account.is_native()); assert!(account.is_native());
assert_eq!(account.amount, 42); assert_eq!(account.amount, 42);
Ok(())
})
.unwrap();
// close non-native account with balance // close non-native account with balance
assert_eq!( assert_eq!(
@ -4432,11 +4324,8 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!(account_account.lamports, 0); assert_eq!(account_account.lamports, 0);
assert_eq!(account3_account.lamports, 2 * account_minimum_balance()); assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, 0); assert_eq!(account.amount, 0);
Ok(())
})
.unwrap();
// fund and initialize new non-native account to test close authority // fund and initialize new non-native account to test close authority
let account_key = pubkey_rand(); let account_key = pubkey_rand();
@ -4502,11 +4391,8 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!(account_account.lamports, 0); assert_eq!(account_account.lamports, 0);
assert_eq!(account3_account.lamports, 2 * account_minimum_balance() + 2); assert_eq!(account3_account.lamports, 2 * account_minimum_balance() + 2);
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, 0); assert_eq!(account.amount, 0);
Ok(())
})
.unwrap();
// close native account // close native account
do_process_instruction( do_process_instruction(
@ -4518,7 +4404,7 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account2_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account2_account.data).unwrap();
assert!(account.is_native()); assert!(account.is_native());
assert_eq!(account_account.lamports, 0); assert_eq!(account_account.lamports, 0);
assert_eq!(account.amount, 0); assert_eq!(account.amount, 0);
@ -4526,9 +4412,6 @@ mod tests {
account3_account.lamports, account3_account.lamports,
3 * account_minimum_balance() + 2 + 42 3 * account_minimum_balance() + 2 + 42
); );
Ok(())
})
.unwrap();
} }
#[test] #[test]
@ -4571,12 +4454,9 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert!(account.is_native()); assert!(account.is_native());
assert_eq!(account.amount, 40); assert_eq!(account.amount, 40);
Ok(())
})
.unwrap();
// initialize native account // initialize native account
do_process_instruction( do_process_instruction(
@ -4595,12 +4475,9 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account2_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account2_account.data).unwrap();
assert!(account.is_native()); assert!(account.is_native());
assert_eq!(account.amount, 0); assert_eq!(account.amount, 0);
Ok(())
})
.unwrap();
// mint_to unsupported // mint_to unsupported
assert_eq!( assert_eq!(
@ -4689,19 +4566,13 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!(account_account.lamports, account_minimum_balance()); assert_eq!(account_account.lamports, account_minimum_balance());
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert!(account.is_native()); assert!(account.is_native());
assert_eq!(account.amount, 0); assert_eq!(account.amount, 0);
Ok(())
})
.unwrap();
assert_eq!(account2_account.lamports, account_minimum_balance() + 40); assert_eq!(account2_account.lamports, account_minimum_balance() + 40);
Account::unpack_unchecked_mut(&mut account2_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account2_account.data).unwrap();
assert!(account.is_native()); assert!(account.is_native());
assert_eq!(account.amount, 40); assert_eq!(account.amount, 40);
Ok(())
})
.unwrap();
// close native account // close native account
do_process_instruction( do_process_instruction(
@ -4715,12 +4586,9 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!(account_account.lamports, 0); assert_eq!(account_account.lamports, 0);
assert_eq!(account3_account.lamports, 2 * account_minimum_balance()); assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert!(account.is_native()); assert!(account.is_native());
assert_eq!(account.amount, 0); assert_eq!(account.amount, 0);
Ok(())
})
.unwrap();
} }
#[test] #[test]
@ -4798,11 +4666,8 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, u64::MAX); assert_eq!(account.amount, u64::MAX);
Ok(())
})
.unwrap();
// attempt to mint one more to account // attempt to mint one more to account
assert_eq!( assert_eq!(
@ -4824,11 +4689,8 @@ mod tests {
], ],
) )
); );
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, u64::MAX); assert_eq!(account.amount, u64::MAX);
Ok(())
})
.unwrap();
// atttempt to mint one more to the other account // atttempt to mint one more to the other account
assert_eq!( assert_eq!(
@ -4857,11 +4719,8 @@ mod tests {
vec![&mut account_account, &mut mint_account, &mut owner_account], vec![&mut account_account, &mut mint_account, &mut owner_account],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, u64::MAX - 100); assert_eq!(account.amount, u64::MAX - 100);
Ok(())
})
.unwrap();
do_process_instruction( do_process_instruction(
mint_to( mint_to(
@ -4880,18 +4739,13 @@ mod tests {
], ],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.amount, u64::MAX); assert_eq!(account.amount, u64::MAX);
Ok(())
})
.unwrap();
// manipulate account balance to attempt overflow transfer // manipulate account balance to attempt overflow transfer
Account::unpack_unchecked_mut(&mut account2_account.data, &mut |account: &mut Account| { let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
account.amount = 1; account.amount = 1;
Ok(()) Account::pack(account, &mut account2_account.data).unwrap();
})
.unwrap();
assert_eq!( assert_eq!(
Err(TokenError::Overflow.into()), Err(TokenError::Overflow.into()),
@ -4975,11 +4829,9 @@ mod tests {
.unwrap(); .unwrap();
// no transfer if either account is frozen // no transfer if either account is frozen
Account::unpack_unchecked_mut(&mut account2_account.data, &mut |account: &mut Account| { let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
account.state = AccountState::Frozen; account.state = AccountState::Frozen;
Ok(()) Account::pack(account, &mut account2_account.data).unwrap();
})
.unwrap();
assert_eq!( assert_eq!(
Err(TokenError::AccountFrozen.into()), Err(TokenError::AccountFrozen.into()),
do_process_instruction( do_process_instruction(
@ -5000,16 +4852,12 @@ mod tests {
) )
); );
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
account.state = AccountState::Initialized; account.state = AccountState::Initialized;
Ok(()) Account::pack(account, &mut account_account.data).unwrap();
}) let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
.unwrap();
Account::unpack_unchecked_mut(&mut account2_account.data, &mut |account: &mut Account| {
account.state = AccountState::Frozen; account.state = AccountState::Frozen;
Ok(()) Account::pack(account, &mut account2_account.data).unwrap();
})
.unwrap();
assert_eq!( assert_eq!(
Err(TokenError::AccountFrozen.into()), Err(TokenError::AccountFrozen.into()),
do_process_instruction( do_process_instruction(
@ -5031,11 +4879,9 @@ mod tests {
); );
// no approve if account is frozen // no approve if account is frozen
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
account.state = AccountState::Frozen; account.state = AccountState::Frozen;
Ok(()) Account::pack(account, &mut account_account.data).unwrap();
})
.unwrap();
let delegate_key = pubkey_rand(); let delegate_key = pubkey_rand();
let mut delegate_account = SolanaAccount::default(); let mut delegate_account = SolanaAccount::default();
assert_eq!( assert_eq!(
@ -5059,12 +4905,10 @@ mod tests {
); );
// no revoke if account is frozen // no revoke if account is frozen
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let mut account = Account::unpack_unchecked(&account_account.data).unwrap();
account.delegate = COption::Some(delegate_key); account.delegate = COption::Some(delegate_key);
account.delegated_amount = 100; account.delegated_amount = 100;
Ok(()) Account::pack(account, &mut account_account.data).unwrap();
})
.unwrap();
assert_eq!( assert_eq!(
Err(TokenError::AccountFrozen.into()), Err(TokenError::AccountFrozen.into()),
do_process_instruction( do_process_instruction(
@ -5160,14 +5004,9 @@ mod tests {
.unwrap(); .unwrap();
// thaw where mint freeze_authority is account // thaw where mint freeze_authority is account
Account::unpack_unchecked_mut( let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap();
&mut account1_info.data.borrow_mut(),
&mut |account: &mut Account| {
account.state = AccountState::Frozen; account.state = AccountState::Frozen;
Ok(()) Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap();
},
)
.unwrap();
do_process_instruction_dups( do_process_instruction_dups(
thaw_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(), thaw_account(&program_id, &account1_key, &mint_key, &account1_key, &[]).unwrap(),
vec![ vec![
@ -5235,11 +5074,9 @@ mod tests {
); );
// missing freeze_authority // missing freeze_authority
Mint::unpack_unchecked_mut(&mut mint_account.data, &mut |mint: &mut Mint| { let mut mint = Mint::unpack_unchecked(&mint_account.data).unwrap();
mint.freeze_authority = COption::Some(owner_key); mint.freeze_authority = COption::Some(owner_key);
Ok(()) Mint::pack(mint, &mut mint_account.data).unwrap();
})
.unwrap();
assert_eq!( assert_eq!(
Err(TokenError::OwnerMismatch.into()), Err(TokenError::OwnerMismatch.into()),
do_process_instruction( do_process_instruction(
@ -5263,11 +5100,8 @@ mod tests {
vec![&mut account_account, &mut mint_account, &mut owner_account], vec![&mut account_account, &mut mint_account, &mut owner_account],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.state, AccountState::Frozen); assert_eq!(account.state, AccountState::Frozen);
Ok(())
})
.unwrap();
// check explicit freeze // check explicit freeze
assert_eq!( assert_eq!(
@ -5293,10 +5127,7 @@ mod tests {
vec![&mut account_account, &mut mint_account, &mut owner_account], vec![&mut account_account, &mut mint_account, &mut owner_account],
) )
.unwrap(); .unwrap();
Account::unpack_unchecked_mut(&mut account_account.data, &mut |account: &mut Account| { let account = Account::unpack_unchecked(&account_account.data).unwrap();
assert_eq!(account.state, AccountState::Initialized); assert_eq!(account.state, AccountState::Initialized);
Ok(())
})
.unwrap();
} }
} }