1mod branch;
2mod extension;
3mod leaf;
4
5use alloc::sync::Arc;
6#[cfg(not(feature = "std"))]
7use alloc::{boxed::Box, vec::Vec};
8#[cfg(feature = "std")]
9pub use std::sync::OnceLock;
10
11#[cfg(not(feature = "std"))]
25pub struct OnceLock<T>(core::cell::UnsafeCell<Option<T>>);
26
27#[cfg(not(feature = "std"))]
28impl<T> OnceLock<T> {
29 #[inline]
30 fn new() -> Self {
31 Self(core::cell::UnsafeCell::new(None))
32 }
33
34 #[inline]
35 fn get(&self) -> Option<&T> {
36 unsafe { &*self.0.get() }.as_ref()
37 }
38
39 #[inline]
40 fn get_or_init(&self, f: impl FnOnce() -> T) -> &T {
41 match self.get_or_try_init(|| Ok::<T, core::convert::Infallible>(f())) {
42 Ok(val) => val,
43 Err(e) => match e {},
44 }
45 }
46
47 #[inline]
48 fn get_or_try_init<E>(&self, f: impl FnOnce() -> Result<T, E>) -> Result<&T, E> {
49 if let Some(val) = self.get() {
50 return Ok(val);
51 }
52 self.try_init(f)
53 }
54
55 #[inline]
56 fn set(&self, value: T) -> Result<(), T> {
57 match self.try_insert(value) {
58 Ok(_) => Ok(()),
59 Err((_, value)) => Err(value),
60 }
61 }
62
63 #[inline]
64 fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
65 if let Some(old) = self.get() {
66 return Err((old, value));
67 }
68 let slot = unsafe { &mut *self.0.get() };
69 Ok(slot.insert(value))
70 }
71
72 #[inline]
73 fn try_init<E>(&self, f: impl FnOnce() -> Result<T, E>) -> Result<&T, E> {
74 let val = f()?;
75 let slot = unsafe { &mut *self.0.get() };
76 debug_assert!(slot.is_none());
77 Ok(slot.insert(val))
78 }
79
80 #[inline]
81 fn take(&mut self) -> Option<T> {
82 self.0.get_mut().take()
83 }
84}
85
86#[cfg(not(feature = "std"))]
87impl<T: PartialEq> PartialEq for OnceLock<T> {
88 #[inline]
89 fn eq(&self, other: &Self) -> bool {
90 self.get() == other.get()
91 }
92}
93
94#[cfg(not(feature = "std"))]
95impl<T> Default for OnceLock<T> {
96 #[inline]
97 fn default() -> Self {
98 Self::new()
99 }
100}
101
102#[cfg(not(feature = "std"))]
103impl<T: Eq> Eq for OnceLock<T> {}
104
105#[cfg(not(feature = "std"))]
106impl<T: Clone> Clone for OnceLock<T> {
107 #[inline]
108 fn clone(&self) -> OnceLock<T> {
109 match self.get() {
110 Some(value) => OnceLock::from(value.clone()),
111 None => OnceLock::new(),
112 }
113 }
114}
115
116#[cfg(not(feature = "std"))]
117impl<T: core::fmt::Debug> core::fmt::Debug for OnceLock<T> {
118 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
119 let mut d = f.debug_tuple("OnceLock");
120 match self.get() {
121 Some(v) => d.field(v),
122 None => d.field(&format_args!("<uninit>")),
123 };
124 d.finish()
125 }
126}
127
128#[cfg(not(feature = "std"))]
129impl<T> From<T> for OnceLock<T> {
130 #[inline]
131 fn from(value: T) -> Self {
132 OnceLock(core::cell::UnsafeCell::new(Some(value)))
133 }
134}
135
136pub use branch::BranchNode;
137use ethrex_rlp::{decode::RLPDecode, encode::RLPEncode};
138pub use extension::ExtensionNode;
139pub use leaf::LeafNode;
140use rkyv::{
141 de::Pooling,
142 rancor::Source,
143 ser::{Allocator, Sharing, Writer},
144 validation::{ArchiveContext, SharedContext},
145 with::Skip,
146};
147
148use ethrex_crypto::{Crypto, NativeCrypto};
149
150use crate::{NodeRLP, TrieDB, error::TrieError, nibbles::Nibbles};
151
152use super::{ValueRLP, node_hash::NodeHash};
153
154#[derive(
159 Clone,
160 Debug,
161 serde::Serialize,
162 serde::Deserialize,
163 rkyv::Serialize,
164 rkyv::Deserialize,
165 rkyv::Archive,
166)]
167#[rkyv(serialize_bounds(__S: Writer + Allocator + Sharing, __S::Error: Source))]
168#[rkyv(deserialize_bounds(__D: Pooling, __D::Error: Source))]
169#[rkyv(bytecheck(bounds(__C: ArchiveContext + SharedContext)))]
170pub enum NodeRef {
171 Node(
173 #[rkyv(omit_bounds)] Arc<Node>,
174 #[rkyv(with = Skip)]
175 #[serde(skip)]
176 OnceLock<NodeHash>,
177 ),
178 Hash(NodeHash),
180}
181
182impl NodeRef {
183 pub fn get_node(&self, db: &dyn TrieDB, path: Nibbles) -> Result<Option<Arc<Node>>, TrieError> {
187 match self {
188 NodeRef::Node(node, _) => Ok(Some(node.clone())),
189 NodeRef::Hash(hash @ NodeHash::Inline(_)) => {
190 Ok(Some(Arc::new(Node::decode(hash.as_ref())?)))
191 }
192 NodeRef::Hash(_) => db
193 .get(path)?
194 .filter(|rlp| !rlp.is_empty())
195 .map(|rlp| Ok(Arc::new(Node::decode(&rlp)?)))
196 .transpose(),
197 }
198 }
199
200 pub fn get_node_checked(
208 &self,
209 db: &dyn TrieDB,
210 path: Nibbles,
211 ) -> Result<Option<Arc<Node>>, TrieError> {
212 match self {
213 NodeRef::Node(node, _) => Ok(Some(node.clone())),
214 NodeRef::Hash(hash @ NodeHash::Inline(_)) => {
215 Ok(Some(Arc::new(Node::decode(hash.as_ref())?)))
216 }
217 NodeRef::Hash(hash @ NodeHash::Hashed(_)) => {
218 db.get(path)?
219 .filter(|rlp| !rlp.is_empty())
220 .and_then(|rlp| match Node::decode(&rlp) {
221 Ok(node) => (node.compute_hash(&NativeCrypto) == *hash)
222 .then_some(Ok(Arc::new(node))),
223 Err(err) => Some(Err(TrieError::RLPDecode(err))),
224 })
225 .transpose()
226 }
227 }
228 }
229
230 pub(crate) fn get_node_mut(
237 &mut self,
238 db: &dyn TrieDB,
239 path: Nibbles,
240 ) -> Result<Option<&mut Node>, TrieError> {
241 match self {
242 NodeRef::Node(node, _) => Ok(Some(Arc::make_mut(node))),
243 NodeRef::Hash(hash @ NodeHash::Inline(_)) => {
244 let node = Node::decode(hash.as_ref())?;
245 *self = NodeRef::Node(Arc::new(node), OnceLock::from(*hash));
246 self.get_node_mut(db, path)
247 }
248 NodeRef::Hash(hash @ NodeHash::Hashed(_)) => {
249 let Some(node) = db
250 .get(path.clone())?
251 .filter(|rlp| !rlp.is_empty())
252 .map(|rlp| Node::decode(&rlp).map_err(TrieError::RLPDecode))
253 .transpose()?
254 else {
255 return Ok(None);
256 };
257 *self = NodeRef::Node(Arc::new(node), OnceLock::from(*hash));
258 self.get_node_mut(db, path)
259 }
260 }
261 }
262
263 pub fn is_valid(&self) -> bool {
264 match self {
265 NodeRef::Node(_, _) => true,
266 NodeRef::Hash(hash) => hash.is_valid(),
267 }
268 }
269
270 pub fn commit(
271 &mut self,
272 path: Nibbles,
273 acc: &mut Vec<(Nibbles, Vec<u8>)>,
274 crypto: &dyn Crypto,
275 ) -> NodeHash {
276 match *self {
277 NodeRef::Node(ref mut node, ref mut hash) => {
278 if let Some(hash) = hash.get() {
279 return *hash;
280 }
281 match Arc::make_mut(node) {
282 Node::Branch(node) => {
283 for (choice, node) in &mut node.choices.iter_mut().enumerate() {
284 node.commit(path.append_new(choice as u8), acc, crypto);
285 }
286 }
287 Node::Extension(node) => {
288 node.child.commit(path.concat(&node.prefix), acc, crypto);
289 }
290 Node::Leaf(_) => {}
291 }
292 let mut buf = Vec::new();
293 node.encode(&mut buf);
294 let hash = *hash.get_or_init(|| NodeHash::from_encoded(&buf, crypto));
295 if let Node::Leaf(leaf) = node.as_ref() {
296 acc.push((path.concat(&leaf.partial), leaf.value.clone()));
297 }
298 acc.push((path, buf));
299
300 hash
301 }
302 NodeRef::Hash(hash) => hash,
303 }
304 }
305
306 pub fn compute_hash(&self, crypto: &dyn Crypto) -> NodeHash {
307 *self.compute_hash_ref(crypto)
308 }
309
310 pub fn compute_hash_ref(&self, crypto: &dyn Crypto) -> &NodeHash {
311 match self {
312 NodeRef::Node(node, hash) => hash.get_or_init(|| node.compute_hash(crypto)),
313 NodeRef::Hash(hash) => hash,
314 }
315 }
316
317 pub fn compute_hash_no_alloc(&self, buf: &mut Vec<u8>, crypto: &dyn Crypto) -> &NodeHash {
318 match self {
319 NodeRef::Node(node, hash) => {
320 hash.get_or_init(|| node.compute_hash_no_alloc(buf, crypto))
321 }
322 NodeRef::Hash(hash) => hash,
323 }
324 }
325
326 pub fn memoize_hashes(&self, buf: &mut Vec<u8>, crypto: &dyn Crypto) {
327 if let NodeRef::Node(node, hash) = &self
328 && hash.get().is_none()
329 {
330 node.memoize_hashes(buf, crypto);
331 let _ = hash.set(node.compute_hash_no_alloc(buf, crypto));
332 }
333 }
334
335 pub fn clear_hash(&mut self) {
340 if let NodeRef::Node(_, hash) = self {
341 hash.take();
342 }
343 }
344}
345
346impl Default for NodeRef {
347 fn default() -> Self {
348 Self::Hash(NodeHash::default())
349 }
350}
351
352impl From<Node> for NodeRef {
353 fn from(value: Node) -> Self {
354 Self::Node(Arc::new(value), OnceLock::new())
355 }
356}
357
358impl From<NodeHash> for NodeRef {
359 fn from(value: NodeHash) -> Self {
360 Self::Hash(value)
361 }
362}
363
364impl From<Arc<Node>> for NodeRef {
365 fn from(value: Arc<Node>) -> Self {
366 Self::Node(value, OnceLock::new())
367 }
368}
369
370impl PartialEq for NodeRef {
371 fn eq(&self, other: &Self) -> bool {
372 let mut buf = Vec::new();
373 self.compute_hash_no_alloc(&mut buf, &NativeCrypto)
374 == other.compute_hash_no_alloc(&mut buf, &NativeCrypto)
375 }
376}
377
378pub enum ValueOrHash {
379 Value(ValueRLP),
380 Hash(NodeHash),
381}
382
383impl From<ValueRLP> for ValueOrHash {
384 fn from(value: ValueRLP) -> Self {
385 Self::Value(value)
386 }
387}
388
389impl From<NodeHash> for ValueOrHash {
390 fn from(value: NodeHash) -> Self {
391 Self::Hash(value)
392 }
393}
394
395#[derive(
396 Debug,
397 Clone,
398 PartialEq,
399 serde::Serialize,
400 serde::Deserialize,
401 rkyv::Deserialize,
402 rkyv::Serialize,
403 rkyv::Archive,
404)]
405pub enum Node {
407 Branch(Box<BranchNode>),
408 Extension(ExtensionNode),
409 Leaf(LeafNode),
410}
411
412impl Default for Node {
413 fn default() -> Self {
414 Self::Leaf(LeafNode {
416 partial: Nibbles::from_bytes(&[]),
417 value: Vec::new(),
418 })
419 }
420}
421
422impl From<Box<BranchNode>> for Node {
423 fn from(val: Box<BranchNode>) -> Self {
424 Node::Branch(val)
425 }
426}
427
428impl From<BranchNode> for Node {
429 fn from(val: BranchNode) -> Self {
430 Node::Branch(Box::new(val))
431 }
432}
433
434impl From<ExtensionNode> for Node {
435 fn from(val: ExtensionNode) -> Self {
436 Node::Extension(val)
437 }
438}
439
440impl From<LeafNode> for Node {
441 fn from(val: LeafNode) -> Self {
442 Node::Leaf(val)
443 }
444}
445
446impl Node {
447 pub fn get(&self, db: &dyn TrieDB, path: Nibbles) -> Result<Option<ValueRLP>, TrieError> {
449 match self {
450 Node::Branch(n) => n.get(db, path),
451 Node::Extension(n) => n.get(db, path),
452 Node::Leaf(n) => n.get(path),
453 }
454 }
455
456 pub fn insert(
458 &mut self,
459 db: &dyn TrieDB,
460 path: Nibbles,
461 value: impl Into<ValueOrHash>,
462 ) -> Result<(), TrieError> {
463 let new_node = match self {
464 Node::Branch(n) => {
465 n.insert(db, path, value.into())?;
466 Ok(None)
467 }
468 Node::Extension(n) => n.insert(db, path, value.into()),
469 Node::Leaf(n) => n.insert(path, value.into()),
470 };
471 if let Some(new_node) = new_node? {
472 *self = new_node;
473 }
474 Ok(())
475 }
476
477 pub fn remove(
480 &mut self,
481 db: &dyn TrieDB,
482 path: Nibbles,
483 ) -> Result<(bool, Option<ValueRLP>), TrieError> {
484 let (new_root, value) = match self {
485 Node::Branch(n) => n.remove(db, path),
486 Node::Extension(n) => n.remove(db, path),
487 Node::Leaf(n) => n.remove(path),
488 }?;
489
490 let is_trie_empty = new_root.is_none();
491 if let Some(NodeRemoveResult::New(new_root)) = new_root {
492 *self = new_root;
493 }
494 Ok((is_trie_empty, value))
495 }
496
497 pub fn get_path(
501 &self,
502 db: &dyn TrieDB,
503 path: Nibbles,
504 node_path: &mut Vec<Vec<u8>>,
505 ) -> Result<(), TrieError> {
506 match self {
507 Node::Branch(n) => n.get_path(db, path, node_path),
508 Node::Extension(n) => n.get_path(db, path, node_path),
509 Node::Leaf(n) => n.get_path(node_path),
510 }
511 }
512
513 pub fn compute_hash(&self, crypto: &dyn Crypto) -> NodeHash {
515 let mut buf = Vec::new();
516 self.memoize_hashes(&mut buf, crypto);
517 match self {
518 Node::Branch(n) => n.compute_hash_no_alloc(&mut buf, crypto),
519 Node::Extension(n) => n.compute_hash_no_alloc(&mut buf, crypto),
520 Node::Leaf(n) => n.compute_hash_no_alloc(&mut buf, crypto),
521 }
522 }
523
524 pub fn compute_hash_no_alloc(&self, buf: &mut Vec<u8>, crypto: &dyn Crypto) -> NodeHash {
526 self.memoize_hashes(buf, crypto);
527 match self {
528 Node::Branch(n) => n.compute_hash_no_alloc(buf, crypto),
529 Node::Extension(n) => n.compute_hash_no_alloc(buf, crypto),
530 Node::Leaf(n) => n.compute_hash_no_alloc(buf, crypto),
531 }
532 }
533
534 pub fn memoize_hashes(&self, buf: &mut Vec<u8>, crypto: &dyn Crypto) {
537 match self {
538 Node::Branch(n) => {
539 for child in &n.choices {
540 child.memoize_hashes(buf, crypto);
541 }
542 }
543 Node::Extension(n) => n.child.memoize_hashes(buf, crypto),
544 _ => {}
545 }
546 }
547
548 pub fn encode_subtrie(&self, encoded: &mut Vec<NodeRLP>) -> Result<(), TrieError> {
553 match self {
554 Node::Branch(node) => {
555 for choice in &node.choices {
556 if let NodeRef::Node(choice, _) = choice {
557 choice.encode_subtrie(encoded)?;
558 }
559 }
560 }
561 Node::Extension(node) => {
562 if let NodeRef::Node(child, _) = &node.child {
563 child.encode_subtrie(encoded)?;
564 }
565 }
566 Node::Leaf(_) => {}
567 };
568
569 encoded.push(self.encode_to_vec());
570 Ok(())
571 }
572}
573
574pub enum NodeRemoveResult {
578 Mutated,
579 New(Node),
580}