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};
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
#[cfg(not(feature = "program"))]
|
#[cfg(not(feature = "program"))]
|
||||||
use std::error;
|
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"))]
|
#[cfg(not(feature = "program"))]
|
||||||
pub fn new_rand() -> Self {
|
pub fn new_rand() -> Self {
|
||||||
Self::new(&rand::random::<[u8; 32]>())
|
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]
|
#[test]
|
||||||
fn test_read_write_pubkey() -> Result<(), Box<dyn error::Error>> {
|
fn test_read_write_pubkey() -> Result<(), Box<dyn error::Error>> {
|
||||||
let filename = "test_pubkey.json";
|
let filename = "test_pubkey.json";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user