瀏覽代碼

p-token: Improve code generation (#90)

* Make amount optional

* Update import

* Use compiler hints

* More hints

* Update hint import

* Revert dependencies

* Clean up
Fernando Otero 3 周之前
父節點
當前提交
7511655051

+ 1 - 0
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
 }

+ 6 - 2
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)
     }
 }
 

+ 9 - 5
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);
                     }

+ 5 - 2
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());

+ 6 - 3
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>(mint_info.borrow_data_unchecked())? };
 
-        if expected_decimals != mint.decimals {
+        if unlikely(expected_decimals != mint.decimals) {
             return Err(TokenError::MintDecimalsMismatch.into());
         }
     }

+ 7 - 4
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)? };
 

+ 4 - 1
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());

+ 4 - 2
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());
     }
 

+ 4 - 2
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());
     }
 

+ 4 - 3
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());
         }
 

+ 5 - 2
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)