mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-20 22:38:34 +00:00
changes
This commit is contained in:
@@ -91,6 +91,7 @@ pub enum Operation {
|
||||
AssertHeadPayloadStatus {
|
||||
head_root: Hash256,
|
||||
expected_status: PayloadStatus,
|
||||
current_slot: Slot,
|
||||
},
|
||||
SetPayloadTiebreak {
|
||||
block_root: Hash256,
|
||||
@@ -456,9 +457,13 @@ impl ForkChoiceTestDefinition {
|
||||
Operation::AssertHeadPayloadStatus {
|
||||
head_root,
|
||||
expected_status,
|
||||
current_slot,
|
||||
} => {
|
||||
let actual = fork_choice
|
||||
.head_payload_status::<MainnetEthSpec>(&head_root)
|
||||
.head_payload_status::<MainnetEthSpec>(
|
||||
&head_root,
|
||||
current_slot,
|
||||
)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"AssertHeadPayloadStatus: head root not found at op index {}",
|
||||
|
||||
@@ -145,6 +145,7 @@ pub fn get_gloas_payload_probe_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::AssertHeadPayloadStatus {
|
||||
head_root: get_root(1),
|
||||
expected_status: PayloadStatus::Empty,
|
||||
current_slot: Slot::new(0),
|
||||
});
|
||||
|
||||
// Flip validator 0 to Empty; both bits now clear.
|
||||
@@ -170,6 +171,7 @@ pub fn get_gloas_payload_probe_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::AssertHeadPayloadStatus {
|
||||
head_root: get_root(1),
|
||||
expected_status: PayloadStatus::Empty,
|
||||
current_slot: Slot::new(0),
|
||||
});
|
||||
|
||||
// Same-slot attestation to a new head candidate should be Pending (no payload bucket change).
|
||||
@@ -204,6 +206,7 @@ pub fn get_gloas_payload_probe_test_definition() -> ForkChoiceTestDefinition {
|
||||
ops.push(Operation::AssertHeadPayloadStatus {
|
||||
head_root: get_root(5),
|
||||
expected_status: PayloadStatus::Empty,
|
||||
current_slot: Slot::new(0),
|
||||
});
|
||||
|
||||
ForkChoiceTestDefinition {
|
||||
|
||||
@@ -1448,8 +1448,8 @@ fn child_matches_parent_payload_preference(
|
||||
&& parent_v29.empty_payload_weight > parent_v29.full_payload_weight
|
||||
{
|
||||
false
|
||||
} else {
|
||||
// Equal weights (or current-slot parent): tiebreaker per spec.
|
||||
} else if use_tiebreaker_only {
|
||||
// Previous slot: should_extend_payload = is_payload_timely && is_payload_data_available.
|
||||
is_payload_timely(
|
||||
&parent_v29.payload_timeliness_votes,
|
||||
ptc_size,
|
||||
@@ -1459,6 +1459,10 @@ fn child_matches_parent_payload_preference(
|
||||
ptc_size,
|
||||
parent_v29.payload_received,
|
||||
)
|
||||
} else {
|
||||
// Not previous slot: should_extend_payload = true.
|
||||
// Full wins the tiebreaker (1 > 0) when the payload has been received.
|
||||
parent_v29.payload_received
|
||||
};
|
||||
if prefers_full {
|
||||
child_v29.parent_payload_status == PayloadStatus::Full
|
||||
|
||||
@@ -991,29 +991,43 @@ impl ProtoArrayForkChoice {
|
||||
.map(|node| node.weight())
|
||||
}
|
||||
|
||||
/// Returns the payload status of the head node based on accumulated weights.
|
||||
/// Returns the payload status of the head node based on accumulated weights and tiebreaker.
|
||||
///
|
||||
/// Returns `Full` if `full_payload_weight > empty_payload_weight`.
|
||||
/// Returns `Empty` if `empty_payload_weight > full_payload_weight`.
|
||||
/// On ties, consult the node's runtime `payload_tiebreak`: prefer `Full` only when timely and
|
||||
/// data is available, otherwise `Empty`.
|
||||
/// Returns `Empty` otherwise. Returns `None` for V17 nodes.
|
||||
pub fn head_payload_status<E: EthSpec>(&self, head_root: &Hash256) -> Option<PayloadStatus> {
|
||||
/// On ties:
|
||||
/// - Previous slot (`slot + 1 == current_slot`): prefer Full only when timely and
|
||||
/// data available (per `should_extend_payload`).
|
||||
/// - Otherwise: prefer Full when payload has been received.
|
||||
/// Returns `None` for V17 nodes.
|
||||
pub fn head_payload_status<E: EthSpec>(
|
||||
&self,
|
||||
head_root: &Hash256,
|
||||
current_slot: Slot,
|
||||
) -> Option<PayloadStatus> {
|
||||
let node = self.get_proto_node(head_root)?;
|
||||
let v29 = node.as_v29().ok()?;
|
||||
if v29.full_payload_weight > v29.empty_payload_weight {
|
||||
Some(PayloadStatus::Full)
|
||||
} else if v29.empty_payload_weight > v29.full_payload_weight {
|
||||
Some(PayloadStatus::Empty)
|
||||
} else if is_payload_timely(
|
||||
&v29.payload_timeliness_votes,
|
||||
E::ptc_size(),
|
||||
v29.payload_received,
|
||||
) && is_payload_data_available(
|
||||
&v29.payload_data_availability_votes,
|
||||
E::ptc_size(),
|
||||
v29.payload_received,
|
||||
) {
|
||||
} else if node.slot() + 1 == current_slot {
|
||||
// Previous slot: should_extend_payload = is_payload_timely && is_payload_data_available
|
||||
if is_payload_timely(
|
||||
&v29.payload_timeliness_votes,
|
||||
E::ptc_size(),
|
||||
v29.payload_received,
|
||||
) && is_payload_data_available(
|
||||
&v29.payload_data_availability_votes,
|
||||
E::ptc_size(),
|
||||
v29.payload_received,
|
||||
) {
|
||||
Some(PayloadStatus::Full)
|
||||
} else {
|
||||
Some(PayloadStatus::Empty)
|
||||
}
|
||||
} else if v29.payload_received {
|
||||
// Not previous slot: Full wins tiebreaker (1 > 0) when payload received.
|
||||
Some(PayloadStatus::Full)
|
||||
} else {
|
||||
Some(PayloadStatus::Empty)
|
||||
|
||||
Reference in New Issue
Block a user