Passing 3/6 compliance tests, but a bit sketchy

This commit is contained in:
Michael Sproul
2026-05-12 15:31:06 +10:00
parent e0ba04d198
commit e9ae5babc8

View File

@@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
use ssz::{Decode, Encode}; use ssz::{Decode, Encode};
use ssz_derive::{Decode, Encode}; use ssz_derive::{Decode, Encode};
use std::{ use std::{
collections::{BTreeSet, HashMap}, collections::{BTreeSet, HashMap, HashSet},
fmt, fmt,
time::Duration, time::Duration,
}; };
@@ -1110,80 +1110,74 @@ impl ProtoArrayForkChoice {
justified_checkpoint, justified_checkpoint,
finalized_checkpoint, finalized_checkpoint,
); );
let viable_indices = viable.iter().copied().collect::<HashSet<_>>();
let apply_proposer_boost = self let apply_proposer_boost = self
.proto_array .proto_array
.should_apply_proposer_boost::<E>(proposer_boost_root, justified_balances, spec) .should_apply_proposer_boost::<E>(proposer_boost_root, justified_balances, spec)
.map_err(|e| format!("should_apply_proposer_boost failed: {e:?}"))?; .map_err(|e| format!("should_apply_proposer_boost failed: {e:?}"))?;
let mut leaves = Vec::with_capacity(viable.len()); let mut leaves = Vec::new();
for &i in &viable { let mut stack = vec![IndexedForkChoiceNode {
let has_viable_child = viable root: *justified_root,
.iter() proto_node_index: start_index,
.any(|&j| self.proto_array.nodes.get(j).and_then(|n| n.parent()) == Some(i)); payload_status: PayloadStatus::Pending,
if has_viable_child { }];
continue;
} while let Some(fc_node) = stack.pop() {
let node = self let proto_node = self
.proto_array .proto_array
.nodes .nodes
.get(i) .get(fc_node.proto_node_index)
.ok_or_else(|| format!("invalid viable node index {i}"))?; .ok_or_else(|| format!("invalid viable node index {}", fc_node.proto_node_index))?;
let is_gloas = node.payload_received().is_ok(); let children = if proto_node.payload_received().is_ok() {
if is_gloas { if fc_node.payload_status == PayloadStatus::Pending {
// Gloas: expand into Empty/Full virtual children. let mut children = vec![fc_node.with_status(PayloadStatus::Empty)];
let empty_fc = IndexedForkChoiceNode { if proto_node.payload_received().is_ok_and(|received| received) {
root: node.root(), children.push(fc_node.with_status(PayloadStatus::Full));
proto_node_index: i, }
payload_status: PayloadStatus::Empty, children
}; } else {
let empty_weight = self self.proto_array
.proto_array .nodes
.get_weight::<E>( .iter()
&empty_fc, .enumerate()
node, .filter(|(child_index, child_node)| {
apply_proposer_boost, viable_indices.contains(child_index)
proposer_boost_root, && child_node.parent() == Some(fc_node.proto_node_index)
current_slot, && child_node.get_parent_payload_status() == fc_node.payload_status
justified_balances, })
spec, .map(|(child_index, child_node)| IndexedForkChoiceNode {
) root: child_node.root(),
.map_err(|e| format!("get_weight failed: {e:?}"))?; proto_node_index: child_index,
leaves.push((node.root(), PayloadStatus::Empty, empty_weight)); payload_status: PayloadStatus::Pending,
})
if node.payload_received().is_ok_and(|r| r) { .collect()
let full_fc = IndexedForkChoiceNode {
root: node.root(),
proto_node_index: i,
payload_status: PayloadStatus::Full,
};
let full_weight = self
.proto_array
.get_weight::<E>(
&full_fc,
node,
apply_proposer_boost,
proposer_boost_root,
current_slot,
justified_balances,
spec,
)
.map_err(|e| format!("get_weight failed: {e:?}"))?;
leaves.push((node.root(), PayloadStatus::Full, full_weight));
} }
} else { } else {
// Pre-Gloas: use Pending status (no payload split). self.proto_array
let fc_node = IndexedForkChoiceNode { .nodes
root: node.root(), .iter()
proto_node_index: i, .enumerate()
.filter(|(child_index, child_node)| {
viable_indices.contains(child_index)
&& child_node.parent() == Some(fc_node.proto_node_index)
})
.map(|(child_index, child_node)| IndexedForkChoiceNode {
root: child_node.root(),
proto_node_index: child_index,
payload_status: PayloadStatus::Pending, payload_status: PayloadStatus::Pending,
})
.collect()
}; };
if children.is_empty() {
let weight = self let weight = self
.proto_array .proto_array
.get_weight::<E>( .get_weight::<E>(
&fc_node, &fc_node,
node, proto_node,
apply_proposer_boost, apply_proposer_boost,
proposer_boost_root, proposer_boost_root,
current_slot, current_slot,
@@ -1191,9 +1185,12 @@ impl ProtoArrayForkChoice {
spec, spec,
) )
.map_err(|e| format!("get_weight failed: {e:?}"))?; .map_err(|e| format!("get_weight failed: {e:?}"))?;
leaves.push((node.root(), PayloadStatus::Pending, weight)); leaves.push((fc_node.root, fc_node.payload_status, weight));
} else {
stack.extend(children);
} }
} }
Ok(leaves) Ok(leaves)
} }