@@ -14,7 +14,7 @@ use cb_common::{
1414 pbs:: {
1515 error:: { PbsError , ValidationError } ,
1616 GetHeaderParams , GetHeaderResponse , RelayClient , VersionedResponse , EMPTY_TX_ROOT_HASH ,
17- HEADER_START_TIME_UNIX_MS ,
17+ HEADER_START_TIME_UNIX_MS , HEADER_TIMEOUT_MS ,
1818 } ,
1919 signature:: verify_signed_message,
2020 types:: { BlsPublicKey , BlsSignature , Chain } ,
@@ -81,6 +81,19 @@ pub async fn get_header<S: BuilderApiState>(
8181 return Ok ( None ) ;
8282 }
8383
84+ // Use the minimum of the time left and the user provided timeout header
85+ let max_timeout_ms = req_headers
86+ . get ( HEADER_TIMEOUT_MS )
87+ . map ( |header| match header. to_str ( ) . ok ( ) . and_then ( |v| v. parse :: < u64 > ( ) . ok ( ) ) {
88+ None | Some ( 0 ) => {
89+ // Header can't be stringified, or parsed, or it's set to 0
90+ warn ! ( ?header, "invalid user-supplied timeout header, using {max_timeout_ms}ms" ) ;
91+ max_timeout_ms
92+ }
93+ Some ( user_timeout) => user_timeout. min ( max_timeout_ms) ,
94+ } )
95+ . unwrap_or ( max_timeout_ms) ;
96+
8497 // prepare headers, except for start time which is set in `send_one_get_header`
8598 let mut send_headers = HeaderMap :: new ( ) ;
8699 send_headers. insert ( USER_AGENT , get_user_agent_with_version ( & req_headers) ?) ;
@@ -301,6 +314,10 @@ async fn send_one_get_header(
301314 let start_request_time = utcnow_ms ( ) ;
302315 req_config. headers . insert ( HEADER_START_TIME_UNIX_MS , HeaderValue :: from ( start_request_time) ) ;
303316
317+ // The timeout header indicating how long a relay has to respond, so they can
318+ // minimize timing games without losing the bid
319+ req_config. headers . insert ( HEADER_TIMEOUT_MS , HeaderValue :: from ( req_config. timeout_ms ) ) ;
320+
304321 let start_request = Instant :: now ( ) ;
305322 let res = match relay
306323 . client
0 commit comments