mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-30 19:23:50 +00:00
Revert parent->child optimisation AGAIN
This commit is contained in:
@@ -1104,26 +1104,6 @@ impl ProtoArray {
|
|||||||
Ok((best_fc_node.root, best_fc_node.payload_status))
|
Ok((best_fc_node.root, best_fc_node.payload_status))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a parent->children index. Invalid nodes are excluded
|
|
||||||
/// (they aren't in store.blocks in the spec).
|
|
||||||
fn build_children_index(&self) -> Vec<Vec<usize>> {
|
|
||||||
let mut children = vec![vec![]; self.nodes.len()];
|
|
||||||
for (i, node) in self.nodes.iter().enumerate() {
|
|
||||||
if node
|
|
||||||
.execution_status()
|
|
||||||
.is_ok_and(|status| status.is_invalid())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some(parent) = node.parent()
|
|
||||||
&& parent < children.len()
|
|
||||||
{
|
|
||||||
children[parent].push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
children
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Spec: `get_filtered_block_tree`.
|
/// Spec: `get_filtered_block_tree`.
|
||||||
///
|
///
|
||||||
/// Returns the set of node indices on viable branches — those with at least
|
/// Returns the set of node indices on viable branches — those with at least
|
||||||
@@ -1134,7 +1114,6 @@ impl ProtoArray {
|
|||||||
current_slot: Slot,
|
current_slot: Slot,
|
||||||
best_justified_checkpoint: Checkpoint,
|
best_justified_checkpoint: Checkpoint,
|
||||||
best_finalized_checkpoint: Checkpoint,
|
best_finalized_checkpoint: Checkpoint,
|
||||||
children_index: &[Vec<usize>],
|
|
||||||
) -> HashSet<usize> {
|
) -> HashSet<usize> {
|
||||||
let mut viable = HashSet::new();
|
let mut viable = HashSet::new();
|
||||||
self.filter_block_tree::<E>(
|
self.filter_block_tree::<E>(
|
||||||
@@ -1142,7 +1121,6 @@ impl ProtoArray {
|
|||||||
current_slot,
|
current_slot,
|
||||||
best_justified_checkpoint,
|
best_justified_checkpoint,
|
||||||
best_finalized_checkpoint,
|
best_finalized_checkpoint,
|
||||||
children_index,
|
|
||||||
&mut viable,
|
&mut viable,
|
||||||
);
|
);
|
||||||
viable
|
viable
|
||||||
@@ -1155,17 +1133,25 @@ impl ProtoArray {
|
|||||||
current_slot: Slot,
|
current_slot: Slot,
|
||||||
best_justified_checkpoint: Checkpoint,
|
best_justified_checkpoint: Checkpoint,
|
||||||
best_finalized_checkpoint: Checkpoint,
|
best_finalized_checkpoint: Checkpoint,
|
||||||
children_index: &[Vec<usize>],
|
|
||||||
viable: &mut HashSet<usize>,
|
viable: &mut HashSet<usize>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(node) = self.nodes.get(node_index) else {
|
let Some(node) = self.nodes.get(node_index) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
let children = children_index
|
// Skip invalid children — they aren't in store.blocks in the spec.
|
||||||
.get(node_index)
|
let children: Vec<usize> = self
|
||||||
.map(|c| c.as_slice())
|
.nodes
|
||||||
.unwrap_or(&[]);
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, child)| {
|
||||||
|
child.parent() == Some(node_index)
|
||||||
|
&& !child
|
||||||
|
.execution_status()
|
||||||
|
.is_ok_and(|status| status.is_invalid())
|
||||||
|
})
|
||||||
|
.map(|(i, _)| i)
|
||||||
|
.collect();
|
||||||
|
|
||||||
if !children.is_empty() {
|
if !children.is_empty() {
|
||||||
// Evaluate ALL children (no short-circuit) to mark all viable branches.
|
// Evaluate ALL children (no short-circuit) to mark all viable branches.
|
||||||
@@ -1177,7 +1163,6 @@ impl ProtoArray {
|
|||||||
current_slot,
|
current_slot,
|
||||||
best_justified_checkpoint,
|
best_justified_checkpoint,
|
||||||
best_finalized_checkpoint,
|
best_finalized_checkpoint,
|
||||||
children_index,
|
|
||||||
viable,
|
viable,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -1222,16 +1207,12 @@ impl ProtoArray {
|
|||||||
payload_status: PayloadStatus::Pending,
|
payload_status: PayloadStatus::Pending,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build parent->children index once for O(1) lookups.
|
|
||||||
let children_index = self.build_children_index();
|
|
||||||
|
|
||||||
// Spec: `get_filtered_block_tree`.
|
// Spec: `get_filtered_block_tree`.
|
||||||
let viable_nodes = self.get_filtered_block_tree::<E>(
|
let viable_nodes = self.get_filtered_block_tree::<E>(
|
||||||
start_index,
|
start_index,
|
||||||
current_slot,
|
current_slot,
|
||||||
best_justified_checkpoint,
|
best_justified_checkpoint,
|
||||||
best_finalized_checkpoint,
|
best_finalized_checkpoint,
|
||||||
&children_index,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Compute once rather than per-child per-level.
|
// Compute once rather than per-child per-level.
|
||||||
@@ -1240,7 +1221,7 @@ impl ProtoArray {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
let children: Vec<_> = self
|
let children: Vec<_> = self
|
||||||
.get_node_children(&head, &children_index)?
|
.get_node_children(&head)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(fc_node, _)| viable_nodes.contains(&fc_node.proto_node_index))
|
.filter(|(fc_node, _)| viable_nodes.contains(&fc_node.proto_node_index))
|
||||||
.collect();
|
.collect();
|
||||||
@@ -1403,7 +1384,6 @@ impl ProtoArray {
|
|||||||
fn get_node_children(
|
fn get_node_children(
|
||||||
&self,
|
&self,
|
||||||
node: &IndexedForkChoiceNode,
|
node: &IndexedForkChoiceNode,
|
||||||
children_index: &[Vec<usize>],
|
|
||||||
) -> Result<Vec<(IndexedForkChoiceNode, ProtoNode)>, Error> {
|
) -> Result<Vec<(IndexedForkChoiceNode, ProtoNode)>, Error> {
|
||||||
if node.payload_status == PayloadStatus::Pending {
|
if node.payload_status == PayloadStatus::Pending {
|
||||||
let proto_node = self
|
let proto_node = self
|
||||||
@@ -1417,25 +1397,23 @@ impl ProtoArray {
|
|||||||
}
|
}
|
||||||
Ok(children)
|
Ok(children)
|
||||||
} else {
|
} else {
|
||||||
let child_indices = children_index
|
Ok(self
|
||||||
.get(node.proto_node_index)
|
.nodes
|
||||||
.map(|c| c.as_slice())
|
|
||||||
.unwrap_or(&[]);
|
|
||||||
Ok(child_indices
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|&child_index| {
|
.enumerate()
|
||||||
let child_node = self.nodes.get(child_index)?;
|
.filter(|(_, child_node)| {
|
||||||
if child_node.get_parent_payload_status() != node.payload_status {
|
child_node.parent() == Some(node.proto_node_index)
|
||||||
return None;
|
&& child_node.get_parent_payload_status() == node.payload_status
|
||||||
}
|
})
|
||||||
Some((
|
.map(|(child_index, child_node)| {
|
||||||
|
(
|
||||||
IndexedForkChoiceNode {
|
IndexedForkChoiceNode {
|
||||||
root: child_node.root(),
|
root: child_node.root(),
|
||||||
proto_node_index: child_index,
|
proto_node_index: child_index,
|
||||||
payload_status: PayloadStatus::Pending,
|
payload_status: PayloadStatus::Pending,
|
||||||
},
|
},
|
||||||
child_node.clone(),
|
child_node.clone(),
|
||||||
))
|
)
|
||||||
})
|
})
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user