Integrate execute_payload

This commit is contained in:
Paul Hauner
2021-09-27 19:28:26 +10:00
parent 1c2b59f851
commit 7091adf58c
3 changed files with 53 additions and 27 deletions

View File

@@ -48,8 +48,9 @@ use crate::{
BLOCK_PROCESSING_CACHE_LOCK_TIMEOUT, MAXIMUM_GOSSIP_CLOCK_DISPARITY, BLOCK_PROCESSING_CACHE_LOCK_TIMEOUT, MAXIMUM_GOSSIP_CLOCK_DISPARITY,
VALIDATOR_PUBKEY_CACHE_LOCK_TIMEOUT, VALIDATOR_PUBKEY_CACHE_LOCK_TIMEOUT,
}, },
eth1_chain, metrics, BeaconChain, BeaconChainError, BeaconChainTypes, metrics, BeaconChain, BeaconChainError, BeaconChainTypes,
}; };
use execution_layer::ExecutePayloadResponse;
use fork_choice::{ForkChoice, ForkChoiceStore}; use fork_choice::{ForkChoice, ForkChoiceStore};
use parking_lot::RwLockReadGuard; use parking_lot::RwLockReadGuard;
use proto_array::Block as ProtoBlock; use proto_array::Block as ProtoBlock;
@@ -242,19 +243,25 @@ pub enum ExecutionPayloadError {
/// ## Peer scoring /// ## Peer scoring
/// ///
/// As this is our fault, do not penalize the peer /// As this is our fault, do not penalize the peer
NoEth1Connection, NoExecutionConnection,
/// Error occurred during engine_executePayload /// Error occurred during engine_executePayload
/// ///
/// ## Peer scoring /// ## Peer scoring
/// ///
/// Some issue with our configuration, do not penalize peer /// Some issue with our configuration, do not penalize peer
Eth1VerificationError(eth1_chain::Error), RequestFailed(execution_layer::Error),
/// The execution engine returned INVALID for the payload /// The execution engine returned INVALID for the payload
/// ///
/// ## Peer scoring /// ## Peer scoring
/// ///
/// The block is invalid and the peer is faulty /// The block is invalid and the peer is faulty
RejectedByExecutionEngine, RejectedByExecutionEngine,
/// The execution engine returned SYNCING for the payload
///
/// ## Peer scoring
///
/// It is not known if the block is valid or invalid.
ExecutionEngineIsSyncing,
/// The execution payload timestamp does not match the slot /// The execution payload timestamp does not match the slot
/// ///
/// ## Peer scoring /// ## Peer scoring
@@ -281,6 +288,24 @@ pub enum ExecutionPayloadError {
TransactionDataExceedsSizeLimit, TransactionDataExceedsSizeLimit,
} }
impl From<execution_layer::Error> for ExecutionPayloadError {
fn from(e: execution_layer::Error) -> Self {
ExecutionPayloadError::RequestFailed(e)
}
}
impl<T: EthSpec> From<ExecutionPayloadError> for BlockError<T> {
fn from(e: ExecutionPayloadError) -> Self {
BlockError::ExecutionPayloadError(e)
}
}
impl<T: EthSpec> From<InconsistentFork> for BlockError<T> {
fn from(e: InconsistentFork) -> Self {
BlockError::InconsistentFork(e)
}
}
impl<T: EthSpec> std::fmt::Display for BlockError<T> { impl<T: EthSpec> std::fmt::Display for BlockError<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
@@ -1056,31 +1081,33 @@ impl<'a, T: BeaconChainTypes> FullyVerifiedBlock<'a, T> {
// This is the soonest we can run these checks as they must be called AFTER per_slot_processing // This is the soonest we can run these checks as they must be called AFTER per_slot_processing
if is_execution_enabled(&state, block.message().body()) { if is_execution_enabled(&state, block.message().body()) {
let eth1_chain = chain let execution_layer = chain
.eth1_chain .execution_layer
.as_ref() .as_ref()
.ok_or(BlockError::ExecutionPayloadError( .ok_or(ExecutionPayloadError::NoExecutionConnection)?;
ExecutionPayloadError::NoEth1Connection, let execution_payload =
))?; block
.message()
let payload_valid = eth1_chain .body()
.on_payload(block.message().body().execution_payload().ok_or_else(|| { .execution_payload()
BlockError::InconsistentFork(InconsistentFork { .ok_or_else(|| InconsistentFork {
fork_at_slot: eth2::types::ForkName::Merge, fork_at_slot: eth2::types::ForkName::Merge,
object_fork: block.message().body().fork_name(), object_fork: block.message().body().fork_name(),
})
})?)
.map_err(|e| {
BlockError::ExecutionPayloadError(ExecutionPayloadError::Eth1VerificationError(
e,
))
})?; })?;
if !payload_valid { let payload_status = execution_layer
return Err(BlockError::ExecutionPayloadError( .block_on(|execution_layer| execution_layer.execute_payload(execution_payload))
ExecutionPayloadError::RejectedByExecutionEngine, .map_err(ExecutionPayloadError::from)?;
));
match payload_status {
ExecutePayloadResponse::Valid => Ok(()),
ExecutePayloadResponse::Invalid => {
Err(ExecutionPayloadError::RejectedByExecutionEngine)
} }
ExecutePayloadResponse::Syncing => {
Err(ExecutionPayloadError::ExecutionEngineIsSyncing)
}
}?;
} }
// If the block is sufficiently recent, notify the validator monitor. // If the block is sufficiently recent, notify the validator monitor.

View File

@@ -47,5 +47,4 @@ http_metrics = { path = "../http_metrics" }
slasher = { path = "../../slasher" } slasher = { path = "../../slasher" }
slasher_service = { path = "../../slasher/service" } slasher_service = { path = "../../slasher/service" }
monitoring_api = {path = "../../common/monitoring_api"} monitoring_api = {path = "../../common/monitoring_api"}
sensitive_url = { path = "../../common/sensitive_url" }
execution_layer = { path = "../execution_layer" } execution_layer = { path = "../execution_layer" }

View File

@@ -696,8 +696,8 @@ impl<T: BeaconChainTypes> Worker<T> {
// TODO: check that this is what we're supposed to do when we don't want to // TODO: check that this is what we're supposed to do when we don't want to
// penalize a peer for our configuration issue // penalize a peer for our configuration issue
// in the verification process BUT is this the proper way to handle it? // in the verification process BUT is this the proper way to handle it?
Err(e @BlockError::ExecutionPayloadError(ExecutionPayloadError::Eth1VerificationError(_))) Err(e @BlockError::ExecutionPayloadError(ExecutionPayloadError::RequestFailed(_)))
| Err(e @BlockError::ExecutionPayloadError(ExecutionPayloadError::NoEth1Connection)) => { | Err(e @BlockError::ExecutionPayloadError(ExecutionPayloadError::NoExecutionConnection)) => {
debug!(self.log, "Could not verify block for gossip, ignoring the block"; debug!(self.log, "Could not verify block for gossip, ignoring the block";
"error" => %e); "error" => %e);
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore); self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);