@@ -14,29 +14,31 @@ use pinocchio::pubkey::{Pubkey, MAX_SEEDS, PDA_MARKER};
1414#[ cfg( target_os = "solana" ) ]
1515use pinocchio:: syscalls:: sol_sha256;
1616
17- /// Derive a [program address][pda] from the given seeds, bump and program id.
17+ /// Derive a [program address][pda] from the given its seeds and program id.
1818///
1919/// [pda]: https://solana.com/docs/core/pda
2020///
21- /// This function avoids the cost of the `create_program_address` syscall,
22- /// which is `1500` compute units, by directly computing the derived address
23- /// calculating the hash of the seeds, bump, and program id using the
24- /// `sol_sha256` syscall.
21+ /// In general, the seeds include a bump (byte) value to ensure a valid PDA
22+ /// (off-curve) is generated. The bump is typically the last byte of the seeds
23+ /// array. Even when a program stores a bump to derive a program address, it is
24+ /// necessary to use the [`pinocchio::pubkey::create_program_address`] to validate
25+ /// the derivation. In most cases, the program has the correct seeds for the
26+ /// derivation, so it would be sufficient to just perform the derivation and compare
27+ /// it against the expected resulting address.
2528///
26- /// Even when a program stores a bump to derive a program address, it is necessary
27- /// to use the [`pinocchio::pubkey::create_program_address`] to validate the
28- /// derivation. In most cases, the program has the correct seeds for the derivation,
29- /// so it would be sufficient to just perform the derivation and compare it against
30- /// the expected resulting address.
29+ /// This function avoids the cost of the `create_program_address` syscall
30+ /// (`1500` compute units) by directly computing the derived address
31+ /// calculating the hash of the seeds and program id using the
32+ /// `sol_sha256` syscall.
3133///
3234/// # Important
3335///
3436/// This function differs from [`pinocchio::pubkey::create_program_address`] in that it
3537/// does not perform a validation to ensure that the derived address is a valid
3638/// (off-curve) program derived address. It is intended for use in cases where the
37- /// seeds, bump, and program id are known to be valid, and the caller wants to derive
39+ /// seeds and program id are known to be valid, and the caller wants to derive
3840/// the address without incurring the cost of the `create_program_address` syscall.
39- pub fn derive_address < const N : usize > ( seeds : & [ & [ u8 ] ; N ] , bump : u8 , program_id : & Pubkey ) -> Pubkey {
41+ pub fn derive_address < const N : usize > ( seeds : & [ & [ u8 ] ; N ] , program_id : & Pubkey ) -> Pubkey {
4042 const {
4143 assert ! (
4244 N <= MAX_SEEDS ,
@@ -45,37 +47,34 @@ pub fn derive_address<const N: usize>(seeds: &[&[u8]; N], bump: u8, program_id:
4547 }
4648
4749 const UNINIT : MaybeUninit < & [ u8 ] > = MaybeUninit :: < & [ u8 ] > :: uninit ( ) ;
48- let mut data = [ UNINIT ; MAX_SEEDS + 3 ] ;
50+ let mut data = [ UNINIT ; MAX_SEEDS + 2 ] ;
4951 let mut i = 0 ;
5052
5153 while i < N {
52- // SAFETY: `data` is guanranteed to have enough space for `N` seeds,
54+ // SAFETY: `data` is guaranteed to have enough space for `N` seeds,
5355 // so `i` will always be within bounds.
5456 unsafe {
5557 data. get_unchecked_mut ( i) . write ( seeds. get_unchecked ( i) ) ;
5658 }
5759 i += 1 ;
5860 }
5961
60- let bump = [ bump] ;
61-
62- // SAFETY: `data` is guaranteed to have enough space for `MAX_SEEDS + 3`
62+ // SAFETY: `data` is guaranteed to have enough space for `MAX_SEEDS + 2`
6363 // elements, and `MAX_SEEDS` is as large as `N`.
6464 unsafe {
65- data. get_unchecked_mut ( i) . write ( bump. as_ref ( ) ) ;
66- data. get_unchecked_mut ( i + 1 ) . write ( program_id. as_ref ( ) ) ;
67- data. get_unchecked_mut ( i + 2 ) . write ( PDA_MARKER . as_ref ( ) ) ;
65+ data. get_unchecked_mut ( i) . write ( program_id. as_ref ( ) ) ;
66+ data. get_unchecked_mut ( i + 1 ) . write ( PDA_MARKER . as_ref ( ) ) ;
6867 }
6968
7069 #[ cfg( target_os = "solana" ) ]
7170 {
7271 let mut pda = MaybeUninit :: < [ u8 ; 32 ] > :: uninit ( ) ;
7372
74- // SAFETY: `data` has `i + 3 ` elements initialized.
73+ // SAFETY: `data` has `N + 2 ` elements initialized.
7574 unsafe {
7675 sol_sha256 (
7776 data. as_ptr ( ) as * const u8 ,
78- ( N + 3 ) as u64 ,
77+ ( N + 2 ) as u64 ,
7978 pda. as_mut_ptr ( ) as * mut u8 ,
8079 ) ;
8180 }
@@ -88,15 +87,20 @@ pub fn derive_address<const N: usize>(seeds: &[&[u8]; N], bump: u8, program_id:
8887 unreachable ! ( "deriving a pda is only available on target `solana`" ) ;
8988}
9089
91- /// Derive a [program address][pda] from the given seeds, bump and program id.
90+ /// Derive a [program address][pda] from the given seeds and program id.
9291///
9392/// [pda]: https://solana.com/docs/core/pda
9493///
95- /// This function avoids the cost of the `create_program_address` syscall,
96- /// which is `1500` compute units, by directly computing the derived address
97- /// using the SHA-256 hash of the seeds, bump, and program id.
94+ /// In general, the seeds include a bump (byte) value to ensure a valid PDA
95+ /// (off-curve) is generated. The bump is typically the last byte of the seeds
96+ /// array.
97+ ///
98+ /// This function avoids the cost of the `create_program_address` syscall
99+ /// (`1500` compute units) by directly computing the derived address
100+ /// using the SHA-256 hash of the seeds and program id.
98101///
99- /// This function is intended for use in `const` contexts.
102+ /// This function is intended for use in `const` contexts - i.e., the seeds are
103+ /// known at compile time and the program id is also a constant.
100104///
101105/// # Important
102106///
@@ -110,7 +114,6 @@ pub fn derive_address<const N: usize>(seeds: &[&[u8]; N], bump: u8, program_id:
110114#[ cfg( feature = "const" ) ]
111115pub const fn derive_address_const < const N : usize > (
112116 seeds : & [ & [ u8 ] ; N ] ,
113- bump : u8 ,
114117 program_id : & Pubkey ,
115118) -> Pubkey {
116119 const {
@@ -128,13 +131,7 @@ pub const fn derive_address_const<const N: usize>(
128131 i += 1 ;
129132 }
130133
131- let bump = [ bump] ;
132-
133- hasher
134- . update ( & bump)
135- . update ( program_id)
136- . update ( PDA_MARKER )
137- . finalize ( )
134+ hasher. update ( program_id) . update ( PDA_MARKER ) . finalize ( )
138135}
139136
140137/// Convenience macro to define a static `Pubkey` value.
0 commit comments