1#[cfg(not(feature = "std"))]
2use alloc::vec::Vec;
3use ethereum_types::H256;
4use ethrex_crypto::Crypto;
5use ethrex_rlp::{decode::RLPDecode, encode::RLPEncode, error::RLPDecodeError, structs::Encoder};
6
7use crate::rkyv_utils::H256Wrapper;
8
9#[derive(
14 Debug,
15 Clone,
16 Copy,
17 PartialEq,
18 Hash,
19 PartialOrd,
20 Ord,
21 Eq,
22 serde::Serialize,
23 serde::Deserialize,
24 rkyv::Serialize,
25 rkyv::Deserialize,
26 rkyv::Archive,
27)]
28pub enum NodeHash {
29 Hashed(#[rkyv(with=H256Wrapper)] H256),
30 Inline(([u8; 31], u8)),
32}
33
34impl AsRef<[u8]> for NodeHash {
35 fn as_ref(&self) -> &[u8] {
36 match self {
37 NodeHash::Inline((slice, len)) => &slice[0..(*len as usize)],
38 NodeHash::Hashed(x) => x.as_bytes(),
39 }
40 }
41}
42
43impl NodeHash {
44 pub fn from_encoded(encoded: &[u8], crypto: &dyn Crypto) -> NodeHash {
46 if encoded.len() >= 32 {
47 let hash = crypto.keccak256(encoded);
48 NodeHash::Hashed(H256::from_slice(&hash))
49 } else {
50 NodeHash::from_slice(encoded)
51 }
52 }
53
54 pub(crate) fn from_slice(slice: &[u8]) -> NodeHash {
58 match slice.len() {
59 0..32 => {
60 let mut buffer = [0; 31];
61 buffer[0..slice.len()].copy_from_slice(slice);
62 NodeHash::Inline((buffer, slice.len() as u8))
63 }
64 _ => NodeHash::Hashed(H256::from_slice(slice)),
65 }
66 }
67
68 pub fn finalize(self, crypto: &dyn Crypto) -> H256 {
71 match self {
72 NodeHash::Inline(_) => H256(crypto.keccak256(self.as_ref())),
73 NodeHash::Hashed(x) => x,
74 }
75 }
76
77 pub fn is_valid(&self) -> bool {
81 !matches!(self, NodeHash::Inline(v) if v.1 == 0)
82 }
83
84 pub fn encode<'a>(&self, mut encoder: Encoder<'a>) -> Encoder<'a> {
86 match self {
87 NodeHash::Inline(_) => {
88 encoder = encoder.encode_raw(self.as_ref());
89 }
90 NodeHash::Hashed(_) => {
91 encoder = encoder.encode_bytes(self.as_ref());
92 }
93 }
94 encoder
95 }
96
97 pub fn len(&self) -> usize {
98 match self {
99 NodeHash::Hashed(h256) => h256.as_bytes().len(),
100 NodeHash::Inline(value) => value.1 as usize,
101 }
102 }
103
104 pub fn is_empty(&self) -> bool {
105 match self {
106 NodeHash::Hashed(h256) => h256.as_bytes().is_empty(),
107 NodeHash::Inline(value) => value.1 == 0,
108 }
109 }
110}
111
112impl From<H256> for NodeHash {
113 fn from(value: H256) -> Self {
114 NodeHash::Hashed(value)
115 }
116}
117
118impl From<NodeHash> for Vec<u8> {
119 fn from(val: NodeHash) -> Self {
120 val.as_ref().to_vec()
121 }
122}
123
124impl From<&NodeHash> for Vec<u8> {
125 fn from(val: &NodeHash) -> Self {
126 val.as_ref().to_vec()
127 }
128}
129
130impl Default for NodeHash {
131 fn default() -> Self {
132 NodeHash::Inline(([0; 31], 0))
133 }
134}
135
136impl RLPEncode for NodeHash {
138 fn encode(&self, buf: &mut dyn bytes::BufMut) {
139 RLPEncode::encode(&Into::<Vec<u8>>::into(self), buf)
140 }
141
142 fn length(&self) -> usize {
143 match self {
144 NodeHash::Hashed(_) => 33, NodeHash::Inline((_, 0)) => 1, NodeHash::Inline((_, len)) => *len as usize, }
148 }
149}
150
151impl RLPDecode for NodeHash {
152 fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), ethrex_rlp::error::RLPDecodeError> {
153 let (hash, rest): (Vec<u8>, &[u8]);
154 (hash, rest) = RLPDecode::decode_unfinished(rlp)?;
155 if hash.len() > 32 {
156 return Err(RLPDecodeError::InvalidLength);
157 }
158 let hash = NodeHash::from_slice(&hash);
159 Ok((hash, rest))
160 }
161}