@@ -8,7 +8,10 @@ use std::{
88 time:: Duration ,
99} ;
1010
11- use alloy:: { primitives:: U256 , rpc:: types:: beacon:: relay:: ValidatorRegistration } ;
11+ use alloy:: {
12+ eips:: eip7594:: CELLS_PER_EXT_BLOB , primitives:: U256 ,
13+ rpc:: types:: beacon:: relay:: ValidatorRegistration ,
14+ } ;
1215use axum:: {
1316 Json , Router ,
1417 extract:: { Path , State } ,
@@ -76,6 +79,10 @@ pub struct MockRelayState {
7679 /// negotiated via `Accept`. Used to exercise PBS tolerance of
7780 /// MIME-parameter suffixes like `application/octet-stream; charset=binary`.
7881 response_content_type_override : Option < String > ,
82+ /// If set, `handle_submit_block_v1` labels its JSON response with this fork
83+ /// in the `version` field instead of the request's fork. Used to drive the
84+ /// fork-mismatch rejection test
85+ submit_block_version_override : Option < ForkName > ,
7986 received_get_header : Arc < AtomicU64 > ,
8087 received_get_status : Arc < AtomicU64 > ,
8188 received_register_validator : Arc < AtomicU64 > ,
@@ -112,6 +119,9 @@ impl MockRelayState {
112119 pub fn response_content_type_override ( & self ) -> Option < & str > {
113120 self . response_content_type_override . as_deref ( )
114121 }
122+ pub fn submit_block_version_override ( & self ) -> Option < ForkName > {
123+ self . submit_block_version_override
124+ }
115125 pub fn set_response_override ( & self , status : StatusCode ) {
116126 * self . response_override . write ( ) . unwrap ( ) = Some ( status) ;
117127 }
@@ -127,6 +137,7 @@ impl MockRelayState {
127137 use_not_found_for_submit_block : false ,
128138 submit_block_ssz_status_override : None ,
129139 response_content_type_override : None ,
140+ submit_block_version_override : None ,
130141 received_get_header : Default :: default ( ) ,
131142 received_get_status : Default :: default ( ) ,
132143 received_register_validator : Default :: default ( ) ,
@@ -174,6 +185,13 @@ impl MockRelayState {
174185 pub fn with_response_content_type ( self , raw_content_type : impl Into < String > ) -> Self {
175186 Self { response_content_type_override : Some ( raw_content_type. into ( ) ) , ..self }
176187 }
188+
189+ /// Make `handle_submit_block_v1` label its JSON response with `fork` in the
190+ /// `version` field, regardless of the request's fork. Used to exercise the
191+ /// PBS fork-mismatch rejection.
192+ pub fn with_submit_block_version ( self , fork : ForkName ) -> Self {
193+ Self { submit_block_version_override : Some ( fork) , ..self }
194+ }
177195}
178196
179197pub fn mock_relay_app_router ( state : Arc < MockRelayState > ) -> Router {
@@ -366,7 +384,17 @@ async fn handle_submit_block_v1(
366384 blobs_bundle. blobs . push ( Default :: default ( ) ) . unwrap ( ) ;
367385 blobs_bundle. commitments =
368386 submit_block. as_electra ( ) . unwrap ( ) . message . body . blob_kzg_commitments . clone ( ) ;
369- blobs_bundle. proofs . push ( KzgProof ( [ 0 ; 48 ] ) ) . unwrap ( ) ;
387+ // Emit a proof layout matching the fork we label the response with, so a
388+ // mismatch-labelled response still passes that fork's blob validation and
389+ // the only thing left to reject it is the fork check itself. Electra uses
390+ // one proof per blob; Fulu uses CELLS_PER_EXT_BLOB per blob.
391+ let proofs_per_blob = match state. submit_block_version_override ( ) {
392+ Some ( ForkName :: Fulu ) => CELLS_PER_EXT_BLOB ,
393+ _ => 1 ,
394+ } ;
395+ for _ in 0 ..( blobs_bundle. blobs . len ( ) * proofs_per_blob) {
396+ blobs_bundle. proofs . push ( KzgProof ( [ 0 ; 48 ] ) ) . unwrap ( ) ;
397+ }
370398
371399 let response =
372400 PayloadAndBlobs { execution_payload : execution_payload. into ( ) , blobs_bundle } ;
@@ -376,7 +404,7 @@ async fn handle_submit_block_v1(
376404 } else {
377405 // Return JSON for everything else; this is fine for the mock
378406 let response = SubmitBlindedBlockResponse {
379- version : ForkName :: Electra ,
407+ version : state . submit_block_version_override ( ) . unwrap_or ( ForkName :: Electra ) ,
380408 metadata : Default :: default ( ) ,
381409 data : response,
382410 } ;
0 commit comments