@@ -5,13 +5,137 @@ mod leaf;
55use std:: array;
66
77pub 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+ } ;
914pub use extension:: ExtensionNode ;
1015pub 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
42166impl 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