| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  | use crate::{
 | 
					
						
							| 
									
										
										
										
											2020-06-17 10:39:14 -07:00
										 |  |  |     decode_error::DecodeError,
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |     hash::{hash, hashv, Hasher},
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  | };
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  | use num_derive::{FromPrimitive, ToPrimitive};
 | 
					
						
							| 
									
										
										
										
											2020-03-20 18:07:37 -07:00
										 |  |  | #[cfg(not(feature = "program"))]
 | 
					
						
							|  |  |  | use std::error;
 | 
					
						
							|  |  |  | use std::{convert::TryFrom, fmt, mem, str::FromStr};
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  | use thiserror::Error;
 | 
					
						
							| 
									
										
										
										
											2018-09-26 17:55:36 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 16:22:20 -07:00
										 |  |  | pub use bs58;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  | /// maximum length of derived pubkey seed
 | 
					
						
							|  |  |  | pub const MAX_SEED_LEN: usize = 32;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #[derive(Error, Debug, Serialize, Clone, PartialEq, FromPrimitive, ToPrimitive)]
 | 
					
						
							|  |  |  | pub enum PubkeyError {
 | 
					
						
							| 
									
										
										
										
											2020-06-23 11:19:27 -07:00
										 |  |  |     /// Length of the seed is too long for address generation
 | 
					
						
							|  |  |  |     #[error("Length of the seed is too long for address generation")]
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  |     MaxSeedLengthExceeded,
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | impl<T> DecodeError<T> for PubkeyError {
 | 
					
						
							|  |  |  |     fn type_of() -> &'static str {
 | 
					
						
							|  |  |  |         "PubkeyError"
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-15 13:17:17 -06:00
										 |  |  | #[repr(transparent)]
 | 
					
						
							| 
									
										
										
										
											2020-07-06 20:22:23 +09:00
										 |  |  | #[derive(
 | 
					
						
							|  |  |  |     Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash, AbiExample,
 | 
					
						
							|  |  |  | )]
 | 
					
						
							| 
									
										
										
										
											2019-07-15 13:17:17 -06:00
										 |  |  | pub struct Pubkey([u8; 32]);
 | 
					
						
							| 
									
										
										
										
											2018-09-26 17:55:36 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-27 11:06:00 -07:00
										 |  |  | impl crate::sanitize::Sanitize for Pubkey {}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-20 18:07:37 -07:00
										 |  |  | #[derive(Error, Debug, Serialize, Clone, PartialEq, FromPrimitive, ToPrimitive)]
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  | pub enum ParsePubkeyError {
 | 
					
						
							| 
									
										
										
										
											2020-03-20 18:07:37 -07:00
										 |  |  |     #[error("String is the wrong size")]
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  |     WrongSize,
 | 
					
						
							| 
									
										
										
										
											2020-03-20 18:07:37 -07:00
										 |  |  |     #[error("Invalid Base58 string")]
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  |     Invalid,
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2020-03-20 18:07:37 -07:00
										 |  |  | impl<T> DecodeError<T> for ParsePubkeyError {
 | 
					
						
							|  |  |  |     fn type_of() -> &'static str {
 | 
					
						
							|  |  |  |         "ParsePubkeyError"
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:19:50 -06:00
										 |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  | impl FromStr for Pubkey {
 | 
					
						
							|  |  |  |     type Err = ParsePubkeyError;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fn from_str(s: &str) -> Result<Self, Self::Err> {
 | 
					
						
							|  |  |  |         let pubkey_vec = bs58::decode(s)
 | 
					
						
							|  |  |  |             .into_vec()
 | 
					
						
							|  |  |  |             .map_err(|_| ParsePubkeyError::Invalid)?;
 | 
					
						
							|  |  |  |         if pubkey_vec.len() != mem::size_of::<Pubkey>() {
 | 
					
						
							|  |  |  |             Err(ParsePubkeyError::WrongSize)
 | 
					
						
							|  |  |  |         } else {
 | 
					
						
							|  |  |  |             Ok(Pubkey::new(&pubkey_vec))
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-26 17:55:36 -06:00
										 |  |  | impl Pubkey {
 | 
					
						
							|  |  |  |     pub fn new(pubkey_vec: &[u8]) -> Self {
 | 
					
						
							| 
									
										
										
										
											2019-07-15 13:17:17 -06:00
										 |  |  |         Self(
 | 
					
						
							|  |  |  |             <[u8; 32]>::try_from(<&[u8]>::clone(&pubkey_vec))
 | 
					
						
							|  |  |  |                 .expect("Slice must be the same length as a Pubkey"),
 | 
					
						
							|  |  |  |         )
 | 
					
						
							| 
									
										
										
										
											2018-09-26 17:55:36 -06:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2019-03-30 21:37:33 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-03 20:55:18 -05:00
										 |  |  |     pub const fn new_from_array(pubkey_array: [u8; 32]) -> Self {
 | 
					
						
							|  |  |  |         Self(pubkey_array)
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  |     pub fn create_with_seed(
 | 
					
						
							|  |  |  |         base: &Pubkey,
 | 
					
						
							|  |  |  |         seed: &str,
 | 
					
						
							| 
									
										
										
										
											2020-05-18 12:55:41 -07:00
										 |  |  |         owner: &Pubkey,
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  |     ) -> Result<Pubkey, PubkeyError> {
 | 
					
						
							|  |  |  |         if seed.len() > MAX_SEED_LEN {
 | 
					
						
							|  |  |  |             return Err(PubkeyError::MaxSeedLengthExceeded);
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Ok(Pubkey::new(
 | 
					
						
							| 
									
										
										
										
											2020-05-18 12:55:41 -07:00
										 |  |  |             hashv(&[base.as_ref(), seed.as_ref(), owner.as_ref()]).as_ref(),
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  |         ))
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |     pub fn create_program_address(
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |         seeds: &[&[u8]],
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |         program_id: &Pubkey,
 | 
					
						
							|  |  |  |     ) -> Result<Pubkey, PubkeyError> {
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |         let mut hasher = Hasher::default();
 | 
					
						
							|  |  |  |         for seed in seeds.iter() {
 | 
					
						
							|  |  |  |             if seed.len() > MAX_SEED_LEN {
 | 
					
						
							|  |  |  |                 return Err(PubkeyError::MaxSeedLengthExceeded);
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |             hasher.hash(seed);
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |         hasher.hashv(&[program_id.as_ref(), "ProgramDerivedAddress".as_ref()]);
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |         Ok(Pubkey::new(hash(hasher.result().as_ref()).as_ref()))
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-06 09:20:14 -07:00
										 |  |  |     #[cfg(not(feature = "program"))]
 | 
					
						
							| 
									
										
										
										
											2019-03-30 21:37:33 -06:00
										 |  |  |     pub fn new_rand() -> Self {
 | 
					
						
							|  |  |  |         Self::new(&rand::random::<[u8; 32]>())
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2019-09-06 12:40:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-02 06:23:14 -07:00
										 |  |  |     pub fn to_bytes(self) -> [u8; 32] {
 | 
					
						
							|  |  |  |         self.0
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2018-09-26 17:55:36 -06:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | impl AsRef<[u8]> for Pubkey {
 | 
					
						
							|  |  |  |     fn as_ref(&self) -> &[u8] {
 | 
					
						
							|  |  |  |         &self.0[..]
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | impl fmt::Debug for Pubkey {
 | 
					
						
							|  |  |  |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
					
						
							|  |  |  |         write!(f, "{}", bs58::encode(self.0).into_string())
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | impl fmt::Display for Pubkey {
 | 
					
						
							|  |  |  |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
					
						
							|  |  |  |         write!(f, "{}", bs58::encode(self.0).into_string())
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-06 09:20:14 -07:00
										 |  |  | #[cfg(not(feature = "program"))]
 | 
					
						
							| 
									
										
										
										
											2019-11-06 11:18:25 -08:00
										 |  |  | pub fn write_pubkey_file(outfile: &str, pubkey: Pubkey) -> Result<(), Box<dyn error::Error>> {
 | 
					
						
							| 
									
										
										
										
											2019-09-06 09:20:14 -07:00
										 |  |  |     use std::io::Write;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:19:50 -06:00
										 |  |  |     let printable = format!("{}", pubkey);
 | 
					
						
							|  |  |  |     let serialized = serde_json::to_string(&printable)?;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-06 09:20:14 -07:00
										 |  |  |     if let Some(outdir) = std::path::Path::new(&outfile).parent() {
 | 
					
						
							|  |  |  |         std::fs::create_dir_all(outdir)?;
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:19:50 -06:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2019-09-06 09:20:14 -07:00
										 |  |  |     let mut f = std::fs::File::create(outfile)?;
 | 
					
						
							| 
									
										
										
										
											2019-12-19 23:27:54 -08:00
										 |  |  |     f.write_all(&serialized.into_bytes())?;
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:19:50 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Ok(())
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-06 09:20:14 -07:00
										 |  |  | #[cfg(not(feature = "program"))]
 | 
					
						
							| 
									
										
										
										
											2019-11-06 11:18:25 -08:00
										 |  |  | pub fn read_pubkey_file(infile: &str) -> Result<Pubkey, Box<dyn error::Error>> {
 | 
					
						
							| 
									
										
										
										
											2019-09-06 09:20:14 -07:00
										 |  |  |     let f = std::fs::File::open(infile.to_string())?;
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:19:50 -06:00
										 |  |  |     let printable: String = serde_json::from_reader(f)?;
 | 
					
						
							|  |  |  |     Ok(Pubkey::from_str(&printable)?)
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  | #[cfg(test)]
 | 
					
						
							|  |  |  | mod tests {
 | 
					
						
							|  |  |  |     use super::*;
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  |     use std::{fs::remove_file, str::from_utf8};
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn pubkey_fromstr() {
 | 
					
						
							| 
									
										
										
										
											2019-03-30 21:37:33 -06:00
										 |  |  |         let pubkey = Pubkey::new_rand();
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  |         let mut pubkey_base58_str = bs58::encode(pubkey.0).into_string();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert_eq!(pubkey_base58_str.parse::<Pubkey>(), Ok(pubkey));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pubkey_base58_str.push_str(&bs58::encode(pubkey.0).into_string());
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             pubkey_base58_str.parse::<Pubkey>(),
 | 
					
						
							|  |  |  |             Err(ParsePubkeyError::WrongSize)
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pubkey_base58_str.truncate(pubkey_base58_str.len() / 2);
 | 
					
						
							|  |  |  |         assert_eq!(pubkey_base58_str.parse::<Pubkey>(), Ok(pubkey));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pubkey_base58_str.truncate(pubkey_base58_str.len() / 2);
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             pubkey_base58_str.parse::<Pubkey>(),
 | 
					
						
							|  |  |  |             Err(ParsePubkeyError::WrongSize)
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let mut pubkey_base58_str = bs58::encode(pubkey.0).into_string();
 | 
					
						
							|  |  |  |         assert_eq!(pubkey_base58_str.parse::<Pubkey>(), Ok(pubkey));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // throw some non-base58 stuff in there
 | 
					
						
							|  |  |  |         pubkey_base58_str.replace_range(..1, "I");
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             pubkey_base58_str.parse::<Pubkey>(),
 | 
					
						
							|  |  |  |             Err(ParsePubkeyError::Invalid)
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-20 15:20:48 -07:00
										 |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test_create_with_seed() {
 | 
					
						
							|  |  |  |         assert!(Pubkey::create_with_seed(&Pubkey::new_rand(), "☉", &Pubkey::new_rand()).is_ok());
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             Pubkey::create_with_seed(
 | 
					
						
							|  |  |  |                 &Pubkey::new_rand(),
 | 
					
						
							|  |  |  |                 from_utf8(&[127; MAX_SEED_LEN + 1]).unwrap(),
 | 
					
						
							|  |  |  |                 &Pubkey::new_rand()
 | 
					
						
							|  |  |  |             ),
 | 
					
						
							|  |  |  |             Err(PubkeyError::MaxSeedLengthExceeded)
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |         assert!(Pubkey::create_with_seed(
 | 
					
						
							|  |  |  |             &Pubkey::new_rand(),
 | 
					
						
							|  |  |  |             "\
 | 
					
						
							|  |  |  |              \u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\
 | 
					
						
							|  |  |  |              ",
 | 
					
						
							|  |  |  |             &Pubkey::new_rand()
 | 
					
						
							|  |  |  |         )
 | 
					
						
							|  |  |  |         .is_ok());
 | 
					
						
							|  |  |  |         // utf-8 abuse ;)
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             Pubkey::create_with_seed(
 | 
					
						
							|  |  |  |                 &Pubkey::new_rand(),
 | 
					
						
							|  |  |  |                 "\
 | 
					
						
							|  |  |  |                  x\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\
 | 
					
						
							|  |  |  |                  ",
 | 
					
						
							|  |  |  |                 &Pubkey::new_rand()
 | 
					
						
							|  |  |  |             ),
 | 
					
						
							|  |  |  |             Err(PubkeyError::MaxSeedLengthExceeded)
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert!(Pubkey::create_with_seed(
 | 
					
						
							|  |  |  |             &Pubkey::new_rand(),
 | 
					
						
							|  |  |  |             std::str::from_utf8(&[0; MAX_SEED_LEN]).unwrap(),
 | 
					
						
							|  |  |  |             &Pubkey::new_rand(),
 | 
					
						
							|  |  |  |         )
 | 
					
						
							|  |  |  |         .is_ok());
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert!(Pubkey::create_with_seed(&Pubkey::new_rand(), "", &Pubkey::new_rand(),).is_ok());
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             Pubkey::create_with_seed(
 | 
					
						
							|  |  |  |                 &Pubkey::default(),
 | 
					
						
							|  |  |  |                 "limber chicken: 4/45",
 | 
					
						
							|  |  |  |                 &Pubkey::default(),
 | 
					
						
							|  |  |  |             ),
 | 
					
						
							|  |  |  |             Ok("9h1HyLCW5dZnBVap8C5egQ9Z6pHyjsh5MNy83iPqqRuq"
 | 
					
						
							|  |  |  |                 .parse()
 | 
					
						
							|  |  |  |                 .unwrap())
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |     #[test]
 | 
					
						
							|  |  |  |     fn test_create_program_address() {
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |         let exceeded_seed = &[127; MAX_SEED_LEN + 1];
 | 
					
						
							|  |  |  |         let max_seed = &[0; MAX_SEED_LEN];
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |         let program_id = Pubkey::from_str("BPFLoader1111111111111111111111111111111111").unwrap();
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |         let public_key = Pubkey::from_str("SeedPubey1111111111111111111111111111111111").unwrap();
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             Pubkey::create_program_address(&[exceeded_seed], &program_id),
 | 
					
						
							|  |  |  |             Err(PubkeyError::MaxSeedLengthExceeded)
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |             Pubkey::create_program_address(&[b"short_seed", exceeded_seed], &program_id),
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |             Err(PubkeyError::MaxSeedLengthExceeded)
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |         assert!(Pubkey::create_program_address(&[max_seed], &Pubkey::new_rand()).is_ok());
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |         assert_eq!(
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |             Pubkey::create_program_address(&[b""], &program_id),
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |             Ok("CsdSsqp6Upkh2qajhZMBM8xT4GAyDNSmcV37g4pN8rsc"
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |                 .parse()
 | 
					
						
							|  |  |  |                 .unwrap())
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |             Pubkey::create_program_address(&["☉".as_ref()], &program_id),
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |             Ok("A8mYnN8Pfx7Nn6f8RoQgsPNtAGAWmmKSBCDfyDvE6sXF"
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |                 .parse()
 | 
					
						
							|  |  |  |                 .unwrap())
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  |         assert_eq!(
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |             Pubkey::create_program_address(&[b"Talking", b"Squirrels"], &program_id),
 | 
					
						
							| 
									
										
										
										
											2020-05-26 19:32:19 -07:00
										 |  |  |             Ok("CawYq8Rmj4JRR992wVnGEFUjMEkmtmcFgEL4iS1qPczu"
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |                 .parse()
 | 
					
						
							|  |  |  |                 .unwrap())
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |         assert_eq!(
 | 
					
						
							|  |  |  |             Pubkey::create_program_address(&[public_key.as_ref()], &program_id),
 | 
					
						
							|  |  |  |             Ok("4ak7qJacCKMAGP8xJtDkg2VYZh5QKExa71ijMDjZGQyb"
 | 
					
						
							|  |  |  |                 .parse()
 | 
					
						
							|  |  |  |                 .unwrap())
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |         assert_ne!(
 | 
					
						
							| 
									
										
										
										
											2020-06-22 16:51:43 -07:00
										 |  |  |             Pubkey::create_program_address(&[b"Talking", b"Squirrels"], &program_id),
 | 
					
						
							|  |  |  |             Pubkey::create_program_address(&[b"Talking"], &program_id),
 | 
					
						
							| 
									
										
										
										
											2020-03-23 12:38:56 -07:00
										 |  |  |         );
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:19:50 -06:00
										 |  |  |     #[test]
 | 
					
						
							| 
									
										
										
										
											2019-07-14 13:37:55 -07:00
										 |  |  |     fn test_read_write_pubkey() -> Result<(), Box<dyn error::Error>> {
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:19:50 -06:00
										 |  |  |         let filename = "test_pubkey.json";
 | 
					
						
							| 
									
										
										
										
											2019-03-30 21:37:33 -06:00
										 |  |  |         let pubkey = Pubkey::new_rand();
 | 
					
						
							| 
									
										
										
										
											2019-11-06 11:18:25 -08:00
										 |  |  |         write_pubkey_file(filename, pubkey)?;
 | 
					
						
							|  |  |  |         let read = read_pubkey_file(filename)?;
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:19:50 -06:00
										 |  |  |         assert_eq!(read, pubkey);
 | 
					
						
							|  |  |  |         remove_file(filename)?;
 | 
					
						
							|  |  |  |         Ok(())
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2019-03-08 18:29:08 -08:00
										 |  |  | }
 |