mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-16 02:08:29 +00:00
gloas-head-block-number
This commit is contained in:
@@ -124,6 +124,14 @@ pub enum Operation {
|
||||
#[serde(default)]
|
||||
proposer_boost_root: Option<Hash256>,
|
||||
},
|
||||
/// Assert the root returned by `latest_parent_full_block` for `block_root`.
|
||||
AssertLatestFullPayloadBlock {
|
||||
block_root: Hash256,
|
||||
expected: Option<Hash256>,
|
||||
/// Override the proposer boost root. Defaults to `Hash256::zero()`.
|
||||
#[serde(default)]
|
||||
proposer_boost_root: Option<Hash256>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -606,6 +614,24 @@ impl ForkChoiceTestDefinition {
|
||||
op_index
|
||||
);
|
||||
}
|
||||
Operation::AssertLatestFullPayloadBlock {
|
||||
block_root,
|
||||
expected,
|
||||
proposer_boost_root,
|
||||
} => {
|
||||
let actual = fork_choice
|
||||
.latest_parent_full_block::<MainnetEthSpec>(
|
||||
block_root,
|
||||
proposer_boost_root.unwrap_or_else(Hash256::zero),
|
||||
&spec,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
actual, expected,
|
||||
"latest_parent_full_block mismatch at op index {}",
|
||||
op_index
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,4 +1235,158 @@ mod tests {
|
||||
}
|
||||
.run();
|
||||
}
|
||||
|
||||
/// `latest_parent_full_block` returns the block itself when its own payload is Full.
|
||||
#[test]
|
||||
fn latest_full_payload_block_returns_head_when_full() {
|
||||
let mut ops = vec![];
|
||||
|
||||
// Gloas block with a received payload, so it is Full at its own slot.
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(1),
|
||||
root: get_root(1),
|
||||
parent_root: get_root(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: Some(get_hash(0)),
|
||||
execution_payload_block_hash: Some(get_hash(1)),
|
||||
});
|
||||
ops.push(Operation::ProcessExecutionPayloadEnvelope {
|
||||
block_root: get_root(1),
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertLatestFullPayloadBlock {
|
||||
block_root: get_root(1),
|
||||
expected: Some(get_root(1)),
|
||||
proposer_boost_root: None,
|
||||
});
|
||||
|
||||
ForkChoiceTestDefinition {
|
||||
finalized_block_slot: Slot::new(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: Some(get_hash(42)),
|
||||
execution_payload_block_hash: Some(get_hash(0)),
|
||||
spec: Some(gloas_spec()),
|
||||
}
|
||||
.run();
|
||||
}
|
||||
|
||||
/// `latest_parent_full_block` walks back past Empty descendants to the latest Full ancestor.
|
||||
///
|
||||
/// root_1 (Full) -> root_2 (Empty) -> root_3 (Empty)
|
||||
#[test]
|
||||
fn latest_full_payload_block_walks_back_to_full_ancestor() {
|
||||
let mut ops = vec![];
|
||||
|
||||
// root_1: payload received -> Full.
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(1),
|
||||
root: get_root(1),
|
||||
parent_root: get_root(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: Some(get_hash(0)),
|
||||
execution_payload_block_hash: Some(get_hash(1)),
|
||||
});
|
||||
ops.push(Operation::ProcessExecutionPayloadEnvelope {
|
||||
block_root: get_root(1),
|
||||
});
|
||||
|
||||
// root_2 and root_3: no payload received -> Empty.
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(2),
|
||||
root: get_root(2),
|
||||
parent_root: get_root(1),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: Some(get_hash(1)),
|
||||
execution_payload_block_hash: Some(get_hash(2)),
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(3),
|
||||
root: get_root(3),
|
||||
parent_root: get_root(2),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: Some(get_hash(2)),
|
||||
execution_payload_block_hash: Some(get_hash(3)),
|
||||
});
|
||||
|
||||
ops.push(Operation::AssertLatestFullPayloadBlock {
|
||||
block_root: get_root(3),
|
||||
expected: Some(get_root(1)),
|
||||
proposer_boost_root: None,
|
||||
});
|
||||
|
||||
ForkChoiceTestDefinition {
|
||||
finalized_block_slot: Slot::new(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: Some(get_hash(42)),
|
||||
execution_payload_block_hash: Some(get_hash(0)),
|
||||
spec: Some(gloas_spec()),
|
||||
}
|
||||
.run();
|
||||
}
|
||||
|
||||
/// `latest_parent_full_block` returns `None` when the walk reaches the pre-Gloas boundary
|
||||
/// without finding a Full payload (the documented TODO case).
|
||||
///
|
||||
/// root_1 (V17, slot 31) -> root_2 (V29 Empty) -> root_3 (V29 Empty)
|
||||
#[test]
|
||||
fn latest_full_payload_block_none_at_pre_gloas_boundary() {
|
||||
let mut ops = vec![];
|
||||
|
||||
// Pre-Gloas (V17) block at the last pre-Gloas slot.
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(31),
|
||||
root: get_root(1),
|
||||
parent_root: get_root(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
});
|
||||
|
||||
// Two Gloas (V29) blocks with no payload received -> Empty.
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(32),
|
||||
root: get_root(2),
|
||||
parent_root: get_root(1),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: Some(get_hash(1)),
|
||||
execution_payload_block_hash: Some(get_hash(2)),
|
||||
});
|
||||
ops.push(Operation::ProcessBlock {
|
||||
slot: Slot::new(33),
|
||||
root: get_root(3),
|
||||
parent_root: get_root(2),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
execution_payload_parent_hash: Some(get_hash(2)),
|
||||
execution_payload_block_hash: Some(get_hash(3)),
|
||||
});
|
||||
|
||||
// The walk hits the V17 boundary block before any Full payload, so returns `None`.
|
||||
ops.push(Operation::AssertLatestFullPayloadBlock {
|
||||
block_root: get_root(3),
|
||||
expected: None,
|
||||
proposer_boost_root: None,
|
||||
});
|
||||
|
||||
ForkChoiceTestDefinition {
|
||||
finalized_block_slot: Slot::new(0),
|
||||
justified_checkpoint: get_checkpoint(0),
|
||||
finalized_checkpoint: get_checkpoint(0),
|
||||
operations: ops,
|
||||
execution_payload_parent_hash: None,
|
||||
execution_payload_block_hash: None,
|
||||
spec: Some(gloas_fork_boundary_spec()),
|
||||
}
|
||||
.run();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user