Skip to content

Commit

Permalink
Initial Commit of Retrospective OTB Verification (#3372)
Browse files Browse the repository at this point in the history
## Issue Addressed

* #2983 

## Proposed Changes

Basically followed the [instructions laid out here](#2983 (comment))


Co-authored-by: Paul Hauner <[email protected]>
Co-authored-by: ethDreamer <[email protected]>
  • Loading branch information
3 people committed Jul 30, 2022
1 parent 6c2d8b2 commit 034260b
Show file tree
Hide file tree
Showing 12 changed files with 1,013 additions and 7 deletions.
4 changes: 4 additions & 0 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ const MAX_PER_SLOT_FORK_CHOICE_DISTANCE: u64 = 4;
pub const INVALID_JUSTIFIED_PAYLOAD_SHUTDOWN_REASON: &str =
"Justified block has an invalid execution payload.";

pub const INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON: &str =
"Finalized merge transition block is invalid.";

/// Defines the behaviour when a block/block-root for a skipped slot is requested.
pub enum WhenSlotSkipped {
/// If the slot is a skip slot, return `None`.
Expand Down Expand Up @@ -528,6 +531,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

/// Even more efficient variant of `forwards_iter_block_roots` that will avoid cloning the head
/// state if it isn't required for the requested range of blocks.
/// The range [start_slot, end_slot] is inclusive (ie `start_slot <= end_slot`)
pub fn forwards_iter_block_roots_until(
&self,
start_slot: Slot,
Expand Down
4 changes: 2 additions & 2 deletions beacon_node/beacon_chain/src/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
//! ```
use crate::execution_payload::{
is_optimistic_candidate_block, validate_execution_payload_for_gossip, validate_merge_block,
PayloadNotifier,
AllowOptimisticImport, PayloadNotifier,
};
use crate::snapshot_cache::PreProcessingSnapshot;
use crate::validator_monitor::HISTORIC_EPOCHS as VALIDATOR_MONITOR_HISTORIC_EPOCHS;
Expand Down Expand Up @@ -1199,7 +1199,7 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
// - Doing the check here means we can keep our fork-choice implementation "pure". I.e., no
// calls to remote servers.
if is_valid_merge_transition_block {
validate_merge_block(&chain, block.message()).await?;
validate_merge_block(&chain, block.message(), AllowOptimisticImport::Yes).await?;
};

// The specification declares that this should be run *inside* `per_block_processing`,
Expand Down
17 changes: 15 additions & 2 deletions beacon_node/beacon_chain/src/execution_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! So, this module contains functions that one might expect to find in other crates, but they live
//! here for good reason.
use crate::otb_verification_service::OptimisticTransitionBlock;
use crate::{
BeaconChain, BeaconChainError, BeaconChainTypes, BlockError, BlockProductionError,
ExecutionPayloadError,
Expand All @@ -27,6 +28,12 @@ use types::*;
pub type PreparePayloadResult<Payload> = Result<Payload, BlockProductionError>;
pub type PreparePayloadHandle<Payload> = JoinHandle<Option<PreparePayloadResult<Payload>>>;

#[derive(PartialEq)]
pub enum AllowOptimisticImport {
Yes,
No,
}

/// Used to await the result of executing payload with a remote EE.
pub struct PayloadNotifier<T: BeaconChainTypes> {
pub chain: Arc<BeaconChain<T>>,
Expand Down Expand Up @@ -146,6 +153,7 @@ async fn notify_new_payload<'a, T: BeaconChainTypes>(
pub async fn validate_merge_block<'a, T: BeaconChainTypes>(
chain: &Arc<BeaconChain<T>>,
block: BeaconBlockRef<'a, T::EthSpec>,
allow_optimistic_import: AllowOptimisticImport,
) -> Result<(), BlockError<T::EthSpec>> {
let spec = &chain.spec;
let block_epoch = block.slot().epoch(T::EthSpec::slots_per_epoch());
Expand Down Expand Up @@ -188,13 +196,18 @@ pub async fn validate_merge_block<'a, T: BeaconChainTypes>(
}
.into()),
None => {
if is_optimistic_candidate_block(chain, block.slot(), block.parent_root()).await? {
if allow_optimistic_import == AllowOptimisticImport::Yes
&& is_optimistic_candidate_block(chain, block.slot(), block.parent_root()).await?
{
debug!(
chain.log,
"Optimistically accepting terminal block";
"Optimistically importing merge transition block";
"block_hash" => ?execution_payload.parent_hash(),
"msg" => "the terminal block/parent was unavailable"
);
// Store Optimistic Transition Block in Database for later Verification
OptimisticTransitionBlock::from_block(block)
.persist_in_store::<T, _>(&chain.store)?;
Ok(())
} else {
Err(ExecutionPayloadError::UnverifiedNonOptimisticCandidate.into())
Expand Down
2 changes: 2 additions & 0 deletions beacon_node/beacon_chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mod observed_aggregates;
mod observed_attesters;
mod observed_block_producers;
pub mod observed_operations;
pub mod otb_verification_service;
mod persisted_beacon_chain;
mod persisted_fork_choice;
mod pre_finalization_cache;
Expand All @@ -45,6 +46,7 @@ mod validator_pubkey_cache;
pub use self::beacon_chain::{
AttestationProcessingOutcome, BeaconChain, BeaconChainTypes, BeaconStore, ChainSegmentResult,
CountUnrealized, ForkChoiceError, ProduceBlockVerification, StateSkipConfig, WhenSlotSkipped,
INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON,
INVALID_JUSTIFIED_PAYLOAD_SHUTDOWN_REASON, MAXIMUM_GOSSIP_CLOCK_DISPARITY,
};
pub use self::beacon_snapshot::BeaconSnapshot;
Expand Down
Loading

0 comments on commit 034260b

Please sign in to comment.