1- use std:: time:: { Duration , Instant } ;
1+ use std:: {
2+ str:: FromStr ,
3+ time:: { Duration , Instant } ,
4+ } ;
25
3- use alloy:: eips:: eip7594:: CELLS_PER_EXT_BLOB ;
6+ use alloy:: { eips:: eip7594:: CELLS_PER_EXT_BLOB , primitives :: B256 } ;
47use axum:: http:: { HeaderMap , HeaderValue } ;
58use cb_common:: {
69 pbs:: {
7- BlindedBeaconBlock , BlindedBeaconBlockElectra , BlindedBeaconBlockFulu , BlobsBundle ,
8- BuilderApiVersion , ExecutionPayload , ExecutionPayloadElectra , ExecutionPayloadFulu ,
9- HEADER_CONSENSUS_VERSION , HEADER_START_TIME_UNIX_MS , RelayClient , SignedBlindedBeaconBlock ,
10+ BlindedBeaconBlock , BlobsBundle , BuilderApiVersion , ForkName , HEADER_CONSENSUS_VERSION ,
11+ HEADER_START_TIME_UNIX_MS , KzgCommitments , RelayClient , SignedBlindedBeaconBlock ,
1012 SubmitBlindedBlockResponse ,
1113 error:: { PbsError , ValidationError } ,
1214 } ,
@@ -35,14 +37,21 @@ pub async fn submit_block<S: BuilderApiState>(
3537 api_version : & BuilderApiVersion ,
3638) -> eyre:: Result < Option < SubmitBlindedBlockResponse > > {
3739 debug ! ( ?req_headers, "received headers" ) ;
38- let consensus_version =
39- req_headers. get ( HEADER_CONSENSUS_VERSION ) . cloned ( ) . unwrap_or_else ( || {
40+
41+ let fork_name = req_headers
42+ . get ( HEADER_CONSENSUS_VERSION )
43+ . and_then ( |h| {
44+ let str = h. to_str ( ) . ok ( ) ?;
45+ ForkName :: from_str ( str) . ok ( )
46+ } )
47+ . unwrap_or_else ( || {
4048 let slot = signed_blinded_block. slot ( ) . as_u64 ( ) ;
41- let fork = state. config . chain . fork_by_slot ( slot) ;
42- // safe because ForkName is visible ASCII chars
43- HeaderValue :: from_str ( & fork. to_string ( ) ) . unwrap ( )
49+ state. config . chain . fork_by_slot ( slot)
4450 } ) ;
4551
52+ // safe because ForkName is visible ASCII chars
53+ let consensus_version = HeaderValue :: from_str ( & fork_name. to_string ( ) ) . unwrap ( ) ;
54+
4655 // prepare headers
4756 let mut send_headers = HeaderMap :: new ( ) ;
4857 send_headers. insert ( HEADER_START_TIME_UNIX_MS , HeaderValue :: from ( utcnow_ms ( ) ) ) ;
@@ -58,6 +67,7 @@ pub async fn submit_block<S: BuilderApiState>(
5867 send_headers. clone ( ) ,
5968 state. pbs_config ( ) . timeout_get_payload_ms ,
6069 api_version,
70+ fork_name,
6171 ) ) ) ;
6272 }
6373
@@ -76,6 +86,7 @@ async fn submit_block_with_timeout(
7686 headers : HeaderMap ,
7787 timeout_ms : u64 ,
7888 api_version : & BuilderApiVersion ,
89+ fork_name : ForkName ,
7990) -> Result < Option < SubmitBlindedBlockResponse > , PbsError > {
8091 let url = relay. submit_block_url ( * api_version) ?;
8192 let mut remaining_timeout_ms = timeout_ms;
@@ -92,6 +103,7 @@ async fn submit_block_with_timeout(
92103 remaining_timeout_ms,
93104 retry,
94105 api_version,
106+ fork_name,
95107 )
96108 . await
97109 {
@@ -118,6 +130,7 @@ async fn submit_block_with_timeout(
118130
119131// submits blinded signed block and expects the execution payload + blobs bundle
120132// back
133+ #[ allow( clippy:: too_many_arguments) ]
121134async fn send_submit_block (
122135 url : Url ,
123136 signed_blinded_block : & SignedBlindedBeaconBlock ,
@@ -126,6 +139,7 @@ async fn send_submit_block(
126139 timeout_ms : u64 ,
127140 retry : u32 ,
128141 api_version : & BuilderApiVersion ,
142+ fork_name : ForkName ,
129143) -> Result < Option < SubmitBlindedBlockResponse > , PbsError > {
130144 let start_request = Instant :: now ( ) ;
131145 let res = match relay
@@ -194,23 +208,36 @@ async fn send_submit_block(
194208 "received unblinded block"
195209 ) ;
196210
211+ let got_block_hash = block_response. data . execution_payload . block_hash ( ) . 0 ;
212+
197213 // request has different type so cant be deserialized in the wrong version,
198214 // response has a "version" field
199- match ( & signed_blinded_block. message ( ) , & block_response. data . execution_payload ) {
200- (
201- BlindedBeaconBlock :: Electra ( blinded_block) ,
202- ExecutionPayload :: Electra ( execution_payload) ,
203- ) => validate_unblinded_block_electra (
204- blinded_block,
205- execution_payload,
206- & block_response. data . blobs_bundle ,
207- ) ,
215+ match & signed_blinded_block. message ( ) {
216+ BlindedBeaconBlock :: Electra ( blinded_block) => {
217+ let expected_block_hash =
218+ blinded_block. body . execution_payload . execution_payload_header . block_hash . 0 ;
219+ let expected_commitments = & blinded_block. body . blob_kzg_commitments ;
220+
221+ validate_unblinded_block (
222+ expected_block_hash,
223+ got_block_hash,
224+ expected_commitments,
225+ & block_response. data . blobs_bundle ,
226+ fork_name,
227+ )
228+ }
229+
230+ BlindedBeaconBlock :: Fulu ( blinded_block) => {
231+ let expected_block_hash =
232+ blinded_block. body . execution_payload . execution_payload_header . block_hash . 0 ;
233+ let expected_commitments = & blinded_block. body . blob_kzg_commitments ;
208234
209- ( BlindedBeaconBlock :: Fulu ( blinded_block ) , ExecutionPayload :: Fulu ( execution_payload ) ) => {
210- validate_unblinded_block_fulu (
211- blinded_block ,
212- execution_payload ,
235+ validate_unblinded_block (
236+ expected_block_hash ,
237+ got_block_hash ,
238+ expected_commitments ,
213239 & block_response. data . blobs_bundle ,
240+ fork_name,
214241 )
215242 }
216243
@@ -220,23 +247,48 @@ async fn send_submit_block(
220247 Ok ( Some ( block_response) )
221248}
222249
223- fn validate_unblinded_block_electra (
224- signed_blinded_block : & BlindedBeaconBlockElectra ,
225- execution_payload : & ExecutionPayloadElectra ,
250+ fn validate_unblinded_block (
251+ expected_block_hash : B256 ,
252+ got_block_hash : B256 ,
253+ expected_commitments : & KzgCommitments ,
226254 blobs_bundle : & BlobsBundle ,
255+ fork_name : ForkName ,
227256) -> Result < ( ) , PbsError > {
228- let expected_block_hash =
229- signed_blinded_block. body . execution_payload . execution_payload_header . block_hash . 0 ;
230- let got_block_hash = execution_payload. block_hash . 0 ;
257+ match fork_name {
258+ ForkName :: Base |
259+ ForkName :: Altair |
260+ ForkName :: Bellatrix |
261+ ForkName :: Capella |
262+ ForkName :: Deneb |
263+ ForkName :: Gloas => Err ( PbsError :: Validation ( ValidationError :: UnsupportedFork ) ) ,
264+ ForkName :: Electra => validate_unblinded_block_electra (
265+ expected_block_hash,
266+ got_block_hash,
267+ expected_commitments,
268+ blobs_bundle,
269+ ) ,
270+ ForkName :: Fulu => validate_unblinded_block_fulu (
271+ expected_block_hash,
272+ got_block_hash,
273+ expected_commitments,
274+ blobs_bundle,
275+ ) ,
276+ }
277+ }
231278
279+ fn validate_unblinded_block_electra (
280+ expected_block_hash : B256 ,
281+ got_block_hash : B256 ,
282+ expected_commitments : & KzgCommitments ,
283+ blobs_bundle : & BlobsBundle ,
284+ ) -> Result < ( ) , PbsError > {
232285 if expected_block_hash != got_block_hash {
233286 return Err ( PbsError :: Validation ( ValidationError :: BlockHashMismatch {
234287 expected : expected_block_hash,
235288 got : got_block_hash,
236289 } ) ) ;
237290 }
238291
239- let expected_commitments = & signed_blinded_block. body . blob_kzg_commitments ;
240292 if expected_commitments. len ( ) != blobs_bundle. blobs . len ( ) ||
241293 expected_commitments. len ( ) != blobs_bundle. commitments . len ( ) ||
242294 expected_commitments. len ( ) != blobs_bundle. proofs . len ( )
@@ -264,22 +316,18 @@ fn validate_unblinded_block_electra(
264316}
265317
266318fn validate_unblinded_block_fulu (
267- signed_blinded_block : & BlindedBeaconBlockFulu ,
268- execution_payload : & ExecutionPayloadFulu ,
319+ expected_block_hash : B256 ,
320+ got_block_hash : B256 ,
321+ expected_commitments : & KzgCommitments ,
269322 blobs_bundle : & BlobsBundle ,
270323) -> Result < ( ) , PbsError > {
271- let expected_block_hash =
272- signed_blinded_block. body . execution_payload . execution_payload_header . block_hash . 0 ;
273- let got_block_hash = execution_payload. block_hash . 0 ;
274-
275324 if expected_block_hash != got_block_hash {
276325 return Err ( PbsError :: Validation ( ValidationError :: BlockHashMismatch {
277326 expected : expected_block_hash,
278327 got : got_block_hash,
279328 } ) ) ;
280329 }
281330
282- let expected_commitments = & signed_blinded_block. body . blob_kzg_commitments ;
283331 if expected_commitments. len ( ) != blobs_bundle. blobs . len ( ) ||
284332 expected_commitments. len ( ) != blobs_bundle. commitments . len ( ) ||
285333 expected_commitments. len ( ) * CELLS_PER_EXT_BLOB != blobs_bundle. proofs . len ( )
0 commit comments