diff --git a/p-interface/src/native_mint.rs b/p-interface/src/native_mint.rs index f0a0d736..0d7f1bba 100644 --- a/p-interface/src/native_mint.rs +++ b/p-interface/src/native_mint.rs @@ -10,5 +10,6 @@ pub const ID: Pubkey = pinocchio_pubkey::pubkey!("So1111111111111111111111111111 #[inline(always)] pub fn is_native_mint(mint: &Pubkey) -> bool { + // Avoid using `pubkey_eq` since it increased CU consumption. mint == &ID } diff --git a/p-interface/src/state/account.rs b/p-interface/src/state/account.rs index 6647d25c..401e1c2d 100644 --- a/p-interface/src/state/account.rs +++ b/p-interface/src/state/account.rs @@ -1,6 +1,10 @@ use { super::{account_state::AccountState, COption, Initializable, Transmutable}, - pinocchio::{hint::likely, program_error::ProgramError, pubkey::Pubkey}, + pinocchio::{ + hint::likely, + program_error::ProgramError, + pubkey::{pubkey_eq, Pubkey}, + }, }; /// Incinerator address. @@ -147,7 +151,7 @@ impl Account { #[inline(always)] pub fn is_owned_by_system_program_or_incinerator(&self) -> bool { - SYSTEM_PROGRAM_ID == self.owner || INCINERATOR_ID == self.owner + pubkey_eq(&SYSTEM_PROGRAM_ID, &self.owner) || pubkey_eq(&INCINERATOR_ID, &self.owner) } } diff --git a/p-token/src/processor/mod.rs b/p-token/src/processor/mod.rs index b71d1d63..07cb8985 100644 --- a/p-token/src/processor/mod.rs +++ b/p-token/src/processor/mod.rs @@ -1,8 +1,12 @@ use { core::{slice::from_raw_parts, str::from_utf8_unchecked}, pinocchio::{ - account_info::AccountInfo, hint::unlikely, program_error::ProgramError, pubkey::Pubkey, - syscalls::sol_memcpy_, ProgramResult, + account_info::AccountInfo, + hint::{likely, unlikely}, + program_error::ProgramError, + pubkey::{pubkey_eq, Pubkey}, + syscalls::sol_memcpy_, + ProgramResult, }, pinocchio_token_interface::{ error::TokenError, @@ -79,7 +83,7 @@ const MAX_FORMATTED_DIGITS: usize = u8::MAX as usize + 2; /// Checks that the account is owned by the expected program. #[inline(always)] fn check_account_owner(account_info: &AccountInfo) -> ProgramResult { - if account_info.is_owned_by(&TOKEN_PROGRAM_ID) { + if likely(account_info.is_owned_by(&TOKEN_PROGRAM_ID)) { Ok(()) } else { Err(ProgramError::IncorrectProgramId) @@ -101,7 +105,7 @@ unsafe fn validate_owner( owner_account_info: &AccountInfo, signers: &[AccountInfo], ) -> ProgramResult { - if expected_owner != owner_account_info.key() { + if unlikely(!pubkey_eq(expected_owner, owner_account_info.key())) { return Err(TokenError::OwnerMismatch.into()); } @@ -121,7 +125,7 @@ unsafe fn validate_owner( for signer in signers.iter() { for (position, key) in multisig.signers[0..multisig.n as usize].iter().enumerate() { - if key == signer.key() && !matched[position] { + if pubkey_eq(key, signer.key()) && !matched[position] { if !signer.is_signer() { return Err(ProgramError::MissingRequiredSignature); } diff --git a/p-token/src/processor/set_authority.rs b/p-token/src/processor/set_authority.rs index ade89ac0..681e0983 100644 --- a/p-token/src/processor/set_authority.rs +++ b/p-token/src/processor/set_authority.rs @@ -1,7 +1,8 @@ use { super::validate_owner, pinocchio::{ - account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult, + account_info::AccountInfo, hint::likely, program_error::ProgramError, pubkey::Pubkey, + ProgramResult, }, pinocchio_token_interface::{ error::TokenError, @@ -22,7 +23,9 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8]) let authority_type = AuthorityType::try_from(*instruction_data.get_unchecked(0))?; let new_authority = if *instruction_data.get_unchecked(1) == 0 { None - } else if *instruction_data.get_unchecked(1) == 1 && instruction_data.len() >= 34 { + } else if likely(*instruction_data.get_unchecked(1) == 1) + && instruction_data.len() >= 34 + { Some(&*(instruction_data.as_ptr().add(2) as *const Pubkey)) } else { return Err(TokenError::InvalidInstruction.into()); diff --git a/p-token/src/processor/shared/approve.rs b/p-token/src/processor/shared/approve.rs index 06129528..d1c1b981 100644 --- a/p-token/src/processor/shared/approve.rs +++ b/p-token/src/processor/shared/approve.rs @@ -1,6 +1,9 @@ use { crate::processor::validate_owner, - pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult}, + pinocchio::{ + account_info::AccountInfo, hint::unlikely, program_error::ProgramError, pubkey::pubkey_eq, + ProgramResult, + }, pinocchio_token_interface::{ error::TokenError, state::{account::Account, load, load_mut, mint::Mint}, @@ -56,7 +59,7 @@ pub fn process_approve( } if let Some((mint_info, expected_decimals)) = expected_mint_info { - if mint_info.key() != &source_account.mint { + if unlikely(!pubkey_eq(mint_info.key(), &source_account.mint)) { return Err(TokenError::MintMismatch.into()); } @@ -64,7 +67,7 @@ pub fn process_approve( // `load` validates that the mint is initialized. let mint = unsafe { load::(mint_info.borrow_data_unchecked())? }; - if expected_decimals != mint.decimals { + if unlikely(expected_decimals != mint.decimals) { return Err(TokenError::MintDecimalsMismatch.into()); } } diff --git a/p-token/src/processor/shared/burn.rs b/p-token/src/processor/shared/burn.rs index bf25f2ba..e3b2d02c 100644 --- a/p-token/src/processor/shared/burn.rs +++ b/p-token/src/processor/shared/burn.rs @@ -1,6 +1,9 @@ use { crate::processor::{check_account_owner, validate_owner}, - pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult}, + pinocchio::{ + account_info::AccountInfo, hint::likely, program_error::ProgramError, pubkey::pubkey_eq, + ProgramResult, + }, pinocchio_token_interface::{ error::TokenError, state::{account::Account, load_mut, mint::Mint}, @@ -42,7 +45,7 @@ pub fn process_burn( .checked_sub(amount) .ok_or(TokenError::InsufficientFunds)?; - if mint_info.key() != &source_account.mint { + if !pubkey_eq(mint_info.key(), &source_account.mint) { return Err(TokenError::MintMismatch.into()); } @@ -52,9 +55,9 @@ pub fn process_burn( } } - if !source_account.is_owned_by_system_program_or_incinerator() { + if likely(!source_account.is_owned_by_system_program_or_incinerator()) { match source_account.delegate() { - Some(delegate) if authority_info.key() == delegate => { + Some(delegate) if pubkey_eq(authority_info.key(), delegate) => { // SAFETY: `authority_info` is not currently borrowed. unsafe { validate_owner(delegate, authority_info, remaining)? }; diff --git a/p-token/src/processor/shared/initialize_mint.rs b/p-token/src/processor/shared/initialize_mint.rs index 3dff60b0..750d2521 100644 --- a/p-token/src/processor/shared/initialize_mint.rs +++ b/p-token/src/processor/shared/initialize_mint.rs @@ -1,6 +1,7 @@ use { pinocchio::{ account_info::AccountInfo, + hint::likely, program_error::ProgramError, pubkey::Pubkey, sysvars::{rent::Rent, Sysvar}, @@ -30,7 +31,9 @@ pub fn process_initialize_mint( let mint_authority = &*(instruction_data.as_ptr().add(1) as *const Pubkey); let freeze_authority = if *instruction_data.get_unchecked(33) == 0 { None - } else if *instruction_data.get_unchecked(33) == 1 && instruction_data.len() >= 66 { + } else if likely(*instruction_data.get_unchecked(33) == 1) + && instruction_data.len() >= 66 + { Some(&*(instruction_data.as_ptr().add(34) as *const Pubkey)) } else { return Err(TokenError::InvalidInstruction.into()); diff --git a/p-token/src/processor/shared/mint_to.rs b/p-token/src/processor/shared/mint_to.rs index 7f205c0e..d8c3373d 100644 --- a/p-token/src/processor/shared/mint_to.rs +++ b/p-token/src/processor/shared/mint_to.rs @@ -1,6 +1,8 @@ use { crate::processor::{check_account_owner, validate_owner}, - pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult}, + pinocchio::{ + account_info::AccountInfo, program_error::ProgramError, pubkey::pubkey_eq, ProgramResult, + }, pinocchio_token_interface::{ error::TokenError, state::{account::Account, load_mut, mint::Mint}, @@ -33,7 +35,7 @@ pub fn process_mint_to( return Err(TokenError::NativeNotSupported.into()); } - if mint_info.key() != &destination_account.mint { + if !pubkey_eq(mint_info.key(), &destination_account.mint) { return Err(TokenError::MintMismatch.into()); } diff --git a/p-token/src/processor/shared/toggle_account_state.rs b/p-token/src/processor/shared/toggle_account_state.rs index e09c7118..32cb4470 100644 --- a/p-token/src/processor/shared/toggle_account_state.rs +++ b/p-token/src/processor/shared/toggle_account_state.rs @@ -1,6 +1,8 @@ use { crate::processor::validate_owner, - pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult}, + pinocchio::{ + account_info::AccountInfo, program_error::ProgramError, pubkey::pubkey_eq, ProgramResult, + }, pinocchio_token_interface::{ error::TokenError, state::{account::Account, account_state::AccountState, load, load_mut, mint::Mint}, @@ -24,7 +26,7 @@ pub fn process_toggle_account_state(accounts: &[AccountInfo], freeze: bool) -> P if source_account.is_native() { return Err(TokenError::NativeNotSupported.into()); } - if mint_info.key() != &source_account.mint { + if !pubkey_eq(mint_info.key(), &source_account.mint) { return Err(TokenError::MintMismatch.into()); } diff --git a/p-token/src/processor/shared/transfer.rs b/p-token/src/processor/shared/transfer.rs index c637989a..07c5fad8 100644 --- a/p-token/src/processor/shared/transfer.rs +++ b/p-token/src/processor/shared/transfer.rs @@ -1,7 +1,8 @@ use { crate::processor::{check_account_owner, validate_owner}, pinocchio::{ - account_info::AccountInfo, hint::unlikely, program_error::ProgramError, ProgramResult, + account_info::AccountInfo, hint::unlikely, program_error::ProgramError, pubkey::pubkey_eq, + ProgramResult, }, pinocchio_token_interface::{ error::TokenError, @@ -103,7 +104,7 @@ pub fn process_transfer( .checked_sub(amount) .ok_or(TokenError::InsufficientFunds)?; - if source_account.mint != destination_account.mint { + if !pubkey_eq(&source_account.mint, &destination_account.mint) { return Err(TokenError::MintMismatch.into()); } @@ -113,7 +114,7 @@ pub fn process_transfer( // Validates the mint information. if let Some((mint_info, decimals)) = expected_mint_info { - if mint_info.key() != &source_account.mint { + if !pubkey_eq(mint_info.key(), &source_account.mint) { return Err(TokenError::MintMismatch.into()); } diff --git a/p-token/src/processor/unwrap_lamports.rs b/p-token/src/processor/unwrap_lamports.rs index 3bf91659..30e0f5d2 100644 --- a/p-token/src/processor/unwrap_lamports.rs +++ b/p-token/src/processor/unwrap_lamports.rs @@ -2,7 +2,10 @@ use { super::validate_owner, crate::processor::{check_account_owner, unpack_amount}, pinocchio::{ - account_info::AccountInfo, hint::likely, program_error::ProgramError, ProgramResult, + account_info::AccountInfo, + hint::{likely, unlikely}, + program_error::ProgramError, + ProgramResult, }, pinocchio_token_interface::{ error::TokenError, @@ -62,7 +65,7 @@ pub fn process_unwrap_lamports(accounts: &[AccountInfo], instruction_data: &[u8] // raw pointer. let self_transfer = source_account_info == destination_account_info; - if self_transfer || amount == 0 { + if unlikely(self_transfer || amount == 0) { // Validates the token account owner since we are not writing // to the account. check_account_owner(source_account_info)