Skip to content

Commit

Permalink
Partially add PayloadNotifier
Browse files Browse the repository at this point in the history
  • Loading branch information
paulhauner committed Jun 28, 2022
1 parent ac35a43 commit 2d0f5b9
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
7 changes: 4 additions & 3 deletions beacon_node/beacon_chain/src/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
//!
//! ```
use crate::execution_payload::{
notify_new_payload, validate_execution_payload_for_gossip, validate_merge_block,
validate_execution_payload_for_gossip, validate_merge_block, PayloadNotifier,
};
use crate::snapshot_cache::PreProcessingSnapshot;
use crate::validator_monitor::HISTORIC_EPOCHS as VALIDATOR_MONITOR_HISTORIC_EPOCHS;
Expand Down Expand Up @@ -1164,12 +1164,14 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
}
}

let block = Arc::new(block);
let block_slot = block.slot();
let state_current_epoch = state.current_epoch();

// Define a future that will verify the execution payload with an execution engine (but
// don't execute it yet).
let inner_chain = chain.clone();
let payload_notifier = PayloadNotifier::new(chain.clone(), block.clone(), &state)?;
let payload_verification_future = async move {
let chain = inner_chain;
// If this block triggers the merge, check to ensure that it references valid execution
Expand All @@ -1196,8 +1198,7 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
//
// It is important that this function is called *after* `per_slot_processing`, since the
// `randao` may change.
let payload_verification_status =
notify_new_payload(&chain, &state, block.message()).await?;
let payload_verification_status = payload_notifier.notify_new_payload().await?;

// If the payload did not validate or invalidate the block, check to see if this block is
// valid for optimistic import.
Expand Down
60 changes: 47 additions & 13 deletions beacon_node/beacon_chain/src/execution_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,52 @@ use state_processing::per_block_processing::{
use std::sync::Arc;
use types::*;

pub struct PayloadNotifier<T: BeaconChainTypes> {
chain: Arc<BeaconChain<T>>,
block: Arc<SignedBeaconBlock<T::EthSpec>>,
payload_verification_status: Option<PayloadVerificationStatus>,
}

impl<T: BeaconChainTypes> PayloadNotifier<T> {
pub fn new(
chain: Arc<BeaconChain<T>>,
block: Arc<SignedBeaconBlock<T::EthSpec>>,
state: &BeaconState<T::EthSpec>,
) -> Result<Self, BlockError<T::EthSpec>> {
let payload_verification_status = if is_execution_enabled(state, block.message().body()) {
// Perform the initial stages of payload verification.
//
// We will duplicate these checks again during `per_block_processing`, however these checks
// are cheap and doing them here ensures we protect the execution engine from junk.
partially_verify_execution_payload(
state,
block.message().execution_payload()?,
&chain.spec,
)
.map_err(BlockError::PerBlockProcessingError)?;
None
} else {
Some(PayloadVerificationStatus::Irrelevant)
};

Ok(Self {
chain,
block,
payload_verification_status,
})
}

pub async fn notify_new_payload(
self,
) -> Result<PayloadVerificationStatus, BlockError<T::EthSpec>> {
if let Some(precomputed_status) = self.payload_verification_status {
Ok(precomputed_status)
} else {
notify_new_payload(&self.chain, self.block.message()).await
}
}
}

/// Verify that `execution_payload` contained by `block` is considered valid by an execution
/// engine.
///
Expand All @@ -32,24 +78,12 @@ use types::*;
/// contains a few extra checks by running `partially_verify_execution_payload` first:
///
/// https://github.com/ethereum/consensus-specs/blob/v1.1.9/specs/bellatrix/beacon-chain.md#notify_new_payload
pub async fn notify_new_payload<'a, T: BeaconChainTypes>(
async fn notify_new_payload<'a, T: BeaconChainTypes>(
chain: &Arc<BeaconChain<T>>,
state: &BeaconState<T::EthSpec>,
block: BeaconBlockRef<'a, T::EthSpec>,
) -> Result<PayloadVerificationStatus, BlockError<T::EthSpec>> {
if !is_execution_enabled(state, block.body()) {
return Ok(PayloadVerificationStatus::Irrelevant);
}

let execution_payload = block.execution_payload()?;

// Perform the initial stages of payload verification.
//
// We will duplicate these checks again during `per_block_processing`, however these checks
// are cheap and doing them here ensures we protect the execution payload from junk.
partially_verify_execution_payload(state, execution_payload, &chain.spec)
.map_err(BlockError::PerBlockProcessingError)?;

let execution_layer = chain
.execution_layer
.as_ref()
Expand Down

0 comments on commit 2d0f5b9

Please sign in to comment.