Program address generator (#8995)
This commit is contained in:
parent
d75a470ffa
commit
fee002382e
@ -1,4 +1,7 @@
|
||||
use crate::{hash::hashv, program_utils::DecodeError};
|
||||
use crate::{
|
||||
hash::{hashv, Hasher},
|
||||
program_utils::DecodeError,
|
||||
};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
#[cfg(not(feature = "program"))]
|
||||
use std::error;
|
||||
@ -79,6 +82,22 @@ impl Pubkey {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn create_program_address(
|
||||
seeds: &[&str],
|
||||
program_id: &Pubkey,
|
||||
) -> Result<Pubkey, PubkeyError> {
|
||||
let mut hasher = Hasher::default();
|
||||
for seed in seeds.iter() {
|
||||
if seed.len() > MAX_SEED_LEN {
|
||||
return Err(PubkeyError::MaxSeedLengthExceeded);
|
||||
}
|
||||
hasher.hash(seed.as_ref());
|
||||
}
|
||||
hasher.hashv(&[program_id.as_ref(), "ProgramDerivedAddress".as_ref()]);
|
||||
|
||||
Ok(Pubkey::new(hashv(&[hasher.result().as_ref()]).as_ref()))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "program"))]
|
||||
pub fn new_rand() -> Self {
|
||||
Self::new(&rand::random::<[u8; 32]>())
|
||||
@ -220,6 +239,45 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_program_address() {
|
||||
let exceeded_seed = from_utf8(&[127; MAX_SEED_LEN + 1]).unwrap();
|
||||
let max_seed = from_utf8(&[0; MAX_SEED_LEN]).unwrap();
|
||||
let program_id = Pubkey::new(b"BPFLoader11111111111111111111111");
|
||||
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&[exceeded_seed], &program_id),
|
||||
Err(PubkeyError::MaxSeedLengthExceeded)
|
||||
);
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&["short_seed", exceeded_seed], &program_id),
|
||||
Err(PubkeyError::MaxSeedLengthExceeded)
|
||||
);
|
||||
assert!(Pubkey::create_program_address(&[max_seed], &Pubkey::new_rand(),).is_ok());
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&[""], &program_id),
|
||||
Ok("FXjJsFsMXM8LFXynZvEkED7yECADnaEgAzWD6yyg91QG"
|
||||
.parse()
|
||||
.unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&["☉"], &program_id),
|
||||
Ok("MAuKBzPvme5QmCNALp5iAEasZeazkpRyCZbwtJVkJEG"
|
||||
.parse()
|
||||
.unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
Pubkey::create_program_address(&["Talking", "Squirrels"], &program_id),
|
||||
Ok("3beXgJ9MfstiGfzav45bicJ7ygiwUEoCfsM4W94EuRii"
|
||||
.parse()
|
||||
.unwrap())
|
||||
);
|
||||
assert_ne!(
|
||||
Pubkey::create_program_address(&["Talking", "Squirrels"], &program_id),
|
||||
Pubkey::create_program_address(&["Talking"], &program_id),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_write_pubkey() -> Result<(), Box<dyn error::Error>> {
|
||||
let filename = "test_pubkey.json";
|
||||
|
Loading…
x
Reference in New Issue
Block a user