1use alloc::{
4 format,
5 string::{String, ToString},
6 vec::Vec,
7};
8
9use core::{
10 convert::TryFrom,
11 fmt::{self, Debug, Display, Formatter},
12 str::FromStr,
13};
14
15#[cfg(any(feature = "testing", test))]
16use crate::testing::TestRng;
17
18#[cfg(doc)]
19use crate::CLValue;
20use blake2::{
21 digest::{Update, VariableOutput},
22 VarBlake2b,
23};
24#[cfg(feature = "datasize")]
25use datasize::DataSize;
26#[cfg(any(feature = "testing", test))]
27use rand::{
28 distributions::{Distribution, Standard},
29 Rng,
30};
31#[cfg(feature = "json-schema")]
32use schemars::JsonSchema;
33use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer};
34use tracing::{error, warn};
35
36use crate::{
37 account::{AccountHash, ACCOUNT_HASH_LENGTH},
38 addressable_entity::{
39 self, AddressableEntityHash, EntityAddr, EntityKindTag, EntryPointAddr, NamedKeyAddr,
40 },
41 block::BlockGlobalAddr,
42 byte_code,
43 bytesrepr::{
44 self, Error, FromBytes, ToBytes, U32_SERIALIZED_LENGTH, U64_SERIALIZED_LENGTH,
45 U8_SERIALIZED_LENGTH,
46 },
47 checksummed_hex,
48 contract_messages::{self, MessageAddr, TopicNameHash, TOPIC_NAME_HASH_LENGTH},
49 contract_wasm::ContractWasmHash,
50 contracts::{ContractHash, ContractPackageHash},
51 package::PackageHash,
52 system::{
53 auction::{BidAddr, BidAddrTag},
54 mint::BalanceHoldAddr,
55 },
56 uref::{self, URef, URefAddr, UREF_SERIALIZED_LENGTH},
57 ByteCodeAddr, DeployHash, Digest, EraId, Tagged, TransferAddr, TransferFromStrError,
58 TRANSFER_ADDR_LENGTH, UREF_ADDR_LENGTH,
59};
60
61const HASH_PREFIX: &str = "hash-";
62const DEPLOY_INFO_PREFIX: &str = "deploy-";
63const TRANSFER_PREFIX: &str = "transfer-";
64const ERA_INFO_PREFIX: &str = "era-";
65const BALANCE_PREFIX: &str = "balance-";
66const BALANCE_HOLD_PREFIX: &str = "balance-hold-";
67const BID_PREFIX: &str = "bid-";
68const WITHDRAW_PREFIX: &str = "withdraw-";
69const DICTIONARY_PREFIX: &str = "dictionary-";
70const UNBOND_PREFIX: &str = "unbond-";
71const SYSTEM_ENTITY_REGISTRY_PREFIX: &str = "system-entity-registry-";
72const ERA_SUMMARY_PREFIX: &str = "era-summary-";
73const CHAINSPEC_REGISTRY_PREFIX: &str = "chainspec-registry-";
74const CHECKSUM_REGISTRY_PREFIX: &str = "checksum-registry-";
75const BID_ADDR_PREFIX: &str = "bid-addr-";
76const PACKAGE_PREFIX: &str = "package-";
77const BLOCK_GLOBAL_TIME_PREFIX: &str = "block-time-";
78const BLOCK_GLOBAL_MESSAGE_COUNT_PREFIX: &str = "block-message-count-";
79const BLOCK_GLOBAL_PROTOCOL_VERSION_PREFIX: &str = "block-protocol-version-";
80const BLOCK_GLOBAL_ADDRESSABLE_ENTITY_PREFIX: &str = "block-addressable-entity-";
81const STATE_PREFIX: &str = "state-";
82
83pub const BLAKE2B_DIGEST_LENGTH: usize = 32;
85pub const KEY_HASH_LENGTH: usize = 32;
87pub const KEY_TRANSFER_LENGTH: usize = TRANSFER_ADDR_LENGTH;
89pub const KEY_DEPLOY_INFO_LENGTH: usize = DeployHash::LENGTH;
91pub const KEY_DICTIONARY_LENGTH: usize = 32;
93pub const DICTIONARY_ITEM_KEY_MAX_LENGTH: usize = 128;
95pub const ADDR_LENGTH: usize = 32;
97const PADDING_BYTES: [u8; 32] = [0u8; 32];
98const BLOCK_GLOBAL_PADDING_BYTES: [u8; 31] = [0u8; 31];
99const KEY_ID_SERIALIZED_LENGTH: usize = 1;
100const KEY_HASH_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LENGTH;
102const KEY_UREF_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + UREF_SERIALIZED_LENGTH;
103const KEY_TRANSFER_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_TRANSFER_LENGTH;
104const KEY_DEPLOY_INFO_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_DEPLOY_INFO_LENGTH;
105const KEY_ERA_INFO_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + U64_SERIALIZED_LENGTH;
106const KEY_BALANCE_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + UREF_ADDR_LENGTH;
107const KEY_BID_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LENGTH;
108const KEY_WITHDRAW_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LENGTH;
109const KEY_UNBOND_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_HASH_LENGTH;
110const KEY_DICTIONARY_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + KEY_DICTIONARY_LENGTH;
111const KEY_SYSTEM_ENTITY_REGISTRY_SERIALIZED_LENGTH: usize =
112 KEY_ID_SERIALIZED_LENGTH + PADDING_BYTES.len();
113const KEY_ERA_SUMMARY_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + PADDING_BYTES.len();
114const KEY_CHAINSPEC_REGISTRY_SERIALIZED_LENGTH: usize =
115 KEY_ID_SERIALIZED_LENGTH + PADDING_BYTES.len();
116const KEY_CHECKSUM_REGISTRY_SERIALIZED_LENGTH: usize =
117 KEY_ID_SERIALIZED_LENGTH + PADDING_BYTES.len();
118const KEY_PACKAGE_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH + 32;
119const KEY_MESSAGE_SERIALIZED_LENGTH: usize = KEY_ID_SERIALIZED_LENGTH
120 + U8_SERIALIZED_LENGTH
121 + KEY_HASH_LENGTH
122 + TOPIC_NAME_HASH_LENGTH
123 + U8_SERIALIZED_LENGTH
124 + U32_SERIALIZED_LENGTH;
125
126const MAX_SERIALIZED_LENGTH: usize = KEY_MESSAGE_SERIALIZED_LENGTH;
127
128pub type HashAddr = [u8; KEY_HASH_LENGTH];
130
131pub type PackageAddr = [u8; ADDR_LENGTH];
133
134pub type DictionaryAddr = [u8; KEY_DICTIONARY_LENGTH];
136
137#[allow(missing_docs)]
138#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
139#[repr(u8)]
140pub enum KeyTag {
141 Account = 0,
142 Hash = 1,
143 URef = 2,
144 Transfer = 3,
145 DeployInfo = 4,
146 EraInfo = 5,
147 Balance = 6,
148 Bid = 7,
149 Withdraw = 8,
150 Dictionary = 9,
151 SystemEntityRegistry = 10,
152 EraSummary = 11,
153 Unbond = 12,
154 ChainspecRegistry = 13,
155 ChecksumRegistry = 14,
156 BidAddr = 15,
157 Package = 16,
158 AddressableEntity = 17,
159 ByteCode = 18,
160 Message = 19,
161 NamedKey = 20,
162 BlockGlobal = 21,
163 BalanceHold = 22,
164 EntryPoint = 23,
165 State = 24,
166}
167
168impl KeyTag {
169 #[cfg(any(feature = "testing", test))]
171 pub fn random(rng: &mut TestRng) -> Self {
172 match rng.gen_range(0..=23) {
173 0 => KeyTag::Account,
174 1 => KeyTag::Hash,
175 2 => KeyTag::URef,
176 3 => KeyTag::Transfer,
177 4 => KeyTag::DeployInfo,
178 5 => KeyTag::EraInfo,
179 6 => KeyTag::Balance,
180 7 => KeyTag::Bid,
181 8 => KeyTag::Withdraw,
182 9 => KeyTag::Dictionary,
183 10 => KeyTag::SystemEntityRegistry,
184 11 => KeyTag::EraSummary,
185 12 => KeyTag::Unbond,
186 13 => KeyTag::ChainspecRegistry,
187 14 => KeyTag::ChecksumRegistry,
188 15 => KeyTag::BidAddr,
189 16 => KeyTag::Package,
190 17 => KeyTag::AddressableEntity,
191 18 => KeyTag::ByteCode,
192 19 => KeyTag::Message,
193 20 => KeyTag::NamedKey,
194 21 => KeyTag::BlockGlobal,
195 22 => KeyTag::BalanceHold,
196 23 => KeyTag::EntryPoint,
197 24 => KeyTag::State,
198 _ => panic!(),
199 }
200 }
201}
202
203impl Display for KeyTag {
204 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
205 match self {
206 KeyTag::Account => write!(f, "Account"),
207 KeyTag::Hash => write!(f, "Hash"),
208 KeyTag::URef => write!(f, "URef"),
209 KeyTag::Transfer => write!(f, "Transfer"),
210 KeyTag::DeployInfo => write!(f, "DeployInfo"),
211 KeyTag::EraInfo => write!(f, "EraInfo"),
212 KeyTag::Balance => write!(f, "Balance"),
213 KeyTag::Bid => write!(f, "Bid"),
214 KeyTag::Withdraw => write!(f, "Withdraw"),
215 KeyTag::Dictionary => write!(f, "Dictionary"),
216 KeyTag::SystemEntityRegistry => write!(f, "SystemEntityRegistry"),
217 KeyTag::EraSummary => write!(f, "EraSummary"),
218 KeyTag::Unbond => write!(f, "Unbond"),
219 KeyTag::ChainspecRegistry => write!(f, "ChainspecRegistry"),
220 KeyTag::ChecksumRegistry => write!(f, "ChecksumRegistry"),
221 KeyTag::BidAddr => write!(f, "BidAddr"),
222 KeyTag::Package => write!(f, "Package"),
223 KeyTag::AddressableEntity => write!(f, "AddressableEntity"),
224 KeyTag::ByteCode => write!(f, "ByteCode"),
225 KeyTag::Message => write!(f, "Message"),
226 KeyTag::NamedKey => write!(f, "NamedKey"),
227 KeyTag::BlockGlobal => write!(f, "BlockGlobal"),
228 KeyTag::BalanceHold => write!(f, "BalanceHold"),
229 KeyTag::State => write!(f, "State"),
230 KeyTag::EntryPoint => write!(f, "EntryPoint"),
231 }
232 }
233}
234
235impl ToBytes for KeyTag {
236 fn to_bytes(&self) -> Result<Vec<u8>, Error> {
237 let mut result = bytesrepr::unchecked_allocate_buffer(self);
238 self.write_bytes(&mut result)?;
239 Ok(result)
240 }
241
242 fn serialized_length(&self) -> usize {
243 KEY_ID_SERIALIZED_LENGTH
244 }
245
246 fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
247 writer.push(*self as u8);
248 Ok(())
249 }
250}
251
252impl FromBytes for KeyTag {
253 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
254 let (id, rem) = u8::from_bytes(bytes)?;
255 let tag = match id {
256 tag if tag == KeyTag::Account as u8 => KeyTag::Account,
257 tag if tag == KeyTag::Hash as u8 => KeyTag::Hash,
258 tag if tag == KeyTag::URef as u8 => KeyTag::URef,
259 tag if tag == KeyTag::Transfer as u8 => KeyTag::Transfer,
260 tag if tag == KeyTag::DeployInfo as u8 => KeyTag::DeployInfo,
261 tag if tag == KeyTag::EraInfo as u8 => KeyTag::EraInfo,
262 tag if tag == KeyTag::Balance as u8 => KeyTag::Balance,
263 tag if tag == KeyTag::Bid as u8 => KeyTag::Bid,
264 tag if tag == KeyTag::Withdraw as u8 => KeyTag::Withdraw,
265 tag if tag == KeyTag::Dictionary as u8 => KeyTag::Dictionary,
266 tag if tag == KeyTag::SystemEntityRegistry as u8 => KeyTag::SystemEntityRegistry,
267 tag if tag == KeyTag::EraSummary as u8 => KeyTag::EraSummary,
268 tag if tag == KeyTag::Unbond as u8 => KeyTag::Unbond,
269 tag if tag == KeyTag::ChainspecRegistry as u8 => KeyTag::ChainspecRegistry,
270 tag if tag == KeyTag::ChecksumRegistry as u8 => KeyTag::ChecksumRegistry,
271 tag if tag == KeyTag::BidAddr as u8 => KeyTag::BidAddr,
272 tag if tag == KeyTag::Package as u8 => KeyTag::Package,
273 tag if tag == KeyTag::AddressableEntity as u8 => KeyTag::AddressableEntity,
274 tag if tag == KeyTag::ByteCode as u8 => KeyTag::ByteCode,
275 tag if tag == KeyTag::Message as u8 => KeyTag::Message,
276 tag if tag == KeyTag::NamedKey as u8 => KeyTag::NamedKey,
277 tag if tag == KeyTag::BlockGlobal as u8 => KeyTag::BlockGlobal,
278 tag if tag == KeyTag::BalanceHold as u8 => KeyTag::BalanceHold,
279 tag if tag == KeyTag::EntryPoint as u8 => KeyTag::EntryPoint,
280 tag if tag == KeyTag::State as u8 => KeyTag::State,
281 _ => return Err(Error::Formatting),
282 };
283 Ok((tag, rem))
284 }
285}
286
287#[repr(C)]
290#[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
291#[cfg_attr(feature = "datasize", derive(DataSize))]
292pub enum Key {
293 Account(AccountHash),
295 Hash(HashAddr),
298 URef(URef),
300 Transfer(TransferAddr),
302 DeployInfo(DeployHash),
304 EraInfo(EraId),
306 Balance(URefAddr),
308 Bid(AccountHash),
310 Withdraw(AccountHash),
312 Dictionary(DictionaryAddr),
315 SystemEntityRegistry,
317 EraSummary,
319 Unbond(AccountHash),
321 ChainspecRegistry,
323 ChecksumRegistry,
325 BidAddr(BidAddr),
327 SmartContract(PackageAddr),
329 AddressableEntity(EntityAddr),
331 ByteCode(ByteCodeAddr),
333 Message(MessageAddr),
335 NamedKey(NamedKeyAddr),
337 BlockGlobal(BlockGlobalAddr),
339 BalanceHold(BalanceHoldAddr),
341 EntryPoint(EntryPointAddr),
343 State(EntityAddr),
345}
346
347#[cfg(feature = "json-schema")]
348impl JsonSchema for Key {
349 fn schema_name() -> String {
350 String::from("Key")
351 }
352
353 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
354 let schema = gen.subschema_for::<String>();
355 let mut schema_object = schema.into_object();
356 schema_object.metadata().description = Some(
357 "The key as a formatted string, under which data (e.g. `CLValue`s, smart contracts, \
358 user accounts) are stored in global state."
359 .to_string(),
360 );
361 schema_object.into()
362 }
363}
364
365#[derive(Debug)]
367#[non_exhaustive]
368pub enum FromStrError {
369 Account(addressable_entity::FromStrError),
371 Hash(String),
373 URef(uref::FromStrError),
375 Transfer(TransferFromStrError),
377 DeployInfo(String),
379 EraInfo(String),
381 Balance(String),
383 Bid(String),
385 Withdraw(String),
387 Dictionary(String),
389 SystemEntityRegistry(String),
391 EraSummary(String),
393 Unbond(String),
395 ChainspecRegistry(String),
397 ChecksumRegistry(String),
399 BidAddr(String),
401 Package(String),
403 AddressableEntity(String),
405 ByteCode(String),
407 Message(contract_messages::FromStrError),
409 NamedKey(String),
411 BlockGlobal(String),
413 BalanceHold(String),
415 EntryPoint(String),
417 State(String),
419 UnknownPrefix,
421}
422
423impl From<addressable_entity::FromStrError> for FromStrError {
424 fn from(error: addressable_entity::FromStrError) -> Self {
425 FromStrError::Account(error)
426 }
427}
428
429impl From<uref::FromStrError> for FromStrError {
430 fn from(error: uref::FromStrError) -> Self {
431 FromStrError::URef(error)
432 }
433}
434
435impl From<contract_messages::FromStrError> for FromStrError {
436 fn from(error: contract_messages::FromStrError) -> Self {
437 FromStrError::Message(error)
438 }
439}
440
441impl Display for FromStrError {
442 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
443 match self {
444 FromStrError::Account(error) => write!(f, "account-key from string error: {}", error),
445 FromStrError::Hash(error) => write!(f, "hash-key from string error: {}", error),
446 FromStrError::URef(error) => write!(f, "uref-key from string error: {}", error),
447 FromStrError::Transfer(error) => {
448 write!(f, "legacy-transfer-key from string error: {}", error)
449 }
450 FromStrError::DeployInfo(error) => {
451 write!(f, "deploy-info-key from string error: {}", error)
452 }
453 FromStrError::EraInfo(error) => write!(f, "era-info-key from string error: {}", error),
454 FromStrError::Balance(error) => write!(f, "balance-key from string error: {}", error),
455 FromStrError::Bid(error) => write!(f, "bid-key from string error: {}", error),
456 FromStrError::Withdraw(error) => write!(f, "withdraw-key from string error: {}", error),
457 FromStrError::Dictionary(error) => {
458 write!(f, "dictionary-key from string error: {}", error)
459 }
460 FromStrError::SystemEntityRegistry(error) => {
461 write!(
462 f,
463 "system-contract-registry-key from string error: {}",
464 error
465 )
466 }
467 FromStrError::EraSummary(error) => {
468 write!(f, "era-summary-key from string error: {}", error)
469 }
470 FromStrError::Unbond(error) => {
471 write!(f, "unbond-key from string error: {}", error)
472 }
473 FromStrError::ChainspecRegistry(error) => {
474 write!(f, "chainspec-registry-key from string error: {}", error)
475 }
476 FromStrError::ChecksumRegistry(error) => {
477 write!(f, "checksum-registry-key from string error: {}", error)
478 }
479 FromStrError::BidAddr(error) => write!(f, "bid-addr-key from string error: {}", error),
480 FromStrError::Package(error) => write!(f, "package-key from string error: {}", error),
481 FromStrError::AddressableEntity(error) => {
482 write!(f, "addressable-entity-key from string error: {}", error)
483 }
484 FromStrError::ByteCode(error) => {
485 write!(f, "byte-code-key from string error: {}", error)
486 }
487 FromStrError::Message(error) => {
488 write!(f, "message-key from string error: {}", error)
489 }
490 FromStrError::NamedKey(error) => {
491 write!(f, "named-key from string error: {}", error)
492 }
493 FromStrError::BlockGlobal(error) => {
494 write!(f, "block-message-count-key form string error: {}", error)
495 }
496 FromStrError::BalanceHold(error) => {
497 write!(f, "balance-hold from string error: {}", error)
498 }
499 FromStrError::EntryPoint(error) => {
500 write!(f, "entry-point from string error: {}", error)
501 }
502 FromStrError::UnknownPrefix => write!(f, "unknown prefix for key"),
503 FromStrError::State(error) => write!(f, "state-key from string error: {}", error),
504 }
505 }
506}
507
508impl Key {
509 #[doc(hidden)]
511 pub fn type_string(&self) -> String {
512 match self {
513 Key::Account(_) => String::from("Key::Account"),
514 Key::Hash(_) => String::from("Key::Hash"),
515 Key::URef(_) => String::from("Key::URef"),
516 Key::Transfer(_) => String::from("Key::Transfer"),
517 Key::DeployInfo(_) => String::from("Key::DeployInfo"),
518 Key::EraInfo(_) => String::from("Key::EraInfo"),
519 Key::Balance(_) => String::from("Key::Balance"),
520 Key::Bid(_) => String::from("Key::Bid"),
521 Key::Withdraw(_) => String::from("Key::Unbond"),
522 Key::Dictionary(_) => String::from("Key::Dictionary"),
523 Key::SystemEntityRegistry => String::from("Key::SystemEntityRegistry"),
524 Key::EraSummary => String::from("Key::EraSummary"),
525 Key::Unbond(_) => String::from("Key::Unbond"),
526 Key::ChainspecRegistry => String::from("Key::ChainspecRegistry"),
527 Key::ChecksumRegistry => String::from("Key::ChecksumRegistry"),
528 Key::BidAddr(_) => String::from("Key::BidAddr"),
529 Key::SmartContract(_) => String::from("Key::SmartContract"),
530 Key::AddressableEntity(_) => String::from("Key::AddressableEntity"),
531 Key::ByteCode(_) => String::from("Key::ByteCode"),
532 Key::Message(_) => String::from("Key::Message"),
533 Key::NamedKey(_) => String::from("Key::NamedKey"),
534 Key::BlockGlobal(_) => String::from("Key::BlockGlobal"),
535 Key::BalanceHold(_) => String::from("Key::BalanceHold"),
536 Key::EntryPoint(_) => String::from("Key::EntryPoint"),
537 Key::State(_) => String::from("Key::State"),
538 }
539 }
540
541 pub const fn max_serialized_length() -> usize {
543 MAX_SERIALIZED_LENGTH
544 }
545
546 #[must_use]
550 pub fn normalize(self) -> Key {
551 match self {
552 Key::URef(uref) => Key::URef(uref.remove_access_rights()),
553 other => other,
554 }
555 }
556
557 pub fn to_formatted_string(self) -> String {
559 match self {
560 Key::Account(account_hash) => account_hash.to_formatted_string(),
561 Key::Hash(addr) => format!("{}{}", HASH_PREFIX, base16::encode_lower(&addr)),
562 Key::URef(uref) => uref.to_formatted_string(),
563 Key::Transfer(transfer_v1_addr) => {
564 format!(
565 "{}{}",
566 TRANSFER_PREFIX,
567 base16::encode_lower(&transfer_v1_addr.value())
568 )
569 }
570 Key::DeployInfo(deploy_hash) => {
571 format!(
572 "{}{}",
573 DEPLOY_INFO_PREFIX,
574 base16::encode_lower(deploy_hash.as_ref())
575 )
576 }
577 Key::EraInfo(era_id) => {
578 format!("{}{}", ERA_INFO_PREFIX, era_id.value())
579 }
580 Key::Balance(uref_addr) => {
581 format!("{}{}", BALANCE_PREFIX, base16::encode_lower(&uref_addr))
582 }
583 Key::Bid(account_hash) => {
584 format!("{}{}", BID_PREFIX, base16::encode_lower(&account_hash))
585 }
586 Key::Withdraw(account_hash) => {
587 format!("{}{}", WITHDRAW_PREFIX, base16::encode_lower(&account_hash))
588 }
589 Key::Dictionary(dictionary_addr) => {
590 format!(
591 "{}{}",
592 DICTIONARY_PREFIX,
593 base16::encode_lower(&dictionary_addr)
594 )
595 }
596 Key::SystemEntityRegistry => {
597 format!(
598 "{}{}",
599 SYSTEM_ENTITY_REGISTRY_PREFIX,
600 base16::encode_lower(&PADDING_BYTES)
601 )
602 }
603 Key::EraSummary => {
604 format!(
605 "{}{}",
606 ERA_SUMMARY_PREFIX,
607 base16::encode_lower(&PADDING_BYTES)
608 )
609 }
610 Key::Unbond(account_hash) => {
611 format!("{}{}", UNBOND_PREFIX, base16::encode_lower(&account_hash))
612 }
613 Key::ChainspecRegistry => {
614 format!(
615 "{}{}",
616 CHAINSPEC_REGISTRY_PREFIX,
617 base16::encode_lower(&PADDING_BYTES)
618 )
619 }
620 Key::ChecksumRegistry => {
621 format!(
622 "{}{}",
623 CHECKSUM_REGISTRY_PREFIX,
624 base16::encode_lower(&PADDING_BYTES)
625 )
626 }
627 Key::BidAddr(bid_addr) => {
628 format!("{}{}", BID_ADDR_PREFIX, bid_addr)
629 }
630 Key::Message(message_addr) => message_addr.to_formatted_string(),
631 Key::SmartContract(package_addr) => {
632 format!("{}{}", PACKAGE_PREFIX, base16::encode_lower(&package_addr))
633 }
634 Key::AddressableEntity(entity_addr) => {
635 format!("{}", entity_addr)
636 }
637 Key::ByteCode(byte_code_addr) => {
638 format!("{}", byte_code_addr)
639 }
640 Key::NamedKey(named_key) => {
641 format!("{}", named_key)
642 }
643 Key::BlockGlobal(addr) => {
644 let prefix = match addr {
645 BlockGlobalAddr::BlockTime => BLOCK_GLOBAL_TIME_PREFIX,
646 BlockGlobalAddr::MessageCount => BLOCK_GLOBAL_MESSAGE_COUNT_PREFIX,
647 BlockGlobalAddr::ProtocolVersion => BLOCK_GLOBAL_PROTOCOL_VERSION_PREFIX,
648 BlockGlobalAddr::AddressableEntity => BLOCK_GLOBAL_ADDRESSABLE_ENTITY_PREFIX,
649 };
650 format!(
651 "{}{}",
652 prefix,
653 base16::encode_lower(&BLOCK_GLOBAL_PADDING_BYTES)
654 )
655 }
656 Key::BalanceHold(balance_hold_addr) => {
657 let tail = BalanceHoldAddr::to_formatted_string(&balance_hold_addr);
658 format!("{}{}", BALANCE_HOLD_PREFIX, tail)
659 }
660 Key::State(entity_addr) => {
661 format!("{}{}", STATE_PREFIX, entity_addr)
662 }
663 Key::EntryPoint(entry_point_addr) => {
664 format!("{}", entry_point_addr)
665 }
666 }
667 }
668
669 pub fn from_formatted_str(input: &str) -> Result<Key, FromStrError> {
671 match AccountHash::from_formatted_str(input) {
672 Ok(account_hash) => return Ok(Key::Account(account_hash)),
673 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
674 Err(error) => return Err(error.into()),
675 }
676
677 if let Some(hex) = input.strip_prefix(HASH_PREFIX) {
678 let addr = checksummed_hex::decode(hex)
679 .map_err(|error| FromStrError::Hash(error.to_string()))?;
680 let hash_addr = HashAddr::try_from(addr.as_ref())
681 .map_err(|error| FromStrError::Hash(error.to_string()))?;
682 return Ok(Key::Hash(hash_addr));
683 }
684
685 if let Some(hex) = input.strip_prefix(DEPLOY_INFO_PREFIX) {
686 let hash = checksummed_hex::decode(hex)
687 .map_err(|error| FromStrError::DeployInfo(error.to_string()))?;
688 let hash_array = <[u8; DeployHash::LENGTH]>::try_from(hash.as_ref())
689 .map_err(|error| FromStrError::DeployInfo(error.to_string()))?;
690 return Ok(Key::DeployInfo(DeployHash::new(Digest::from(hash_array))));
691 }
692
693 if let Some(hex) = input.strip_prefix(TRANSFER_PREFIX) {
694 let addr = checksummed_hex::decode(hex)
695 .map_err(|error| FromStrError::Transfer(TransferFromStrError::from(error)))?;
696 let addr_array = <[u8; TRANSFER_ADDR_LENGTH]>::try_from(addr.as_ref())
697 .map_err(|error| FromStrError::Transfer(TransferFromStrError::from(error)))?;
698 return Ok(Key::Transfer(TransferAddr::new(addr_array)));
699 }
700
701 match URef::from_formatted_str(input) {
702 Ok(uref) => return Ok(Key::URef(uref)),
703 Err(uref::FromStrError::InvalidPrefix) => {}
704 Err(error) => return Err(error.into()),
705 }
706
707 if let Some(era_summary_padding) = input.strip_prefix(ERA_SUMMARY_PREFIX) {
708 let padded_bytes = checksummed_hex::decode(era_summary_padding)
709 .map_err(|error| FromStrError::EraSummary(error.to_string()))?;
710 let _padding: [u8; 32] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
711 FromStrError::EraSummary("Failed to deserialize era summary key".to_string())
712 })?;
713 return Ok(Key::EraSummary);
714 }
715
716 if let Some(era_id_str) = input.strip_prefix(ERA_INFO_PREFIX) {
717 let era_id = EraId::from_str(era_id_str)
718 .map_err(|error| FromStrError::EraInfo(error.to_string()))?;
719 return Ok(Key::EraInfo(era_id));
720 }
721
722 if let Some(hex) = input.strip_prefix(BALANCE_HOLD_PREFIX) {
724 let balance_hold_addr = BalanceHoldAddr::from_formatted_string(hex)?;
725 return Ok(Key::BalanceHold(balance_hold_addr));
726 }
727
728 if let Some(hex) = input.strip_prefix(BALANCE_PREFIX) {
729 let addr = checksummed_hex::decode(hex)
730 .map_err(|error| FromStrError::Balance(error.to_string()))?;
731 let uref_addr = URefAddr::try_from(addr.as_ref())
732 .map_err(|error| FromStrError::Balance(error.to_string()))?;
733 return Ok(Key::Balance(uref_addr));
734 }
735
736 if let Some(hex) = input.strip_prefix(BID_ADDR_PREFIX) {
738 let bytes = checksummed_hex::decode(hex)
739 .map_err(|error| FromStrError::BidAddr(error.to_string()))?;
740 if bytes.is_empty() {
741 return Err(FromStrError::BidAddr(
742 "bytes should not be 0 len".to_string(),
743 ));
744 }
745 let tag_bytes = <[u8; BidAddrTag::BID_ADDR_TAG_LENGTH]>::try_from(bytes[0..1].as_ref())
746 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
747 let tag = BidAddrTag::try_from_u8(tag_bytes[0])
748 .ok_or_else(|| FromStrError::BidAddr("failed to parse bid addr tag".to_string()))?;
749 let validator_bytes = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(
750 bytes[1..BidAddr::VALIDATOR_BID_ADDR_LENGTH].as_ref(),
751 )
752 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
753
754 let bid_addr = match tag {
755 BidAddrTag::Unified => BidAddr::legacy(validator_bytes),
756 BidAddrTag::Validator => BidAddr::new_validator_addr(validator_bytes),
757 BidAddrTag::ValidatorRev => BidAddr::new_validator_rev_addr(validator_bytes),
758 BidAddrTag::DelegatedAccount => {
759 let delegator_bytes = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(
760 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
761 )
762 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
763 BidAddr::new_delegator_account_addr((validator_bytes, delegator_bytes))
764 }
765 BidAddrTag::DelegatedPurse => {
766 let uref = <[u8; UREF_ADDR_LENGTH]>::try_from(
767 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
768 )
769 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
770 BidAddr::DelegatedPurse {
771 validator: AccountHash::new(validator_bytes),
772 delegator: uref,
773 }
774 }
775 BidAddrTag::Credit => {
776 let era_id = bytesrepr::deserialize_from_slice(
777 &bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..],
778 )
779 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
780 BidAddr::Credit {
781 validator: AccountHash::new(validator_bytes),
782 era_id,
783 }
784 }
785 BidAddrTag::ReservedDelegationAccount => {
786 let delegator_bytes = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(
787 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
788 )
789 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
790 BidAddr::new_reservation_account_addr((validator_bytes, delegator_bytes))
791 }
792 BidAddrTag::ReservedDelegationPurse => {
793 let uref = <[u8; UREF_ADDR_LENGTH]>::try_from(
794 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
795 )
796 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
797 BidAddr::ReservedDelegationPurse {
798 validator: AccountHash::new(validator_bytes),
799 delegator: uref,
800 }
801 }
802 BidAddrTag::UnbondAccount => {
803 let unbonder_bytes = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(
804 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
805 )
806 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
807 BidAddr::UnbondAccount {
808 validator: AccountHash::new(validator_bytes),
809 unbonder: AccountHash::new(unbonder_bytes),
810 }
811 }
812 BidAddrTag::UnbondPurse => {
813 let uref = <[u8; UREF_ADDR_LENGTH]>::try_from(
814 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
815 )
816 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
817 BidAddr::UnbondPurse {
818 validator: AccountHash::new(validator_bytes),
819 unbonder: uref,
820 }
821 }
822 };
823 return Ok(Key::BidAddr(bid_addr));
824 }
825
826 if let Some(hex) = input.strip_prefix(BID_PREFIX) {
827 let hash = checksummed_hex::decode(hex)
828 .map_err(|error| FromStrError::Bid(error.to_string()))?;
829 let account_hash = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(hash.as_ref())
830 .map_err(|error| FromStrError::Bid(error.to_string()))?;
831 return Ok(Key::Bid(AccountHash::new(account_hash)));
832 }
833
834 if let Some(hex) = input.strip_prefix(WITHDRAW_PREFIX) {
835 let hash = checksummed_hex::decode(hex)
836 .map_err(|error| FromStrError::Withdraw(error.to_string()))?;
837 let account_hash = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(hash.as_ref())
838 .map_err(|error| FromStrError::Withdraw(error.to_string()))?;
839 return Ok(Key::Withdraw(AccountHash::new(account_hash)));
840 }
841
842 if let Some(hex) = input.strip_prefix(UNBOND_PREFIX) {
843 let hash = checksummed_hex::decode(hex)
844 .map_err(|error| FromStrError::Unbond(error.to_string()))?;
845 let account_hash = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(hash.as_ref())
846 .map_err(|error| FromStrError::Unbond(error.to_string()))?;
847 return Ok(Key::Unbond(AccountHash::new(account_hash)));
848 }
849
850 if let Some(dictionary_addr) = input.strip_prefix(DICTIONARY_PREFIX) {
851 let dictionary_addr_bytes = checksummed_hex::decode(dictionary_addr)
852 .map_err(|error| FromStrError::Dictionary(error.to_string()))?;
853 let addr = DictionaryAddr::try_from(dictionary_addr_bytes.as_ref())
854 .map_err(|error| FromStrError::Dictionary(error.to_string()))?;
855 return Ok(Key::Dictionary(addr));
856 }
857
858 if let Some(registry_address) = input.strip_prefix(SYSTEM_ENTITY_REGISTRY_PREFIX) {
859 let padded_bytes = checksummed_hex::decode(registry_address)
860 .map_err(|error| FromStrError::SystemEntityRegistry(error.to_string()))?;
861 let _padding: [u8; 32] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
862 FromStrError::SystemEntityRegistry(
863 "Failed to deserialize system registry key".to_string(),
864 )
865 })?;
866 return Ok(Key::SystemEntityRegistry);
867 }
868
869 if let Some(registry_address) = input.strip_prefix(CHAINSPEC_REGISTRY_PREFIX) {
870 let padded_bytes = checksummed_hex::decode(registry_address)
871 .map_err(|error| FromStrError::ChainspecRegistry(error.to_string()))?;
872 let _padding: [u8; 32] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
873 FromStrError::ChainspecRegistry(
874 "Failed to deserialize chainspec registry key".to_string(),
875 )
876 })?;
877 return Ok(Key::ChainspecRegistry);
878 }
879
880 if let Some(registry_address) = input.strip_prefix(CHECKSUM_REGISTRY_PREFIX) {
881 let padded_bytes = checksummed_hex::decode(registry_address)
882 .map_err(|error| FromStrError::ChecksumRegistry(error.to_string()))?;
883 let _padding: [u8; 32] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
884 FromStrError::ChecksumRegistry(
885 "Failed to deserialize checksum registry key".to_string(),
886 )
887 })?;
888 return Ok(Key::ChecksumRegistry);
889 }
890
891 if let Some(package_addr) = input.strip_prefix(PACKAGE_PREFIX) {
892 let package_addr_bytes = checksummed_hex::decode(package_addr)
893 .map_err(|error| FromStrError::Dictionary(error.to_string()))?;
894 let addr = PackageAddr::try_from(package_addr_bytes.as_ref())
895 .map_err(|error| FromStrError::Package(error.to_string()))?;
896 return Ok(Key::SmartContract(addr));
897 }
898
899 match EntityAddr::from_formatted_str(input) {
900 Ok(entity_addr) => return Ok(Key::AddressableEntity(entity_addr)),
901 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
902 Err(error) => {
903 return Err(FromStrError::AddressableEntity(error.to_string()));
904 }
905 }
906
907 match ByteCodeAddr::from_formatted_string(input) {
908 Ok(byte_code_addr) => return Ok(Key::ByteCode(byte_code_addr)),
909 Err(byte_code::FromStrError::InvalidPrefix) => {}
910 Err(error) => return Err(FromStrError::ByteCode(error.to_string())),
911 }
912
913 match MessageAddr::from_formatted_str(input) {
914 Ok(message_addr) => return Ok(Key::Message(message_addr)),
915 Err(contract_messages::FromStrError::InvalidPrefix) => {}
916 Err(error) => return Err(error.into()),
917 }
918
919 match NamedKeyAddr::from_formatted_str(input) {
920 Ok(named_key) => return Ok(Key::NamedKey(named_key)),
921 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
922 Err(error) => return Err(FromStrError::NamedKey(error.to_string())),
923 }
924
925 if let Some(block_time) = input.strip_prefix(BLOCK_GLOBAL_TIME_PREFIX) {
926 let padded_bytes = checksummed_hex::decode(block_time)
927 .map_err(|error| FromStrError::BlockGlobal(error.to_string()))?;
928 let _padding: [u8; 31] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
929 FromStrError::BlockGlobal("Failed to deserialize global block time key".to_string())
930 })?;
931 return Ok(BlockGlobalAddr::BlockTime.into());
932 }
933
934 if let Some(message_count) = input.strip_prefix(BLOCK_GLOBAL_MESSAGE_COUNT_PREFIX) {
935 let padded_bytes = checksummed_hex::decode(message_count)
936 .map_err(|error| FromStrError::BlockGlobal(error.to_string()))?;
937 let _padding: [u8; 31] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
938 FromStrError::BlockGlobal(
939 "Failed to deserialize global block message count key".to_string(),
940 )
941 })?;
942 return Ok(BlockGlobalAddr::MessageCount.into());
943 }
944
945 if let Some(protocol_version) = input.strip_prefix(BLOCK_GLOBAL_PROTOCOL_VERSION_PREFIX) {
946 let padded_bytes = checksummed_hex::decode(protocol_version)
947 .map_err(|error| FromStrError::BlockGlobal(error.to_string()))?;
948 let _padding: [u8; 31] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
949 FromStrError::BlockGlobal(
950 "Failed to deserialize global block protocol version key".to_string(),
951 )
952 })?;
953 return Ok(BlockGlobalAddr::ProtocolVersion.into());
954 }
955
956 if let Some(addressable_entity) = input.strip_prefix(BLOCK_GLOBAL_ADDRESSABLE_ENTITY_PREFIX)
957 {
958 let padded_bytes = checksummed_hex::decode(addressable_entity)
959 .map_err(|error| FromStrError::BlockGlobal(error.to_string()))?;
960 let _padding: [u8; 31] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
961 FromStrError::BlockGlobal(
962 "Failed to deserialize global block addressable entity key".to_string(),
963 )
964 })?;
965 return Ok(BlockGlobalAddr::AddressableEntity.into());
966 }
967
968 match EntryPointAddr::from_formatted_str(input) {
969 Ok(entry_point_addr) => return Ok(Key::EntryPoint(entry_point_addr)),
970 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
971 Err(error) => return Err(FromStrError::EntryPoint(error.to_string())),
972 }
973
974 if let Some(entity_addr_formatted) = input.strip_prefix(STATE_PREFIX) {
975 match EntityAddr::from_formatted_str(entity_addr_formatted) {
976 Ok(entity_addr) => return Ok(Key::State(entity_addr)),
977 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
978 Err(error) => {
979 return Err(FromStrError::State(error.to_string()));
980 }
981 }
982 }
983
984 Err(FromStrError::UnknownPrefix)
985 }
986
987 pub fn into_account(self) -> Option<AccountHash> {
990 match self {
991 Key::Account(bytes) => Some(bytes),
992 _ => None,
993 }
994 }
995
996 pub fn into_hash_addr(self) -> Option<HashAddr> {
999 match self {
1000 Key::Hash(hash) => Some(hash),
1001 _ => None,
1002 }
1003 }
1004
1005 pub fn into_entity_hash_addr(self) -> Option<HashAddr> {
1008 match self {
1009 Key::AddressableEntity(entity_addr) => Some(entity_addr.value()),
1010 Key::Account(account_hash) => Some(account_hash.value()),
1011 Key::Hash(hash) => Some(hash),
1012 _ => None,
1013 }
1014 }
1015
1016 pub fn into_package_addr(self) -> Option<PackageAddr> {
1019 match self {
1020 Key::Hash(hash) => Some(hash),
1021 Key::SmartContract(package_addr) => Some(package_addr),
1022 _ => None,
1023 }
1024 }
1025
1026 pub fn into_entity_hash(self) -> Option<AddressableEntityHash> {
1029 let entity_addr = self.into_entity_hash_addr()?;
1030 Some(AddressableEntityHash::new(entity_addr))
1031 }
1032
1033 pub fn into_package_hash(self) -> Option<PackageHash> {
1036 let package_addr = self.into_package_addr()?;
1037 Some(PackageHash::new(package_addr))
1038 }
1039
1040 pub fn into_named_key_addr(self) -> Option<NamedKeyAddr> {
1043 match self {
1044 Key::NamedKey(addr) => Some(addr),
1045 _ => None,
1046 }
1047 }
1048
1049 pub fn into_uref(self) -> Option<URef> {
1051 match self {
1052 Key::URef(uref) => Some(uref),
1053 _ => None,
1054 }
1055 }
1056
1057 pub fn as_uref(&self) -> Option<&URef> {
1060 match self {
1061 Key::URef(uref) => Some(uref),
1062 _ => None,
1063 }
1064 }
1065
1066 pub fn as_uref_mut(&mut self) -> Option<&mut URef> {
1069 match self {
1070 Key::URef(uref) => Some(uref),
1071 _ => None,
1072 }
1073 }
1074
1075 pub fn as_balance(&self) -> Option<&URefAddr> {
1078 if let Self::Balance(v) = self {
1079 Some(v)
1080 } else {
1081 None
1082 }
1083 }
1084
1085 pub fn as_balance_hold(&self) -> Option<&BalanceHoldAddr> {
1088 if let Self::BalanceHold(addr) = self {
1089 Some(addr)
1090 } else {
1091 None
1092 }
1093 }
1094
1095 pub fn as_dictionary(&self) -> Option<&DictionaryAddr> {
1098 match self {
1099 Key::Dictionary(v) => Some(v),
1100 _ => None,
1101 }
1102 }
1103
1104 pub fn as_bid_addr(&self) -> Option<&BidAddr> {
1107 if let Self::BidAddr(addr) = self {
1108 Some(addr)
1109 } else {
1110 None
1111 }
1112 }
1113
1114 pub fn as_message_topic_name_hash(&self) -> Option<TopicNameHash> {
1117 if let Self::Message(addr) = self {
1118 Some(addr.topic_name_hash())
1119 } else {
1120 None
1121 }
1122 }
1123
1124 pub fn uref_to_hash(&self) -> Option<Key> {
1126 let uref = self.as_uref()?;
1127 let addr = uref.addr();
1128 Some(Key::Hash(addr))
1129 }
1130
1131 pub fn withdraw_to_unbond(&self) -> Option<Key> {
1133 if let Key::Withdraw(account_hash) = self {
1134 return Some(Key::Unbond(*account_hash));
1135 }
1136 None
1137 }
1138
1139 pub fn dictionary(seed_uref: URef, dictionary_item_key: &[u8]) -> Key {
1142 let mut hasher = VarBlake2b::new(BLAKE2B_DIGEST_LENGTH).expect("should create hasher");
1144 hasher.update(seed_uref.addr().as_ref());
1145 hasher.update(dictionary_item_key);
1146 let mut addr = HashAddr::default();
1148 hasher.finalize_variable(|hash| addr.clone_from_slice(hash));
1149 Key::Dictionary(addr)
1150 }
1151
1152 pub fn addressable_entity_key(
1155 entity_kind_tag: EntityKindTag,
1156 entity_hash: AddressableEntityHash,
1157 ) -> Self {
1158 let entity_addr = match entity_kind_tag {
1159 EntityKindTag::System => EntityAddr::new_system(entity_hash.value()),
1160 EntityKindTag::Account => EntityAddr::new_account(entity_hash.value()),
1161 EntityKindTag::SmartContract => EntityAddr::new_smart_contract(entity_hash.value()),
1162 };
1163
1164 Key::AddressableEntity(entity_addr)
1165 }
1166
1167 pub fn contract_entity_key(entity_hash: AddressableEntityHash) -> Key {
1169 Self::addressable_entity_key(EntityKindTag::SmartContract, entity_hash)
1170 }
1171
1172 pub fn byte_code_key(byte_code_addr: ByteCodeAddr) -> Self {
1174 Key::ByteCode(byte_code_addr)
1175 }
1176
1177 pub fn message(entity_addr: EntityAddr, topic_name_hash: TopicNameHash, index: u32) -> Key {
1180 Key::Message(MessageAddr::new_message_addr(
1181 entity_addr,
1182 topic_name_hash,
1183 index,
1184 ))
1185 }
1186
1187 pub fn message_topic(entity_addr: EntityAddr, topic_name_hash: TopicNameHash) -> Key {
1190 Key::Message(MessageAddr::new_topic_addr(entity_addr, topic_name_hash))
1191 }
1192
1193 pub fn entry_point(entry_point_addr: EntryPointAddr) -> Self {
1195 Key::EntryPoint(entry_point_addr)
1196 }
1197
1198 pub fn is_dictionary_key(&self) -> bool {
1200 if let Key::Dictionary(_) = self {
1201 return true;
1202 }
1203 false
1204 }
1205
1206 pub fn is_balance_key(&self) -> bool {
1208 if let Key::Balance(_) = self {
1209 return true;
1210 }
1211 false
1212 }
1213
1214 pub fn is_bid_addr_key(&self) -> bool {
1216 if let Key::BidAddr(_) = self {
1217 return true;
1218 }
1219 false
1220 }
1221
1222 pub fn is_named_key(&self) -> bool {
1224 if let Key::NamedKey(_) = self {
1225 return true;
1226 }
1227
1228 false
1229 }
1230
1231 pub fn is_system_key(&self) -> bool {
1233 if let Self::AddressableEntity(entity_addr) = self {
1234 return match entity_addr.tag() {
1235 EntityKindTag::System => true,
1236 EntityKindTag::SmartContract | EntityKindTag::Account => false,
1237 };
1238 }
1239 false
1240 }
1241
1242 pub fn is_smart_contract_key(&self) -> bool {
1244 matches!(
1245 self,
1246 Self::AddressableEntity(EntityAddr::SmartContract(_)) | Self::Hash(_)
1247 )
1248 }
1249
1250 pub fn is_named_key_entry(&self) -> bool {
1252 matches!(self, Self::NamedKey(_))
1253 }
1254
1255 pub fn is_entry_for_base(&self, entity_addr: &EntityAddr) -> bool {
1258 if let Self::NamedKey(named_key_addr) = self {
1259 named_key_addr.entity_addr() == *entity_addr
1260 } else {
1261 false
1262 }
1263 }
1264
1265 pub fn is_readable(&self, entity_addr: &EntityAddr) -> bool {
1267 if entity_addr.is_system() {
1268 return true;
1270 }
1271 let ret = match self {
1272 Key::BidAddr(_) => {
1273 true
1275 }
1276 Key::URef(uref) => {
1277 uref.is_readable()
1279 }
1280 Key::SystemEntityRegistry | Key::SmartContract(_) => {
1281 true
1283 }
1284 Key::Unbond(account_hash) => {
1285 entity_addr.tag() == EntityKindTag::Account
1287 && entity_addr.value() == account_hash.value()
1288 }
1289 Key::NamedKey(named_key_addr) => {
1290 &named_key_addr.entity_addr() == entity_addr
1292 }
1293 Key::ByteCode(_)
1294 | Key::Account(_)
1295 | Key::Hash(_)
1296 | Key::AddressableEntity(_)
1297 | Key::Balance(_)
1298 | Key::BalanceHold(_)
1299 | Key::Dictionary(_)
1300 | Key::Message(_)
1301 | Key::BlockGlobal(_)
1302 | Key::EntryPoint(_) => true,
1303 _ => false,
1304 };
1305 if !ret {
1306 let reading_entity_key = Key::AddressableEntity(*entity_addr);
1307 warn!(?reading_entity_key, attempted_key=?self, "attempt to read without permission")
1308 }
1309 ret
1310 }
1311
1312 pub fn is_addable(&self, entity_addr: &EntityAddr) -> bool {
1314 let ret = match self {
1317 Key::URef(uref) => uref.is_addable(),
1318 Key::AddressableEntity(addr_entity_addr) => {
1319 entity_addr == addr_entity_addr
1321 }
1322 Key::NamedKey(named_key_addr) => {
1323 &named_key_addr.entity_addr() == entity_addr
1325 }
1326 _ => {
1327 let adding_entity_key = Key::AddressableEntity(*entity_addr);
1329 warn!(?adding_entity_key, attempted_key=?self, "attempt to add on an unsupported data type");
1330 return false; }
1332 };
1333 if !ret {
1334 let adding_entity_key = Key::AddressableEntity(*entity_addr);
1335 warn!(?adding_entity_key, attempted_key=?self, "attempt to add without permission");
1336 }
1337 ret
1338 }
1339
1340 pub fn is_writeable(&self, entity_addr: &EntityAddr) -> bool {
1342 if entity_addr.is_system() {
1343 return true;
1345 }
1346 let ret = match self {
1347 Key::URef(uref) => uref.is_writeable(),
1348 Key::NamedKey(named_key_addr) => {
1349 &named_key_addr.entity_addr() == entity_addr
1351 }
1352 _ => {
1353 false
1355 }
1356 };
1357 if !ret {
1358 let writing_entity_key = Key::AddressableEntity(*entity_addr);
1359 warn!(?writing_entity_key, attempted_key=?self, "attempt to write without permission")
1360 }
1361 ret
1362 }
1363
1364 pub fn into_entity_addr(self) -> Option<EntityAddr> {
1366 match self {
1367 Key::AddressableEntity(entity_addr) => Some(entity_addr),
1368 _ => None,
1369 }
1370 }
1371}
1372
1373impl Display for Key {
1374 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1375 match self {
1376 Key::Account(account_hash) => write!(f, "Key::Account({})", account_hash),
1377 Key::Hash(addr) => write!(f, "Key::Hash({})", base16::encode_lower(&addr)),
1378 Key::URef(uref) => write!(f, "Key::{}", uref), Key::Transfer(transfer_v1_addr) => {
1380 write!(f, "Key::Transfer({})", transfer_v1_addr)
1381 }
1382 Key::DeployInfo(addr) => write!(
1383 f,
1384 "Key::DeployInfo({})",
1385 base16::encode_lower(addr.as_ref())
1386 ),
1387 Key::EraInfo(era_id) => write!(f, "Key::EraInfo({})", era_id),
1388 Key::Balance(uref_addr) => {
1389 write!(f, "Key::Balance({})", base16::encode_lower(uref_addr))
1390 }
1391 Key::Bid(account_hash) => write!(f, "Key::Bid({})", account_hash),
1392 Key::Withdraw(account_hash) => write!(f, "Key::Withdraw({})", account_hash),
1393 Key::Dictionary(addr) => {
1394 write!(f, "Key::Dictionary({})", base16::encode_lower(addr))
1395 }
1396 Key::SystemEntityRegistry => write!(
1397 f,
1398 "Key::SystemEntityRegistry({})",
1399 base16::encode_lower(&PADDING_BYTES)
1400 ),
1401 Key::EraSummary => write!(
1402 f,
1403 "Key::EraSummary({})",
1404 base16::encode_lower(&PADDING_BYTES),
1405 ),
1406 Key::Unbond(account_hash) => write!(f, "Key::Unbond({})", account_hash),
1407 Key::ChainspecRegistry => write!(
1408 f,
1409 "Key::ChainspecRegistry({})",
1410 base16::encode_lower(&PADDING_BYTES)
1411 ),
1412 Key::ChecksumRegistry => {
1413 write!(
1414 f,
1415 "Key::ChecksumRegistry({})",
1416 base16::encode_lower(&PADDING_BYTES)
1417 )
1418 }
1419 Key::BidAddr(bid_addr) => write!(f, "Key::BidAddr({})", bid_addr),
1420 Key::Message(message_addr) => {
1421 write!(f, "Key::Message({})", message_addr)
1422 }
1423 Key::SmartContract(package_addr) => {
1424 write!(f, "Key::Package({})", base16::encode_lower(package_addr))
1425 }
1426 Key::AddressableEntity(entity_addr) => write!(
1427 f,
1428 "Key::AddressableEntity({}-{})",
1429 entity_addr.tag(),
1430 base16::encode_lower(&entity_addr.value())
1431 ),
1432 Key::ByteCode(byte_code_addr) => {
1433 write!(f, "Key::ByteCode({})", byte_code_addr)
1434 }
1435 Key::NamedKey(named_key_addr) => {
1436 write!(f, "Key::NamedKey({})", named_key_addr)
1437 }
1438 Key::BlockGlobal(addr) => {
1439 write!(
1440 f,
1441 "Key::BlockGlobal({}-{})",
1442 addr,
1443 base16::encode_lower(&BLOCK_GLOBAL_PADDING_BYTES)
1444 )
1445 }
1446 Key::BalanceHold(balance_hold_addr) => {
1447 write!(f, "Key::BalanceHold({})", balance_hold_addr)
1448 }
1449 Key::EntryPoint(entry_point_addr) => {
1450 write!(f, "Key::EntryPointAddr({})", entry_point_addr)
1451 }
1452 Key::State(entity_addr) => {
1453 write!(f, "Key::State({})", entity_addr)
1454 }
1455 }
1456 }
1457}
1458
1459impl Debug for Key {
1460 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1461 write!(f, "{}", self)
1462 }
1463}
1464
1465impl Tagged<KeyTag> for Key {
1466 fn tag(&self) -> KeyTag {
1467 match self {
1468 Key::Account(_) => KeyTag::Account,
1469 Key::Hash(_) => KeyTag::Hash,
1470 Key::URef(_) => KeyTag::URef,
1471 Key::Transfer(_) => KeyTag::Transfer,
1472 Key::DeployInfo(_) => KeyTag::DeployInfo,
1473 Key::EraInfo(_) => KeyTag::EraInfo,
1474 Key::Balance(_) => KeyTag::Balance,
1475 Key::Bid(_) => KeyTag::Bid,
1476 Key::Withdraw(_) => KeyTag::Withdraw,
1477 Key::Dictionary(_) => KeyTag::Dictionary,
1478 Key::SystemEntityRegistry => KeyTag::SystemEntityRegistry,
1479 Key::EraSummary => KeyTag::EraSummary,
1480 Key::Unbond(_) => KeyTag::Unbond,
1481 Key::ChainspecRegistry => KeyTag::ChainspecRegistry,
1482 Key::ChecksumRegistry => KeyTag::ChecksumRegistry,
1483 Key::BidAddr(_) => KeyTag::BidAddr,
1484 Key::SmartContract(_) => KeyTag::Package,
1485 Key::AddressableEntity(..) => KeyTag::AddressableEntity,
1486 Key::ByteCode(..) => KeyTag::ByteCode,
1487 Key::Message(_) => KeyTag::Message,
1488 Key::NamedKey(_) => KeyTag::NamedKey,
1489 Key::BlockGlobal(_) => KeyTag::BlockGlobal,
1490 Key::BalanceHold(_) => KeyTag::BalanceHold,
1491 Key::EntryPoint(_) => KeyTag::EntryPoint,
1492 Key::State(_) => KeyTag::State,
1493 }
1494 }
1495}
1496
1497impl Tagged<u8> for Key {
1498 fn tag(&self) -> u8 {
1499 let key_tag: KeyTag = self.tag();
1500 key_tag as u8
1501 }
1502}
1503
1504impl From<URef> for Key {
1505 fn from(uref: URef) -> Key {
1506 Key::URef(uref)
1507 }
1508}
1509
1510impl From<AccountHash> for Key {
1511 fn from(account_hash: AccountHash) -> Key {
1512 Key::Account(account_hash)
1513 }
1514}
1515
1516impl From<PackageHash> for Key {
1517 fn from(package_hash: PackageHash) -> Key {
1518 Key::SmartContract(package_hash.value())
1519 }
1520}
1521
1522impl From<ContractWasmHash> for Key {
1523 fn from(wasm_hash: ContractWasmHash) -> Self {
1524 Key::Hash(wasm_hash.value())
1525 }
1526}
1527
1528impl From<ContractPackageHash> for Key {
1529 fn from(contract_package_hash: ContractPackageHash) -> Self {
1530 Key::Hash(contract_package_hash.value())
1531 }
1532}
1533
1534impl From<ContractHash> for Key {
1535 fn from(contract_hash: ContractHash) -> Self {
1536 Key::Hash(contract_hash.value())
1537 }
1538}
1539
1540impl From<EntityAddr> for Key {
1541 fn from(entity_addr: EntityAddr) -> Self {
1542 Key::AddressableEntity(entity_addr)
1543 }
1544}
1545
1546impl From<NamedKeyAddr> for Key {
1547 fn from(value: NamedKeyAddr) -> Self {
1548 Key::NamedKey(value)
1549 }
1550}
1551
1552impl From<ByteCodeAddr> for Key {
1553 fn from(value: ByteCodeAddr) -> Self {
1554 Key::ByteCode(value)
1555 }
1556}
1557
1558impl ToBytes for Key {
1559 fn to_bytes(&self) -> Result<Vec<u8>, Error> {
1560 let mut result = bytesrepr::unchecked_allocate_buffer(self);
1561 self.write_bytes(&mut result)?;
1562 Ok(result)
1563 }
1564
1565 fn serialized_length(&self) -> usize {
1566 match self {
1567 Key::Account(account_hash) => {
1568 KEY_ID_SERIALIZED_LENGTH + account_hash.serialized_length()
1569 }
1570 Key::Hash(_) => KEY_HASH_SERIALIZED_LENGTH,
1571 Key::URef(_) => KEY_UREF_SERIALIZED_LENGTH,
1572 Key::Transfer(_) => KEY_TRANSFER_SERIALIZED_LENGTH,
1573 Key::DeployInfo(_) => KEY_DEPLOY_INFO_SERIALIZED_LENGTH,
1574 Key::EraInfo(_) => KEY_ERA_INFO_SERIALIZED_LENGTH,
1575 Key::Balance(_) => KEY_BALANCE_SERIALIZED_LENGTH,
1576 Key::Bid(_) => KEY_BID_SERIALIZED_LENGTH,
1577 Key::Withdraw(_) => KEY_WITHDRAW_SERIALIZED_LENGTH,
1578 Key::Dictionary(_) => KEY_DICTIONARY_SERIALIZED_LENGTH,
1579 Key::SystemEntityRegistry => KEY_SYSTEM_ENTITY_REGISTRY_SERIALIZED_LENGTH,
1580 Key::EraSummary => KEY_ERA_SUMMARY_SERIALIZED_LENGTH,
1581 Key::Unbond(_) => KEY_UNBOND_SERIALIZED_LENGTH,
1582 Key::ChainspecRegistry => KEY_CHAINSPEC_REGISTRY_SERIALIZED_LENGTH,
1583 Key::ChecksumRegistry => KEY_CHECKSUM_REGISTRY_SERIALIZED_LENGTH,
1584 Key::BidAddr(bid_addr) => KEY_ID_SERIALIZED_LENGTH + bid_addr.serialized_length(),
1585 Key::SmartContract(_) => KEY_PACKAGE_SERIALIZED_LENGTH,
1586 Key::AddressableEntity(entity_addr) => {
1587 KEY_ID_SERIALIZED_LENGTH + entity_addr.serialized_length()
1588 }
1589 Key::ByteCode(byte_code_addr) => {
1590 KEY_ID_SERIALIZED_LENGTH + byte_code_addr.serialized_length()
1591 }
1592 Key::Message(message_addr) => {
1593 KEY_ID_SERIALIZED_LENGTH + message_addr.serialized_length()
1594 }
1595 Key::NamedKey(named_key_addr) => {
1596 KEY_ID_SERIALIZED_LENGTH + named_key_addr.serialized_length()
1597 }
1598 Key::BlockGlobal(addr) => {
1599 KEY_ID_SERIALIZED_LENGTH
1600 + addr.serialized_length()
1601 + BLOCK_GLOBAL_PADDING_BYTES.len()
1602 }
1603 Key::BalanceHold(balance_hold_addr) => {
1604 KEY_ID_SERIALIZED_LENGTH + balance_hold_addr.serialized_length()
1605 }
1606 Key::EntryPoint(entry_point_addr) => {
1607 U8_SERIALIZED_LENGTH + entry_point_addr.serialized_length()
1608 }
1609 Key::State(entity_addr) => KEY_ID_SERIALIZED_LENGTH + entity_addr.serialized_length(),
1610 }
1611 }
1612
1613 fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
1614 writer.push(self.tag());
1615 match self {
1616 Key::Account(account_hash) => account_hash.write_bytes(writer),
1617 Key::Hash(hash) => hash.write_bytes(writer),
1618 Key::URef(uref) => uref.write_bytes(writer),
1619 Key::Transfer(addr) => addr.write_bytes(writer),
1620 Key::DeployInfo(deploy_hash) => deploy_hash.write_bytes(writer),
1621 Key::EraInfo(era_id) => era_id.write_bytes(writer),
1622 Key::Balance(uref_addr) => uref_addr.write_bytes(writer),
1623 Key::Bid(account_hash) => account_hash.write_bytes(writer),
1624 Key::Withdraw(account_hash) => account_hash.write_bytes(writer),
1625 Key::Dictionary(addr) => addr.write_bytes(writer),
1626 Key::Unbond(account_hash) => account_hash.write_bytes(writer),
1627 Key::SystemEntityRegistry
1628 | Key::EraSummary
1629 | Key::ChainspecRegistry
1630 | Key::ChecksumRegistry => PADDING_BYTES.write_bytes(writer),
1631 Key::BlockGlobal(addr) => {
1632 addr.write_bytes(writer)?;
1633 BLOCK_GLOBAL_PADDING_BYTES.write_bytes(writer)
1634 }
1635 Key::BidAddr(bid_addr) => bid_addr.write_bytes(writer),
1636 Key::SmartContract(package_addr) => package_addr.write_bytes(writer),
1637 Key::AddressableEntity(entity_addr) => entity_addr.write_bytes(writer),
1638 Key::ByteCode(byte_code_addr) => byte_code_addr.write_bytes(writer),
1639 Key::Message(message_addr) => message_addr.write_bytes(writer),
1640 Key::NamedKey(named_key_addr) => named_key_addr.write_bytes(writer),
1641 Key::BalanceHold(balance_hold_addr) => balance_hold_addr.write_bytes(writer),
1642 Key::EntryPoint(entry_point_addr) => entry_point_addr.write_bytes(writer),
1643 Key::State(entity_addr) => entity_addr.write_bytes(writer),
1644 }
1645 }
1646}
1647
1648impl FromBytes for Key {
1649 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
1650 if bytes.is_empty() {
1651 error!("FromBytes for Key: bytes length should not be 0");
1652 }
1653 let (tag, remainder) = match KeyTag::from_bytes(bytes) {
1654 Ok((tag, rem)) => (tag, rem),
1655 Err(err) => {
1656 error!(%err, "FromBytes for Key");
1657 return Err(err);
1658 }
1659 };
1660 match tag {
1661 KeyTag::Account => {
1662 let (account_hash, rem) = AccountHash::from_bytes(remainder)?;
1663 Ok((Key::Account(account_hash), rem))
1664 }
1665 KeyTag::Hash => {
1666 let (hash, rem) = HashAddr::from_bytes(remainder)?;
1667 Ok((Key::Hash(hash), rem))
1668 }
1669 KeyTag::URef => {
1670 let (uref, rem) = URef::from_bytes(remainder)?;
1671 Ok((Key::URef(uref), rem))
1672 }
1673 KeyTag::Transfer => {
1674 let (transfer_v1_addr, rem) = TransferAddr::from_bytes(remainder)?;
1675 Ok((Key::Transfer(transfer_v1_addr), rem))
1676 }
1677 KeyTag::DeployInfo => {
1678 let (deploy_hash, rem) = DeployHash::from_bytes(remainder)?;
1679 Ok((Key::DeployInfo(deploy_hash), rem))
1680 }
1681 KeyTag::EraInfo => {
1682 let (era_id, rem) = EraId::from_bytes(remainder)?;
1683 Ok((Key::EraInfo(era_id), rem))
1684 }
1685 KeyTag::Balance => {
1686 let (uref_addr, rem) = URefAddr::from_bytes(remainder)?;
1687 Ok((Key::Balance(uref_addr), rem))
1688 }
1689 KeyTag::Bid => {
1690 let (account_hash, rem) = AccountHash::from_bytes(remainder)?;
1691 Ok((Key::Bid(account_hash), rem))
1692 }
1693 KeyTag::Withdraw => {
1694 let (account_hash, rem) = AccountHash::from_bytes(remainder)?;
1695 Ok((Key::Withdraw(account_hash), rem))
1696 }
1697 KeyTag::Dictionary => {
1698 let (addr, rem) = DictionaryAddr::from_bytes(remainder)?;
1699 Ok((Key::Dictionary(addr), rem))
1700 }
1701 KeyTag::SystemEntityRegistry => {
1702 let (_, rem) = <[u8; 32]>::from_bytes(remainder)?;
1703 Ok((Key::SystemEntityRegistry, rem))
1704 }
1705 KeyTag::EraSummary => {
1706 let (_, rem) = <[u8; 32]>::from_bytes(remainder)?;
1707 Ok((Key::EraSummary, rem))
1708 }
1709 KeyTag::Unbond => {
1710 let (account_hash, rem) = AccountHash::from_bytes(remainder)?;
1711 Ok((Key::Unbond(account_hash), rem))
1712 }
1713 KeyTag::ChainspecRegistry => {
1714 let (_, rem) = <[u8; 32]>::from_bytes(remainder)?;
1715 Ok((Key::ChainspecRegistry, rem))
1716 }
1717 KeyTag::ChecksumRegistry => {
1718 let (_, rem) = <[u8; 32]>::from_bytes(remainder)?;
1719 Ok((Key::ChecksumRegistry, rem))
1720 }
1721 KeyTag::BidAddr => {
1722 let (bid_addr, rem) = BidAddr::from_bytes(remainder)?;
1723 Ok((Key::BidAddr(bid_addr), rem))
1724 }
1725 KeyTag::Package => {
1726 let (package_addr, rem) = PackageAddr::from_bytes(remainder)?;
1727 Ok((Key::SmartContract(package_addr), rem))
1728 }
1729 KeyTag::AddressableEntity => {
1730 let (entity_addr, rem) = EntityAddr::from_bytes(remainder)?;
1731 Ok((Key::AddressableEntity(entity_addr), rem))
1732 }
1733 KeyTag::ByteCode => {
1734 let (byte_code_addr, rem) = ByteCodeAddr::from_bytes(remainder)?;
1735 Ok((Key::ByteCode(byte_code_addr), rem))
1736 }
1737 KeyTag::Message => {
1738 let (message_addr, rem) = MessageAddr::from_bytes(remainder)?;
1739 Ok((Key::Message(message_addr), rem))
1740 }
1741 KeyTag::NamedKey => {
1742 let (named_key_addr, rem) = NamedKeyAddr::from_bytes(remainder)?;
1743 Ok((Key::NamedKey(named_key_addr), rem))
1744 }
1745 KeyTag::BlockGlobal => {
1746 let (addr, rem) = BlockGlobalAddr::from_bytes(remainder)?;
1747 let (_, rem) = <[u8; 31]>::from_bytes(rem)?; Ok((Key::BlockGlobal(addr), rem))
1749 }
1750 KeyTag::BalanceHold => {
1751 let (balance_hold_addr, rem) = BalanceHoldAddr::from_bytes(remainder)?;
1752 Ok((Key::BalanceHold(balance_hold_addr), rem))
1753 }
1754 KeyTag::EntryPoint => {
1755 let (entry_point_addr, rem) = EntryPointAddr::from_bytes(remainder)?;
1756 Ok((Key::EntryPoint(entry_point_addr), rem))
1757 }
1758 KeyTag::State => {
1759 let (entity_addr, rem) = EntityAddr::from_bytes(remainder)?;
1760 Ok((Key::State(entity_addr), rem))
1761 }
1762 }
1763 }
1764}
1765
1766#[allow(dead_code)]
1767fn please_add_to_distribution_impl(key: Key) {
1768 match key {
1771 Key::Account(_) => unimplemented!(),
1772 Key::Hash(_) => unimplemented!(),
1773 Key::URef(_) => unimplemented!(),
1774 Key::Transfer(_) => unimplemented!(),
1775 Key::DeployInfo(_) => unimplemented!(),
1776 Key::EraInfo(_) => unimplemented!(),
1777 Key::Balance(_) => unimplemented!(),
1778 Key::Bid(_) => unimplemented!(),
1779 Key::Withdraw(_) => unimplemented!(),
1780 Key::Dictionary(_) => unimplemented!(),
1781 Key::SystemEntityRegistry => unimplemented!(),
1782 Key::EraSummary => unimplemented!(),
1783 Key::Unbond(_) => unimplemented!(),
1784 Key::ChainspecRegistry => unimplemented!(),
1785 Key::ChecksumRegistry => unimplemented!(),
1786 Key::BidAddr(_) => unimplemented!(),
1787 Key::SmartContract(_) => unimplemented!(),
1788 Key::AddressableEntity(..) => unimplemented!(),
1789 Key::ByteCode(..) => unimplemented!(),
1790 Key::Message(_) => unimplemented!(),
1791 Key::NamedKey(_) => unimplemented!(),
1792 Key::BlockGlobal(_) => unimplemented!(),
1793 Key::BalanceHold(_) => unimplemented!(),
1794 Key::EntryPoint(_) => unimplemented!(),
1795 Key::State(_) => unimplemented!(),
1796 }
1797}
1798
1799#[cfg(any(feature = "testing", test))]
1800impl Distribution<Key> for Standard {
1801 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Key {
1802 match rng.gen_range(0..=24) {
1803 0 => Key::Account(rng.gen()),
1804 1 => Key::Hash(rng.gen()),
1805 2 => Key::URef(rng.gen()),
1806 3 => Key::Transfer(TransferAddr::new(rng.gen())),
1807 4 => Key::DeployInfo(DeployHash::from_raw(rng.gen())),
1808 5 => Key::EraInfo(EraId::new(rng.gen())),
1809 6 => Key::Balance(rng.gen()),
1810 7 => Key::Bid(rng.gen()),
1811 8 => Key::Withdraw(rng.gen()),
1812 9 => Key::Dictionary(rng.gen()),
1813 10 => Key::SystemEntityRegistry,
1814 11 => Key::EraSummary,
1815 12 => Key::Unbond(rng.gen()),
1816 13 => Key::ChainspecRegistry,
1817 14 => Key::ChecksumRegistry,
1818 15 => Key::BidAddr(rng.gen()),
1819 16 => Key::SmartContract(rng.gen()),
1820 17 => Key::AddressableEntity(rng.gen()),
1821 18 => Key::ByteCode(rng.gen()),
1822 19 => Key::Message(rng.gen()),
1823 20 => Key::NamedKey(NamedKeyAddr::new_named_key_entry(rng.gen(), rng.gen())),
1824 21 => Key::BlockGlobal(rng.gen()),
1825 22 => Key::BalanceHold(rng.gen()),
1826 23 => Key::EntryPoint(rng.gen()),
1827 24 => Key::State(rng.gen()),
1828 _ => unreachable!(),
1829 }
1830 }
1831}
1832
1833mod serde_helpers {
1834 use super::*;
1835
1836 #[derive(Serialize)]
1837 pub(super) enum BinarySerHelper<'a> {
1838 Account(&'a AccountHash),
1839 Hash(&'a HashAddr),
1840 URef(&'a URef),
1841 Transfer(&'a TransferAddr),
1842 #[serde(with = "crate::serde_helpers::deploy_hash_as_array")]
1843 DeployInfo(&'a DeployHash),
1844 EraInfo(&'a EraId),
1845 Balance(&'a URefAddr),
1846 Bid(&'a AccountHash),
1847 Withdraw(&'a AccountHash),
1848 Dictionary(&'a HashAddr),
1849 SystemEntityRegistry,
1850 EraSummary,
1851 Unbond(&'a AccountHash),
1852 ChainspecRegistry,
1853 ChecksumRegistry,
1854 BidAddr(&'a BidAddr),
1855 Package(&'a PackageAddr),
1856 AddressableEntity(&'a EntityAddr),
1857 ByteCode(&'a ByteCodeAddr),
1858 Message(&'a MessageAddr),
1859 NamedKey(&'a NamedKeyAddr),
1860 BlockGlobal(&'a BlockGlobalAddr),
1861 BalanceHold(&'a BalanceHoldAddr),
1862 EntryPoint(&'a EntryPointAddr),
1863 State(&'a EntityAddr),
1864 }
1865
1866 #[derive(Deserialize)]
1867 pub(super) enum BinaryDeserHelper {
1868 Account(AccountHash),
1869 Hash(HashAddr),
1870 URef(URef),
1871 Transfer(TransferAddr),
1872 #[serde(with = "crate::serde_helpers::deploy_hash_as_array")]
1873 DeployInfo(DeployHash),
1874 EraInfo(EraId),
1875 Balance(URefAddr),
1876 Bid(AccountHash),
1877 Withdraw(AccountHash),
1878 Dictionary(DictionaryAddr),
1879 SystemEntityRegistry,
1880 EraSummary,
1881 Unbond(AccountHash),
1882 ChainspecRegistry,
1883 ChecksumRegistry,
1884 BidAddr(BidAddr),
1885 Package(PackageAddr),
1886 AddressableEntity(EntityAddr),
1887 ByteCode(ByteCodeAddr),
1888 Message(MessageAddr),
1889 NamedKey(NamedKeyAddr),
1890 BlockGlobal(BlockGlobalAddr),
1891 BalanceHold(BalanceHoldAddr),
1892 EntryPoint(EntryPointAddr),
1893 State(EntityAddr),
1894 }
1895
1896 impl<'a> From<&'a Key> for BinarySerHelper<'a> {
1897 fn from(key: &'a Key) -> Self {
1898 match key {
1899 Key::Account(account_hash) => BinarySerHelper::Account(account_hash),
1900 Key::Hash(hash_addr) => BinarySerHelper::Hash(hash_addr),
1901 Key::URef(uref) => BinarySerHelper::URef(uref),
1902 Key::Transfer(transfer_v1_addr) => BinarySerHelper::Transfer(transfer_v1_addr),
1903 Key::DeployInfo(deploy_hash) => BinarySerHelper::DeployInfo(deploy_hash),
1904 Key::EraInfo(era_id) => BinarySerHelper::EraInfo(era_id),
1905 Key::Balance(uref_addr) => BinarySerHelper::Balance(uref_addr),
1906 Key::Bid(account_hash) => BinarySerHelper::Bid(account_hash),
1907 Key::Withdraw(account_hash) => BinarySerHelper::Withdraw(account_hash),
1908 Key::Dictionary(addr) => BinarySerHelper::Dictionary(addr),
1909 Key::SystemEntityRegistry => BinarySerHelper::SystemEntityRegistry,
1910 Key::EraSummary => BinarySerHelper::EraSummary,
1911 Key::Unbond(account_hash) => BinarySerHelper::Unbond(account_hash),
1912 Key::ChainspecRegistry => BinarySerHelper::ChainspecRegistry,
1913 Key::ChecksumRegistry => BinarySerHelper::ChecksumRegistry,
1914 Key::BidAddr(bid_addr) => BinarySerHelper::BidAddr(bid_addr),
1915 Key::Message(message_addr) => BinarySerHelper::Message(message_addr),
1916 Key::SmartContract(package_addr) => BinarySerHelper::Package(package_addr),
1917 Key::AddressableEntity(entity_addr) => {
1918 BinarySerHelper::AddressableEntity(entity_addr)
1919 }
1920 Key::ByteCode(byte_code_addr) => BinarySerHelper::ByteCode(byte_code_addr),
1921 Key::NamedKey(named_key_addr) => BinarySerHelper::NamedKey(named_key_addr),
1922 Key::BlockGlobal(addr) => BinarySerHelper::BlockGlobal(addr),
1923 Key::BalanceHold(balance_hold_addr) => {
1924 BinarySerHelper::BalanceHold(balance_hold_addr)
1925 }
1926 Key::EntryPoint(entry_point_addr) => BinarySerHelper::EntryPoint(entry_point_addr),
1927 Key::State(entity_addr) => BinarySerHelper::State(entity_addr),
1928 }
1929 }
1930 }
1931
1932 impl From<BinaryDeserHelper> for Key {
1933 fn from(helper: BinaryDeserHelper) -> Self {
1934 match helper {
1935 BinaryDeserHelper::Account(account_hash) => Key::Account(account_hash),
1936 BinaryDeserHelper::Hash(hash_addr) => Key::Hash(hash_addr),
1937 BinaryDeserHelper::URef(uref) => Key::URef(uref),
1938 BinaryDeserHelper::Transfer(transfer_v1_addr) => Key::Transfer(transfer_v1_addr),
1939 BinaryDeserHelper::DeployInfo(deploy_hash) => Key::DeployInfo(deploy_hash),
1940 BinaryDeserHelper::EraInfo(era_id) => Key::EraInfo(era_id),
1941 BinaryDeserHelper::Balance(uref_addr) => Key::Balance(uref_addr),
1942 BinaryDeserHelper::Bid(account_hash) => Key::Bid(account_hash),
1943 BinaryDeserHelper::Withdraw(account_hash) => Key::Withdraw(account_hash),
1944 BinaryDeserHelper::Dictionary(addr) => Key::Dictionary(addr),
1945 BinaryDeserHelper::SystemEntityRegistry => Key::SystemEntityRegistry,
1946 BinaryDeserHelper::EraSummary => Key::EraSummary,
1947 BinaryDeserHelper::Unbond(account_hash) => Key::Unbond(account_hash),
1948 BinaryDeserHelper::ChainspecRegistry => Key::ChainspecRegistry,
1949 BinaryDeserHelper::ChecksumRegistry => Key::ChecksumRegistry,
1950 BinaryDeserHelper::BidAddr(bid_addr) => Key::BidAddr(bid_addr),
1951 BinaryDeserHelper::Message(message_addr) => Key::Message(message_addr),
1952 BinaryDeserHelper::Package(package_addr) => Key::SmartContract(package_addr),
1953 BinaryDeserHelper::AddressableEntity(entity_addr) => {
1954 Key::AddressableEntity(entity_addr)
1955 }
1956 BinaryDeserHelper::ByteCode(byte_code_addr) => Key::ByteCode(byte_code_addr),
1957 BinaryDeserHelper::NamedKey(named_key_addr) => Key::NamedKey(named_key_addr),
1958 BinaryDeserHelper::BlockGlobal(addr) => Key::BlockGlobal(addr),
1959 BinaryDeserHelper::BalanceHold(balance_hold_addr) => {
1960 Key::BalanceHold(balance_hold_addr)
1961 }
1962 BinaryDeserHelper::EntryPoint(entry_point_addr) => {
1963 Key::EntryPoint(entry_point_addr)
1964 }
1965 BinaryDeserHelper::State(entity_addr) => Key::State(entity_addr),
1966 }
1967 }
1968 }
1969}
1970
1971impl Serialize for Key {
1972 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1973 if serializer.is_human_readable() {
1974 self.to_formatted_string().serialize(serializer)
1975 } else {
1976 serde_helpers::BinarySerHelper::from(self).serialize(serializer)
1977 }
1978 }
1979}
1980
1981impl<'de> Deserialize<'de> for Key {
1982 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1983 if deserializer.is_human_readable() {
1984 let formatted_key = String::deserialize(deserializer)?;
1985 Key::from_formatted_str(&formatted_key).map_err(SerdeError::custom)
1986 } else {
1987 let binary_helper = serde_helpers::BinaryDeserHelper::deserialize(deserializer)?;
1988 Ok(Key::from(binary_helper))
1989 }
1990 }
1991}
1992
1993#[cfg(test)]
1994mod tests {
1995 use std::string::ToString;
1996
1997 use super::*;
1998 use crate::{
1999 account::ACCOUNT_HASH_FORMATTED_STRING_PREFIX,
2000 bytesrepr::{Error, FromBytes},
2001 uref::UREF_FORMATTED_STRING_PREFIX,
2002 AccessRights, BlockTime, URef,
2003 };
2004
2005 const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-";
2006 const ENTITY_PREFIX: &str = "entity-";
2007 const ACCOUNT_ENTITY_PREFIX: &str = "account-";
2008
2009 const BYTE_CODE_PREFIX: &str = "byte-code-";
2010 const EMPTY_PREFIX: &str = "empty-";
2011
2012 const ACCOUNT_KEY: Key = Key::Account(AccountHash::new([42; 32]));
2013 const HASH_KEY: Key = Key::Hash([42; 32]);
2014 const UREF_KEY: Key = Key::URef(URef::new([42; 32], AccessRights::READ));
2015 const TRANSFER_KEY: Key = Key::Transfer(TransferAddr::new([42; 32]));
2016 const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32]));
2017 const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42));
2018 const BALANCE_KEY: Key = Key::Balance([42; 32]);
2019 const BID_KEY: Key = Key::Bid(AccountHash::new([42; 32]));
2020 const UNIFIED_BID_KEY: Key = Key::BidAddr(BidAddr::legacy([42; 32]));
2021 const VALIDATOR_BID_KEY: Key = Key::BidAddr(BidAddr::new_validator_addr([2; 32]));
2022 const DELEGATOR_BID_KEY: Key =
2023 Key::BidAddr(BidAddr::new_delegator_account_addr(([2; 32], [9; 32])));
2024 const WITHDRAW_KEY: Key = Key::Withdraw(AccountHash::new([42; 32]));
2025 const DICTIONARY_KEY: Key = Key::Dictionary([42; 32]);
2026 const SYSTEM_ENTITY_REGISTRY_KEY: Key = Key::SystemEntityRegistry;
2027 const ERA_SUMMARY_KEY: Key = Key::EraSummary;
2028 const UNBOND_KEY: Key = Key::Unbond(AccountHash::new([42; 32]));
2029 const CHAINSPEC_REGISTRY_KEY: Key = Key::ChainspecRegistry;
2030 const CHECKSUM_REGISTRY_KEY: Key = Key::ChecksumRegistry;
2031 const PACKAGE_KEY: Key = Key::SmartContract([42; 32]);
2032 const ADDRESSABLE_ENTITY_SYSTEM_KEY: Key =
2033 Key::AddressableEntity(EntityAddr::new_system([42; 32]));
2034 const ADDRESSABLE_ENTITY_ACCOUNT_KEY: Key =
2035 Key::AddressableEntity(EntityAddr::new_account([42; 32]));
2036 const ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY: Key =
2037 Key::AddressableEntity(EntityAddr::new_smart_contract([42; 32]));
2038 const BYTE_CODE_EMPTY_KEY: Key = Key::ByteCode(ByteCodeAddr::Empty);
2039 const BYTE_CODE_V1_WASM_KEY: Key = Key::ByteCode(ByteCodeAddr::V1CasperWasm([42; 32]));
2040 const MESSAGE_TOPIC_KEY: Key = Key::Message(MessageAddr::new_topic_addr(
2041 EntityAddr::SmartContract([42; 32]),
2042 TopicNameHash::new([42; 32]),
2043 ));
2044 const MESSAGE_KEY: Key = Key::Message(MessageAddr::new_message_addr(
2045 EntityAddr::SmartContract([42; 32]),
2046 TopicNameHash::new([2; 32]),
2047 15,
2048 ));
2049 const NAMED_KEY: Key = Key::NamedKey(NamedKeyAddr::new_named_key_entry(
2050 EntityAddr::new_smart_contract([42; 32]),
2051 [43; 32],
2052 ));
2053 const BLOCK_TIME_KEY: Key = Key::BlockGlobal(BlockGlobalAddr::BlockTime);
2054 const BLOCK_MESSAGE_COUNT_KEY: Key = Key::BlockGlobal(BlockGlobalAddr::MessageCount);
2055 const BALANCE_HOLD: Key =
2057 Key::BalanceHold(BalanceHoldAddr::new_gas([42; 32], BlockTime::new(100)));
2058 const STATE_KEY: Key = Key::State(EntityAddr::new_smart_contract([42; 32]));
2059 const KEYS: &[Key] = &[
2060 ACCOUNT_KEY,
2061 HASH_KEY,
2062 UREF_KEY,
2063 TRANSFER_KEY,
2064 DEPLOY_INFO_KEY,
2065 ERA_INFO_KEY,
2066 BALANCE_KEY,
2067 BID_KEY,
2068 WITHDRAW_KEY,
2069 DICTIONARY_KEY,
2070 SYSTEM_ENTITY_REGISTRY_KEY,
2071 ERA_SUMMARY_KEY,
2072 UNBOND_KEY,
2073 CHAINSPEC_REGISTRY_KEY,
2074 CHECKSUM_REGISTRY_KEY,
2075 UNIFIED_BID_KEY,
2076 VALIDATOR_BID_KEY,
2077 DELEGATOR_BID_KEY,
2078 PACKAGE_KEY,
2079 ADDRESSABLE_ENTITY_SYSTEM_KEY,
2080 ADDRESSABLE_ENTITY_ACCOUNT_KEY,
2081 ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY,
2082 BYTE_CODE_EMPTY_KEY,
2083 BYTE_CODE_V1_WASM_KEY,
2084 MESSAGE_TOPIC_KEY,
2085 MESSAGE_KEY,
2086 NAMED_KEY,
2087 BLOCK_TIME_KEY,
2088 BLOCK_MESSAGE_COUNT_KEY,
2089 BALANCE_HOLD,
2090 STATE_KEY,
2091 ];
2092 const HEX_STRING: &str = "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a";
2093 const TOPIC_NAME_HEX_STRING: &str =
2094 "0202020202020202020202020202020202020202020202020202020202020202";
2095 const MESSAGE_INDEX_HEX_STRING: &str = "f";
2096 const UNIFIED_HEX_STRING: &str =
2097 "002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a";
2098 const VALIDATOR_HEX_STRING: &str =
2099 "010202020202020202020202020202020202020202020202020202020202020202";
2100 const DELEGATOR_HEX_STRING: &str =
2101 "0202020202020202020202020202020202020202020202020202020202020202020909090909090909090909090909090909090909090909090909090909090909";
2102
2103 fn test_readable(right: AccessRights, is_true: bool) {
2104 assert_eq!(right.is_readable(), is_true)
2105 }
2106
2107 #[test]
2108 fn test_is_readable() {
2109 test_readable(AccessRights::READ, true);
2110 test_readable(AccessRights::READ_ADD, true);
2111 test_readable(AccessRights::READ_WRITE, true);
2112 test_readable(AccessRights::READ_ADD_WRITE, true);
2113 test_readable(AccessRights::ADD, false);
2114 test_readable(AccessRights::ADD_WRITE, false);
2115 test_readable(AccessRights::WRITE, false);
2116 }
2117
2118 fn test_writable(right: AccessRights, is_true: bool) {
2119 assert_eq!(right.is_writeable(), is_true)
2120 }
2121
2122 #[test]
2123 fn test_is_writable() {
2124 test_writable(AccessRights::WRITE, true);
2125 test_writable(AccessRights::READ_WRITE, true);
2126 test_writable(AccessRights::ADD_WRITE, true);
2127 test_writable(AccessRights::READ, false);
2128 test_writable(AccessRights::ADD, false);
2129 test_writable(AccessRights::READ_ADD, false);
2130 test_writable(AccessRights::READ_ADD_WRITE, true);
2131 }
2132
2133 fn test_addable(right: AccessRights, is_true: bool) {
2134 assert_eq!(right.is_addable(), is_true)
2135 }
2136
2137 #[test]
2138 fn test_is_addable() {
2139 test_addable(AccessRights::ADD, true);
2140 test_addable(AccessRights::READ_ADD, true);
2141 test_addable(AccessRights::READ_WRITE, false);
2142 test_addable(AccessRights::ADD_WRITE, true);
2143 test_addable(AccessRights::READ, false);
2144 test_addable(AccessRights::WRITE, false);
2145 test_addable(AccessRights::READ_ADD_WRITE, true);
2146 }
2147
2148 #[test]
2149 fn should_display_key() {
2150 assert_eq!(
2151 format!("{}", ACCOUNT_KEY),
2152 format!("Key::Account({})", HEX_STRING)
2153 );
2154 assert_eq!(
2155 format!("{}", HASH_KEY),
2156 format!("Key::Hash({})", HEX_STRING)
2157 );
2158 assert_eq!(
2159 format!("{}", UREF_KEY),
2160 format!("Key::URef({}, READ)", HEX_STRING)
2161 );
2162 assert_eq!(
2163 format!("{}", TRANSFER_KEY),
2164 format!("Key::Transfer({})", HEX_STRING)
2165 );
2166 assert_eq!(
2167 format!("{}", DEPLOY_INFO_KEY),
2168 format!("Key::DeployInfo({})", HEX_STRING)
2169 );
2170 assert_eq!(
2171 format!("{}", ERA_INFO_KEY),
2172 "Key::EraInfo(era 42)".to_string()
2173 );
2174 assert_eq!(
2175 format!("{}", BALANCE_KEY),
2176 format!("Key::Balance({})", HEX_STRING)
2177 );
2178 assert_eq!(format!("{}", BID_KEY), format!("Key::Bid({})", HEX_STRING));
2179 assert_eq!(
2180 format!("{}", UNIFIED_BID_KEY),
2181 format!("Key::BidAddr({})", UNIFIED_HEX_STRING)
2182 );
2183 assert_eq!(
2184 format!("{}", VALIDATOR_BID_KEY),
2185 format!("Key::BidAddr({})", VALIDATOR_HEX_STRING)
2186 );
2187 assert_eq!(
2188 format!("{}", DELEGATOR_BID_KEY),
2189 format!("Key::BidAddr({})", DELEGATOR_HEX_STRING)
2190 );
2191 assert_eq!(
2192 format!("{}", WITHDRAW_KEY),
2193 format!("Key::Withdraw({})", HEX_STRING)
2194 );
2195 assert_eq!(
2196 format!("{}", DICTIONARY_KEY),
2197 format!("Key::Dictionary({})", HEX_STRING)
2198 );
2199 assert_eq!(
2200 format!("{}", SYSTEM_ENTITY_REGISTRY_KEY),
2201 format!(
2202 "Key::SystemEntityRegistry({})",
2203 base16::encode_lower(&PADDING_BYTES)
2204 )
2205 );
2206 assert_eq!(
2207 format!("{}", ERA_SUMMARY_KEY),
2208 format!("Key::EraSummary({})", base16::encode_lower(&PADDING_BYTES))
2209 );
2210 assert_eq!(
2211 format!("{}", UNBOND_KEY),
2212 format!("Key::Unbond({})", HEX_STRING)
2213 );
2214 assert_eq!(
2215 format!("{}", CHAINSPEC_REGISTRY_KEY),
2216 format!(
2217 "Key::ChainspecRegistry({})",
2218 base16::encode_lower(&PADDING_BYTES)
2219 )
2220 );
2221 assert_eq!(
2222 format!("{}", CHECKSUM_REGISTRY_KEY),
2223 format!(
2224 "Key::ChecksumRegistry({})",
2225 base16::encode_lower(&PADDING_BYTES),
2226 )
2227 );
2228 assert_eq!(
2229 format!("{}", PACKAGE_KEY),
2230 format!("Key::Package({})", HEX_STRING)
2231 );
2232 assert_eq!(
2233 format!("{}", ADDRESSABLE_ENTITY_SYSTEM_KEY),
2234 format!("Key::AddressableEntity(system-{})", HEX_STRING)
2235 );
2236 assert_eq!(
2237 format!("{}", ADDRESSABLE_ENTITY_ACCOUNT_KEY),
2238 format!("Key::AddressableEntity(account-{})", HEX_STRING)
2239 );
2240 assert_eq!(
2241 format!("{}", ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY),
2242 format!("Key::AddressableEntity(contract-{})", HEX_STRING)
2243 );
2244 assert_eq!(
2245 format!("{}", BYTE_CODE_EMPTY_KEY),
2246 format!(
2247 "Key::ByteCode(byte-code-empty-{})",
2248 base16::encode_lower(&[0u8; 32])
2249 )
2250 );
2251 assert_eq!(
2252 format!("{}", BYTE_CODE_V1_WASM_KEY),
2253 format!("Key::ByteCode(byte-code-v1-wasm-{})", HEX_STRING)
2254 );
2255 assert_eq!(
2256 format!("{}", MESSAGE_TOPIC_KEY),
2257 format!(
2258 "Key::Message(entity-contract-{}-{})",
2259 HEX_STRING, HEX_STRING
2260 )
2261 );
2262 assert_eq!(
2263 format!("{}", MESSAGE_KEY),
2264 format!(
2265 "Key::Message(entity-contract-{}-{}-{})",
2266 HEX_STRING, TOPIC_NAME_HEX_STRING, MESSAGE_INDEX_HEX_STRING
2267 )
2268 );
2269
2270 assert_eq!(
2271 format!("{}", STATE_KEY),
2272 format!(
2273 "Key::State(entity-contract-{})",
2274 base16::encode_lower(&[42; 32])
2275 )
2276 );
2277 assert_eq!(
2278 format!("{}", BLOCK_TIME_KEY),
2279 format!(
2280 "Key::BlockGlobal({}-{})",
2281 BlockGlobalAddr::BlockTime,
2282 base16::encode_lower(&BLOCK_GLOBAL_PADDING_BYTES)
2283 )
2284 );
2285 assert_eq!(
2286 format!("{}", BLOCK_MESSAGE_COUNT_KEY),
2287 format!(
2288 "Key::BlockGlobal({}-{})",
2289 BlockGlobalAddr::MessageCount,
2290 base16::encode_lower(&BLOCK_GLOBAL_PADDING_BYTES)
2291 )
2292 );
2293 }
2294
2295 #[test]
2296 fn abuse_vec_key() {
2297 let bytes: Vec<u8> = vec![255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2299 let res: Result<(Vec<Key>, &[u8]), _> = FromBytes::from_bytes(&bytes);
2300 assert_eq!(
2301 res.expect_err("should fail"),
2302 Error::EarlyEndOfStream,
2303 "length prefix says 2^32-1, but there's not enough data in the stream"
2304 );
2305
2306 let bytes: Vec<u8> = vec![255, 255, 255, 254, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2308 let res: Result<(Vec<Key>, &[u8]), _> = FromBytes::from_bytes(&bytes);
2309 assert_eq!(
2310 res.expect_err("should fail"),
2311 Error::EarlyEndOfStream,
2312 "length prefix says 2^32-2, but there's not enough data in the stream"
2313 );
2314
2315 let bytes: Vec<u8> = vec![0, 0, 0, 254, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2317 let res: Result<(Vec<Key>, &[u8]), _> = FromBytes::from_bytes(&bytes);
2318 assert_eq!(
2319 res.expect_err("should fail"),
2320 Error::EarlyEndOfStream,
2321 "length prefix says 254, but there's not enough data in the stream"
2322 );
2323 }
2324
2325 #[test]
2326 fn check_key_account_getters() {
2327 let account = [42; 32];
2328 let account_hash = AccountHash::new(account);
2329 let key1 = Key::Account(account_hash);
2330 assert_eq!(key1.into_account(), Some(account_hash));
2331 assert!(key1.into_entity_hash_addr().is_some());
2332 assert!(key1.as_uref().is_none());
2333 }
2334
2335 #[test]
2336 fn check_key_hash_getters() {
2337 let hash = [42; KEY_HASH_LENGTH];
2338 let key1 = Key::Hash(hash);
2339 assert!(key1.into_account().is_none());
2340 assert_eq!(key1.into_hash_addr(), Some(hash));
2341 assert!(key1.as_uref().is_none());
2342 }
2343
2344 #[test]
2345 fn check_entity_key_getters() {
2346 let hash = [42; KEY_HASH_LENGTH];
2347 let key1 = Key::contract_entity_key(AddressableEntityHash::new(hash));
2348 assert!(key1.into_account().is_none());
2349 assert_eq!(key1.into_entity_hash_addr(), Some(hash));
2350 assert!(key1.as_uref().is_none());
2351 }
2352
2353 #[test]
2354 fn check_package_key_getters() {
2355 let hash = [42; KEY_HASH_LENGTH];
2356 let key1 = Key::SmartContract(hash);
2357 assert!(key1.into_account().is_none());
2358 assert_eq!(key1.into_package_addr(), Some(hash));
2359 assert!(key1.as_uref().is_none());
2360 }
2361
2362 #[test]
2363 fn check_key_uref_getters() {
2364 let uref = URef::new([42; 32], AccessRights::READ_ADD_WRITE);
2365 let key1 = Key::URef(uref);
2366 assert!(key1.into_account().is_none());
2367 assert!(key1.into_entity_hash_addr().is_none());
2368 assert_eq!(key1.as_uref(), Some(&uref));
2369 }
2370
2371 #[test]
2372 fn key_max_serialized_length() {
2373 let mut got_max = false;
2374 for key in KEYS {
2375 let expected = Key::max_serialized_length();
2376 let actual = key.serialized_length();
2377 assert!(
2378 actual <= expected,
2379 "key too long {} expected {} actual {}",
2380 key,
2381 expected,
2382 actual
2383 );
2384 if actual == Key::max_serialized_length() {
2385 got_max = true;
2386 }
2387 }
2388 assert!(
2389 got_max,
2390 "None of the Key variants has a serialized_length equal to \
2391 Key::max_serialized_length(), so Key::max_serialized_length() should be reduced"
2392 );
2393 }
2394
2395 #[test]
2396 fn should_parse_legacy_bid_key_from_string() {
2397 let account_hash = AccountHash([1; 32]);
2398 let legacy_bid_key = Key::Bid(account_hash);
2399 let original_string = legacy_bid_key.to_formatted_string();
2400
2401 let parsed_bid_key =
2402 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2403 if let Key::Bid(parsed_account_hash) = parsed_bid_key {
2404 assert_eq!(parsed_account_hash, account_hash,);
2405 assert_eq!(legacy_bid_key, parsed_bid_key);
2406
2407 let translated_string = parsed_bid_key.to_formatted_string();
2408 assert_eq!(original_string, translated_string);
2409 } else {
2410 panic!("should have account hash");
2411 }
2412 }
2413
2414 #[test]
2415 fn should_parse_legacy_unified_bid_key_from_string() {
2416 let legacy_bid_addr = BidAddr::legacy([1; 32]);
2417 let legacy_bid_key = Key::BidAddr(legacy_bid_addr);
2418 assert_eq!(legacy_bid_addr.tag(), BidAddrTag::Unified,);
2419
2420 let original_string = legacy_bid_key.to_formatted_string();
2421 let parsed_key =
2422 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2423 let parsed_bid_addr = parsed_key.as_bid_addr().expect("must have bid addr");
2424 assert!(parsed_key.is_bid_addr_key());
2425 assert_eq!(parsed_bid_addr.tag(), legacy_bid_addr.tag(),);
2426 assert_eq!(*parsed_bid_addr, legacy_bid_addr);
2427
2428 let translated_string = parsed_key.to_formatted_string();
2429 assert_eq!(original_string, translated_string);
2430 assert_eq!(parsed_key.as_bid_addr(), legacy_bid_key.as_bid_addr(),);
2431 }
2432
2433 #[test]
2434 fn should_parse_validator_bid_key_from_string() {
2435 let validator_bid_addr = BidAddr::new_validator_addr([1; 32]);
2436 let validator_bid_key = Key::BidAddr(validator_bid_addr);
2437 assert_eq!(validator_bid_addr.tag(), BidAddrTag::Validator,);
2438
2439 let original_string = validator_bid_key.to_formatted_string();
2440 let parsed_key =
2441 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2442 let parsed_bid_addr = parsed_key.as_bid_addr().expect("must have bid addr");
2443 assert!(parsed_key.is_bid_addr_key());
2444 assert_eq!(parsed_bid_addr.tag(), validator_bid_addr.tag(),);
2445 assert_eq!(*parsed_bid_addr, validator_bid_addr,);
2446
2447 let translated_string = parsed_key.to_formatted_string();
2448 assert_eq!(original_string, translated_string);
2449 assert_eq!(parsed_key.as_bid_addr(), validator_bid_key.as_bid_addr(),);
2450 }
2451
2452 #[test]
2453 fn should_parse_delegator_bid_key_from_string() {
2454 let delegator_bid_addr = BidAddr::new_delegator_account_addr(([1; 32], [9; 32]));
2455 let delegator_bid_key = Key::BidAddr(delegator_bid_addr);
2456 assert_eq!(delegator_bid_addr.tag(), BidAddrTag::DelegatedAccount);
2457
2458 let original_string = delegator_bid_key.to_formatted_string();
2459
2460 let parsed_key =
2461 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2462 let parsed_bid_addr = parsed_key.as_bid_addr().expect("must have bid addr");
2463 assert!(parsed_key.is_bid_addr_key());
2464 assert_eq!(parsed_bid_addr.tag(), delegator_bid_addr.tag(),);
2465 assert_eq!(*parsed_bid_addr, delegator_bid_addr,);
2466
2467 let translated_string = parsed_key.to_formatted_string();
2468 assert_eq!(original_string, translated_string);
2469 assert_eq!(parsed_key.as_bid_addr(), delegator_bid_key.as_bid_addr(),);
2470 }
2471
2472 #[test]
2473 fn should_parse_credit_bid_key_from_string() {
2474 let credit_bid_addr = BidAddr::Credit {
2475 validator: AccountHash::new([1; 32]),
2476 era_id: 1.into(),
2477 };
2478 let delegator_bid_key = Key::BidAddr(credit_bid_addr);
2479 assert_eq!(credit_bid_addr.tag(), BidAddrTag::Credit);
2480
2481 let original_string = delegator_bid_key.to_formatted_string();
2482
2483 let parsed_key =
2484 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2485 let parsed_bid_addr = parsed_key.as_bid_addr().expect("must have bid addr");
2486 assert!(parsed_key.is_bid_addr_key());
2487 assert_eq!(parsed_bid_addr.tag(), credit_bid_addr.tag(),);
2488 assert_eq!(*parsed_bid_addr, credit_bid_addr,);
2489
2490 let translated_string = parsed_key.to_formatted_string();
2491 assert_eq!(original_string, translated_string);
2492 assert_eq!(parsed_key.as_bid_addr(), delegator_bid_key.as_bid_addr());
2493 }
2494
2495 #[test]
2496 fn should_parse_key_from_str() {
2497 for key in KEYS {
2498 let string = key.to_formatted_string();
2499 let parsed_key = Key::from_formatted_str(&string).expect("{string} (key = {key:?})");
2500 assert_eq!(parsed_key, *key, "{string} (key = {key:?})");
2501 }
2502 }
2503
2504 #[test]
2505 fn should_fail_to_parse_key_from_str() {
2506 assert!(
2507 Key::from_formatted_str(ACCOUNT_HASH_FORMATTED_STRING_PREFIX)
2508 .unwrap_err()
2509 .to_string()
2510 .starts_with("account-key from string error: ")
2511 );
2512 assert!(Key::from_formatted_str(HASH_PREFIX)
2513 .unwrap_err()
2514 .to_string()
2515 .starts_with("hash-key from string error: "));
2516 assert!(Key::from_formatted_str(UREF_FORMATTED_STRING_PREFIX)
2517 .unwrap_err()
2518 .to_string()
2519 .starts_with("uref-key from string error: "));
2520 assert!(
2521 Key::from_formatted_str(TRANSFER_ADDR_FORMATTED_STRING_PREFIX)
2522 .unwrap_err()
2523 .to_string()
2524 .starts_with("legacy-transfer-key from string error: ")
2525 );
2526 assert!(Key::from_formatted_str(DEPLOY_INFO_PREFIX)
2527 .unwrap_err()
2528 .to_string()
2529 .starts_with("deploy-info-key from string error: "));
2530 assert!(Key::from_formatted_str(ERA_INFO_PREFIX)
2531 .unwrap_err()
2532 .to_string()
2533 .starts_with("era-info-key from string error: "));
2534 assert!(Key::from_formatted_str(BALANCE_PREFIX)
2535 .unwrap_err()
2536 .to_string()
2537 .starts_with("balance-key from string error: "));
2538 assert!(Key::from_formatted_str(BID_PREFIX)
2539 .unwrap_err()
2540 .to_string()
2541 .starts_with("bid-key from string error: "));
2542 assert!(Key::from_formatted_str(WITHDRAW_PREFIX)
2543 .unwrap_err()
2544 .to_string()
2545 .starts_with("withdraw-key from string error: "));
2546 assert!(Key::from_formatted_str(DICTIONARY_PREFIX)
2547 .unwrap_err()
2548 .to_string()
2549 .starts_with("dictionary-key from string error: "));
2550 assert!(Key::from_formatted_str(SYSTEM_ENTITY_REGISTRY_PREFIX)
2551 .unwrap_err()
2552 .to_string()
2553 .starts_with("system-contract-registry-key from string error: "));
2554 assert!(Key::from_formatted_str(ERA_SUMMARY_PREFIX)
2555 .unwrap_err()
2556 .to_string()
2557 .starts_with("era-summary-key from string error"));
2558 assert!(Key::from_formatted_str(UNBOND_PREFIX)
2559 .unwrap_err()
2560 .to_string()
2561 .starts_with("unbond-key from string error: "));
2562 assert!(Key::from_formatted_str(CHAINSPEC_REGISTRY_PREFIX)
2563 .unwrap_err()
2564 .to_string()
2565 .starts_with("chainspec-registry-key from string error: "));
2566 assert!(Key::from_formatted_str(CHECKSUM_REGISTRY_PREFIX)
2567 .unwrap_err()
2568 .to_string()
2569 .starts_with("checksum-registry-key from string error: "));
2570 let bid_addr_err = Key::from_formatted_str(BID_ADDR_PREFIX)
2571 .unwrap_err()
2572 .to_string();
2573 assert!(
2574 bid_addr_err.starts_with("bid-addr-key from string error: "),
2575 "{}",
2576 bid_addr_err
2577 );
2578 assert!(Key::from_formatted_str(PACKAGE_PREFIX)
2579 .unwrap_err()
2580 .to_string()
2581 .starts_with("package-key from string error: "));
2582
2583 let error_string =
2584 Key::from_formatted_str(&format!("{}{}", ENTITY_PREFIX, ACCOUNT_ENTITY_PREFIX))
2585 .unwrap_err()
2586 .to_string();
2587 assert!(error_string.starts_with("addressable-entity-key from string error: "));
2588 assert!(
2589 Key::from_formatted_str(&format!("{}{}", BYTE_CODE_PREFIX, EMPTY_PREFIX))
2590 .unwrap_err()
2591 .to_string()
2592 .starts_with("byte-code-key from string error: ")
2593 );
2594 let invalid_prefix = "a-0000000000000000000000000000000000000000000000000000000000000000";
2595 assert_eq!(
2596 Key::from_formatted_str(invalid_prefix)
2597 .unwrap_err()
2598 .to_string(),
2599 "unknown prefix for key"
2600 );
2601
2602 let missing_hyphen_prefix =
2603 "hash0000000000000000000000000000000000000000000000000000000000000000";
2604 assert_eq!(
2605 Key::from_formatted_str(missing_hyphen_prefix)
2606 .unwrap_err()
2607 .to_string(),
2608 "unknown prefix for key"
2609 );
2610
2611 let no_prefix = "0000000000000000000000000000000000000000000000000000000000000000";
2612 assert_eq!(
2613 Key::from_formatted_str(no_prefix).unwrap_err().to_string(),
2614 "unknown prefix for key"
2615 );
2616
2617 let balance_hold_err = Key::from_formatted_str(BALANCE_HOLD_PREFIX)
2618 .unwrap_err()
2619 .to_string();
2620 assert!(
2621 balance_hold_err.starts_with("balance-hold from string error: "),
2622 "{}",
2623 bid_addr_err
2624 );
2625 }
2626
2627 #[test]
2628 fn key_to_json() {
2629 for key in KEYS.iter() {
2630 assert_eq!(
2631 serde_json::to_string(key).unwrap(),
2632 format!("\"{}\"", key.to_formatted_string())
2633 );
2634 }
2635 }
2636
2637 #[test]
2638 fn serialization_roundtrip_bincode() {
2639 for key in KEYS {
2640 let encoded = bincode::serialize(key).unwrap();
2641 let decoded = bincode::deserialize(&encoded).unwrap();
2642 assert_eq!(key, &decoded);
2643 }
2644 }
2645
2646 #[test]
2647 fn key_tag_bytes_roundtrip() {
2648 for key in KEYS {
2649 let tag: KeyTag = key.tag();
2650 bytesrepr::test_serialization_roundtrip(&tag);
2651 }
2652 }
2653
2654 #[test]
2655 fn bytesrepr_serialization_roundtrip() {
2656 bytesrepr::test_serialization_roundtrip(&ACCOUNT_KEY);
2657 bytesrepr::test_serialization_roundtrip(&HASH_KEY);
2658 bytesrepr::test_serialization_roundtrip(&UREF_KEY);
2659 bytesrepr::test_serialization_roundtrip(&TRANSFER_KEY);
2660 bytesrepr::test_serialization_roundtrip(&DEPLOY_INFO_KEY);
2661 bytesrepr::test_serialization_roundtrip(&ERA_INFO_KEY);
2662 bytesrepr::test_serialization_roundtrip(&BALANCE_KEY);
2663 bytesrepr::test_serialization_roundtrip(&BID_KEY);
2664 bytesrepr::test_serialization_roundtrip(&WITHDRAW_KEY);
2665 bytesrepr::test_serialization_roundtrip(&DICTIONARY_KEY);
2666 bytesrepr::test_serialization_roundtrip(&ERA_SUMMARY_KEY);
2668 bytesrepr::test_serialization_roundtrip(&UNBOND_KEY);
2669 bytesrepr::test_serialization_roundtrip(&CHAINSPEC_REGISTRY_KEY);
2670 bytesrepr::test_serialization_roundtrip(&CHECKSUM_REGISTRY_KEY);
2671 bytesrepr::test_serialization_roundtrip(&VALIDATOR_BID_KEY);
2673 bytesrepr::test_serialization_roundtrip(&DELEGATOR_BID_KEY);
2674 bytesrepr::test_serialization_roundtrip(&PACKAGE_KEY);
2675 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SYSTEM_KEY);
2676 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_ACCOUNT_KEY);
2677 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY);
2678 bytesrepr::test_serialization_roundtrip(&BYTE_CODE_EMPTY_KEY);
2679 bytesrepr::test_serialization_roundtrip(&BYTE_CODE_V1_WASM_KEY);
2680 bytesrepr::test_serialization_roundtrip(&MESSAGE_TOPIC_KEY);
2681 bytesrepr::test_serialization_roundtrip(&MESSAGE_KEY);
2682 bytesrepr::test_serialization_roundtrip(&NAMED_KEY);
2683 bytesrepr::test_serialization_roundtrip(&STATE_KEY);
2684 }
2685
2686 #[test]
2687 fn serialization_roundtrip_json() {
2688 for key in KEYS {
2689 round_trip(key);
2690 }
2691
2692 let zeros = [0; BLAKE2B_DIGEST_LENGTH];
2693 let nines = [9; BLAKE2B_DIGEST_LENGTH];
2694
2695 round_trip(&Key::Account(AccountHash::new(zeros)));
2696 round_trip(&Key::Hash(zeros));
2697 round_trip(&Key::URef(URef::new(zeros, AccessRights::READ)));
2698 round_trip(&Key::Transfer(TransferAddr::new(zeros)));
2699 round_trip(&Key::DeployInfo(DeployHash::from_raw(zeros)));
2700 round_trip(&Key::EraInfo(EraId::from(0)));
2701 round_trip(&Key::Balance(URef::new(zeros, AccessRights::READ).addr()));
2702 round_trip(&Key::Bid(AccountHash::new(zeros)));
2703 round_trip(&Key::BidAddr(BidAddr::legacy(zeros)));
2704 round_trip(&Key::BidAddr(BidAddr::new_validator_addr(zeros)));
2705 round_trip(&Key::BidAddr(BidAddr::new_delegator_account_addr((
2706 zeros, nines,
2707 ))));
2708 round_trip(&Key::Withdraw(AccountHash::new(zeros)));
2709 round_trip(&Key::Dictionary(zeros));
2710 round_trip(&Key::Unbond(AccountHash::new(zeros)));
2711 round_trip(&Key::SmartContract(zeros));
2712 round_trip(&Key::AddressableEntity(EntityAddr::new_system(zeros)));
2713 round_trip(&Key::AddressableEntity(EntityAddr::new_account(zeros)));
2714 round_trip(&Key::AddressableEntity(EntityAddr::new_smart_contract(
2715 zeros,
2716 )));
2717 round_trip(&Key::ByteCode(ByteCodeAddr::Empty));
2718 round_trip(&Key::ByteCode(ByteCodeAddr::V1CasperWasm(zeros)));
2719 round_trip(&Key::Message(MessageAddr::new_topic_addr(
2720 EntityAddr::new_smart_contract(zeros),
2721 nines.into(),
2722 )));
2723 round_trip(&Key::Message(MessageAddr::new_message_addr(
2724 EntityAddr::new_smart_contract(zeros),
2725 nines.into(),
2726 1,
2727 )));
2728 round_trip(&Key::NamedKey(NamedKeyAddr::default()));
2729 round_trip(&Key::BlockGlobal(BlockGlobalAddr::BlockTime));
2730 round_trip(&Key::BlockGlobal(BlockGlobalAddr::MessageCount));
2731 round_trip(&Key::BlockGlobal(BlockGlobalAddr::ProtocolVersion));
2732 round_trip(&Key::BlockGlobal(BlockGlobalAddr::AddressableEntity));
2733 round_trip(&Key::BalanceHold(BalanceHoldAddr::default()));
2734 round_trip(&Key::State(EntityAddr::new_system(zeros)));
2735 }
2736
2737 #[test]
2738 fn state_json_deserialization() {
2739 let mut test_rng = TestRng::new();
2740 let state_key = Key::State(EntityAddr::new_account(test_rng.gen()));
2741 round_trip(&state_key);
2742
2743 let state_key = Key::State(EntityAddr::new_system(test_rng.gen()));
2744 round_trip(&state_key);
2745
2746 let state_key = Key::State(EntityAddr::new_smart_contract(test_rng.gen()));
2747 round_trip(&state_key);
2748 }
2749
2750 #[test]
2751 fn roundtrip() {
2752 bytesrepr::test_serialization_roundtrip(&ACCOUNT_KEY);
2753 bytesrepr::test_serialization_roundtrip(&HASH_KEY);
2754 bytesrepr::test_serialization_roundtrip(&UREF_KEY);
2755 bytesrepr::test_serialization_roundtrip(&TRANSFER_KEY);
2756 bytesrepr::test_serialization_roundtrip(&DEPLOY_INFO_KEY);
2757 bytesrepr::test_serialization_roundtrip(&ERA_INFO_KEY);
2758 bytesrepr::test_serialization_roundtrip(&BALANCE_KEY);
2759 bytesrepr::test_serialization_roundtrip(&BID_KEY);
2760 bytesrepr::test_serialization_roundtrip(&WITHDRAW_KEY);
2761 bytesrepr::test_serialization_roundtrip(&DICTIONARY_KEY);
2762 bytesrepr::test_serialization_roundtrip(&SYSTEM_ENTITY_REGISTRY_KEY);
2763 bytesrepr::test_serialization_roundtrip(&ERA_SUMMARY_KEY);
2764 bytesrepr::test_serialization_roundtrip(&UNBOND_KEY);
2765 bytesrepr::test_serialization_roundtrip(&CHAINSPEC_REGISTRY_KEY);
2766 bytesrepr::test_serialization_roundtrip(&CHECKSUM_REGISTRY_KEY);
2767 bytesrepr::test_serialization_roundtrip(&UNIFIED_BID_KEY);
2768 bytesrepr::test_serialization_roundtrip(&VALIDATOR_BID_KEY);
2769 bytesrepr::test_serialization_roundtrip(&DELEGATOR_BID_KEY);
2770 bytesrepr::test_serialization_roundtrip(&PACKAGE_KEY);
2771 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SYSTEM_KEY);
2772 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_ACCOUNT_KEY);
2773 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY);
2774 bytesrepr::test_serialization_roundtrip(&BYTE_CODE_EMPTY_KEY);
2775 bytesrepr::test_serialization_roundtrip(&BYTE_CODE_V1_WASM_KEY);
2776 bytesrepr::test_serialization_roundtrip(&MESSAGE_TOPIC_KEY);
2777 bytesrepr::test_serialization_roundtrip(&MESSAGE_KEY);
2778 bytesrepr::test_serialization_roundtrip(&NAMED_KEY);
2779 }
2780
2781 fn round_trip(key: &Key) {
2782 let encoded = serde_json::to_value(key).unwrap();
2783 let decoded = serde_json::from_value(encoded.clone())
2784 .unwrap_or_else(|_| panic!("{} {}", key, encoded));
2785 assert_eq!(key, &decoded);
2786 }
2787}
2788
2789#[cfg(test)]
2790mod proptest {
2791 use crate::gens;
2792 use proptest::prelude::*;
2793
2794 proptest! {
2795 #[test]
2796 fn test_json_roundtrip_for_bidaddr_key(key in gens::all_keys_arb()) {
2797 let json_string = serde_json::to_string_pretty(&key).unwrap();
2798 let decoded = serde_json::from_str(&json_string).unwrap();
2799 assert_eq!(key, decoded);
2800 }
2801 }
2802}