mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 10:22:38 +00:00
Indicate that invalid blocks are optimistic (#3383)
## Issue Addressed NA ## Proposed Changes This PR will make Lighthouse return blocks with invalid payloads via the API with `execution_optimistic = true`. This seems a bit awkward, however I think it's better than returning a 404 or some other error. Let's consider the case where the only possible head is invalid (#3370 deals with this). In such a scenario all of the duties endpoints will start failing because the head is invalid. I think it would be better if the duties endpoints continue to work, because it's likely that even though the head is invalid the duties are still based upon valid blocks and we want the VC to have them cached. There's no risk to the VC here because we won't actually produce an attestation pointing to an invalid head. Ultimately, I don't think it's particularly important for us to distinguish between optimistic and invalid blocks on the API. Neither should be trusted and the only *real* reason that we track this is so we can try and fork around the invalid blocks. ## Additional Info - ~~Blocked on #3370~~
This commit is contained in:
@@ -4131,8 +4131,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// Returns the value of `execution_optimistic` for `block`.
|
||||
///
|
||||
/// Returns `Ok(false)` if the block is pre-Bellatrix, or has `ExecutionStatus::Valid`.
|
||||
/// Returns `Ok(true)` if the block has `ExecutionStatus::Optimistic`.
|
||||
pub fn is_optimistic_block<Payload: ExecPayload<T::EthSpec>>(
|
||||
/// Returns `Ok(true)` if the block has `ExecutionStatus::Optimistic` or has
|
||||
/// `ExecutionStatus::Invalid`.
|
||||
pub fn is_optimistic_or_invalid_block<Payload: ExecPayload<T::EthSpec>>(
|
||||
&self,
|
||||
block: &SignedBeaconBlock<T::EthSpec, Payload>,
|
||||
) -> Result<bool, BeaconChainError> {
|
||||
@@ -4142,7 +4143,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
} else {
|
||||
self.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.is_optimistic_block(&block.canonical_root())
|
||||
.is_optimistic_or_invalid_block(&block.canonical_root())
|
||||
.map_err(BeaconChainError::ForkChoiceError)
|
||||
}
|
||||
}
|
||||
@@ -4150,7 +4151,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// Returns the value of `execution_optimistic` for `head_block`.
|
||||
///
|
||||
/// Returns `Ok(false)` if the block is pre-Bellatrix, or has `ExecutionStatus::Valid`.
|
||||
/// Returns `Ok(true)` if the block has `ExecutionStatus::Optimistic`.
|
||||
/// Returns `Ok(true)` if the block has `ExecutionStatus::Optimistic` or `ExecutionStatus::Invalid`.
|
||||
///
|
||||
/// This function will return an error if `head_block` is not present in the fork choice store
|
||||
/// and so should only be used on the head block or when the block *should* be present in the
|
||||
@@ -4158,7 +4159,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
///
|
||||
/// There is a potential race condition when syncing where the block_root of `head_block` could
|
||||
/// be pruned from the fork choice store before being read.
|
||||
pub fn is_optimistic_head_block<Payload: ExecPayload<T::EthSpec>>(
|
||||
pub fn is_optimistic_or_invalid_head_block<Payload: ExecPayload<T::EthSpec>>(
|
||||
&self,
|
||||
head_block: &SignedBeaconBlock<T::EthSpec, Payload>,
|
||||
) -> Result<bool, BeaconChainError> {
|
||||
@@ -4168,7 +4169,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
} else {
|
||||
self.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.is_optimistic_block_no_fallback(&head_block.canonical_root())
|
||||
.is_optimistic_or_invalid_block_no_fallback(&head_block.canonical_root())
|
||||
.map_err(BeaconChainError::ForkChoiceError)
|
||||
}
|
||||
}
|
||||
@@ -4177,17 +4178,17 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// You can optionally provide `head_info` if it was computed previously.
|
||||
///
|
||||
/// Returns `Ok(false)` if the head block is pre-Bellatrix, or has `ExecutionStatus::Valid`.
|
||||
/// Returns `Ok(true)` if the head block has `ExecutionStatus::Optimistic`.
|
||||
/// Returns `Ok(true)` if the head block has `ExecutionStatus::Optimistic` or `ExecutionStatus::Invalid`.
|
||||
///
|
||||
/// There is a potential race condition when syncing where the block root of `head_info` could
|
||||
/// be pruned from the fork choice store before being read.
|
||||
pub fn is_optimistic_head(&self) -> Result<bool, BeaconChainError> {
|
||||
pub fn is_optimistic_or_invalid_head(&self) -> Result<bool, BeaconChainError> {
|
||||
self.canonical_head
|
||||
.head_execution_status()
|
||||
.map(|status| status.is_optimistic())
|
||||
.map(|status| status.is_optimistic_or_invalid())
|
||||
}
|
||||
|
||||
pub fn is_optimistic_block_root(
|
||||
pub fn is_optimistic_or_invalid_block_root(
|
||||
&self,
|
||||
block_slot: Slot,
|
||||
block_root: &Hash256,
|
||||
@@ -4198,7 +4199,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
} else {
|
||||
self.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
.is_optimistic_block_no_fallback(block_root)
|
||||
.is_optimistic_or_invalid_block_no_fallback(block_root)
|
||||
.map_err(BeaconChainError::ForkChoiceError)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,7 +752,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
) -> Result<(), Error> {
|
||||
let old_snapshot = &old_cached_head.snapshot;
|
||||
let new_snapshot = &new_cached_head.snapshot;
|
||||
let new_head_is_optimistic = new_head_proto_block.execution_status.is_optimistic();
|
||||
let new_head_is_optimistic = new_head_proto_block
|
||||
.execution_status
|
||||
.is_optimistic_or_invalid();
|
||||
|
||||
// Detect and potentially report any re-orgs.
|
||||
let reorg_distance = detect_reorg(
|
||||
@@ -883,7 +885,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
finalized_proto_block: ProtoBlock,
|
||||
) -> Result<(), Error> {
|
||||
let new_snapshot = &new_cached_head.snapshot;
|
||||
let finalized_block_is_optimistic = finalized_proto_block.execution_status.is_optimistic();
|
||||
let finalized_block_is_optimistic = finalized_proto_block
|
||||
.execution_status
|
||||
.is_optimistic_or_invalid();
|
||||
|
||||
self.op_pool
|
||||
.prune_all(&new_snapshot.beacon_state, self.epoch()?);
|
||||
@@ -1260,7 +1264,7 @@ fn observe_head_block_delays<E: EthSpec, S: SlotClock>(
|
||||
let block_time_set_as_head = timestamp_now();
|
||||
let head_block_root = head_block.root;
|
||||
let head_block_slot = head_block.slot;
|
||||
let head_block_is_optimistic = head_block.execution_status.is_optimistic();
|
||||
let head_block_is_optimistic = head_block.execution_status.is_optimistic_or_invalid();
|
||||
|
||||
// Calculate the total delay between the start of the slot and when it was set as head.
|
||||
let block_delay_total = get_slot_delay_ms(block_time_set_as_head, head_block_slot, slot_clock);
|
||||
|
||||
Reference in New Issue
Block a user