File tree Expand file tree Collapse file tree 7 files changed +39
-12
lines changed Expand file tree Collapse file tree 7 files changed +39
-12
lines changed Original file line number Diff line number Diff line change @@ -10,7 +10,11 @@ use core::{
1010#[ cfg( target_os = "solana" ) ]
1111use crate :: syscalls:: sol_memset_;
1212
13- use crate :: { program_error:: ProgramError , pubkey:: Pubkey , ProgramResult } ;
13+ use crate :: {
14+ program_error:: ProgramError ,
15+ pubkey:: { pubkey_eq, Pubkey } ,
16+ ProgramResult ,
17+ } ;
1418
1519/// Maximum number of bytes a program may add to an account during a
1620/// single top-level instruction.
@@ -186,7 +190,7 @@ impl AccountInfo {
186190 /// Checks if the account is owned by the given program.
187191 #[ inline( always) ]
188192 pub fn is_owned_by ( & self , program : & Pubkey ) -> bool {
189- self . owner ( ) == program
193+ pubkey_eq ( self . owner ( ) , program)
190194 }
191195
192196 /// Changes the owner of the account.
Original file line number Diff line number Diff line change @@ -6,7 +6,7 @@ use crate::{
66 account_info:: { AccountInfo , BorrowState } ,
77 instruction:: { Account , Instruction , Signer } ,
88 program_error:: ProgramError ,
9- pubkey:: Pubkey ,
9+ pubkey:: { pubkey_eq , Pubkey } ,
1010 ProgramResult ,
1111} ;
1212
@@ -299,7 +299,7 @@ unsafe fn inner_invoke_signed_with_bounds<const MAX_ACCOUNTS: usize>(
299299 // In order to check whether the borrow state is compatible
300300 // with the invocation, we need to check that we have the
301301 // correct account info and meta pair.
302- if account_info. key ( ) != account_meta. pubkey {
302+ if ! pubkey_eq ( account_info. key ( ) , account_meta. pubkey ) {
303303 return Err ( ProgramError :: InvalidArgument ) ;
304304 }
305305
Original file line number Diff line number Diff line change 11//! Public key type and functions.
22
3+ use core:: ptr:: read_unaligned;
4+
35use crate :: program_error:: ProgramError ;
46
57/// Number of bytes in a pubkey.
@@ -33,6 +35,24 @@ pub fn log(pubkey: &Pubkey) {
3335 core:: hint:: black_box ( pubkey) ;
3436}
3537
38+ /// Compare two `Pubkey`s for equality.
39+ ///
40+ /// The implementation of this function is currectly more efficient
41+ /// than `p1 == p2` since it compares 8 bytes at a time instead of
42+ /// byte-by-byte.
43+ #[ inline( always) ]
44+ pub const fn pubkey_eq ( p1 : & Pubkey , p2 : & Pubkey ) -> bool {
45+ let p1_ptr = p1. as_ptr ( ) as * const u64 ;
46+ let p2_ptr = p2. as_ptr ( ) as * const u64 ;
47+
48+ unsafe {
49+ read_unaligned ( p1_ptr) == read_unaligned ( p2_ptr)
50+ && read_unaligned ( p1_ptr. add ( 1 ) ) == read_unaligned ( p2_ptr. add ( 1 ) )
51+ && read_unaligned ( p1_ptr. add ( 2 ) ) == read_unaligned ( p2_ptr. add ( 2 ) )
52+ && read_unaligned ( p1_ptr. add ( 3 ) ) == read_unaligned ( p2_ptr. add ( 3 ) )
53+ }
54+ }
55+
3656/// Find a valid [program derived address][pda] and its corresponding bump seed.
3757///
3858/// [pda]: https://solana.com/docs/core/cpi#program-derived-addresses
Original file line number Diff line number Diff line change 33use super :: Sysvar ;
44use crate :: {
55 account_info:: { AccountInfo , Ref } ,
6+ hint:: unlikely,
67 impl_sysvar_get,
78 program_error:: ProgramError ,
8- pubkey:: Pubkey ,
9+ pubkey:: { pubkey_eq , Pubkey } ,
910} ;
1011
1112/// The ID of the clock sysvar.
@@ -86,7 +87,7 @@ impl Clock {
8687 /// This method performs a check on the account info key.
8788 #[ inline]
8889 pub fn from_account_info ( account_info : & AccountInfo ) -> Result < Ref < Clock > , ProgramError > {
89- if account_info. key ( ) != & CLOCK_ID {
90+ if unlikely ( ! pubkey_eq ( account_info. key ( ) , & CLOCK_ID ) ) {
9091 return Err ( ProgramError :: InvalidArgument ) ;
9192 }
9293 Ok ( Ref :: map ( account_info. try_borrow_data ( ) ?, |data| unsafe {
Original file line number Diff line number Diff line change 55use super :: Sysvar ;
66use crate :: {
77 account_info:: { AccountInfo , Ref } ,
8+ hint:: unlikely,
89 impl_sysvar_get,
910 program_error:: ProgramError ,
10- pubkey:: Pubkey ,
11+ pubkey:: { pubkey_eq , Pubkey } ,
1112} ;
1213
1314/// The ID of the rent sysvar.
@@ -94,7 +95,7 @@ impl Rent {
9495 pub unsafe fn from_account_info_unchecked (
9596 account_info : & AccountInfo ,
9697 ) -> Result < & Self , ProgramError > {
97- if account_info. key ( ) != & RENT_ID {
98+ if unlikely ( ! pubkey_eq ( account_info. key ( ) , & RENT_ID ) ) {
9899 return Err ( ProgramError :: InvalidArgument ) ;
99100 }
100101 Ok ( Self :: from_bytes_unchecked (
Original file line number Diff line number Diff line change @@ -15,8 +15,9 @@ mod test_utils;
1515
1616use crate :: {
1717 account_info:: { AccountInfo , Ref } ,
18+ hint:: unlikely,
1819 program_error:: ProgramError ,
19- pubkey:: Pubkey ,
20+ pubkey:: { pubkey_eq , Pubkey } ,
2021 sysvars:: clock:: Slot ,
2122} ;
2223use core:: { mem, ops:: Deref , slice:: from_raw_parts} ;
@@ -277,7 +278,7 @@ impl<'a> SlotHashes<Ref<'a, [u8]>> {
277278 /// - `ProgramError::AccountBorrowFailed` if the account data is already mutably borrowed
278279 #[ inline( always) ]
279280 pub fn from_account_info ( account_info : & ' a AccountInfo ) -> Result < Self , ProgramError > {
280- if account_info. key ( ) != & SLOTHASHES_ID {
281+ if unlikely ( ! pubkey_eq ( account_info. key ( ) , & SLOTHASHES_ID ) ) {
281282 return Err ( ProgramError :: InvalidArgument ) ;
282283 }
283284
Original file line number Diff line number Diff line change 44#[ doc( hidden) ]
55// Re-export dependencies used in macros.
66pub mod reexport {
7- pub use pinocchio:: pubkey:: Pubkey ;
7+ pub use pinocchio:: pubkey:: { pubkey_eq , Pubkey } ;
88}
99
1010use core:: mem:: MaybeUninit ;
@@ -176,7 +176,7 @@ macro_rules! declare_id {
176176 #[ doc = "Returns `true` if given pubkey is the program ID." ]
177177 #[ inline]
178178 pub fn check_id( id: & $crate:: reexport:: Pubkey ) -> bool {
179- id == & ID
179+ $crate :: reexport :: pubkey_eq ( id , & ID )
180180 }
181181
182182 #[ doc = "Returns the program ID." ]
You can’t perform that action at this time.
0 commit comments