Skip to content

Commit 7abbaeb

Browse files
committed
Use descent from finality instead of viability
1 parent 54010b0 commit 7abbaeb

File tree

4 files changed

+16
-41
lines changed

4 files changed

+16
-41
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,13 +1410,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
14101410
///
14111411
/// Returns `(block_root, block_slot)`.
14121412
pub fn heads(&self) -> Vec<(Hash256, Slot)> {
1413-
// Fetching the current slot is only likely to fail pre-genesis. Default to 0 in this case
1414-
// rather than erroring, so that the heads HTTP API endpoint can work pre-genesis.
1415-
let current_slot = self.slot().unwrap_or_default();
14161413
self.canonical_head
14171414
.fork_choice_read_lock()
14181415
.proto_array()
1419-
.viable_heads::<T::EthSpec>(current_slot)
1416+
.heads_descended_from_finalization::<T::EthSpec>()
14201417
.iter()
14211418
.map(|node| (node.root, node.slot))
14221419
.collect()

beacon_node/beacon_chain/src/schema_change/migration_schema_v23.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub fn downgrade_from_v23<T: BeaconChainTypes>(
6464

6565
// TODO: what value to choose here?
6666
let reset_payload_statuses = ResetPayloadStatuses::OnlyWithInvalidPayload;
67-
let mut fork_choice = ForkChoice::from_persisted(
67+
let fork_choice = ForkChoice::from_persisted(
6868
persisted_fork_choice.fork_choice,
6969
reset_payload_statuses,
7070
fc_store,
@@ -75,21 +75,9 @@ pub fn downgrade_from_v23<T: BeaconChainTypes>(
7575
Error::MigrationError(format!("Error loading fork choice from persisted: {e:?}"))
7676
})?;
7777

78-
// TODO: initialize clock
79-
let current_slot = Slot::new(0);
80-
let head_block_root = fork_choice
81-
.get_head(current_slot, &db.spec)
82-
.map_err(|e| Error::MigrationError(format!("Error computing get_head: {e:?}")))?;
83-
84-
let head_proto_block = fork_choice
85-
.get_block(&head_block_root)
86-
.ok_or(Error::MigrationError(format!(
87-
"HeadBlockMissingFromForkChoice({head_block_root:?})"
88-
)))?;
89-
9078
let heads = fork_choice
9179
.proto_array()
92-
.viable_heads::<T::EthSpec>(head_proto_block.slot);
80+
.heads_descended_from_finalization::<T::EthSpec>();
9381

9482
let head_roots = heads.iter().map(|node| node.root).collect();
9583
let head_slots = heads.iter().map(|node| node.slot).collect();

consensus/proto_array/src/proto_array.rs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,28 +1042,18 @@ impl ProtoArray {
10421042
.map(|node| node.root)
10431043
}
10441044

1045-
/// Returns all nodes that have zero children and are viable heads
1046-
pub fn viable_heads<E: EthSpec>(&self, current_slot: Slot) -> Vec<&ProtoNode> {
1047-
self.nodes_without_children()
1048-
.into_iter()
1049-
.filter_map(|index| {
1050-
// An unknown index is not a viable head
1051-
if let Some(node) = self.nodes.get(index) {
1052-
if self.node_is_viable_for_head::<E>(node, current_slot) {
1053-
return Some(node);
1054-
}
1055-
}
1056-
None
1057-
})
1058-
.collect()
1059-
}
1060-
1061-
/// Returns all node indices that have zero children. May include unviable nodes.
1062-
fn nodes_without_children(&self) -> Vec<usize> {
1045+
/// Returns all nodes that have zero children and are descended from the finalized checkpoint.
1046+
///
1047+
/// For informational purposes like the beacon HTTP API, we use this as the list of known heads,
1048+
/// even though some of them might not be viable. We do this to maintain consistency between the
1049+
/// definition of "head" used by pruning (which does not consider viability) and fork choice.
1050+
pub fn heads_descended_from_finalization<E: EthSpec>(&self) -> Vec<&ProtoNode> {
10631051
self.nodes
10641052
.iter()
1065-
.enumerate()
1066-
.filter_map(|(i, node)| node.best_child.is_none().then_some(i))
1053+
.filter(|node| {
1054+
node.best_child.is_none()
1055+
&& self.is_finalized_checkpoint_or_descendant::<E>(node.root)
1056+
})
10671057
.collect()
10681058
}
10691059
}

consensus/proto_array/src/proto_array_fork_choice.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,9 +886,9 @@ impl ProtoArrayForkChoice {
886886
&mut self.proto_array
887887
}
888888

889-
/// Returns all nodes that have zero children and are viable heads
890-
pub fn viable_heads<E: EthSpec>(&self, current_slot: Slot) -> Vec<&ProtoNode> {
891-
self.proto_array.viable_heads::<E>(current_slot)
889+
/// Returns all nodes that have zero children and are descended from the finalized checkpoint.
890+
pub fn heads_descended_from_finalization<E: EthSpec>(&self) -> Vec<&ProtoNode> {
891+
self.proto_array.heads_descended_from_finalization::<E>()
892892
}
893893
}
894894

0 commit comments

Comments
 (0)