diff --git a/app/src/sync_handler.rs b/app/src/sync_handler.rs index b8f42fed..7146dca3 100644 --- a/app/src/sync_handler.rs +++ b/app/src/sync_handler.rs @@ -1,6 +1,6 @@ //! Sync handler functions for processing synced payloads -use alloy_rpc_types_engine::ExecutionPayloadV3; +use alloy_rpc_types_engine::{ExecutionPayloadV3, PayloadStatusEnum}; use bytes::Bytes; use color_eyre::eyre::{self, eyre}; use malachitebft_app_channel::app::types::codec::Codec; @@ -10,7 +10,7 @@ use malachitebft_eth_engine::engine::Engine; use malachitebft_eth_types::codec::proto::ProtobufCodec; use malachitebft_eth_types::{BlockHash, Height, MalakethContext, RetryConfig, Value}; use ssz::{Decode, Encode}; -use tracing::{debug, error, info}; +use tracing::{debug, error, info, warn}; use crate::state::{reconstruct_execution_payload, ValidatedPayloadCache}; use crate::store::Store; @@ -54,14 +54,19 @@ pub async fn validate_payload( ) })?; - if payload_status.status.is_valid() { - Ok(Validity::Valid) - } else { - // INVALID or ACCEPTED - both are treated as invalid - // INVALID: malicious block - // ACCEPTED: Non-canonical payload - should not happen with instant finality - error!(%height, %round, "🔴 Synced block validation failed: {}", payload_status.status); - Ok(Validity::Invalid) + match payload_status.status { + PayloadStatusEnum::Valid => Ok(Validity::Valid), + PayloadStatusEnum::Accepted => { + warn!(%height, %round, "⚠️ Synced block ACCEPTED: {:?}, this shouldn't happen", payload_status.status); + Ok(Validity::Invalid) + } + PayloadStatusEnum::Invalid { validation_error } => { + error!(%height, %round, validation_error = ?validation_error, "🔴 Synced block INVALID"); + Ok(Validity::Invalid) + } + PayloadStatusEnum::Syncing => { + unreachable!("SYNCING status should be handled by notify_new_block_with_retry") + } } } diff --git a/engine/src/engine.rs b/engine/src/engine.rs index 6afef290..2bfae66a 100644 --- a/engine/src/engine.rs +++ b/engine/src/engine.rs @@ -5,7 +5,7 @@ use alloy_rpc_types_engine::{ }; use color_eyre::eyre; use malachitebft_eth_types::{Address, BlockHash, RetryConfig, B256}; -use tracing::{debug, warn}; +use tracing::{debug, error, warn}; use crate::engine_rpc::EngineRPC; use crate::ethereum_rpc::EthereumRPC; @@ -110,11 +110,23 @@ impl Engine { debug!("➡️ payload_status: {:?}", payload_status); - payload_status - .status - .is_valid() - .then(|| payload_status.latest_valid_hash.unwrap()) - .ok_or_else(|| eyre::eyre!("Invalid payload status: {}", payload_status.status)) + match payload_status.status { + PayloadStatusEnum::Valid => Ok(payload_status.latest_valid_hash.unwrap()), + PayloadStatusEnum::Accepted => { + warn!(block_hash = ?head_block_hash, "⚠️ Forkchoice update ACCEPTED, this shouldn't happen"); + Err(eyre::eyre!("Forkchoice update returned ACCEPTED status")) + } + PayloadStatusEnum::Invalid { validation_error } => { + error!(block_hash = ?head_block_hash, validation_error = ?validation_error, "🔴 Forkchoice update INVALID"); + Err(eyre::eyre!( + "Forkchoice update returned INVALID: {:?}", + validation_error + )) + } + PayloadStatusEnum::Syncing => { + unreachable!("SYNCING status should be handled by forkchoice_updated_with_retry") + } + } } pub async fn generate_block( @@ -173,7 +185,22 @@ impl Engine { // See how payload is constructed: https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/validator.md#block-proposal Ok(self.api.get_payload(payload_id).await?) } - status => Err(eyre::eyre!("Invalid payload status: {}", status)), + PayloadStatusEnum::Accepted => { + warn!(block_hash = ?block_hash, "⚠️ Block generation forkchoice update ACCEPTED, this shouldn't happen"); + Err(eyre::eyre!( + "Block generation forkchoice update returned ACCEPTED status" + )) + } + PayloadStatusEnum::Invalid { validation_error } => { + error!(block_hash = ?block_hash, validation_error = ?validation_error, "🔴 Block generation forkchoice update INVALID"); + Err(eyre::eyre!( + "Block generation forkchoice update returned INVALID: {:?}", + validation_error + )) + } + PayloadStatusEnum::Syncing => { + unreachable!("SYNCING status should be handled by forkchoice_updated_with_retry") + } } }