Skip to content

Commit 87221b4

Browse files
authored
Merge 1660e07 into a9adf9c
2 parents a9adf9c + 1660e07 commit 87221b4

15 files changed

Lines changed: 877 additions & 910 deletions

File tree

crates/common/trie/node.rs

Lines changed: 139 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,134 @@ mod branch;
22
mod extension;
33
mod leaf;
44

5-
use std::array;
5+
use std::{
6+
array,
7+
sync::{Arc, OnceLock},
8+
};
69

710
pub use branch::BranchNode;
8-
use ethrex_rlp::{decode::decode_bytes, error::RLPDecodeError, structs::Decoder};
11+
use ethrex_rlp::{
12+
decode::{decode_bytes, RLPDecode},
13+
encode::RLPEncode,
14+
error::RLPDecodeError,
15+
structs::Decoder,
16+
};
917
pub use extension::ExtensionNode;
1018
pub use leaf::LeafNode;
1119

12-
use crate::{error::TrieError, nibbles::Nibbles};
20+
use crate::{error::TrieError, nibbles::Nibbles, TrieDB};
1321

14-
use super::{node_hash::NodeHash, state::TrieState, ValueRLP};
22+
use super::{node_hash::NodeHash, ValueRLP};
23+
24+
/// A reference to a node.
25+
#[derive(Clone, Debug)]
26+
pub enum NodeRef {
27+
/// The node is embedded within the reference.
28+
Node(Arc<Node>, OnceLock<NodeHash>),
29+
/// The node is in the database, referenced by its hash.
30+
Hash(NodeHash),
31+
}
32+
33+
impl NodeRef {
34+
pub const fn const_default() -> Self {
35+
Self::Hash(NodeHash::const_default())
36+
}
37+
38+
pub fn get_node(&self, db: &dyn TrieDB) -> Result<Option<Node>, TrieError> {
39+
match *self {
40+
NodeRef::Node(ref node, _) => Ok(Some(node.as_ref().clone())),
41+
NodeRef::Hash(NodeHash::Inline((data, len))) => {
42+
Ok(Some(Node::decode_raw(&data[..len as usize])?))
43+
}
44+
NodeRef::Hash(hash @ NodeHash::Hashed(_)) => db
45+
.get(hash)?
46+
.map(|rlp| Node::decode(&rlp).map_err(TrieError::RLPDecode))
47+
.transpose(),
48+
}
49+
}
50+
51+
pub fn is_valid(&self) -> bool {
52+
match self {
53+
NodeRef::Node(_, _) => true,
54+
NodeRef::Hash(hash) => hash.is_valid(),
55+
}
56+
}
57+
58+
pub fn commit(&mut self, acc: &mut Vec<(NodeHash, Vec<u8>)>) -> NodeHash {
59+
match *self {
60+
NodeRef::Node(ref mut node, ref mut hash) => {
61+
match Arc::make_mut(node) {
62+
Node::Branch(node) => {
63+
for node in &mut node.choices {
64+
node.commit(acc);
65+
}
66+
}
67+
Node::Extension(node) => {
68+
node.child.commit(acc);
69+
}
70+
Node::Leaf(_) => {}
71+
}
72+
73+
let hash = hash.get_or_init(|| node.compute_hash());
74+
acc.push((*hash, node.encode_to_vec()));
75+
76+
let hash = *hash;
77+
*self = hash.into();
78+
79+
hash
80+
}
81+
NodeRef::Hash(hash) => hash,
82+
}
83+
}
84+
85+
pub fn compute_hash(&self) -> NodeHash {
86+
match self {
87+
NodeRef::Node(node, hash) => *hash.get_or_init(|| node.compute_hash()),
88+
NodeRef::Hash(hash) => *hash,
89+
}
90+
}
91+
}
92+
93+
impl Default for NodeRef {
94+
fn default() -> Self {
95+
Self::const_default()
96+
}
97+
}
98+
99+
impl From<Node> for NodeRef {
100+
fn from(value: Node) -> Self {
101+
Self::Node(Arc::new(value), OnceLock::new())
102+
}
103+
}
104+
105+
impl From<NodeHash> for NodeRef {
106+
fn from(value: NodeHash) -> Self {
107+
Self::Hash(value)
108+
}
109+
}
110+
111+
impl PartialEq for NodeRef {
112+
fn eq(&self, other: &Self) -> bool {
113+
self.compute_hash() == other.compute_hash()
114+
}
115+
}
116+
117+
pub enum ValueOrHash {
118+
Value(ValueRLP),
119+
Hash(NodeHash),
120+
}
121+
122+
impl From<ValueRLP> for ValueOrHash {
123+
fn from(value: ValueRLP) -> Self {
124+
Self::Value(value)
125+
}
126+
}
127+
128+
impl From<NodeHash> for ValueOrHash {
129+
fn from(value: NodeHash) -> Self {
130+
Self::Hash(value)
131+
}
132+
}
15133

