1- use eth2:: types:: { GenericResponse , PublishBlockRequest , SyncingData } ;
1+ use eth2:: types:: {
2+ BuilderPreferenceEntry , GenericResponse , PublishBlockRequest , SubmittedBuilderPreferences ,
3+ SyncingData ,
4+ } ;
25use eth2:: { BLOB_DATA_INCLUDED_HEADER , BeaconNodeHttpClient , CONSENSUS_VERSION_HEADER , Timeouts } ;
36use mockito:: { Matcher , Mock , Server , ServerGuard } ;
47use regex:: Regex ;
@@ -24,6 +27,7 @@ pub struct MockBeaconNode<E: EthSpec> {
2427 pub received_full_blocks : Arc < Mutex < Vec < PublishBlockRequest < E > > > > ,
2528 pub execution_payload_envelope : Arc < Mutex < Vec < SignedExecutionPayloadEnvelope < E > > > > ,
2629 pub payload_attestation_message : Arc < Mutex < Vec < PayloadAttestationMessage > > > ,
30+ pub received_builder_preferences : Arc < Mutex < Vec < ( ForkName , Vec < BuilderPreferenceEntry > ) > > > ,
2731}
2832
2933impl < E : EthSpec > MockBeaconNode < E > {
@@ -42,6 +46,7 @@ impl<E: EthSpec> MockBeaconNode<E> {
4246 received_full_blocks : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
4347 execution_payload_envelope : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
4448 payload_attestation_message : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
49+ received_builder_preferences : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
4550 }
4651 }
4752
@@ -426,6 +431,92 @@ impl<E: EthSpec> MockBeaconNode<E> {
426431 . create ( )
427432 }
428433
434+ /// Mocks `POST /eth/v1/validator/builder_preferences` (SSZ).
435+ pub fn mock_post_validator_builder_preferences_ssz (
436+ & mut self ,
437+ fork_name : ForkName ,
438+ status : u16 ,
439+ response_body : & str ,
440+ ) -> Mock {
441+ self . mock_post_validator_builder_preferences_ssz_with_hook (
442+ fork_name,
443+ status,
444+ response_body,
445+ || { } ,
446+ )
447+ }
448+
449+ /// Mocks `POST /eth/v1/validator/builder_preferences` (SSZ) and runs `hook` after receipt.
450+ pub fn mock_post_validator_builder_preferences_ssz_with_hook < F > (
451+ & mut self ,
452+ fork_name : ForkName ,
453+ status : u16 ,
454+ response_body : & str ,
455+ hook : F ,
456+ ) -> Mock
457+ where
458+ F : Fn ( ) + Send + Sync + ' static ,
459+ {
460+ let path_pattern = Regex :: new ( r"^/eth/v1/validator/builder_preferences$" ) . unwrap ( ) ;
461+ let received_builder_preferences = Arc :: clone ( & self . received_builder_preferences ) ;
462+ let response_body = response_body. as_bytes ( ) . to_vec ( ) ;
463+
464+ self . server
465+ . mock ( "POST" , Matcher :: Regex ( path_pattern. to_string ( ) ) )
466+ . match_header ( "content-type" , "application/octet-stream" )
467+ . match_header (
468+ CONSENSUS_VERSION_HEADER ,
469+ Matcher :: Exact ( fork_name. to_string ( ) ) ,
470+ )
471+ . with_status ( status as usize )
472+ . with_header ( "content-type" , "application/json" )
473+ . with_body_from_request ( move |request| {
474+ let body = request. body ( ) . expect ( "Failed to get request body" ) ;
475+ let entries = SubmittedBuilderPreferences :: from_ssz_bytes ( body)
476+ . expect ( "Failed to deserialize builder preferences as SSZ" ) ;
477+ received_builder_preferences
478+ . lock ( )
479+ . unwrap ( )
480+ . push ( ( fork_name, entries. to_vec ( ) ) ) ;
481+ hook ( ) ;
482+ response_body. clone ( )
483+ } )
484+ . create ( )
485+ }
486+
487+ /// Mocks `POST /eth/v1/validator/builder_preferences` (JSON).
488+ pub fn mock_post_validator_builder_preferences_json (
489+ & mut self ,
490+ fork_name : ForkName ,
491+ status : u16 ,
492+ response_body : & str ,
493+ ) -> Mock {
494+ let path_pattern = Regex :: new ( r"^/eth/v1/validator/builder_preferences$" ) . unwrap ( ) ;
495+ let received_builder_preferences = Arc :: clone ( & self . received_builder_preferences ) ;
496+ let response_body = response_body. as_bytes ( ) . to_vec ( ) ;
497+
498+ self . server
499+ . mock ( "POST" , Matcher :: Regex ( path_pattern. to_string ( ) ) )
500+ . match_header ( "content-type" , "application/json" )
501+ . match_header (
502+ CONSENSUS_VERSION_HEADER ,
503+ Matcher :: Exact ( fork_name. to_string ( ) ) ,
504+ )
505+ . with_status ( status as usize )
506+ . with_header ( "content-type" , "application/json" )
507+ . with_body_from_request ( move |request| {
508+ let body = request. body ( ) . expect ( "Failed to get request body" ) ;
509+ let entries: SubmittedBuilderPreferences = serde_json:: from_slice ( body)
510+ . expect ( "Failed to deserialize builder preferences as JSON" ) ;
511+ received_builder_preferences
512+ . lock ( )
513+ . unwrap ( )
514+ . push ( ( fork_name, entries. to_vec ( ) ) ) ;
515+ response_body. clone ( )
516+ } )
517+ . create ( )
518+ }
519+
429520 /// Mocks `POST /eth/v1/validator/proposer_preferences`
430521 pub fn mock_post_validator_proposer_preferences_json ( & mut self ) -> Mock {
431522 let path_pattern = Regex :: new ( r"^/eth/v1/validator/proposer_preferences$" ) . unwrap ( ) ;
0 commit comments