mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +00:00
changes
This commit is contained in:
@@ -1961,12 +1961,13 @@ fn load_parent<T: BeaconChainTypes, B: AsBlock<T::EthSpec>>(
|
|||||||
{
|
{
|
||||||
if block.as_block().is_parent_block_full(parent_bid_block_hash) {
|
if block.as_block().is_parent_block_full(parent_bid_block_hash) {
|
||||||
// TODO(gloas): loading the envelope here is not very efficient
|
// TODO(gloas): loading the envelope here is not very efficient
|
||||||
let envelope = chain.store.get_payload_envelope(&root)?.ok_or_else(|| {
|
if let Some(envelope) = chain.store.get_payload_envelope(&root)? {
|
||||||
BeaconChainError::DBInconsistent(format!(
|
(StatePayloadStatus::Full, envelope.message.state_root)
|
||||||
"Missing envelope for parent block {root:?}",
|
} else {
|
||||||
))
|
// The envelope hasn't been stored yet (e.g. genesis block, or payload
|
||||||
})?;
|
// not yet delivered). Fall back to the pending/empty state.
|
||||||
(StatePayloadStatus::Full, envelope.message.state_root)
|
(StatePayloadStatus::Pending, parent_block.state_root())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
(StatePayloadStatus::Pending, parent_block.state_root())
|
(StatePayloadStatus::Pending, parent_block.state_root())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ pub enum Operation {
|
|||||||
AssertHeadPayloadStatus {
|
AssertHeadPayloadStatus {
|
||||||
head_root: Hash256,
|
head_root: Hash256,
|
||||||
expected_status: PayloadStatus,
|
expected_status: PayloadStatus,
|
||||||
|
current_slot: Slot,
|
||||||
},
|
},
|
||||||
SetPayloadTiebreak {
|
SetPayloadTiebreak {
|
||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
@@ -456,9 +457,13 @@ impl ForkChoiceTestDefinition {
|
|||||||
Operation::AssertHeadPayloadStatus {
|
Operation::AssertHeadPayloadStatus {
|
||||||
head_root,
|
head_root,
|
||||||
expected_status,
|
expected_status,
|
||||||
|
current_slot,
|
||||||
} => {
|
} => {
|
||||||
let actual = fork_choice
|
let actual = fork_choice
|
||||||
.head_payload_status::<MainnetEthSpec>(&head_root)
|
.head_payload_status::<MainnetEthSpec>(
|
||||||
|
&head_root,
|
||||||
|
current_slot,
|
||||||
|
)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
panic!(
|
panic!(
|
||||||
"AssertHeadPayloadStatus: head root not found at op index {}",
|
"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 {
|
ops.push(Operation::AssertHeadPayloadStatus {
|
||||||
head_root: get_root(1),
|
head_root: get_root(1),
|
||||||
expected_status: PayloadStatus::Empty,
|
expected_status: PayloadStatus::Empty,
|
||||||
|
current_slot: Slot::new(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Flip validator 0 to Empty; both bits now clear.
|
// 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 {
|
ops.push(Operation::AssertHeadPayloadStatus {
|
||||||
head_root: get_root(1),
|
head_root: get_root(1),
|
||||||
expected_status: PayloadStatus::Empty,
|
expected_status: PayloadStatus::Empty,
|
||||||
|
current_slot: Slot::new(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Same-slot attestation to a new head candidate should be Pending (no payload bucket change).
|
// 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 {
|
ops.push(Operation::AssertHeadPayloadStatus {
|
||||||
head_root: get_root(5),
|
head_root: get_root(5),
|
||||||
expected_status: PayloadStatus::Empty,
|
expected_status: PayloadStatus::Empty,
|
||||||
|
current_slot: Slot::new(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
ForkChoiceTestDefinition {
|
ForkChoiceTestDefinition {
|
||||||
|
|||||||
@@ -1448,8 +1448,8 @@ fn child_matches_parent_payload_preference(
|
|||||||
&& parent_v29.empty_payload_weight > parent_v29.full_payload_weight
|
&& parent_v29.empty_payload_weight > parent_v29.full_payload_weight
|
||||||
{
|
{
|
||||||
false
|
false
|
||||||
} else {
|
} else if use_tiebreaker_only {
|
||||||
// Equal weights (or current-slot parent): tiebreaker per spec.
|
// Previous slot: should_extend_payload = is_payload_timely && is_payload_data_available.
|
||||||
is_payload_timely(
|
is_payload_timely(
|
||||||
&parent_v29.payload_timeliness_votes,
|
&parent_v29.payload_timeliness_votes,
|
||||||
ptc_size,
|
ptc_size,
|
||||||
@@ -1459,6 +1459,10 @@ fn child_matches_parent_payload_preference(
|
|||||||
ptc_size,
|
ptc_size,
|
||||||
parent_v29.payload_received,
|
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 {
|
if prefers_full {
|
||||||
child_v29.parent_payload_status == PayloadStatus::Full
|
child_v29.parent_payload_status == PayloadStatus::Full
|
||||||
|
|||||||
@@ -991,29 +991,43 @@ impl ProtoArrayForkChoice {
|
|||||||
.map(|node| node.weight())
|
.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 `Full` if `full_payload_weight > empty_payload_weight`.
|
||||||
/// Returns `Empty` if `empty_payload_weight > full_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
|
/// On ties:
|
||||||
/// data is available, otherwise `Empty`.
|
/// - Previous slot (`slot + 1 == current_slot`): prefer Full only when timely and
|
||||||
/// Returns `Empty` otherwise. Returns `None` for V17 nodes.
|
/// data available (per `should_extend_payload`).
|
||||||
pub fn head_payload_status<E: EthSpec>(&self, head_root: &Hash256) -> Option<PayloadStatus> {
|
/// - 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 node = self.get_proto_node(head_root)?;
|
||||||
let v29 = node.as_v29().ok()?;
|
let v29 = node.as_v29().ok()?;
|
||||||
if v29.full_payload_weight > v29.empty_payload_weight {
|
if v29.full_payload_weight > v29.empty_payload_weight {
|
||||||
Some(PayloadStatus::Full)
|
Some(PayloadStatus::Full)
|
||||||
} else if v29.empty_payload_weight > v29.full_payload_weight {
|
} else if v29.empty_payload_weight > v29.full_payload_weight {
|
||||||
Some(PayloadStatus::Empty)
|
Some(PayloadStatus::Empty)
|
||||||
} else if is_payload_timely(
|
} else if node.slot() + 1 == current_slot {
|
||||||
&v29.payload_timeliness_votes,
|
// Previous slot: should_extend_payload = is_payload_timely && is_payload_data_available
|
||||||
E::ptc_size(),
|
if is_payload_timely(
|
||||||
v29.payload_received,
|
&v29.payload_timeliness_votes,
|
||||||
) && is_payload_data_available(
|
E::ptc_size(),
|
||||||
&v29.payload_data_availability_votes,
|
v29.payload_received,
|
||||||
E::ptc_size(),
|
) && is_payload_data_available(
|
||||||
v29.payload_received,
|
&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)
|
Some(PayloadStatus::Full)
|
||||||
} else {
|
} else {
|
||||||
Some(PayloadStatus::Empty)
|
Some(PayloadStatus::Empty)
|
||||||
|
|||||||
Reference in New Issue
Block a user