16134
/// A Node in an Ethereum Compatible Patricia Merkle Trie
17135
#[derive(Debug, Clone, PartialEq)]
@@ -41,38 +159,38 @@ impl From<LeafNode> for Node {
41159

42160
impl Node {
43161
/// Retrieves a value from the subtrie originating from this node given its path
44-
pub fn get(&self, state: &TrieState, path: Nibbles) -> Result<Option<ValueRLP>, TrieError> {
162+
pub fn get(&self, db: &dyn TrieDB, path: Nibbles) -> Result<Option<ValueRLP>, TrieError> {
45163
match self {
46-
Node::Branch(n) => n.get(state, path),
47-
Node::Extension(n) => n.get(state, path),
164+
Node::Branch(n) => n.get(db, path),
165+
Node::Extension(n) => n.get(db, path),
48166
Node::Leaf(n) => n.get(path),
49167
}
50168
}
51169

52170
/// Inserts a value into the subtrie originating from this node and returns the new root of the subtrie
53171
pub fn insert(
54172
self,
55-
state: &mut TrieState,
173+
db: &dyn TrieDB,
56174
path: Nibbles,
57-
value: ValueRLP,
175+
value: impl Into<ValueOrHash>,
58176
) -> Result<Node, TrieError> {
59177
match self {
60-
Node::Branch(n) => n.insert(state, path, value),
61-
Node::Extension(n) => n.insert(state, path, value),
62-
Node::Leaf(n) => n.insert(state, path, value),
178+
Node::Branch(n) => n.insert(db, path, value.into()),
179+
Node::Extension(n) => n.insert(db, path, value.into()),
180+
Node::Leaf(n) => n.insert(path, value.into()),
63181
}
64182
}
65183

66184
/// Removes a value from the subtrie originating from this node given its path
67185
/// Returns the new root of the subtrie (if any) and the removed value if it existed in the subtrie
68186
pub fn remove(
69187
self,
70-
state: &mut TrieState,
188+
db: &dyn TrieDB,
71189
path: Nibbles,
72190
) -> Result<(Option<Node>, Option<ValueRLP>), TrieError> {
73191
match self {
74-
Node::Branch(n) => n.remove(state, path),
75-
Node::Extension(n) => n.remove(state, path),
192+
Node::Branch(n) => n.remove(db, path),
193+
Node::Extension(n) => n.remove(db, path),
76194
Node::Leaf(n) => n.remove(path),
77195
}
78196
}
@@ -82,25 +200,17 @@ impl Node {
82200
/// Only nodes with encoded len over or equal to 32 bytes are included
83201
pub fn get_path(
84202
&self,
85-
state: &TrieState,
203+
db: &dyn TrieDB,
86204
path: Nibbles,
87205
node_path: &mut Vec<Vec<u8>>,
88206
) -> Result<(), TrieError> {
89207
match self {
90-
Node::Branch(n) => n.get_path(state, path, node_path),
91-
Node::Extension(n) => n.get_path(state, path, node_path),
208+
Node::Branch(n) => n.get_path(db, path, node_path),
209+
Node::Extension(n) => n.get_path(db, path, node_path),
92210
Node::Leaf(n) => n.get_path(node_path),
93211
}
94212
}
95213

96-
pub fn insert_self(self, state: &mut TrieState) -> Result<NodeHash, TrieError> {
97-
match self {
98-
Node::Branch(n) => n.insert_self(state),
99-
Node::Extension(n) => n.insert_self(state),
100-
Node::Leaf(n) => n.insert_self(state),
101-
}
102-
}
103-
104214
/// Encodes the node
105215
pub fn encode_raw(&self) -> Vec<u8> {
106216
match self {
@@ -142,17 +252,17 @@ impl Node {
142252
// Decode as Extension
143253
ExtensionNode {
144254
prefix: path,
145-
child: decode_child(&rlp_items[1]),
255+
child: decode_child(&rlp_items[1]).into(),
146256
}
147257
.into()
148258
}
149259
}
150260
// Branch Node
151261
17 => {
152-
let choices = array::from_fn(|i| decode_child(&rlp_items[i]));
262+
let choices = array::from_fn(|i| decode_child(&rlp_items[i]).into());
153263
let (value, _) = decode_bytes(&rlp_items[16])?;
154264
BranchNode {
155-
choices: Box::new(choices),
265+
choices,
156266
value: value.to_vec(),
157267
}
158268
.into()

0 commit comments

Comments
 (0)