starknet_devnet_types/
patricia_key.rs1use serde::{Deserialize, Deserializer, Serialize};
2use starknet_api::core::PATRICIA_KEY_UPPER_BOUND;
3use starknet_rs_core::types::Felt;
4
5use crate::error::{DevnetResult, Error};
6use crate::serde_helpers::hex_string::{
7 deserialize_to_prefixed_patricia_key, serialize_patricia_key_to_prefixed_hex,
8};
9
10#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct PatriciaKey(pub(crate) Felt);
12
13pub(crate) const PATRICIA_KEY_ZERO: PatriciaKey = PatriciaKey(Felt::ZERO);
14
15impl PatriciaKey {
16 pub fn new(felt: Felt) -> DevnetResult<Self> {
17 if Felt::from_hex_unchecked(PATRICIA_KEY_UPPER_BOUND) < felt {
18 return Err(Error::StarknetApiError(starknet_api::StarknetApiError::OutOfRange {
19 string: format!("[0x0, {PATRICIA_KEY_UPPER_BOUND})"),
20 }));
21 }
22 Ok(Self(felt))
23 }
24
25 pub(crate) fn new_unchecked(felt: Felt) -> Self {
28 debug_assert!(
29 Felt::from_hex_unchecked(PATRICIA_KEY_UPPER_BOUND) >= felt,
30 "PatriciaKey out of range"
31 );
32 Self(felt)
33 }
34
35 pub fn to_felt(&self) -> Felt {
36 self.0
37 }
38}
39
40impl Serialize for PatriciaKey {
41 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42 where
43 S: serde::Serializer,
44 {
45 serialize_patricia_key_to_prefixed_hex(self, serializer)
46 }
47}
48
49impl<'de> Deserialize<'de> for PatriciaKey {
50 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
51 where
52 D: Deserializer<'de>,
53 {
54 deserialize_to_prefixed_patricia_key(deserializer)
55 }
56}
57
58impl From<starknet_api::core::PatriciaKey> for PatriciaKey {
59 fn from(value: starknet_api::core::PatriciaKey) -> Self {
60 Self(*value.key())
61 }
62}
63
64impl From<PatriciaKey> for starknet_api::core::PatriciaKey {
65 fn from(value: PatriciaKey) -> Self {
66 Self::from_hex_unchecked(&value.0.to_hex_string())
67 }
68}
69
70impl TryFrom<Felt> for PatriciaKey {
71 type Error = Error;
72
73 fn try_from(value: Felt) -> Result<Self, Self::Error> {
74 Self::new(value)
75 }
76}
77
78impl From<PatriciaKey> for starknet_api::state::StorageKey {
79 fn from(value: PatriciaKey) -> Self {
80 Self(value.into())
81 }
82}
83
84pub type StorageKey = PatriciaKey;
85
86#[cfg(test)]
87mod tests {
88 use super::PatriciaKey;
89 use crate::felt::felt_from_prefixed_hex;
90
91 #[test]
92 fn creation_of_patricia_key_should_be_successful() {
93 assert!(
94 PatriciaKey::new(
95 felt_from_prefixed_hex(
96 "0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
97 )
98 .unwrap()
99 )
100 .is_ok()
101 );
102 }
103
104 #[test]
105 fn patricia_key_with_too_large_felt_should_return_error() {
106 let result = PatriciaKey::new(
107 felt_from_prefixed_hex(
108 "0x800000000000000000000000000000000000000000000000000000000000001",
109 )
110 .unwrap(),
111 );
112 assert!(result.is_err());
113 }
114}