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::DelegatedAccount => {
758 let delegator_bytes = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(
759 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
760 )
761 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
762 BidAddr::new_delegator_account_addr((validator_bytes, delegator_bytes))
763 }
764 BidAddrTag::DelegatedPurse => {
765 let uref = <[u8; UREF_ADDR_LENGTH]>::try_from(
766 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
767 )
768 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
769 BidAddr::DelegatedPurse {
770 validator: AccountHash::new(validator_bytes),
771 delegator: uref,
772 }
773 }
774 BidAddrTag::Credit => {
775 let era_id = bytesrepr::deserialize_from_slice(
776 &bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..],
777 )
778 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
779 BidAddr::Credit {
780 validator: AccountHash::new(validator_bytes),
781 era_id,
782 }
783 }
784 BidAddrTag::ReservedDelegationAccount => {
785 let delegator_bytes = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(
786 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
787 )
788 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
789 BidAddr::new_reservation_account_addr((validator_bytes, delegator_bytes))
790 }
791 BidAddrTag::ReservedDelegationPurse => {
792 let uref = <[u8; UREF_ADDR_LENGTH]>::try_from(
793 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
794 )
795 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
796 BidAddr::ReservedDelegationPurse {
797 validator: AccountHash::new(validator_bytes),
798 delegator: uref,
799 }
800 }
801 BidAddrTag::UnbondAccount => {
802 let unbonder_bytes = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(
803 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
804 )
805 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
806 BidAddr::UnbondAccount {
807 validator: AccountHash::new(validator_bytes),
808 unbonder: AccountHash::new(unbonder_bytes),
809 }
810 }
811 BidAddrTag::UnbondPurse => {
812 let uref = <[u8; UREF_ADDR_LENGTH]>::try_from(
813 bytes[BidAddr::VALIDATOR_BID_ADDR_LENGTH..].as_ref(),
814 )
815 .map_err(|err| FromStrError::BidAddr(err.to_string()))?;
816 BidAddr::UnbondPurse {
817 validator: AccountHash::new(validator_bytes),
818 unbonder: uref,
819 }
820 }
821 };
822 return Ok(Key::BidAddr(bid_addr));
823 }
824
825 if let Some(hex) = input.strip_prefix(BID_PREFIX) {
826 let hash = checksummed_hex::decode(hex)
827 .map_err(|error| FromStrError::Bid(error.to_string()))?;
828 let account_hash = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(hash.as_ref())
829 .map_err(|error| FromStrError::Bid(error.to_string()))?;
830 return Ok(Key::Bid(AccountHash::new(account_hash)));
831 }
832
833 if let Some(hex) = input.strip_prefix(WITHDRAW_PREFIX) {
834 let hash = checksummed_hex::decode(hex)
835 .map_err(|error| FromStrError::Withdraw(error.to_string()))?;
836 let account_hash = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(hash.as_ref())
837 .map_err(|error| FromStrError::Withdraw(error.to_string()))?;
838 return Ok(Key::Withdraw(AccountHash::new(account_hash)));
839 }
840
841 if let Some(hex) = input.strip_prefix(UNBOND_PREFIX) {
842 let hash = checksummed_hex::decode(hex)
843 .map_err(|error| FromStrError::Unbond(error.to_string()))?;
844 let account_hash = <[u8; ACCOUNT_HASH_LENGTH]>::try_from(hash.as_ref())
845 .map_err(|error| FromStrError::Unbond(error.to_string()))?;
846 return Ok(Key::Unbond(AccountHash::new(account_hash)));
847 }
848
849 if let Some(dictionary_addr) = input.strip_prefix(DICTIONARY_PREFIX) {
850 let dictionary_addr_bytes = checksummed_hex::decode(dictionary_addr)
851 .map_err(|error| FromStrError::Dictionary(error.to_string()))?;
852 let addr = DictionaryAddr::try_from(dictionary_addr_bytes.as_ref())
853 .map_err(|error| FromStrError::Dictionary(error.to_string()))?;
854 return Ok(Key::Dictionary(addr));
855 }
856
857 if let Some(registry_address) = input.strip_prefix(SYSTEM_ENTITY_REGISTRY_PREFIX) {
858 let padded_bytes = checksummed_hex::decode(registry_address)
859 .map_err(|error| FromStrError::SystemEntityRegistry(error.to_string()))?;
860 let _padding: [u8; 32] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
861 FromStrError::SystemEntityRegistry(
862 "Failed to deserialize system registry key".to_string(),
863 )
864 })?;
865 return Ok(Key::SystemEntityRegistry);
866 }
867
868 if let Some(registry_address) = input.strip_prefix(CHAINSPEC_REGISTRY_PREFIX) {
869 let padded_bytes = checksummed_hex::decode(registry_address)
870 .map_err(|error| FromStrError::ChainspecRegistry(error.to_string()))?;
871 let _padding: [u8; 32] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
872 FromStrError::ChainspecRegistry(
873 "Failed to deserialize chainspec registry key".to_string(),
874 )
875 })?;
876 return Ok(Key::ChainspecRegistry);
877 }
878
879 if let Some(registry_address) = input.strip_prefix(CHECKSUM_REGISTRY_PREFIX) {
880 let padded_bytes = checksummed_hex::decode(registry_address)
881 .map_err(|error| FromStrError::ChecksumRegistry(error.to_string()))?;
882 let _padding: [u8; 32] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
883 FromStrError::ChecksumRegistry(
884 "Failed to deserialize checksum registry key".to_string(),
885 )
886 })?;
887 return Ok(Key::ChecksumRegistry);
888 }
889
890 if let Some(package_addr) = input.strip_prefix(PACKAGE_PREFIX) {
891 let package_addr_bytes = checksummed_hex::decode(package_addr)
892 .map_err(|error| FromStrError::Dictionary(error.to_string()))?;
893 let addr = PackageAddr::try_from(package_addr_bytes.as_ref())
894 .map_err(|error| FromStrError::Package(error.to_string()))?;
895 return Ok(Key::SmartContract(addr));
896 }
897
898 match EntityAddr::from_formatted_str(input) {
899 Ok(entity_addr) => return Ok(Key::AddressableEntity(entity_addr)),
900 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
901 Err(error) => {
902 return Err(FromStrError::AddressableEntity(error.to_string()));
903 }
904 }
905
906 match ByteCodeAddr::from_formatted_string(input) {
907 Ok(byte_code_addr) => return Ok(Key::ByteCode(byte_code_addr)),
908 Err(byte_code::FromStrError::InvalidPrefix) => {}
909 Err(error) => return Err(FromStrError::ByteCode(error.to_string())),
910 }
911
912 match MessageAddr::from_formatted_str(input) {
913 Ok(message_addr) => return Ok(Key::Message(message_addr)),
914 Err(contract_messages::FromStrError::InvalidPrefix) => {}
915 Err(error) => return Err(error.into()),
916 }
917
918 match NamedKeyAddr::from_formatted_str(input) {
919 Ok(named_key) => return Ok(Key::NamedKey(named_key)),
920 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
921 Err(error) => return Err(FromStrError::NamedKey(error.to_string())),
922 }
923
924 if let Some(block_time) = input.strip_prefix(BLOCK_GLOBAL_TIME_PREFIX) {
925 let padded_bytes = checksummed_hex::decode(block_time)
926 .map_err(|error| FromStrError::BlockGlobal(error.to_string()))?;
927 let _padding: [u8; 31] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
928 FromStrError::BlockGlobal("Failed to deserialize global block time key".to_string())
929 })?;
930 return Ok(BlockGlobalAddr::BlockTime.into());
931 }
932
933 if let Some(message_count) = input.strip_prefix(BLOCK_GLOBAL_MESSAGE_COUNT_PREFIX) {
934 let padded_bytes = checksummed_hex::decode(message_count)
935 .map_err(|error| FromStrError::BlockGlobal(error.to_string()))?;
936 let _padding: [u8; 31] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
937 FromStrError::BlockGlobal(
938 "Failed to deserialize global block message count key".to_string(),
939 )
940 })?;
941 return Ok(BlockGlobalAddr::MessageCount.into());
942 }
943
944 if let Some(protocol_version) = input.strip_prefix(BLOCK_GLOBAL_PROTOCOL_VERSION_PREFIX) {
945 let padded_bytes = checksummed_hex::decode(protocol_version)
946 .map_err(|error| FromStrError::BlockGlobal(error.to_string()))?;
947 let _padding: [u8; 31] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
948 FromStrError::BlockGlobal(
949 "Failed to deserialize global block protocol version key".to_string(),
950 )
951 })?;
952 return Ok(BlockGlobalAddr::ProtocolVersion.into());
953 }
954
955 if let Some(addressable_entity) = input.strip_prefix(BLOCK_GLOBAL_ADDRESSABLE_ENTITY_PREFIX)
956 {
957 let padded_bytes = checksummed_hex::decode(addressable_entity)
958 .map_err(|error| FromStrError::BlockGlobal(error.to_string()))?;
959 let _padding: [u8; 31] = TryFrom::try_from(padded_bytes.as_ref()).map_err(|_| {
960 FromStrError::BlockGlobal(
961 "Failed to deserialize global block addressable entity key".to_string(),
962 )
963 })?;
964 return Ok(BlockGlobalAddr::AddressableEntity.into());
965 }
966
967 match EntryPointAddr::from_formatted_str(input) {
968 Ok(entry_point_addr) => return Ok(Key::EntryPoint(entry_point_addr)),
969 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
970 Err(error) => return Err(FromStrError::EntryPoint(error.to_string())),
971 }
972
973 if let Some(entity_addr_formatted) = input.strip_prefix(STATE_PREFIX) {
974 match EntityAddr::from_formatted_str(entity_addr_formatted) {
975 Ok(entity_addr) => return Ok(Key::State(entity_addr)),
976 Err(addressable_entity::FromStrError::InvalidPrefix) => {}
977 Err(error) => {
978 return Err(FromStrError::State(error.to_string()));
979 }
980 }
981 }
982
983 Err(FromStrError::UnknownPrefix)
984 }
985
986 pub fn into_account(self) -> Option<AccountHash> {
989 match self {
990 Key::Account(bytes) => Some(bytes),
991 _ => None,
992 }
993 }
994
995 pub fn into_hash_addr(self) -> Option<HashAddr> {
998 match self {
999 Key::Hash(hash) => Some(hash),
1000 _ => None,
1001 }
1002 }
1003
1004 pub fn into_entity_hash_addr(self) -> Option<HashAddr> {
1007 match self {
1008 Key::AddressableEntity(entity_addr) => Some(entity_addr.value()),
1009 Key::Account(account_hash) => Some(account_hash.value()),
1010 Key::Hash(hash) => Some(hash),
1011 _ => None,
1012 }
1013 }
1014
1015 pub fn into_package_addr(self) -> Option<PackageAddr> {
1018 match self {
1019 Key::Hash(hash) => Some(hash),
1020 Key::SmartContract(package_addr) => Some(package_addr),
1021 _ => None,
1022 }
1023 }
1024
1025 pub fn into_entity_hash(self) -> Option<AddressableEntityHash> {
1028 let entity_addr = self.into_entity_hash_addr()?;
1029 Some(AddressableEntityHash::new(entity_addr))
1030 }
1031
1032 pub fn into_package_hash(self) -> Option<PackageHash> {
1035 let package_addr = self.into_package_addr()?;
1036 Some(PackageHash::new(package_addr))
1037 }
1038
1039 pub fn into_named_key_addr(self) -> Option<NamedKeyAddr> {
1042 match self {
1043 Key::NamedKey(addr) => Some(addr),
1044 _ => None,
1045 }
1046 }
1047
1048 pub fn into_uref(self) -> Option<URef> {
1050 match self {
1051 Key::URef(uref) => Some(uref),
1052 _ => None,
1053 }
1054 }
1055
1056 pub fn as_uref(&self) -> Option<&URef> {
1059 match self {
1060 Key::URef(uref) => Some(uref),
1061 _ => None,
1062 }
1063 }
1064
1065 pub fn as_uref_mut(&mut self) -> Option<&mut URef> {
1068 match self {
1069 Key::URef(uref) => Some(uref),
1070 _ => None,
1071 }
1072 }
1073
1074 pub fn as_balance(&self) -> Option<&URefAddr> {
1077 if let Self::Balance(v) = self {
1078 Some(v)
1079 } else {
1080 None
1081 }
1082 }
1083
1084 pub fn as_balance_hold(&self) -> Option<&BalanceHoldAddr> {
1087 if let Self::BalanceHold(addr) = self {
1088 Some(addr)
1089 } else {
1090 None
1091 }
1092 }
1093
1094 pub fn as_dictionary(&self) -> Option<&DictionaryAddr> {
1097 match self {
1098 Key::Dictionary(v) => Some(v),
1099 _ => None,
1100 }
1101 }
1102
1103 pub fn as_bid_addr(&self) -> Option<&BidAddr> {
1106 if let Self::BidAddr(addr) = self {
1107 Some(addr)
1108 } else {
1109 None
1110 }
1111 }
1112
1113 pub fn as_message_topic_name_hash(&self) -> Option<TopicNameHash> {
1116 if let Self::Message(addr) = self {
1117 Some(addr.topic_name_hash())
1118 } else {
1119 None
1120 }
1121 }
1122
1123 pub fn uref_to_hash(&self) -> Option<Key> {
1125 let uref = self.as_uref()?;
1126 let addr = uref.addr();
1127 Some(Key::Hash(addr))
1128 }
1129
1130 pub fn withdraw_to_unbond(&self) -> Option<Key> {
1132 if let Key::Withdraw(account_hash) = self {
1133 return Some(Key::Unbond(*account_hash));
1134 }
1135 None
1136 }
1137
1138 pub fn dictionary(seed_uref: URef, dictionary_item_key: &[u8]) -> Key {
1141 let mut hasher = VarBlake2b::new(BLAKE2B_DIGEST_LENGTH).expect("should create hasher");
1143 hasher.update(seed_uref.addr().as_ref());
1144 hasher.update(dictionary_item_key);
1145 let mut addr = HashAddr::default();
1147 hasher.finalize_variable(|hash| addr.clone_from_slice(hash));
1148 Key::Dictionary(addr)
1149 }
1150
1151 pub fn addressable_entity_key(
1154 entity_kind_tag: EntityKindTag,
1155 entity_hash: AddressableEntityHash,
1156 ) -> Self {
1157 let entity_addr = match entity_kind_tag {
1158 EntityKindTag::System => EntityAddr::new_system(entity_hash.value()),
1159 EntityKindTag::Account => EntityAddr::new_account(entity_hash.value()),
1160 EntityKindTag::SmartContract => EntityAddr::new_smart_contract(entity_hash.value()),
1161 };
1162
1163 Key::AddressableEntity(entity_addr)
1164 }
1165
1166 pub fn contract_entity_key(entity_hash: AddressableEntityHash) -> Key {
1168 Self::addressable_entity_key(EntityKindTag::SmartContract, entity_hash)
1169 }
1170
1171 pub fn byte_code_key(byte_code_addr: ByteCodeAddr) -> Self {
1173 Key::ByteCode(byte_code_addr)
1174 }
1175
1176 pub fn message(entity_addr: EntityAddr, topic_name_hash: TopicNameHash, index: u32) -> Key {
1179 Key::Message(MessageAddr::new_message_addr(
1180 entity_addr,
1181 topic_name_hash,
1182 index,
1183 ))
1184 }
1185
1186 pub fn message_topic(entity_addr: EntityAddr, topic_name_hash: TopicNameHash) -> Key {
1189 Key::Message(MessageAddr::new_topic_addr(entity_addr, topic_name_hash))
1190 }
1191
1192 pub fn entry_point(entry_point_addr: EntryPointAddr) -> Self {
1194 Key::EntryPoint(entry_point_addr)
1195 }
1196
1197 pub fn is_dictionary_key(&self) -> bool {
1199 if let Key::Dictionary(_) = self {
1200 return true;
1201 }
1202 false
1203 }
1204
1205 pub fn is_balance_key(&self) -> bool {
1207 if let Key::Balance(_) = self {
1208 return true;
1209 }
1210 false
1211 }
1212
1213 pub fn is_bid_addr_key(&self) -> bool {
1215 if let Key::BidAddr(_) = self {
1216 return true;
1217 }
1218 false
1219 }
1220
1221 pub fn is_named_key(&self) -> bool {
1223 if let Key::NamedKey(_) = self {
1224 return true;
1225 }
1226
1227 false
1228 }
1229
1230 pub fn is_system_key(&self) -> bool {
1232 if let Self::AddressableEntity(entity_addr) = self {
1233 return match entity_addr.tag() {
1234 EntityKindTag::System => true,
1235 EntityKindTag::SmartContract | EntityKindTag::Account => false,
1236 };
1237 }
1238 false
1239 }
1240
1241 pub fn is_smart_contract_key(&self) -> bool {
1243 matches!(
1244 self,
1245 Self::AddressableEntity(EntityAddr::SmartContract(_)) | Self::Hash(_)
1246 )
1247 }
1248
1249 pub fn is_named_key_entry(&self) -> bool {
1251 matches!(self, Self::NamedKey(_))
1252 }
1253
1254 pub fn is_entry_for_base(&self, entity_addr: &EntityAddr) -> bool {
1257 if let Self::NamedKey(named_key_addr) = self {
1258 named_key_addr.entity_addr() == *entity_addr
1259 } else {
1260 false
1261 }
1262 }
1263
1264 pub fn is_readable(&self, entity_addr: &EntityAddr) -> bool {
1266 if entity_addr.is_system() {
1267 return true;
1269 }
1270 let ret = match self {
1271 Key::BidAddr(_) => {
1272 true
1274 }
1275 Key::URef(uref) => {
1276 uref.is_readable()
1278 }
1279 Key::SystemEntityRegistry | Key::SmartContract(_) => {
1280 true
1282 }
1283 Key::Unbond(account_hash) => {
1284 entity_addr.tag() == EntityKindTag::Account
1286 && entity_addr.value() == account_hash.value()
1287 }
1288 Key::NamedKey(named_key_addr) => {
1289 &named_key_addr.entity_addr() == entity_addr
1291 }
1292 Key::ByteCode(_)
1293 | Key::Account(_)
1294 | Key::Hash(_)
1295 | Key::AddressableEntity(_)
1296 | Key::Balance(_)
1297 | Key::BalanceHold(_)
1298 | Key::Dictionary(_)
1299 | Key::Message(_)
1300 | Key::BlockGlobal(_)
1301 | Key::EntryPoint(_) => true,
1302 _ => false,
1303 };
1304 if !ret {
1305 let reading_entity_key = Key::AddressableEntity(*entity_addr);
1306 warn!(?reading_entity_key, attempted_key=?self, "attempt to read without permission")
1307 }
1308 ret
1309 }
1310
1311 pub fn is_addable(&self, entity_addr: &EntityAddr) -> bool {
1313 let ret = match self {
1316 Key::URef(uref) => uref.is_addable(),
1317 Key::AddressableEntity(addr_entity_addr) => {
1318 entity_addr == addr_entity_addr
1320 }
1321 Key::NamedKey(named_key_addr) => {
1322 &named_key_addr.entity_addr() == entity_addr
1324 }
1325 _ => {
1326 let adding_entity_key = Key::AddressableEntity(*entity_addr);
1328 warn!(?adding_entity_key, attempted_key=?self, "attempt to add on an unsupported data type");
1329 return false; }
1331 };
1332 if !ret {
1333 let adding_entity_key = Key::AddressableEntity(*entity_addr);
1334 warn!(?adding_entity_key, attempted_key=?self, "attempt to add without permission");
1335 }
1336 ret
1337 }
1338
1339 pub fn is_writeable(&self, entity_addr: &EntityAddr) -> bool {
1341 if entity_addr.is_system() {
1342 return true;
1344 }
1345 let ret = match self {
1346 Key::URef(uref) => uref.is_writeable(),
1347 Key::NamedKey(named_key_addr) => {
1348 &named_key_addr.entity_addr() == entity_addr
1350 }
1351 _ => {
1352 false
1354 }
1355 };
1356 if !ret {
1357 let writing_entity_key = Key::AddressableEntity(*entity_addr);
1358 warn!(?writing_entity_key, attempted_key=?self, "attempt to write without permission")
1359 }
1360 ret
1361 }
1362
1363 pub fn into_entity_addr(self) -> Option<EntityAddr> {
1365 match self {
1366 Key::AddressableEntity(entity_addr) => Some(entity_addr),
1367 _ => None,
1368 }
1369 }
1370}
1371
1372impl Display for Key {
1373 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1374 match self {
1375 Key::Account(account_hash) => write!(f, "Key::Account({})", account_hash),
1376 Key::Hash(addr) => write!(f, "Key::Hash({})", base16::encode_lower(&addr)),
1377 Key::URef(uref) => write!(f, "Key::{}", uref), Key::Transfer(transfer_v1_addr) => {
1379 write!(f, "Key::Transfer({})", transfer_v1_addr)
1380 }
1381 Key::DeployInfo(addr) => write!(
1382 f,
1383 "Key::DeployInfo({})",
1384 base16::encode_lower(addr.as_ref())
1385 ),
1386 Key::EraInfo(era_id) => write!(f, "Key::EraInfo({})", era_id),
1387 Key::Balance(uref_addr) => {
1388 write!(f, "Key::Balance({})", base16::encode_lower(uref_addr))
1389 }
1390 Key::Bid(account_hash) => write!(f, "Key::Bid({})", account_hash),
1391 Key::Withdraw(account_hash) => write!(f, "Key::Withdraw({})", account_hash),
1392 Key::Dictionary(addr) => {
1393 write!(f, "Key::Dictionary({})", base16::encode_lower(addr))
1394 }
1395 Key::SystemEntityRegistry => write!(
1396 f,
1397 "Key::SystemEntityRegistry({})",
1398 base16::encode_lower(&PADDING_BYTES)
1399 ),
1400 Key::EraSummary => write!(
1401 f,
1402 "Key::EraSummary({})",
1403 base16::encode_lower(&PADDING_BYTES),
1404 ),
1405 Key::Unbond(account_hash) => write!(f, "Key::Unbond({})", account_hash),
1406 Key::ChainspecRegistry => write!(
1407 f,
1408 "Key::ChainspecRegistry({})",
1409 base16::encode_lower(&PADDING_BYTES)
1410 ),
1411 Key::ChecksumRegistry => {
1412 write!(
1413 f,
1414 "Key::ChecksumRegistry({})",
1415 base16::encode_lower(&PADDING_BYTES)
1416 )
1417 }
1418 Key::BidAddr(bid_addr) => write!(f, "Key::BidAddr({})", bid_addr),
1419 Key::Message(message_addr) => {
1420 write!(f, "Key::Message({})", message_addr)
1421 }
1422 Key::SmartContract(package_addr) => {
1423 write!(f, "Key::Package({})", base16::encode_lower(package_addr))
1424 }
1425 Key::AddressableEntity(entity_addr) => write!(
1426 f,
1427 "Key::AddressableEntity({}-{})",
1428 entity_addr.tag(),
1429 base16::encode_lower(&entity_addr.value())
1430 ),
1431 Key::ByteCode(byte_code_addr) => {
1432 write!(f, "Key::ByteCode({})", byte_code_addr)
1433 }
1434 Key::NamedKey(named_key_addr) => {
1435 write!(f, "Key::NamedKey({})", named_key_addr)
1436 }
1437 Key::BlockGlobal(addr) => {
1438 write!(
1439 f,
1440 "Key::BlockGlobal({}-{})",
1441 addr,
1442 base16::encode_lower(&BLOCK_GLOBAL_PADDING_BYTES)
1443 )
1444 }
1445 Key::BalanceHold(balance_hold_addr) => {
1446 write!(f, "Key::BalanceHold({})", balance_hold_addr)
1447 }
1448 Key::EntryPoint(entry_point_addr) => {
1449 write!(f, "Key::EntryPointAddr({})", entry_point_addr)
1450 }
1451 Key::State(entity_addr) => {
1452 write!(f, "Key::State({})", entity_addr)
1453 }
1454 }
1455 }
1456}
1457
1458impl Debug for Key {
1459 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1460 write!(f, "{}", self)
1461 }
1462}
1463
1464impl Tagged<KeyTag> for Key {
1465 fn tag(&self) -> KeyTag {
1466 match self {
1467 Key::Account(_) => KeyTag::Account,
1468 Key::Hash(_) => KeyTag::Hash,
1469 Key::URef(_) => KeyTag::URef,
1470 Key::Transfer(_) => KeyTag::Transfer,
1471 Key::DeployInfo(_) => KeyTag::DeployInfo,
1472 Key::EraInfo(_) => KeyTag::EraInfo,
1473 Key::Balance(_) => KeyTag::Balance,
1474 Key::Bid(_) => KeyTag::Bid,
1475 Key::Withdraw(_) => KeyTag::Withdraw,
1476 Key::Dictionary(_) => KeyTag::Dictionary,
1477 Key::SystemEntityRegistry => KeyTag::SystemEntityRegistry,
1478 Key::EraSummary => KeyTag::EraSummary,
1479 Key::Unbond(_) => KeyTag::Unbond,
1480 Key::ChainspecRegistry => KeyTag::ChainspecRegistry,
1481 Key::ChecksumRegistry => KeyTag::ChecksumRegistry,
1482 Key::BidAddr(_) => KeyTag::BidAddr,
1483 Key::SmartContract(_) => KeyTag::Package,
1484 Key::AddressableEntity(..) => KeyTag::AddressableEntity,
1485 Key::ByteCode(..) => KeyTag::ByteCode,
1486 Key::Message(_) => KeyTag::Message,
1487 Key::NamedKey(_) => KeyTag::NamedKey,
1488 Key::BlockGlobal(_) => KeyTag::BlockGlobal,
1489 Key::BalanceHold(_) => KeyTag::BalanceHold,
1490 Key::EntryPoint(_) => KeyTag::EntryPoint,
1491 Key::State(_) => KeyTag::State,
1492 }
1493 }
1494}
1495
1496impl Tagged<u8> for Key {
1497 fn tag(&self) -> u8 {
1498 let key_tag: KeyTag = self.tag();
1499 key_tag as u8
1500 }
1501}
1502
1503impl From<URef> for Key {
1504 fn from(uref: URef) -> Key {
1505 Key::URef(uref)
1506 }
1507}
1508
1509impl From<AccountHash> for Key {
1510 fn from(account_hash: AccountHash) -> Key {
1511 Key::Account(account_hash)
1512 }
1513}
1514
1515impl From<PackageHash> for Key {
1516 fn from(package_hash: PackageHash) -> Key {
1517 Key::SmartContract(package_hash.value())
1518 }
1519}
1520
1521impl From<ContractWasmHash> for Key {
1522 fn from(wasm_hash: ContractWasmHash) -> Self {
1523 Key::Hash(wasm_hash.value())
1524 }
1525}
1526
1527impl From<ContractPackageHash> for Key {
1528 fn from(contract_package_hash: ContractPackageHash) -> Self {
1529 Key::Hash(contract_package_hash.value())
1530 }
1531}
1532
1533impl From<ContractHash> for Key {
1534 fn from(contract_hash: ContractHash) -> Self {
1535 Key::Hash(contract_hash.value())
1536 }
1537}
1538
1539impl From<EntityAddr> for Key {
1540 fn from(entity_addr: EntityAddr) -> Self {
1541 Key::AddressableEntity(entity_addr)
1542 }
1543}
1544
1545impl From<NamedKeyAddr> for Key {
1546 fn from(value: NamedKeyAddr) -> Self {
1547 Key::NamedKey(value)
1548 }
1549}
1550
1551impl From<ByteCodeAddr> for Key {
1552 fn from(value: ByteCodeAddr) -> Self {
1553 Key::ByteCode(value)
1554 }
1555}
1556
1557impl ToBytes for Key {
1558 fn to_bytes(&self) -> Result<Vec<u8>, Error> {
1559 let mut result = bytesrepr::unchecked_allocate_buffer(self);
1560 self.write_bytes(&mut result)?;
1561 Ok(result)
1562 }
1563
1564 fn serialized_length(&self) -> usize {
1565 match self {
1566 Key::Account(account_hash) => {
1567 KEY_ID_SERIALIZED_LENGTH + account_hash.serialized_length()
1568 }
1569 Key::Hash(_) => KEY_HASH_SERIALIZED_LENGTH,
1570 Key::URef(_) => KEY_UREF_SERIALIZED_LENGTH,
1571 Key::Transfer(_) => KEY_TRANSFER_SERIALIZED_LENGTH,
1572 Key::DeployInfo(_) => KEY_DEPLOY_INFO_SERIALIZED_LENGTH,
1573 Key::EraInfo(_) => KEY_ERA_INFO_SERIALIZED_LENGTH,
1574 Key::Balance(_) => KEY_BALANCE_SERIALIZED_LENGTH,
1575 Key::Bid(_) => KEY_BID_SERIALIZED_LENGTH,
1576 Key::Withdraw(_) => KEY_WITHDRAW_SERIALIZED_LENGTH,
1577 Key::Dictionary(_) => KEY_DICTIONARY_SERIALIZED_LENGTH,
1578 Key::SystemEntityRegistry => KEY_SYSTEM_ENTITY_REGISTRY_SERIALIZED_LENGTH,
1579 Key::EraSummary => KEY_ERA_SUMMARY_SERIALIZED_LENGTH,
1580 Key::Unbond(_) => KEY_UNBOND_SERIALIZED_LENGTH,
1581 Key::ChainspecRegistry => KEY_CHAINSPEC_REGISTRY_SERIALIZED_LENGTH,
1582 Key::ChecksumRegistry => KEY_CHECKSUM_REGISTRY_SERIALIZED_LENGTH,
1583 Key::BidAddr(bid_addr) => KEY_ID_SERIALIZED_LENGTH + bid_addr.serialized_length(),
1584 Key::SmartContract(_) => KEY_PACKAGE_SERIALIZED_LENGTH,
1585 Key::AddressableEntity(entity_addr) => {
1586 KEY_ID_SERIALIZED_LENGTH + entity_addr.serialized_length()
1587 }
1588 Key::ByteCode(byte_code_addr) => {
1589 KEY_ID_SERIALIZED_LENGTH + byte_code_addr.serialized_length()
1590 }
1591 Key::Message(message_addr) => {
1592 KEY_ID_SERIALIZED_LENGTH + message_addr.serialized_length()
1593 }
1594 Key::NamedKey(named_key_addr) => {
1595 KEY_ID_SERIALIZED_LENGTH + named_key_addr.serialized_length()
1596 }
1597 Key::BlockGlobal(addr) => {
1598 KEY_ID_SERIALIZED_LENGTH
1599 + addr.serialized_length()
1600 + BLOCK_GLOBAL_PADDING_BYTES.len()
1601 }
1602 Key::BalanceHold(balance_hold_addr) => {
1603 KEY_ID_SERIALIZED_LENGTH + balance_hold_addr.serialized_length()
1604 }
1605 Key::EntryPoint(entry_point_addr) => {
1606 U8_SERIALIZED_LENGTH + entry_point_addr.serialized_length()
1607 }
1608 Key::State(entity_addr) => KEY_ID_SERIALIZED_LENGTH + entity_addr.serialized_length(),
1609 }
1610 }
1611
1612 fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
1613 writer.push(self.tag());
1614 match self {
1615 Key::Account(account_hash) => account_hash.write_bytes(writer),
1616 Key::Hash(hash) => hash.write_bytes(writer),
1617 Key::URef(uref) => uref.write_bytes(writer),
1618 Key::Transfer(addr) => addr.write_bytes(writer),
1619 Key::DeployInfo(deploy_hash) => deploy_hash.write_bytes(writer),
1620 Key::EraInfo(era_id) => era_id.write_bytes(writer),
1621 Key::Balance(uref_addr) => uref_addr.write_bytes(writer),
1622 Key::Bid(account_hash) => account_hash.write_bytes(writer),
1623 Key::Withdraw(account_hash) => account_hash.write_bytes(writer),
1624 Key::Dictionary(addr) => addr.write_bytes(writer),
1625 Key::Unbond(account_hash) => account_hash.write_bytes(writer),
1626 Key::SystemEntityRegistry
1627 | Key::EraSummary
1628 | Key::ChainspecRegistry
1629 | Key::ChecksumRegistry => PADDING_BYTES.write_bytes(writer),
1630 Key::BlockGlobal(addr) => {
1631 addr.write_bytes(writer)?;
1632 BLOCK_GLOBAL_PADDING_BYTES.write_bytes(writer)
1633 }
1634 Key::BidAddr(bid_addr) => bid_addr.write_bytes(writer),
1635 Key::SmartContract(package_addr) => package_addr.write_bytes(writer),
1636 Key::AddressableEntity(entity_addr) => entity_addr.write_bytes(writer),
1637 Key::ByteCode(byte_code_addr) => byte_code_addr.write_bytes(writer),
1638 Key::Message(message_addr) => message_addr.write_bytes(writer),
1639 Key::NamedKey(named_key_addr) => named_key_addr.write_bytes(writer),
1640 Key::BalanceHold(balance_hold_addr) => balance_hold_addr.write_bytes(writer),
1641 Key::EntryPoint(entry_point_addr) => entry_point_addr.write_bytes(writer),
1642 Key::State(entity_addr) => entity_addr.write_bytes(writer),
1643 }
1644 }
1645}
1646
1647impl FromBytes for Key {
1648 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
1649 if bytes.is_empty() {
1650 error!("FromBytes for Key: bytes length should not be 0");
1651 }
1652 let (tag, remainder) = match KeyTag::from_bytes(bytes) {
1653 Ok((tag, rem)) => (tag, rem),
1654 Err(err) => {
1655 error!(%err, "FromBytes for Key");
1656 return Err(err);
1657 }
1658 };
1659 match tag {
1660 KeyTag::Account => {
1661 let (account_hash, rem) = AccountHash::from_bytes(remainder)?;
1662 Ok((Key::Account(account_hash), rem))
1663 }
1664 KeyTag::Hash => {
1665 let (hash, rem) = HashAddr::from_bytes(remainder)?;
1666 Ok((Key::Hash(hash), rem))
1667 }
1668 KeyTag::URef => {
1669 let (uref, rem) = URef::from_bytes(remainder)?;
1670 Ok((Key::URef(uref), rem))
1671 }
1672 KeyTag::Transfer => {
1673 let (transfer_v1_addr, rem) = TransferAddr::from_bytes(remainder)?;
1674 Ok((Key::Transfer(transfer_v1_addr), rem))
1675 }
1676 KeyTag::DeployInfo => {
1677 let (deploy_hash, rem) = DeployHash::from_bytes(remainder)?;
1678 Ok((Key::DeployInfo(deploy_hash), rem))
1679 }
1680 KeyTag::EraInfo => {
1681 let (era_id, rem) = EraId::from_bytes(remainder)?;
1682 Ok((Key::EraInfo(era_id), rem))
1683 }
1684 KeyTag::Balance => {
1685 let (uref_addr, rem) = URefAddr::from_bytes(remainder)?;
1686 Ok((Key::Balance(uref_addr), rem))
1687 }
1688 KeyTag::Bid => {
1689 let (account_hash, rem) = AccountHash::from_bytes(remainder)?;
1690 Ok((Key::Bid(account_hash), rem))
1691 }
1692 KeyTag::Withdraw => {
1693 let (account_hash, rem) = AccountHash::from_bytes(remainder)?;
1694 Ok((Key::Withdraw(account_hash), rem))
1695 }
1696 KeyTag::Dictionary => {
1697 let (addr, rem) = DictionaryAddr::from_bytes(remainder)?;
1698 Ok((Key::Dictionary(addr), rem))
1699 }
1700 KeyTag::SystemEntityRegistry => {
1701 let (_, rem) = <[u8; 32]>::from_bytes(remainder)?;
1702 Ok((Key::SystemEntityRegistry, rem))
1703 }
1704 KeyTag::EraSummary => {
1705 let (_, rem) = <[u8; 32]>::from_bytes(remainder)?;
1706 Ok((Key::EraSummary, rem))
1707 }
1708 KeyTag::Unbond => {
1709 let (account_hash, rem) = AccountHash::from_bytes(remainder)?;
1710 Ok((Key::Unbond(account_hash), rem))
1711 }
1712 KeyTag::ChainspecRegistry => {
1713 let (_, rem) = <[u8; 32]>::from_bytes(remainder)?;
1714 Ok((Key::ChainspecRegistry, rem))
1715 }
1716 KeyTag::ChecksumRegistry => {
1717 let (_, rem) = <[u8; 32]>::from_bytes(remainder)?;
1718 Ok((Key::ChecksumRegistry, rem))
1719 }
1720 KeyTag::BidAddr => {
1721 let (bid_addr, rem) = BidAddr::from_bytes(remainder)?;
1722 Ok((Key::BidAddr(bid_addr), rem))
1723 }
1724 KeyTag::Package => {
1725 let (package_addr, rem) = PackageAddr::from_bytes(remainder)?;
1726 Ok((Key::SmartContract(package_addr), rem))
1727 }
1728 KeyTag::AddressableEntity => {
1729 let (entity_addr, rem) = EntityAddr::from_bytes(remainder)?;
1730 Ok((Key::AddressableEntity(entity_addr), rem))
1731 }
1732 KeyTag::ByteCode => {
1733 let (byte_code_addr, rem) = ByteCodeAddr::from_bytes(remainder)?;
1734 Ok((Key::ByteCode(byte_code_addr), rem))
1735 }
1736 KeyTag::Message => {
1737 let (message_addr, rem) = MessageAddr::from_bytes(remainder)?;
1738 Ok((Key::Message(message_addr), rem))
1739 }
1740 KeyTag::NamedKey => {
1741 let (named_key_addr, rem) = NamedKeyAddr::from_bytes(remainder)?;
1742 Ok((Key::NamedKey(named_key_addr), rem))
1743 }
1744 KeyTag::BlockGlobal => {
1745 let (addr, rem) = BlockGlobalAddr::from_bytes(remainder)?;
1746 let (_, rem) = <[u8; 31]>::from_bytes(rem)?; Ok((Key::BlockGlobal(addr), rem))
1748 }
1749 KeyTag::BalanceHold => {
1750 let (balance_hold_addr, rem) = BalanceHoldAddr::from_bytes(remainder)?;
1751 Ok((Key::BalanceHold(balance_hold_addr), rem))
1752 }
1753 KeyTag::EntryPoint => {
1754 let (entry_point_addr, rem) = EntryPointAddr::from_bytes(remainder)?;
1755 Ok((Key::EntryPoint(entry_point_addr), rem))
1756 }
1757 KeyTag::State => {
1758 let (entity_addr, rem) = EntityAddr::from_bytes(remainder)?;
1759 Ok((Key::State(entity_addr), rem))
1760 }
1761 }
1762 }
1763}
1764
1765#[allow(dead_code)]
1766fn please_add_to_distribution_impl(key: Key) {
1767 match key {
1770 Key::Account(_) => unimplemented!(),
1771 Key::Hash(_) => unimplemented!(),
1772 Key::URef(_) => unimplemented!(),
1773 Key::Transfer(_) => unimplemented!(),
1774 Key::DeployInfo(_) => unimplemented!(),
1775 Key::EraInfo(_) => unimplemented!(),
1776 Key::Balance(_) => unimplemented!(),
1777 Key::Bid(_) => unimplemented!(),
1778 Key::Withdraw(_) => unimplemented!(),
1779 Key::Dictionary(_) => unimplemented!(),
1780 Key::SystemEntityRegistry => unimplemented!(),
1781 Key::EraSummary => unimplemented!(),
1782 Key::Unbond(_) => unimplemented!(),
1783 Key::ChainspecRegistry => unimplemented!(),
1784 Key::ChecksumRegistry => unimplemented!(),
1785 Key::BidAddr(_) => unimplemented!(),
1786 Key::SmartContract(_) => unimplemented!(),
1787 Key::AddressableEntity(..) => unimplemented!(),
1788 Key::ByteCode(..) => unimplemented!(),
1789 Key::Message(_) => unimplemented!(),
1790 Key::NamedKey(_) => unimplemented!(),
1791 Key::BlockGlobal(_) => unimplemented!(),
1792 Key::BalanceHold(_) => unimplemented!(),
1793 Key::EntryPoint(_) => unimplemented!(),
1794 Key::State(_) => unimplemented!(),
1795 }
1796}
1797
1798#[cfg(any(feature = "testing", test))]
1799impl Distribution<Key> for Standard {
1800 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Key {
1801 match rng.gen_range(0..=24) {
1802 0 => Key::Account(rng.gen()),
1803 1 => Key::Hash(rng.gen()),
1804 2 => Key::URef(rng.gen()),
1805 3 => Key::Transfer(TransferAddr::new(rng.gen())),
1806 4 => Key::DeployInfo(DeployHash::from_raw(rng.gen())),
1807 5 => Key::EraInfo(EraId::new(rng.gen())),
1808 6 => Key::Balance(rng.gen()),
1809 7 => Key::Bid(rng.gen()),
1810 8 => Key::Withdraw(rng.gen()),
1811 9 => Key::Dictionary(rng.gen()),
1812 10 => Key::SystemEntityRegistry,
1813 11 => Key::EraSummary,
1814 12 => Key::Unbond(rng.gen()),
1815 13 => Key::ChainspecRegistry,
1816 14 => Key::ChecksumRegistry,
1817 15 => Key::BidAddr(rng.gen()),
1818 16 => Key::SmartContract(rng.gen()),
1819 17 => Key::AddressableEntity(rng.gen()),
1820 18 => Key::ByteCode(rng.gen()),
1821 19 => Key::Message(rng.gen()),
1822 20 => Key::NamedKey(NamedKeyAddr::new_named_key_entry(rng.gen(), rng.gen())),
1823 21 => Key::BlockGlobal(rng.gen()),
1824 22 => Key::BalanceHold(rng.gen()),
1825 23 => Key::EntryPoint(rng.gen()),
1826 24 => Key::State(rng.gen()),
1827 _ => unreachable!(),
1828 }
1829 }
1830}
1831
1832mod serde_helpers {
1833 use super::*;
1834
1835 #[derive(Serialize)]
1836 pub(super) enum BinarySerHelper<'a> {
1837 Account(&'a AccountHash),
1838 Hash(&'a HashAddr),
1839 URef(&'a URef),
1840 Transfer(&'a TransferAddr),
1841 #[serde(with = "crate::serde_helpers::deploy_hash_as_array")]
1842 DeployInfo(&'a DeployHash),
1843 EraInfo(&'a EraId),
1844 Balance(&'a URefAddr),
1845 Bid(&'a AccountHash),
1846 Withdraw(&'a AccountHash),
1847 Dictionary(&'a HashAddr),
1848 SystemEntityRegistry,
1849 EraSummary,
1850 Unbond(&'a AccountHash),
1851 ChainspecRegistry,
1852 ChecksumRegistry,
1853 BidAddr(&'a BidAddr),
1854 Package(&'a PackageAddr),
1855 AddressableEntity(&'a EntityAddr),
1856 ByteCode(&'a ByteCodeAddr),
1857 Message(&'a MessageAddr),
1858 NamedKey(&'a NamedKeyAddr),
1859 BlockGlobal(&'a BlockGlobalAddr),
1860 BalanceHold(&'a BalanceHoldAddr),
1861 EntryPoint(&'a EntryPointAddr),
1862 State(&'a EntityAddr),
1863 }
1864
1865 #[derive(Deserialize)]
1866 pub(super) enum BinaryDeserHelper {
1867 Account(AccountHash),
1868 Hash(HashAddr),
1869 URef(URef),
1870 Transfer(TransferAddr),
1871 #[serde(with = "crate::serde_helpers::deploy_hash_as_array")]
1872 DeployInfo(DeployHash),
1873 EraInfo(EraId),
1874 Balance(URefAddr),
1875 Bid(AccountHash),
1876 Withdraw(AccountHash),
1877 Dictionary(DictionaryAddr),
1878 SystemEntityRegistry,
1879 EraSummary,
1880 Unbond(AccountHash),
1881 ChainspecRegistry,
1882 ChecksumRegistry,
1883 BidAddr(BidAddr),
1884 Package(PackageAddr),
1885 AddressableEntity(EntityAddr),
1886 ByteCode(ByteCodeAddr),
1887 Message(MessageAddr),
1888 NamedKey(NamedKeyAddr),
1889 BlockGlobal(BlockGlobalAddr),
1890 BalanceHold(BalanceHoldAddr),
1891 EntryPoint(EntryPointAddr),
1892 State(EntityAddr),
1893 }
1894
1895 impl<'a> From<&'a Key> for BinarySerHelper<'a> {
1896 fn from(key: &'a Key) -> Self {
1897 match key {
1898 Key::Account(account_hash) => BinarySerHelper::Account(account_hash),
1899 Key::Hash(hash_addr) => BinarySerHelper::Hash(hash_addr),
1900 Key::URef(uref) => BinarySerHelper::URef(uref),
1901 Key::Transfer(transfer_v1_addr) => BinarySerHelper::Transfer(transfer_v1_addr),
1902 Key::DeployInfo(deploy_hash) => BinarySerHelper::DeployInfo(deploy_hash),
1903 Key::EraInfo(era_id) => BinarySerHelper::EraInfo(era_id),
1904 Key::Balance(uref_addr) => BinarySerHelper::Balance(uref_addr),
1905 Key::Bid(account_hash) => BinarySerHelper::Bid(account_hash),
1906 Key::Withdraw(account_hash) => BinarySerHelper::Withdraw(account_hash),
1907 Key::Dictionary(addr) => BinarySerHelper::Dictionary(addr),
1908 Key::SystemEntityRegistry => BinarySerHelper::SystemEntityRegistry,
1909 Key::EraSummary => BinarySerHelper::EraSummary,
1910 Key::Unbond(account_hash) => BinarySerHelper::Unbond(account_hash),
1911 Key::ChainspecRegistry => BinarySerHelper::ChainspecRegistry,
1912 Key::ChecksumRegistry => BinarySerHelper::ChecksumRegistry,
1913 Key::BidAddr(bid_addr) => BinarySerHelper::BidAddr(bid_addr),
1914 Key::Message(message_addr) => BinarySerHelper::Message(message_addr),
1915 Key::SmartContract(package_addr) => BinarySerHelper::Package(package_addr),
1916 Key::AddressableEntity(entity_addr) => {
1917 BinarySerHelper::AddressableEntity(entity_addr)
1918 }
1919 Key::ByteCode(byte_code_addr) => BinarySerHelper::ByteCode(byte_code_addr),
1920 Key::NamedKey(named_key_addr) => BinarySerHelper::NamedKey(named_key_addr),
1921 Key::BlockGlobal(addr) => BinarySerHelper::BlockGlobal(addr),
1922 Key::BalanceHold(balance_hold_addr) => {
1923 BinarySerHelper::BalanceHold(balance_hold_addr)
1924 }
1925 Key::EntryPoint(entry_point_addr) => BinarySerHelper::EntryPoint(entry_point_addr),
1926 Key::State(entity_addr) => BinarySerHelper::State(entity_addr),
1927 }
1928 }
1929 }
1930
1931 impl From<BinaryDeserHelper> for Key {
1932 fn from(helper: BinaryDeserHelper) -> Self {
1933 match helper {
1934 BinaryDeserHelper::Account(account_hash) => Key::Account(account_hash),
1935 BinaryDeserHelper::Hash(hash_addr) => Key::Hash(hash_addr),
1936 BinaryDeserHelper::URef(uref) => Key::URef(uref),
1937 BinaryDeserHelper::Transfer(transfer_v1_addr) => Key::Transfer(transfer_v1_addr),
1938 BinaryDeserHelper::DeployInfo(deploy_hash) => Key::DeployInfo(deploy_hash),
1939 BinaryDeserHelper::EraInfo(era_id) => Key::EraInfo(era_id),
1940 BinaryDeserHelper::Balance(uref_addr) => Key::Balance(uref_addr),
1941 BinaryDeserHelper::Bid(account_hash) => Key::Bid(account_hash),
1942 BinaryDeserHelper::Withdraw(account_hash) => Key::Withdraw(account_hash),
1943 BinaryDeserHelper::Dictionary(addr) => Key::Dictionary(addr),
1944 BinaryDeserHelper::SystemEntityRegistry => Key::SystemEntityRegistry,
1945 BinaryDeserHelper::EraSummary => Key::EraSummary,
1946 BinaryDeserHelper::Unbond(account_hash) => Key::Unbond(account_hash),
1947 BinaryDeserHelper::ChainspecRegistry => Key::ChainspecRegistry,
1948 BinaryDeserHelper::ChecksumRegistry => Key::ChecksumRegistry,
1949 BinaryDeserHelper::BidAddr(bid_addr) => Key::BidAddr(bid_addr),
1950 BinaryDeserHelper::Message(message_addr) => Key::Message(message_addr),
1951 BinaryDeserHelper::Package(package_addr) => Key::SmartContract(package_addr),
1952 BinaryDeserHelper::AddressableEntity(entity_addr) => {
1953 Key::AddressableEntity(entity_addr)
1954 }
1955 BinaryDeserHelper::ByteCode(byte_code_addr) => Key::ByteCode(byte_code_addr),
1956 BinaryDeserHelper::NamedKey(named_key_addr) => Key::NamedKey(named_key_addr),
1957 BinaryDeserHelper::BlockGlobal(addr) => Key::BlockGlobal(addr),
1958 BinaryDeserHelper::BalanceHold(balance_hold_addr) => {
1959 Key::BalanceHold(balance_hold_addr)
1960 }
1961 BinaryDeserHelper::EntryPoint(entry_point_addr) => {
1962 Key::EntryPoint(entry_point_addr)
1963 }
1964 BinaryDeserHelper::State(entity_addr) => Key::State(entity_addr),
1965 }
1966 }
1967 }
1968}
1969
1970impl Serialize for Key {
1971 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1972 if serializer.is_human_readable() {
1973 self.to_formatted_string().serialize(serializer)
1974 } else {
1975 serde_helpers::BinarySerHelper::from(self).serialize(serializer)
1976 }
1977 }
1978}
1979
1980impl<'de> Deserialize<'de> for Key {
1981 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1982 if deserializer.is_human_readable() {
1983 let formatted_key = String::deserialize(deserializer)?;
1984 Key::from_formatted_str(&formatted_key).map_err(SerdeError::custom)
1985 } else {
1986 let binary_helper = serde_helpers::BinaryDeserHelper::deserialize(deserializer)?;
1987 Ok(Key::from(binary_helper))
1988 }
1989 }
1990}
1991
1992#[cfg(test)]
1993mod tests {
1994 use std::string::ToString;
1995
1996 use super::*;
1997 use crate::{
1998 account::ACCOUNT_HASH_FORMATTED_STRING_PREFIX,
1999 bytesrepr::{Error, FromBytes},
2000 uref::UREF_FORMATTED_STRING_PREFIX,
2001 AccessRights, BlockTime, URef,
2002 };
2003
2004 const TRANSFER_ADDR_FORMATTED_STRING_PREFIX: &str = "transfer-";
2005 const ENTITY_PREFIX: &str = "entity-";
2006 const ACCOUNT_ENTITY_PREFIX: &str = "account-";
2007
2008 const BYTE_CODE_PREFIX: &str = "byte-code-";
2009 const EMPTY_PREFIX: &str = "empty-";
2010
2011 const ACCOUNT_KEY: Key = Key::Account(AccountHash::new([42; 32]));
2012 const HASH_KEY: Key = Key::Hash([42; 32]);
2013 const UREF_KEY: Key = Key::URef(URef::new([42; 32], AccessRights::READ));
2014 const TRANSFER_KEY: Key = Key::Transfer(TransferAddr::new([42; 32]));
2015 const DEPLOY_INFO_KEY: Key = Key::DeployInfo(DeployHash::from_raw([42; 32]));
2016 const ERA_INFO_KEY: Key = Key::EraInfo(EraId::new(42));
2017 const BALANCE_KEY: Key = Key::Balance([42; 32]);
2018 const BID_KEY: Key = Key::Bid(AccountHash::new([42; 32]));
2019 const UNIFIED_BID_KEY: Key = Key::BidAddr(BidAddr::legacy([42; 32]));
2020 const VALIDATOR_BID_KEY: Key = Key::BidAddr(BidAddr::new_validator_addr([2; 32]));
2021 const DELEGATOR_BID_KEY: Key =
2022 Key::BidAddr(BidAddr::new_delegator_account_addr(([2; 32], [9; 32])));
2023 const WITHDRAW_KEY: Key = Key::Withdraw(AccountHash::new([42; 32]));
2024 const DICTIONARY_KEY: Key = Key::Dictionary([42; 32]);
2025 const SYSTEM_ENTITY_REGISTRY_KEY: Key = Key::SystemEntityRegistry;
2026 const ERA_SUMMARY_KEY: Key = Key::EraSummary;
2027 const UNBOND_KEY: Key = Key::Unbond(AccountHash::new([42; 32]));
2028 const CHAINSPEC_REGISTRY_KEY: Key = Key::ChainspecRegistry;
2029 const CHECKSUM_REGISTRY_KEY: Key = Key::ChecksumRegistry;
2030 const PACKAGE_KEY: Key = Key::SmartContract([42; 32]);
2031 const ADDRESSABLE_ENTITY_SYSTEM_KEY: Key =
2032 Key::AddressableEntity(EntityAddr::new_system([42; 32]));
2033 const ADDRESSABLE_ENTITY_ACCOUNT_KEY: Key =
2034 Key::AddressableEntity(EntityAddr::new_account([42; 32]));
2035 const ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY: Key =
2036 Key::AddressableEntity(EntityAddr::new_smart_contract([42; 32]));
2037 const BYTE_CODE_EMPTY_KEY: Key = Key::ByteCode(ByteCodeAddr::Empty);
2038 const BYTE_CODE_V1_WASM_KEY: Key = Key::ByteCode(ByteCodeAddr::V1CasperWasm([42; 32]));
2039 const MESSAGE_TOPIC_KEY: Key = Key::Message(MessageAddr::new_topic_addr(
2040 EntityAddr::SmartContract([42; 32]),
2041 TopicNameHash::new([42; 32]),
2042 ));
2043 const MESSAGE_KEY: Key = Key::Message(MessageAddr::new_message_addr(
2044 EntityAddr::SmartContract([42; 32]),
2045 TopicNameHash::new([2; 32]),
2046 15,
2047 ));
2048 const NAMED_KEY: Key = Key::NamedKey(NamedKeyAddr::new_named_key_entry(
2049 EntityAddr::new_smart_contract([42; 32]),
2050 [43; 32],
2051 ));
2052 const BLOCK_TIME_KEY: Key = Key::BlockGlobal(BlockGlobalAddr::BlockTime);
2053 const BLOCK_MESSAGE_COUNT_KEY: Key = Key::BlockGlobal(BlockGlobalAddr::MessageCount);
2054 const BALANCE_HOLD: Key =
2056 Key::BalanceHold(BalanceHoldAddr::new_gas([42; 32], BlockTime::new(100)));
2057 const STATE_KEY: Key = Key::State(EntityAddr::new_smart_contract([42; 32]));
2058 const KEYS: &[Key] = &[
2059 ACCOUNT_KEY,
2060 HASH_KEY,
2061 UREF_KEY,
2062 TRANSFER_KEY,
2063 DEPLOY_INFO_KEY,
2064 ERA_INFO_KEY,
2065 BALANCE_KEY,
2066 BID_KEY,
2067 WITHDRAW_KEY,
2068 DICTIONARY_KEY,
2069 SYSTEM_ENTITY_REGISTRY_KEY,
2070 ERA_SUMMARY_KEY,
2071 UNBOND_KEY,
2072 CHAINSPEC_REGISTRY_KEY,
2073 CHECKSUM_REGISTRY_KEY,
2074 UNIFIED_BID_KEY,
2075 VALIDATOR_BID_KEY,
2076 DELEGATOR_BID_KEY,
2077 PACKAGE_KEY,
2078 ADDRESSABLE_ENTITY_SYSTEM_KEY,
2079 ADDRESSABLE_ENTITY_ACCOUNT_KEY,
2080 ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY,
2081 BYTE_CODE_EMPTY_KEY,
2082 BYTE_CODE_V1_WASM_KEY,
2083 MESSAGE_TOPIC_KEY,
2084 MESSAGE_KEY,
2085 NAMED_KEY,
2086 BLOCK_TIME_KEY,
2087 BLOCK_MESSAGE_COUNT_KEY,
2088 BALANCE_HOLD,
2089 STATE_KEY,
2090 ];
2091 const HEX_STRING: &str = "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a";
2092 const TOPIC_NAME_HEX_STRING: &str =
2093 "0202020202020202020202020202020202020202020202020202020202020202";
2094 const MESSAGE_INDEX_HEX_STRING: &str = "f";
2095 const UNIFIED_HEX_STRING: &str =
2096 "002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a";
2097 const VALIDATOR_HEX_STRING: &str =
2098 "010202020202020202020202020202020202020202020202020202020202020202";
2099 const DELEGATOR_HEX_STRING: &str =
2100 "0202020202020202020202020202020202020202020202020202020202020202020909090909090909090909090909090909090909090909090909090909090909";
2101
2102 fn test_readable(right: AccessRights, is_true: bool) {
2103 assert_eq!(right.is_readable(), is_true)
2104 }
2105
2106 #[test]
2107 fn test_is_readable() {
2108 test_readable(AccessRights::READ, true);
2109 test_readable(AccessRights::READ_ADD, true);
2110 test_readable(AccessRights::READ_WRITE, true);
2111 test_readable(AccessRights::READ_ADD_WRITE, true);
2112 test_readable(AccessRights::ADD, false);
2113 test_readable(AccessRights::ADD_WRITE, false);
2114 test_readable(AccessRights::WRITE, false);
2115 }
2116
2117 fn test_writable(right: AccessRights, is_true: bool) {
2118 assert_eq!(right.is_writeable(), is_true)
2119 }
2120
2121 #[test]
2122 fn test_is_writable() {
2123 test_writable(AccessRights::WRITE, true);
2124 test_writable(AccessRights::READ_WRITE, true);
2125 test_writable(AccessRights::ADD_WRITE, true);
2126 test_writable(AccessRights::READ, false);
2127 test_writable(AccessRights::ADD, false);
2128 test_writable(AccessRights::READ_ADD, false);
2129 test_writable(AccessRights::READ_ADD_WRITE, true);
2130 }
2131
2132 fn test_addable(right: AccessRights, is_true: bool) {
2133 assert_eq!(right.is_addable(), is_true)
2134 }
2135
2136 #[test]
2137 fn test_is_addable() {
2138 test_addable(AccessRights::ADD, true);
2139 test_addable(AccessRights::READ_ADD, true);
2140 test_addable(AccessRights::READ_WRITE, false);
2141 test_addable(AccessRights::ADD_WRITE, true);
2142 test_addable(AccessRights::READ, false);
2143 test_addable(AccessRights::WRITE, false);
2144 test_addable(AccessRights::READ_ADD_WRITE, true);
2145 }
2146
2147 #[test]
2148 fn should_display_key() {
2149 assert_eq!(
2150 format!("{}", ACCOUNT_KEY),
2151 format!("Key::Account({})", HEX_STRING)
2152 );
2153 assert_eq!(
2154 format!("{}", HASH_KEY),
2155 format!("Key::Hash({})", HEX_STRING)
2156 );
2157 assert_eq!(
2158 format!("{}", UREF_KEY),
2159 format!("Key::URef({}, READ)", HEX_STRING)
2160 );
2161 assert_eq!(
2162 format!("{}", TRANSFER_KEY),
2163 format!("Key::Transfer({})", HEX_STRING)
2164 );
2165 assert_eq!(
2166 format!("{}", DEPLOY_INFO_KEY),
2167 format!("Key::DeployInfo({})", HEX_STRING)
2168 );
2169 assert_eq!(
2170 format!("{}", ERA_INFO_KEY),
2171 "Key::EraInfo(era 42)".to_string()
2172 );
2173 assert_eq!(
2174 format!("{}", BALANCE_KEY),
2175 format!("Key::Balance({})", HEX_STRING)
2176 );
2177 assert_eq!(format!("{}", BID_KEY), format!("Key::Bid({})", HEX_STRING));
2178 assert_eq!(
2179 format!("{}", UNIFIED_BID_KEY),
2180 format!("Key::BidAddr({})", UNIFIED_HEX_STRING)
2181 );
2182 assert_eq!(
2183 format!("{}", VALIDATOR_BID_KEY),
2184 format!("Key::BidAddr({})", VALIDATOR_HEX_STRING)
2185 );
2186 assert_eq!(
2187 format!("{}", DELEGATOR_BID_KEY),
2188 format!("Key::BidAddr({})", DELEGATOR_HEX_STRING)
2189 );
2190 assert_eq!(
2191 format!("{}", WITHDRAW_KEY),
2192 format!("Key::Withdraw({})", HEX_STRING)
2193 );
2194 assert_eq!(
2195 format!("{}", DICTIONARY_KEY),
2196 format!("Key::Dictionary({})", HEX_STRING)
2197 );
2198 assert_eq!(
2199 format!("{}", SYSTEM_ENTITY_REGISTRY_KEY),
2200 format!(
2201 "Key::SystemEntityRegistry({})",
2202 base16::encode_lower(&PADDING_BYTES)
2203 )
2204 );
2205 assert_eq!(
2206 format!("{}", ERA_SUMMARY_KEY),
2207 format!("Key::EraSummary({})", base16::encode_lower(&PADDING_BYTES))
2208 );
2209 assert_eq!(
2210 format!("{}", UNBOND_KEY),
2211 format!("Key::Unbond({})", HEX_STRING)
2212 );
2213 assert_eq!(
2214 format!("{}", CHAINSPEC_REGISTRY_KEY),
2215 format!(
2216 "Key::ChainspecRegistry({})",
2217 base16::encode_lower(&PADDING_BYTES)
2218 )
2219 );
2220 assert_eq!(
2221 format!("{}", CHECKSUM_REGISTRY_KEY),
2222 format!(
2223 "Key::ChecksumRegistry({})",
2224 base16::encode_lower(&PADDING_BYTES),
2225 )
2226 );
2227 assert_eq!(
2228 format!("{}", PACKAGE_KEY),
2229 format!("Key::Package({})", HEX_STRING)
2230 );
2231 assert_eq!(
2232 format!("{}", ADDRESSABLE_ENTITY_SYSTEM_KEY),
2233 format!("Key::AddressableEntity(system-{})", HEX_STRING)
2234 );
2235 assert_eq!(
2236 format!("{}", ADDRESSABLE_ENTITY_ACCOUNT_KEY),
2237 format!("Key::AddressableEntity(account-{})", HEX_STRING)
2238 );
2239 assert_eq!(
2240 format!("{}", ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY),
2241 format!("Key::AddressableEntity(contract-{})", HEX_STRING)
2242 );
2243 assert_eq!(
2244 format!("{}", BYTE_CODE_EMPTY_KEY),
2245 format!(
2246 "Key::ByteCode(byte-code-empty-{})",
2247 base16::encode_lower(&[0u8; 32])
2248 )
2249 );
2250 assert_eq!(
2251 format!("{}", BYTE_CODE_V1_WASM_KEY),
2252 format!("Key::ByteCode(byte-code-v1-wasm-{})", HEX_STRING)
2253 );
2254 assert_eq!(
2255 format!("{}", MESSAGE_TOPIC_KEY),
2256 format!(
2257 "Key::Message(entity-contract-{}-{})",
2258 HEX_STRING, HEX_STRING
2259 )
2260 );
2261 assert_eq!(
2262 format!("{}", MESSAGE_KEY),
2263 format!(
2264 "Key::Message(entity-contract-{}-{}-{})",
2265 HEX_STRING, TOPIC_NAME_HEX_STRING, MESSAGE_INDEX_HEX_STRING
2266 )
2267 );
2268
2269 assert_eq!(
2270 format!("{}", STATE_KEY),
2271 format!(
2272 "Key::State(entity-contract-{})",
2273 base16::encode_lower(&[42; 32])
2274 )
2275 );
2276 assert_eq!(
2277 format!("{}", BLOCK_TIME_KEY),
2278 format!(
2279 "Key::BlockGlobal({}-{})",
2280 BlockGlobalAddr::BlockTime,
2281 base16::encode_lower(&BLOCK_GLOBAL_PADDING_BYTES)
2282 )
2283 );
2284 assert_eq!(
2285 format!("{}", BLOCK_MESSAGE_COUNT_KEY),
2286 format!(
2287 "Key::BlockGlobal({}-{})",
2288 BlockGlobalAddr::MessageCount,
2289 base16::encode_lower(&BLOCK_GLOBAL_PADDING_BYTES)
2290 )
2291 );
2292 }
2293
2294 #[test]
2295 fn abuse_vec_key() {
2296 let bytes: Vec<u8> = vec![255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2298 let res: Result<(Vec<Key>, &[u8]), _> = FromBytes::from_bytes(&bytes);
2299 assert_eq!(
2300 res.expect_err("should fail"),
2301 Error::EarlyEndOfStream,
2302 "length prefix says 2^32-1, but there's not enough data in the stream"
2303 );
2304
2305 let bytes: Vec<u8> = vec![255, 255, 255, 254, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2307 let res: Result<(Vec<Key>, &[u8]), _> = FromBytes::from_bytes(&bytes);
2308 assert_eq!(
2309 res.expect_err("should fail"),
2310 Error::EarlyEndOfStream,
2311 "length prefix says 2^32-2, but there's not enough data in the stream"
2312 );
2313
2314 let bytes: Vec<u8> = vec![0, 0, 0, 254, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2316 let res: Result<(Vec<Key>, &[u8]), _> = FromBytes::from_bytes(&bytes);
2317 assert_eq!(
2318 res.expect_err("should fail"),
2319 Error::EarlyEndOfStream,
2320 "length prefix says 254, but there's not enough data in the stream"
2321 );
2322 }
2323
2324 #[test]
2325 fn check_key_account_getters() {
2326 let account = [42; 32];
2327 let account_hash = AccountHash::new(account);
2328 let key1 = Key::Account(account_hash);
2329 assert_eq!(key1.into_account(), Some(account_hash));
2330 assert!(key1.into_entity_hash_addr().is_some());
2331 assert!(key1.as_uref().is_none());
2332 }
2333
2334 #[test]
2335 fn check_key_hash_getters() {
2336 let hash = [42; KEY_HASH_LENGTH];
2337 let key1 = Key::Hash(hash);
2338 assert!(key1.into_account().is_none());
2339 assert_eq!(key1.into_hash_addr(), Some(hash));
2340 assert!(key1.as_uref().is_none());
2341 }
2342
2343 #[test]
2344 fn check_entity_key_getters() {
2345 let hash = [42; KEY_HASH_LENGTH];
2346 let key1 = Key::contract_entity_key(AddressableEntityHash::new(hash));
2347 assert!(key1.into_account().is_none());
2348 assert_eq!(key1.into_entity_hash_addr(), Some(hash));
2349 assert!(key1.as_uref().is_none());
2350 }
2351
2352 #[test]
2353 fn check_package_key_getters() {
2354 let hash = [42; KEY_HASH_LENGTH];
2355 let key1 = Key::SmartContract(hash);
2356 assert!(key1.into_account().is_none());
2357 assert_eq!(key1.into_package_addr(), Some(hash));
2358 assert!(key1.as_uref().is_none());
2359 }
2360
2361 #[test]
2362 fn check_key_uref_getters() {
2363 let uref = URef::new([42; 32], AccessRights::READ_ADD_WRITE);
2364 let key1 = Key::URef(uref);
2365 assert!(key1.into_account().is_none());
2366 assert!(key1.into_entity_hash_addr().is_none());
2367 assert_eq!(key1.as_uref(), Some(&uref));
2368 }
2369
2370 #[test]
2371 fn key_max_serialized_length() {
2372 let mut got_max = false;
2373 for key in KEYS {
2374 let expected = Key::max_serialized_length();
2375 let actual = key.serialized_length();
2376 assert!(
2377 actual <= expected,
2378 "key too long {} expected {} actual {}",
2379 key,
2380 expected,
2381 actual
2382 );
2383 if actual == Key::max_serialized_length() {
2384 got_max = true;
2385 }
2386 }
2387 assert!(
2388 got_max,
2389 "None of the Key variants has a serialized_length equal to \
2390 Key::max_serialized_length(), so Key::max_serialized_length() should be reduced"
2391 );
2392 }
2393
2394 #[test]
2395 fn should_parse_legacy_bid_key_from_string() {
2396 let account_hash = AccountHash([1; 32]);
2397 let legacy_bid_key = Key::Bid(account_hash);
2398 let original_string = legacy_bid_key.to_formatted_string();
2399
2400 let parsed_bid_key =
2401 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2402 if let Key::Bid(parsed_account_hash) = parsed_bid_key {
2403 assert_eq!(parsed_account_hash, account_hash,);
2404 assert_eq!(legacy_bid_key, parsed_bid_key);
2405
2406 let translated_string = parsed_bid_key.to_formatted_string();
2407 assert_eq!(original_string, translated_string);
2408 } else {
2409 panic!("should have account hash");
2410 }
2411 }
2412
2413 #[test]
2414 fn should_parse_legacy_unified_bid_key_from_string() {
2415 let legacy_bid_addr = BidAddr::legacy([1; 32]);
2416 let legacy_bid_key = Key::BidAddr(legacy_bid_addr);
2417 assert_eq!(legacy_bid_addr.tag(), BidAddrTag::Unified,);
2418
2419 let original_string = legacy_bid_key.to_formatted_string();
2420 let parsed_key =
2421 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2422 let parsed_bid_addr = parsed_key.as_bid_addr().expect("must have bid addr");
2423 assert!(parsed_key.is_bid_addr_key());
2424 assert_eq!(parsed_bid_addr.tag(), legacy_bid_addr.tag(),);
2425 assert_eq!(*parsed_bid_addr, legacy_bid_addr);
2426
2427 let translated_string = parsed_key.to_formatted_string();
2428 assert_eq!(original_string, translated_string);
2429 assert_eq!(parsed_key.as_bid_addr(), legacy_bid_key.as_bid_addr(),);
2430 }
2431
2432 #[test]
2433 fn should_parse_validator_bid_key_from_string() {
2434 let validator_bid_addr = BidAddr::new_validator_addr([1; 32]);
2435 let validator_bid_key = Key::BidAddr(validator_bid_addr);
2436 assert_eq!(validator_bid_addr.tag(), BidAddrTag::Validator,);
2437
2438 let original_string = validator_bid_key.to_formatted_string();
2439 let parsed_key =
2440 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2441 let parsed_bid_addr = parsed_key.as_bid_addr().expect("must have bid addr");
2442 assert!(parsed_key.is_bid_addr_key());
2443 assert_eq!(parsed_bid_addr.tag(), validator_bid_addr.tag(),);
2444 assert_eq!(*parsed_bid_addr, validator_bid_addr,);
2445
2446 let translated_string = parsed_key.to_formatted_string();
2447 assert_eq!(original_string, translated_string);
2448 assert_eq!(parsed_key.as_bid_addr(), validator_bid_key.as_bid_addr(),);
2449 }
2450
2451 #[test]
2452 fn should_parse_delegator_bid_key_from_string() {
2453 let delegator_bid_addr = BidAddr::new_delegator_account_addr(([1; 32], [9; 32]));
2454 let delegator_bid_key = Key::BidAddr(delegator_bid_addr);
2455 assert_eq!(delegator_bid_addr.tag(), BidAddrTag::DelegatedAccount);
2456
2457 let original_string = delegator_bid_key.to_formatted_string();
2458
2459 let parsed_key =
2460 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2461 let parsed_bid_addr = parsed_key.as_bid_addr().expect("must have bid addr");
2462 assert!(parsed_key.is_bid_addr_key());
2463 assert_eq!(parsed_bid_addr.tag(), delegator_bid_addr.tag(),);
2464 assert_eq!(*parsed_bid_addr, delegator_bid_addr,);
2465
2466 let translated_string = parsed_key.to_formatted_string();
2467 assert_eq!(original_string, translated_string);
2468 assert_eq!(parsed_key.as_bid_addr(), delegator_bid_key.as_bid_addr(),);
2469 }
2470
2471 #[test]
2472 fn should_parse_credit_bid_key_from_string() {
2473 let credit_bid_addr = BidAddr::Credit {
2474 validator: AccountHash::new([1; 32]),
2475 era_id: 1.into(),
2476 };
2477 let delegator_bid_key = Key::BidAddr(credit_bid_addr);
2478 assert_eq!(credit_bid_addr.tag(), BidAddrTag::Credit);
2479
2480 let original_string = delegator_bid_key.to_formatted_string();
2481
2482 let parsed_key =
2483 Key::from_formatted_str(&original_string).expect("{string} (key = {key:?})");
2484 let parsed_bid_addr = parsed_key.as_bid_addr().expect("must have bid addr");
2485 assert!(parsed_key.is_bid_addr_key());
2486 assert_eq!(parsed_bid_addr.tag(), credit_bid_addr.tag(),);
2487 assert_eq!(*parsed_bid_addr, credit_bid_addr,);
2488
2489 let translated_string = parsed_key.to_formatted_string();
2490 assert_eq!(original_string, translated_string);
2491 assert_eq!(parsed_key.as_bid_addr(), delegator_bid_key.as_bid_addr());
2492 }
2493
2494 #[test]
2495 fn should_parse_key_from_str() {
2496 for key in KEYS {
2497 let string = key.to_formatted_string();
2498 let parsed_key = Key::from_formatted_str(&string).expect("{string} (key = {key:?})");
2499 assert_eq!(parsed_key, *key, "{string} (key = {key:?})");
2500 }
2501 }
2502
2503 #[test]
2504 fn should_fail_to_parse_key_from_str() {
2505 assert!(
2506 Key::from_formatted_str(ACCOUNT_HASH_FORMATTED_STRING_PREFIX)
2507 .unwrap_err()
2508 .to_string()
2509 .starts_with("account-key from string error: ")
2510 );
2511 assert!(Key::from_formatted_str(HASH_PREFIX)
2512 .unwrap_err()
2513 .to_string()
2514 .starts_with("hash-key from string error: "));
2515 assert!(Key::from_formatted_str(UREF_FORMATTED_STRING_PREFIX)
2516 .unwrap_err()
2517 .to_string()
2518 .starts_with("uref-key from string error: "));
2519 assert!(
2520 Key::from_formatted_str(TRANSFER_ADDR_FORMATTED_STRING_PREFIX)
2521 .unwrap_err()
2522 .to_string()
2523 .starts_with("legacy-transfer-key from string error: ")
2524 );
2525 assert!(Key::from_formatted_str(DEPLOY_INFO_PREFIX)
2526 .unwrap_err()
2527 .to_string()
2528 .starts_with("deploy-info-key from string error: "));
2529 assert!(Key::from_formatted_str(ERA_INFO_PREFIX)
2530 .unwrap_err()
2531 .to_string()
2532 .starts_with("era-info-key from string error: "));
2533 assert!(Key::from_formatted_str(BALANCE_PREFIX)
2534 .unwrap_err()
2535 .to_string()
2536 .starts_with("balance-key from string error: "));
2537 assert!(Key::from_formatted_str(BID_PREFIX)
2538 .unwrap_err()
2539 .to_string()
2540 .starts_with("bid-key from string error: "));
2541 assert!(Key::from_formatted_str(WITHDRAW_PREFIX)
2542 .unwrap_err()
2543 .to_string()
2544 .starts_with("withdraw-key from string error: "));
2545 assert!(Key::from_formatted_str(DICTIONARY_PREFIX)
2546 .unwrap_err()
2547 .to_string()
2548 .starts_with("dictionary-key from string error: "));
2549 assert!(Key::from_formatted_str(SYSTEM_ENTITY_REGISTRY_PREFIX)
2550 .unwrap_err()
2551 .to_string()
2552 .starts_with("system-contract-registry-key from string error: "));
2553 assert!(Key::from_formatted_str(ERA_SUMMARY_PREFIX)
2554 .unwrap_err()
2555 .to_string()
2556 .starts_with("era-summary-key from string error"));
2557 assert!(Key::from_formatted_str(UNBOND_PREFIX)
2558 .unwrap_err()
2559 .to_string()
2560 .starts_with("unbond-key from string error: "));
2561 assert!(Key::from_formatted_str(CHAINSPEC_REGISTRY_PREFIX)
2562 .unwrap_err()
2563 .to_string()
2564 .starts_with("chainspec-registry-key from string error: "));
2565 assert!(Key::from_formatted_str(CHECKSUM_REGISTRY_PREFIX)
2566 .unwrap_err()
2567 .to_string()
2568 .starts_with("checksum-registry-key from string error: "));
2569 let bid_addr_err = Key::from_formatted_str(BID_ADDR_PREFIX)
2570 .unwrap_err()
2571 .to_string();
2572 assert!(
2573 bid_addr_err.starts_with("bid-addr-key from string error: "),
2574 "{}",
2575 bid_addr_err
2576 );
2577 assert!(Key::from_formatted_str(PACKAGE_PREFIX)
2578 .unwrap_err()
2579 .to_string()
2580 .starts_with("package-key from string error: "));
2581
2582 let error_string =
2583 Key::from_formatted_str(&format!("{}{}", ENTITY_PREFIX, ACCOUNT_ENTITY_PREFIX))
2584 .unwrap_err()
2585 .to_string();
2586 assert!(error_string.starts_with("addressable-entity-key from string error: "));
2587 assert!(
2588 Key::from_formatted_str(&format!("{}{}", BYTE_CODE_PREFIX, EMPTY_PREFIX))
2589 .unwrap_err()
2590 .to_string()
2591 .starts_with("byte-code-key from string error: ")
2592 );
2593 let invalid_prefix = "a-0000000000000000000000000000000000000000000000000000000000000000";
2594 assert_eq!(
2595 Key::from_formatted_str(invalid_prefix)
2596 .unwrap_err()
2597 .to_string(),
2598 "unknown prefix for key"
2599 );
2600
2601 let missing_hyphen_prefix =
2602 "hash0000000000000000000000000000000000000000000000000000000000000000";
2603 assert_eq!(
2604 Key::from_formatted_str(missing_hyphen_prefix)
2605 .unwrap_err()
2606 .to_string(),
2607 "unknown prefix for key"
2608 );
2609
2610 let no_prefix = "0000000000000000000000000000000000000000000000000000000000000000";
2611 assert_eq!(
2612 Key::from_formatted_str(no_prefix).unwrap_err().to_string(),
2613 "unknown prefix for key"
2614 );
2615
2616 let balance_hold_err = Key::from_formatted_str(BALANCE_HOLD_PREFIX)
2617 .unwrap_err()
2618 .to_string();
2619 assert!(
2620 balance_hold_err.starts_with("balance-hold from string error: "),
2621 "{}",
2622 bid_addr_err
2623 );
2624 }
2625
2626 #[test]
2627 fn key_to_json() {
2628 for key in KEYS.iter() {
2629 assert_eq!(
2630 serde_json::to_string(key).unwrap(),
2631 format!("\"{}\"", key.to_formatted_string())
2632 );
2633 }
2634 }
2635
2636 #[test]
2637 fn serialization_roundtrip_bincode() {
2638 for key in KEYS {
2639 let encoded = bincode::serialize(key).unwrap();
2640 let decoded = bincode::deserialize(&encoded).unwrap();
2641 assert_eq!(key, &decoded);
2642 }
2643 }
2644
2645 #[test]
2646 fn key_tag_bytes_roundtrip() {
2647 for key in KEYS {
2648 let tag: KeyTag = key.tag();
2649 bytesrepr::test_serialization_roundtrip(&tag);
2650 }
2651 }
2652
2653 #[test]
2654 fn bytesrepr_serialization_roundtrip() {
2655 bytesrepr::test_serialization_roundtrip(&ACCOUNT_KEY);
2656 bytesrepr::test_serialization_roundtrip(&HASH_KEY);
2657 bytesrepr::test_serialization_roundtrip(&UREF_KEY);
2658 bytesrepr::test_serialization_roundtrip(&TRANSFER_KEY);
2659 bytesrepr::test_serialization_roundtrip(&DEPLOY_INFO_KEY);
2660 bytesrepr::test_serialization_roundtrip(&ERA_INFO_KEY);
2661 bytesrepr::test_serialization_roundtrip(&BALANCE_KEY);
2662 bytesrepr::test_serialization_roundtrip(&BID_KEY);
2663 bytesrepr::test_serialization_roundtrip(&WITHDRAW_KEY);
2664 bytesrepr::test_serialization_roundtrip(&DICTIONARY_KEY);
2665 bytesrepr::test_serialization_roundtrip(&ERA_SUMMARY_KEY);
2667 bytesrepr::test_serialization_roundtrip(&UNBOND_KEY);
2668 bytesrepr::test_serialization_roundtrip(&CHAINSPEC_REGISTRY_KEY);
2669 bytesrepr::test_serialization_roundtrip(&CHECKSUM_REGISTRY_KEY);
2670 bytesrepr::test_serialization_roundtrip(&VALIDATOR_BID_KEY);
2672 bytesrepr::test_serialization_roundtrip(&DELEGATOR_BID_KEY);
2673 bytesrepr::test_serialization_roundtrip(&PACKAGE_KEY);
2674 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SYSTEM_KEY);
2675 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_ACCOUNT_KEY);
2676 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY);
2677 bytesrepr::test_serialization_roundtrip(&BYTE_CODE_EMPTY_KEY);
2678 bytesrepr::test_serialization_roundtrip(&BYTE_CODE_V1_WASM_KEY);
2679 bytesrepr::test_serialization_roundtrip(&MESSAGE_TOPIC_KEY);
2680 bytesrepr::test_serialization_roundtrip(&MESSAGE_KEY);
2681 bytesrepr::test_serialization_roundtrip(&NAMED_KEY);
2682 bytesrepr::test_serialization_roundtrip(&STATE_KEY);
2683 }
2684
2685 #[test]
2686 fn serialization_roundtrip_json() {
2687 for key in KEYS {
2688 round_trip(key);
2689 }
2690
2691 let zeros = [0; BLAKE2B_DIGEST_LENGTH];
2692 let nines = [9; BLAKE2B_DIGEST_LENGTH];
2693
2694 round_trip(&Key::Account(AccountHash::new(zeros)));
2695 round_trip(&Key::Hash(zeros));
2696 round_trip(&Key::URef(URef::new(zeros, AccessRights::READ)));
2697 round_trip(&Key::Transfer(TransferAddr::new(zeros)));
2698 round_trip(&Key::DeployInfo(DeployHash::from_raw(zeros)));
2699 round_trip(&Key::EraInfo(EraId::from(0)));
2700 round_trip(&Key::Balance(URef::new(zeros, AccessRights::READ).addr()));
2701 round_trip(&Key::Bid(AccountHash::new(zeros)));
2702 round_trip(&Key::BidAddr(BidAddr::legacy(zeros)));
2703 round_trip(&Key::BidAddr(BidAddr::new_validator_addr(zeros)));
2704 round_trip(&Key::BidAddr(BidAddr::new_delegator_account_addr((
2705 zeros, nines,
2706 ))));
2707 round_trip(&Key::Withdraw(AccountHash::new(zeros)));
2708 round_trip(&Key::Dictionary(zeros));
2709 round_trip(&Key::Unbond(AccountHash::new(zeros)));
2710 round_trip(&Key::SmartContract(zeros));
2711 round_trip(&Key::AddressableEntity(EntityAddr::new_system(zeros)));
2712 round_trip(&Key::AddressableEntity(EntityAddr::new_account(zeros)));
2713 round_trip(&Key::AddressableEntity(EntityAddr::new_smart_contract(
2714 zeros,
2715 )));
2716 round_trip(&Key::ByteCode(ByteCodeAddr::Empty));
2717 round_trip(&Key::ByteCode(ByteCodeAddr::V1CasperWasm(zeros)));
2718 round_trip(&Key::Message(MessageAddr::new_topic_addr(
2719 EntityAddr::new_smart_contract(zeros),
2720 nines.into(),
2721 )));
2722 round_trip(&Key::Message(MessageAddr::new_message_addr(
2723 EntityAddr::new_smart_contract(zeros),
2724 nines.into(),
2725 1,
2726 )));
2727 round_trip(&Key::NamedKey(NamedKeyAddr::default()));
2728 round_trip(&Key::BlockGlobal(BlockGlobalAddr::BlockTime));
2729 round_trip(&Key::BlockGlobal(BlockGlobalAddr::MessageCount));
2730 round_trip(&Key::BlockGlobal(BlockGlobalAddr::ProtocolVersion));
2731 round_trip(&Key::BlockGlobal(BlockGlobalAddr::AddressableEntity));
2732 round_trip(&Key::BalanceHold(BalanceHoldAddr::default()));
2733 round_trip(&Key::State(EntityAddr::new_system(zeros)));
2734 }
2735
2736 #[test]
2737 fn state_json_deserialization() {
2738 let mut test_rng = TestRng::new();
2739 let state_key = Key::State(EntityAddr::new_account(test_rng.gen()));
2740 round_trip(&state_key);
2741
2742 let state_key = Key::State(EntityAddr::new_system(test_rng.gen()));
2743 round_trip(&state_key);
2744
2745 let state_key = Key::State(EntityAddr::new_smart_contract(test_rng.gen()));
2746 round_trip(&state_key);
2747 }
2748
2749 #[test]
2750 fn roundtrip() {
2751 bytesrepr::test_serialization_roundtrip(&ACCOUNT_KEY);
2752 bytesrepr::test_serialization_roundtrip(&HASH_KEY);
2753 bytesrepr::test_serialization_roundtrip(&UREF_KEY);
2754 bytesrepr::test_serialization_roundtrip(&TRANSFER_KEY);
2755 bytesrepr::test_serialization_roundtrip(&DEPLOY_INFO_KEY);
2756 bytesrepr::test_serialization_roundtrip(&ERA_INFO_KEY);
2757 bytesrepr::test_serialization_roundtrip(&BALANCE_KEY);
2758 bytesrepr::test_serialization_roundtrip(&BID_KEY);
2759 bytesrepr::test_serialization_roundtrip(&WITHDRAW_KEY);
2760 bytesrepr::test_serialization_roundtrip(&DICTIONARY_KEY);
2761 bytesrepr::test_serialization_roundtrip(&SYSTEM_ENTITY_REGISTRY_KEY);
2762 bytesrepr::test_serialization_roundtrip(&ERA_SUMMARY_KEY);
2763 bytesrepr::test_serialization_roundtrip(&UNBOND_KEY);
2764 bytesrepr::test_serialization_roundtrip(&CHAINSPEC_REGISTRY_KEY);
2765 bytesrepr::test_serialization_roundtrip(&CHECKSUM_REGISTRY_KEY);
2766 bytesrepr::test_serialization_roundtrip(&UNIFIED_BID_KEY);
2767 bytesrepr::test_serialization_roundtrip(&VALIDATOR_BID_KEY);
2768 bytesrepr::test_serialization_roundtrip(&DELEGATOR_BID_KEY);
2769 bytesrepr::test_serialization_roundtrip(&PACKAGE_KEY);
2770 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SYSTEM_KEY);
2771 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_ACCOUNT_KEY);
2772 bytesrepr::test_serialization_roundtrip(&ADDRESSABLE_ENTITY_SMART_CONTRACT_KEY);
2773 bytesrepr::test_serialization_roundtrip(&BYTE_CODE_EMPTY_KEY);
2774 bytesrepr::test_serialization_roundtrip(&BYTE_CODE_V1_WASM_KEY);
2775 bytesrepr::test_serialization_roundtrip(&MESSAGE_TOPIC_KEY);
2776 bytesrepr::test_serialization_roundtrip(&MESSAGE_KEY);
2777 bytesrepr::test_serialization_roundtrip(&NAMED_KEY);
2778 }
2779
2780 fn round_trip(key: &Key) {
2781 let encoded = serde_json::to_value(key).unwrap();
2782 let decoded = serde_json::from_value(encoded.clone())
2783 .unwrap_or_else(|_| panic!("{} {}", key, encoded));
2784 assert_eq!(key, &decoded);
2785 }
2786}
2787
2788#[cfg(test)]
2789mod proptest {
2790 use crate::gens;
2791 use proptest::prelude::*;
2792
2793 proptest! {
2794 #[test]
2795 fn test_json_roundtrip_for_bidaddr_key(key in gens::all_keys_arb()) {
2796 let json_string = serde_json::to_string_pretty(&key).unwrap();
2797 let decoded = serde_json::from_str(&json_string).unwrap();
2798 assert_eq!(key, decoded);
2799 }
2800 }
2801}