Skip to content

Commit eb0b028

Browse files
authored
Merge 56cf958 into b47623f
2 parents b47623f + 56cf958 commit eb0b028

12 files changed

Lines changed: 762 additions & 898 deletions

File tree

crates/common/trie/node.rs

Lines changed: 144 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,137 @@ mod leaf;
55
use std::array;
66

77
pub use branch::BranchNode;
8-
use ethrex_rlp::{decode::decode_bytes, error::RLPDecodeError, structs::Decoder};
8+
use ethrex_rlp::{
9+
decode::{decode_bytes, RLPDecode},
10+
encode::RLPEncode,
11+
error::RLPDecodeError,
12+
structs::Decoder,
13+
};
914
pub use extension::ExtensionNode;
1015
pub use leaf::LeafNode;
1116

12-
use crate::{error::TrieError, nibbles::Nibbles};
17+
use crate::{error::TrieError, nibbles::Nibbles, TrieDB};
1318

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

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

42166
impl Node {
43167
/// 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> {
168+
pub fn get(&self, db: &dyn TrieDB, path: Nibbles) -> Result<Option<ValueRLP>, TrieError> {
45169
match self {
46-
Node::Branch(n) => n.get(state, path),
47-
Node::Extension(n) => n.get(state, path),
170+
Node::Branch(n) => n.get(db, path),
171+
Node::Extension(n) => n.get(db, path),
48172
Node::Leaf(n) => n.get(path),
49173
}
50174
}
51175

52176
/// Inserts a value into the subtrie originating from this node and returns the new root of the subtrie
53177
pub fn insert(
54178
self,
55-
state: &mut TrieState,
179+
db: &dyn TrieDB,
56180
path: Nibbles,
57-
value: ValueRLP,
181+
value: impl Into<ValueOrHash>,
58182
) -> Result<Node, TrieError> {
59183
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),
184+
Node::Branch(n) => n.insert(db, path, value.into()),
185+
Node::Extension(n) => n.insert(db, path, value.into()),
186+
Node::Leaf(n) => n.insert(path, value.into()),
63187
}
64188
}
65189

66190
/// Removes a value from the subtrie originating from this node given its path
67191
/// Returns the new root of the subtrie (if any) and the removed value if it existed in the subtrie
68192
pub fn remove(
69193
self,
70-
state: &mut TrieState,
194+
db: &dyn TrieDB,
71195
path: Nibbles,
72196
) -> Result<(Option<Node>, Option<ValueRLP>), TrieError> {
73197
match self {
74-
Node::Branch(n) => n.remove(state, path),
75-
Node::Extension(n) => n.remove(state, path),
198+
Node::Branch(n) => n.remove(db, path),
199+
Node::Extension(n) => n.remove(db, path),
76200
Node::Leaf(n) => n.remove(path),
77201
}
78202
}
@@ -82,25 +206,17 @@ impl Node {
82206
/// Only nodes with encoded len over or equal to 32 bytes are included
83207
pub fn get_path(
84208
&self,
85-
state: &TrieState,
209+
db: &dyn TrieDB,
86210
path: Nibbles,
87211
node_path: &mut Vec<Vec<u8>>,
88212
) -> Result<(), TrieError> {
89213
match self {
90-
Node::Branch(n) => n.get_path(state, path, node_path),
91-
Node::Extension(n) => n.get_path(state, path, node_path),
214+
Node::Branch(n) => n.get_path(db, path, node_path),
215+
Node::Extension(n) => n.get_path(db, path, node_path),
92216
Node::Leaf(n) => n.get_path(node_path),
93217
}
94218
}
95219

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-
104220
/// Encodes the node
105221
pub fn encode_raw(&self) -> Vec<u8> {
106222
match self {
@@ -142,17 +258,17 @@ impl Node {
142258
// Decode as Extension
143259
ExtensionNode {
144260
prefix: path,
145-
child: decode_child(&rlp_items[1]),
261+
child: decode_child(&rlp_items[1]).into(),
146262
}
147263
.into()
148264
}
149265
}
150266
// Branch Node
151267
17 => {
152-
let choices = array::from_fn(|i| decode_child(&rlp_items[i]));
268+
let choices = array::from_fn(|i| decode_child(&rlp_items[i]).into());
153269
let (value, _) = decode_bytes(&rlp_items[16])?;
154270
BranchNode {
155-
choices: Box::new(choices),
271+
choices,
156272
value: value.to_vec(),
157273
}
158274
.into()

0 commit comments

Comments
 (0)