Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions p-token/src/processor/close_account.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
super::validate_owner,
super::{pubkeys_eq, validate_owner},
pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
spl_token_interface::{
error::TokenError,
Expand Down Expand Up @@ -38,7 +38,7 @@ pub fn process_close_account(accounts: &[AccountInfo]) -> ProgramResult {

if !source_account.is_owned_by_system_program_or_incinerator() {
validate_owner(authority, authority_info, remaining)?;
} else if destination_account_info.key() != &INCINERATOR_ID {
} else if !pubkeys_eq(destination_account_info.key(), &INCINERATOR_ID) {
return Err(ProgramError::InvalidAccountData);
}
}
Expand Down
19 changes: 17 additions & 2 deletions p-token/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ pub use {
/// Number of bytes in a `u64`.
const U64_BYTES: usize = core::mem::size_of::<u64>();

/// Optimized pubkey comparison with 64-bit chunks.
#[inline(always)]
pub fn pubkeys_eq(a: &Pubkey, b: &Pubkey) -> bool {
let a_chunks = unsafe { from_raw_parts(a.as_ptr() as *const u64, 4) };
let b_chunks = unsafe { from_raw_parts(b.as_ptr() as *const u64, 4) };

// Iterate over chunks to exit early.
for i in 0..4 {
if a_chunks[i] != b_chunks[i] {
return false;
}
}
true
}

/// Maximum number of digits in a formatted `u64`.
///
/// The maximum number of digits is equal to the maximum number
Expand Down Expand Up @@ -96,7 +111,7 @@ fn validate_owner(
owner_account_info: &AccountInfo,
signers: &[AccountInfo],
) -> ProgramResult {
if expected_owner != owner_account_info.key() {
if !pubkeys_eq(expected_owner, owner_account_info.key()) {
return Err(TokenError::OwnerMismatch.into());
}

Expand All @@ -115,7 +130,7 @@ 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 pubkeys_eq(key, signer.key()) && !matched[position] {
if !signer.is_signer() {
return Err(ProgramError::MissingRequiredSignature);
}
Expand Down
4 changes: 2 additions & 2 deletions p-token/src/processor/shared/approve.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::processor::validate_owner,
crate::processor::{pubkeys_eq, validate_owner},
pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
spl_token_interface::{
error::TokenError,
Expand Down Expand Up @@ -56,7 +56,7 @@ pub fn process_approve(
}

if let Some((mint_info, expected_decimals)) = expected_mint_info {
if mint_info.key() != &source_account.mint {
if !pubkeys_eq(mint_info.key(), &source_account.mint) {
return Err(TokenError::MintMismatch.into());
}

Expand Down
6 changes: 3 additions & 3 deletions p-token/src/processor/shared/burn.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::processor::{check_account_owner, validate_owner},
crate::processor::{check_account_owner, pubkeys_eq, validate_owner},
pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
spl_token_interface::{
error::TokenError,
Expand Down Expand Up @@ -41,7 +41,7 @@ pub fn process_burn(
.checked_sub(amount)
.ok_or(TokenError::InsufficientFunds)?;

if mint_info.key() != &source_account.mint {
if !pubkeys_eq(mint_info.key(), &source_account.mint) {
return Err(TokenError::MintMismatch.into());
}

Expand All @@ -53,7 +53,7 @@ pub fn process_burn(

if !source_account.is_owned_by_system_program_or_incinerator() {
match source_account.delegate() {
Some(delegate) if authority_info.key() == delegate => {
Some(delegate) if pubkeys_eq(authority_info.key(), delegate) => {
validate_owner(delegate, authority_info, remaining)?;

let delegated_amount = source_account
Expand Down
4 changes: 2 additions & 2 deletions p-token/src/processor/shared/mint_to.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::processor::{check_account_owner, validate_owner},
crate::processor::{check_account_owner, pubkeys_eq, validate_owner},
pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
spl_token_interface::{
error::TokenError,
Expand Down Expand Up @@ -33,7 +33,7 @@ pub fn process_mint_to(
return Err(TokenError::NativeNotSupported.into());
}

if mint_info.key() != &destination_account.mint {
if !pubkeys_eq(mint_info.key(), &destination_account.mint) {
return Err(TokenError::MintMismatch.into());
}

Expand Down
4 changes: 2 additions & 2 deletions p-token/src/processor/shared/toggle_account_state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::processor::validate_owner,
crate::processor::{pubkeys_eq, validate_owner},
pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
spl_token_interface::{
error::TokenError,
Expand All @@ -24,7 +24,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 !pubkeys_eq(mint_info.key(), &source_account.mint) {
return Err(TokenError::MintMismatch.into());
}

Expand Down
8 changes: 4 additions & 4 deletions p-token/src/processor/shared/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::processor::{check_account_owner, validate_owner},
crate::processor::{check_account_owner, pubkeys_eq, validate_owner},
pinocchio::{account_info::AccountInfo, program_error::ProgramError, ProgramResult},
spl_token_interface::{
error::TokenError,
Expand Down Expand Up @@ -101,7 +101,7 @@ pub fn process_transfer(
.checked_sub(amount)
.ok_or(TokenError::InsufficientFunds)?;

if source_account.mint != destination_account.mint {
if !pubkeys_eq(&source_account.mint, &destination_account.mint) {
return Err(TokenError::MintMismatch.into());
}

Expand All @@ -111,7 +111,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 !pubkeys_eq(mint_info.key(), &source_account.mint) {
return Err(TokenError::MintMismatch.into());
}

Expand All @@ -126,7 +126,7 @@ pub fn process_transfer(

// Validates the authority (delegate or owner).

if source_account.delegate() == Some(authority_info.key()) {
if source_account.delegate().map_or(false, |delegate| pubkeys_eq(delegate, authority_info.key())) {
validate_owner(authority_info.key(), authority_info, remaining)?;

let delegated_amount = source_account
Expand Down