InitializeMint's mint authority is no longer optional

This commit is contained in:
Michael Vines 2020-08-26 22:58:42 -07:00
parent 5fccbc5ac8
commit 81d18e590d
3 changed files with 19 additions and 41 deletions

View File

@ -22,9 +22,6 @@ pub enum TokenError {
/// The account cannot be initialized because it is already being used.
#[error("AlreadyInUse")]
AlreadyInUse,
/// An owner is required if initial supply is zero.
#[error("An owner is required if supply is zero")]
OwnerRequiredIfNoInitialSupply,
/// Invalid number of provided signers.
#[error("Invalid number of provided signers")]
InvalidNumberOfProvidedSigners,

View File

@ -30,8 +30,8 @@ pub enum TokenInstruction {
InitializeMint {
/// Number of base 10 digits to the right of the decimal place.
decimals: u8,
/// The authority/multisignature to mint tokens. If present, further minting is supported.
mint_authority: COption<Pubkey>,
/// The authority/multisignature to mint tokens.
mint_authority: Pubkey,
/// The freeze authority/multisignature of the mint.
freeze_authority: COption<Pubkey>,
},
@ -226,7 +226,7 @@ impl TokenInstruction {
}
Ok(match input[0] {
0 => {
if input.len() < size_of::<u8>() + size_of::<u8>() + size_of::<bool>() {
if input.len() < size_of::<u8>() + size_of::<Pubkey>() + size_of::<bool>() {
return Err(TokenError::InvalidInstruction.into());
}
let mut input_len = 0;
@ -235,11 +235,9 @@ impl TokenInstruction {
let decimals = unsafe { *(&input[input_len] as *const u8) };
input_len += size_of::<u8>();
let mint_authority = COption::unpack_or(
input,
&mut input_len,
Into::<ProgramError>::into(TokenError::InvalidInstruction),
)?;
let mint_authority = unsafe { *(&input[input_len] as *const u8 as *const Pubkey) };
input_len += size_of::<Pubkey>();
let freeze_authority = COption::unpack_or(
input,
&mut input_len,
@ -338,7 +336,11 @@ impl TokenInstruction {
*value = *decimals;
output_len += size_of::<u8>();
mint_authority.pack(&mut output, &mut output_len);
#[allow(clippy::cast_ptr_alignment)]
let value = unsafe { &mut *(&mut output[output_len] as *mut u8 as *mut Pubkey) };
*value = *mint_authority;
output_len += size_of::<Pubkey>();
freeze_authority.pack(&mut output, &mut output_len);
}
Self::InitializeAccount => {
@ -468,10 +470,9 @@ pub fn initialize_mint(
freeze_authority_pubkey: Option<&Pubkey>,
decimals: u8,
) -> Result<Instruction, ProgramError> {
let mint_authority = COption::Some(*mint_authority_pubkey);
let freeze_authority = freeze_authority_pubkey.cloned().into();
let data = TokenInstruction::InitializeMint {
mint_authority,
mint_authority: *mint_authority_pubkey,
freeze_authority,
decimals,
}
@ -806,23 +807,24 @@ mod test {
fn test_instruction_packing() {
let check = TokenInstruction::InitializeMint {
decimals: 2,
mint_authority: COption::None,
mint_authority: Pubkey::new(&[1u8; 32]),
freeze_authority: COption::None,
};
let packed = check.pack().unwrap();
let expect = Vec::from([0u8, 2, 0, 0]);
let mut expect = Vec::from([0u8, 2]);
expect.extend_from_slice(&[1u8; 32]);
expect.extend_from_slice(&[0]);
assert_eq!(packed, expect);
let unpacked = TokenInstruction::unpack(&expect).unwrap();
assert_eq!(unpacked, check);
let check = TokenInstruction::InitializeMint {
decimals: 2,
mint_authority: COption::Some(Pubkey::new(&[2u8; 32])),
mint_authority: Pubkey::new(&[2u8; 32]),
freeze_authority: COption::Some(Pubkey::new(&[3u8; 32])),
};
let packed = check.pack().unwrap();
let mut expect = vec![0u8, 2];
expect.extend_from_slice(&[1]);
expect.extend_from_slice(&[2u8; 32]);
expect.extend_from_slice(&[1]);
expect.extend_from_slice(&[3u8; 32]);

View File

@ -26,7 +26,7 @@ impl Processor {
pub fn process_initialize_mint(
accounts: &[AccountInfo],
decimals: u8,
mint_authority: COption<Pubkey>,
mint_authority: Pubkey,
freeze_authority: COption<Pubkey>,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
@ -38,11 +38,7 @@ impl Processor {
return Err(TokenError::AlreadyInUse.into());
}
if mint_authority.is_none() {
return Err(TokenError::OwnerRequiredIfNoInitialSupply.into());
}
mint.mint_authority = mint_authority;
mint.mint_authority = COption::Some(mint_authority);
mint.decimals = decimals;
mint.is_initialized = true;
mint.freeze_authority = freeze_authority;
@ -616,9 +612,6 @@ impl PrintProgramError for TokenError {
TokenError::OwnerMismatch => info!("Error: owner does not match"),
TokenError::FixedSupply => info!("Error: the total supply of this token is fixed"),
TokenError::AlreadyInUse => info!("Error: account or token already in use"),
TokenError::OwnerRequiredIfNoInitialSupply => {
info!("Error: An owner is required if supply is zero")
}
TokenError::InvalidNumberOfProvidedSigners => {
info!("Error: Invalid number of provided signers")
}
@ -714,20 +707,6 @@ mod tests {
let mint2_key = pubkey_rand();
let mut mint2_account = SolanaAccount::new(0, size_of::<Mint>(), &program_id);
// mint_authority not provided
let mut instruction = initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap();
instruction.data = TokenInstruction::InitializeMint {
mint_authority: COption::None,
freeze_authority: COption::None,
decimals: 2,
}
.pack()
.unwrap();
assert_eq!(
Err(TokenError::OwnerRequiredIfNoInitialSupply.into()),
do_process_instruction(instruction, vec![&mut mint_account])
);
// create new mint
do_process_instruction(
initialize_mint(&program_id, &mint_key, &owner_key, None, 2).unwrap(),