Skip to content

Commit 28d7b74

Browse files
committed
Add states descendants_of
1 parent 10bbb2e commit 28d7b74

File tree

1 file changed

+44
-21
lines changed

1 file changed

+44
-21
lines changed

beacon_node/beacon_chain/src/summaries_dag.rs

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {
4044
impl 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

255277
pub 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

262285
impl 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

Comments
 (0)