@@ -24,6 +24,9 @@ pub struct StateSummariesDAG {
2424 state_summaries_by_state_root : HashMap < Hash256 , DAGStateSummary > ,
2525 // block_root -> state slot -> (state_root, state summary)
2626 state_summaries_by_block_root : HashMap < Hash256 , BTreeMap < Slot , ( Hash256 , DAGStateSummary ) > > ,
27+ // parent_state_root -> Vec<children_state_root>
28+ // cached value to prevent having to recompute in each recursive call into `descendants_of`
29+ child_state_roots : HashMap < Hash256 , Vec < Hash256 > > ,
2730}
2831
2932#[ derive( Debug ) ]
@@ -32,6 +35,7 @@ pub enum Error {
3235 MissingStateSummaryByBlockRoot ( Hash256 ) ,
3336 MissingStateSummaryAtSlot ( Hash256 , Slot ) ,
3437 MissingChildBlockRoot ( Hash256 ) ,
38+ MissingChildStateRoot ( Hash256 ) ,
3539 MissingBlock ( Hash256 ) ,
3640 RequestedSlotAboveSummary ( Hash256 , Slot ) ,
3741 RootUnknownPreviousStateRoot ( Hash256 , Slot ) ,
@@ -40,8 +44,10 @@ pub enum Error {
4044impl StateSummariesDAG {
4145 pub fn new ( state_summaries : Vec < ( Hash256 , DAGStateSummary ) > ) -> Self {
4246 // Group them by latest block root, and sorted state slot
43- let mut state_summaries_by_block_root = HashMap :: < _ , BTreeMap < _ , _ > > :: new ( ) ;
4447 let mut state_summaries_by_state_root = HashMap :: new ( ) ;
48+ let mut state_summaries_by_block_root = HashMap :: < _ , BTreeMap < _ , _ > > :: new ( ) ;
49+ let mut child_state_roots = HashMap :: < _ , Vec < _ > > :: new ( ) ;
50+
4551 for ( state_root, summary) in state_summaries. into_iter ( ) {
4652 let summaries = state_summaries_by_block_root
4753 . entry ( summary. latest_block_root )
@@ -51,11 +57,19 @@ impl StateSummariesDAG {
5157 summaries. insert ( summary. slot , ( state_root, summary) ) ;
5258
5359 state_summaries_by_state_root. insert ( state_root, summary) ;
60+
61+ child_state_roots
62+ . entry ( summary. previous_state_root )
63+ . or_default ( )
64+ . push ( state_root) ;
65+ // Add empty entry for the child state
66+ child_state_roots. entry ( state_root) . or_default ( ) ;
5467 }
5568
5669 Self {
5770 state_summaries_by_state_root,
5871 state_summaries_by_block_root,
72+ child_state_roots,
5973 }
6074 }
6175
@@ -141,16 +155,14 @@ impl StateSummariesDAG {
141155
142156 /// Returns a vec of state summaries that have an unknown parent when forming the DAG tree
143157 pub fn tree_roots ( & self ) -> Vec < ( Hash256 , DAGStateSummary ) > {
144- self . state_summaries_by_block_root
145- . values ( )
146- . flat_map ( |summaries| {
147- summaries. values ( ) . filter_map ( |( state_root, summary) | {
148- if summary. previous_state_root == Hash256 :: ZERO {
149- Some ( ( * state_root, * summary) )
150- } else {
151- None
152- }
153- } )
158+ self . state_summaries_by_state_root
159+ . iter ( )
160+ . filter_map ( |( state_root, summary) | {
161+ if summary. previous_state_root == Hash256 :: ZERO {
162+ Some ( ( * state_root, * summary) )
163+ } else {
164+ None
165+ }
154166 } )
155167 . collect ( )
156168 }
@@ -164,13 +176,9 @@ impl StateSummariesDAG {
164176
165177 pub fn summaries_by_slot_ascending ( & self ) -> BTreeMap < Slot , Vec < ( Hash256 , DAGStateSummary ) > > {
166178 let mut summaries = BTreeMap :: < Slot , Vec < _ > > :: new ( ) ;
167- for ( slot, ( state_root, summary) ) in self
168- . state_summaries_by_block_root
169- . values ( )
170- . flat_map ( |slot_map| slot_map. iter ( ) )
171- {
179+ for ( state_root, summary) in self . state_summaries_by_state_root . iter ( ) {
172180 summaries
173- . entry ( * slot)
181+ . entry ( summary . slot )
174182 . or_default ( )
175183 . push ( ( * state_root, * summary) ) ;
176184 }
@@ -244,6 +252,20 @@ impl StateSummariesDAG {
244252 }
245253 }
246254 }
255+
256+ /// Returns of the descendant state summaries roots given an initiail state root.
257+ pub fn descendants_of ( & self , query_state_root : & Hash256 ) -> Result < Vec < Hash256 > , Error > {
258+ let mut descendants = vec ! [ ] ;
259+ for child_root in self
260+ . child_state_roots
261+ . get ( query_state_root)
262+ . ok_or ( Error :: MissingChildStateRoot ( * query_state_root) ) ?
263+ {
264+ descendants. push ( * child_root) ;
265+ descendants. extend ( self . descendants_of ( child_root) ?) ;
266+ }
267+ Ok ( descendants)
268+ }
247269}
248270
249271#[ derive( Debug , Clone , Copy ) ]
@@ -253,10 +275,11 @@ pub struct DAGBlockSummary {
253275}
254276
255277pub struct BlockSummariesDAG {
256- // parent_block_root -> Vec<children_block_root>
257- child_block_roots : HashMap < Hash256 , Vec < ( Hash256 , DAGBlockSummary ) > > ,
258278 // block_root -> block
259279 blocks_by_block_root : HashMap < Hash256 , DAGBlockSummary > ,
280+ // parent_block_root -> Vec<children_block_root>
281+ // cached value to prevent having to recompute in each recursive call into `descendants_of`
282+ child_block_roots : HashMap < Hash256 , Vec < Hash256 > > ,
260283}
261284
262285impl BlockSummariesDAG {
@@ -269,7 +292,7 @@ impl BlockSummariesDAG {
269292 child_block_roots
270293 . entry ( block. parent_root )
271294 . or_default ( )
272- . push ( ( * block_root, * block ) ) ;
295+ . push ( * block_root) ;
273296 // Add empty entry for the child block
274297 child_block_roots. entry ( * block_root) . or_default ( ) ;
275298
@@ -284,7 +307,7 @@ impl BlockSummariesDAG {
284307
285308 pub fn descendant_block_roots_of ( & self , block_root : & Hash256 ) -> Result < Vec < Hash256 > , Error > {
286309 let mut descendants = vec ! [ ] ;
287- for ( child_root, _ ) in self
310+ for child_root in self
288311 . child_block_roots
289312 . get ( block_root)
290313 . ok_or ( Error :: MissingChildBlockRoot ( * block_root) ) ?
0 commit comments