@@ -2,16 +2,134 @@ mod branch;
22mod extension;
33mod leaf;
44
5- use std:: array;
5+ use std:: {
6+ array,
7+ sync:: { Arc , OnceLock } ,
8+ } ;
69
710pub 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+ } ;
917pub use extension:: ExtensionNode ;
1018pub 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
42160impl 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