From 81d18e590d2131e029fa6342f102f83add081a00 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 26 Aug 2020 22:58:42 -0700 Subject: [PATCH] InitializeMint's mint authority is no longer optional --- token/program/src/error.rs | 3 --- token/program/src/instruction.rs | 32 +++++++++++++++++--------------- token/program/src/processor.rs | 25 ++----------------------- 3 files changed, 19 insertions(+), 41 deletions(-) diff --git a/token/program/src/error.rs b/token/program/src/error.rs index cc7da55e..a1d3152c 100644 --- a/token/program/src/error.rs +++ b/token/program/src/error.rs @@ -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, diff --git a/token/program/src/instruction.rs b/token/program/src/instruction.rs index 96acf76f..9c77516e 100644 --- a/token/program/src/instruction.rs +++ b/token/program/src/instruction.rs @@ -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, + /// The authority/multisignature to mint tokens. + mint_authority: Pubkey, /// The freeze authority/multisignature of the mint. freeze_authority: COption, }, @@ -226,7 +226,7 @@ impl TokenInstruction { } Ok(match input[0] { 0 => { - if input.len() < size_of::() + size_of::() + size_of::() { + if input.len() < size_of::() + size_of::() + size_of::() { 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::(); - let mint_authority = COption::unpack_or( - input, - &mut input_len, - Into::::into(TokenError::InvalidInstruction), - )?; + let mint_authority = unsafe { *(&input[input_len] as *const u8 as *const Pubkey) }; + input_len += size_of::(); + let freeze_authority = COption::unpack_or( input, &mut input_len, @@ -338,7 +336,11 @@ impl TokenInstruction { *value = *decimals; output_len += size_of::(); - 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::(); + 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 { - 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]); diff --git a/token/program/src/processor.rs b/token/program/src/processor.rs index d8baa685..e4fe5424 100644 --- a/token/program/src/processor.rs +++ b/token/program/src/processor.rs @@ -26,7 +26,7 @@ impl Processor { pub fn process_initialize_mint( accounts: &[AccountInfo], decimals: u8, - mint_authority: COption, + mint_authority: Pubkey, freeze_authority: COption, ) -> 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::(), &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(),