feat: add v5 flashbots relay block validation api for Fusaka (#17179)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Varun Doshi
2025-07-05 09:58:10 +05:30
committed by GitHub
parent 593477c673
commit beb8fac91b
3 changed files with 77 additions and 3 deletions

View File

@@ -3,6 +3,7 @@
use alloy_rpc_types_beacon::relay::{
BuilderBlockValidationRequest, BuilderBlockValidationRequestV2,
BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4,
BuilderBlockValidationRequestV5,
};
use jsonrpsee::proc_macros::rpc;
@@ -37,4 +38,11 @@ pub trait BlockSubmissionValidationApi {
&self,
request: BuilderBlockValidationRequestV4,
) -> jsonrpsee::core::RpcResult<()>;
/// A Request to validate a block submission.
#[method(name = "validateBuilderSubmissionV5")]
async fn validate_builder_submission_v5(
&self,
request: BuilderBlockValidationRequestV5,
) -> jsonrpsee::core::RpcResult<()>;
}

View File

@@ -60,7 +60,7 @@ alloy-rpc-types-trace.workspace = true
alloy-rpc-types-mev.workspace = true
alloy-rpc-types-txpool.workspace = true
alloy-rpc-types-admin.workspace = true
alloy-rpc-types-engine.workspace = true
alloy-rpc-types-engine = { workspace = true, features = ["kzg"] }
alloy-serde.workspace = true
revm = { workspace = true, features = ["optional_block_gas_limit", "optional_eip3607", "optional_no_base_fee"] }
revm-primitives = { workspace = true, features = ["serde"] }

View File

@@ -5,10 +5,11 @@ use alloy_eips::{eip4844::kzg_to_versioned_hash, eip7685::RequestsOrHash};
use alloy_rpc_types_beacon::relay::{
BidTrace, BuilderBlockValidationRequest, BuilderBlockValidationRequestV2,
BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4,
BuilderBlockValidationRequestV5,
};
use alloy_rpc_types_engine::{
BlobsBundleV1, CancunPayloadFields, ExecutionData, ExecutionPayload, ExecutionPayloadSidecar,
PraguePayloadFields,
BlobsBundleV1, BlobsBundleV2, CancunPayloadFields, ExecutionData, ExecutionPayload,
ExecutionPayloadSidecar, PraguePayloadFields,
};
use async_trait::async_trait;
use core::fmt;
@@ -365,6 +366,24 @@ where
Ok(versioned_hashes)
}
/// Validates the given [`BlobsBundleV1`] and returns versioned hashes for blobs.
pub fn validate_blobs_bundle_v2(
&self,
blobs_bundle: BlobsBundleV2,
) -> Result<Vec<B256>, ValidationApiError> {
let versioned_hashes = blobs_bundle
.commitments
.iter()
.map(|c| kzg_to_versioned_hash(c.as_slice()))
.collect::<Vec<_>>();
blobs_bundle
.try_into_sidecar()
.map_err(|_| ValidationApiError::InvalidBlobsBundle)?
.validate(&versioned_hashes, EnvKzgSettings::default().get())?;
Ok(versioned_hashes)
}
/// Core logic for validating the builder submission v3
async fn validate_builder_submission_v3(
@@ -414,6 +433,35 @@ where
)
.await
}
/// Core logic for validating the builder submission v5
async fn validate_builder_submission_v5(
&self,
request: BuilderBlockValidationRequestV5,
) -> Result<(), ValidationApiError> {
let block = self.payload_validator.ensure_well_formed_payload(ExecutionData {
payload: ExecutionPayload::V3(request.request.execution_payload),
sidecar: ExecutionPayloadSidecar::v4(
CancunPayloadFields {
parent_beacon_block_root: request.parent_beacon_block_root,
versioned_hashes: self
.validate_blobs_bundle_v2(request.request.blobs_bundle)?,
},
PraguePayloadFields {
requests: RequestsOrHash::Requests(
request.request.execution_requests.to_requests(),
),
},
),
})?;
self.validate_message_against_block(
block,
request.request.message,
request.registered_gas_limit,
)
.await
}
}
#[async_trait]
@@ -477,6 +525,24 @@ where
rx.await.map_err(|_| internal_rpc_err("Internal blocking task error"))?
}
/// Validates a block submitted to the relay
async fn validate_builder_submission_v5(
&self,
request: BuilderBlockValidationRequestV5,
) -> RpcResult<()> {
let this = self.clone();
let (tx, rx) = oneshot::channel();
self.task_spawner.spawn_blocking(Box::pin(async move {
let result = Self::validate_builder_submission_v5(&this, request)
.await
.map_err(ErrorObject::from);
let _ = tx.send(result);
}));
rx.await.map_err(|_| internal_rpc_err("Internal blocking task error"))?
}
}
pub struct ValidationApiInner<Provider, E: ConfigureEvm> {