diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index 75d6323d3f..eee17c5c3e 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -1080,7 +1080,7 @@ 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 - if is_execution_enabled(&state, block.message().body()) { + let execute_payload_handle = if is_execution_enabled(&state, block.message().body()) { let execution_layer = chain .execution_layer .as_ref() @@ -1095,11 +1095,11 @@ impl<'a, T: BeaconChainTypes> FullyVerifiedBlock<'a, T> { object_fork: block.message().body().fork_name(), })?; - let (payload_status, payload_handle) = execution_layer + let (execute_payload_status, execute_payload_handle) = execution_layer .block_on(|execution_layer| execution_layer.execute_payload(execution_payload)) .map_err(ExecutionPayloadError::from)?; - match payload_status { + match execute_payload_status { ExecutePayloadResponse::Valid => Ok(()), ExecutePayloadResponse::Invalid => { Err(ExecutionPayloadError::RejectedByExecutionEngine) @@ -1108,7 +1108,11 @@ impl<'a, T: BeaconChainTypes> FullyVerifiedBlock<'a, T> { Err(ExecutionPayloadError::ExecutionEngineIsSyncing) } }?; - } + + Some(execute_payload_handle) + } else { + None + }; // If the block is sufficiently recent, notify the validator monitor. if let Some(slot) = chain.slot_clock.now() { @@ -1208,6 +1212,15 @@ impl<'a, T: BeaconChainTypes> FullyVerifiedBlock<'a, T> { }); } + // If this block required an `executePayload` call to the execution node, inform it that the + // block is indeed valid. + // + // If the handle is dropped without explicitly declaring validity, an invalid message will + // be send to the execution engine. + if let Some(execute_payload_handle) = execute_payload_handle { + execute_payload_handle.publish_consensus_valid(); + } + Ok(Self { block, block_root, diff --git a/beacon_node/execution_layer/src/execute_payload_handle.rs b/beacon_node/execution_layer/src/execute_payload_handle.rs index 2b45318e1f..5bb7c10b5c 100644 --- a/beacon_node/execution_layer/src/execute_payload_handle.rs +++ b/beacon_node/execution_layer/src/execute_payload_handle.rs @@ -5,18 +5,21 @@ use types::Hash256; pub struct ExecutePayloadHandle { pub(crate) block_hash: Hash256, pub(crate) execution_layer: ExecutionLayer, + pub(crate) status: Option, } impl ExecutePayloadHandle { - pub fn publish_consensus_valid(self) { + pub fn publish_consensus_valid(mut self) { self.publish(ConsensusStatus::Valid) } - pub fn publish_consensus_invalid(self) { + pub fn publish_consensus_invalid(mut self) { self.publish(ConsensusStatus::Invalid) } - fn publish(&self, status: ConsensusStatus) { + fn publish(&mut self, status: ConsensusStatus) { + self.status = Some(status); + if let Err(e) = self.execution_layer.block_on(|execution_layer| { execution_layer.consensus_validated(self.block_hash, status) }) { @@ -34,6 +37,8 @@ impl ExecutePayloadHandle { impl Drop for ExecutePayloadHandle { fn drop(&mut self) { - self.publish(ConsensusStatus::Invalid) + if self.status.is_none() { + self.publish(ConsensusStatus::Invalid) + } } } diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 316743e42c..ba4a1d3b66 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -152,6 +152,7 @@ impl ExecutionLayer { let execute_payload_handle = ExecutePayloadHandle { block_hash: execution_payload.block_hash, execution_layer: self.clone(), + status: None, }; Ok((execute_payload_response, execute_payload_handle))