11//! /blobs/v{1..4} — blob retrieval from mempool, per execution-apis #793.
22//!
3- //! Requests are a bare `List[VersionedHash]` (v1/v2/v3) or a `BlobsRequestV4`
4- //! container (v4). Responses are a bare `List[BlobV*Entry]`. `/blobs/v2` is
3+ //! Requests are single-field SSZ containers wrapping a `List[VersionedHash]`
4+ //! (`BlobsV1Request`/`BlobsV2Request`) or the `BlobsRequestV4` container (v4) —
5+ //! per execution-apis #793, NOT bare top-level lists. Responses are likewise
6+ //! single-field containers (`BlobsV*Response { entries: List[BlobV*Entry] }`).
7+ //! `/blobs/v2` is
58//! all-or-nothing: if any requested blob is missing the handler returns
69//! `204 No Content` instead of emitting unavailable entries. `/blobs/v3`
710//! surfaces missing blobs per entry. `/blobs/v4` requires per-cell data that
@@ -17,8 +20,8 @@ use crate::engine_rest::extractors::Ssz;
1720use crate :: engine_rest:: handlers:: capabilities:: BLOBS_MAX_COUNT ;
1821use crate :: engine_rest:: responses:: SszBody ;
1922use crate :: engine_rest:: types:: blobs:: {
20- BlobAndProofV1 , BlobAndProofV2 , BlobV1Entry , BlobV2Entry , BlobsRequestV4 , BlobsV1Response ,
21- BlobsV2Response , BlobsV3Response , VersionedHashList ,
23+ BlobAndProofV1 , BlobAndProofV2 , BlobV1Entry , BlobV2Entry , BlobsRequestV4 , BlobsV1Request ,
24+ BlobsV1Response , BlobsV2Request , BlobsV2Response , BlobsV3Response ,
2225} ;
2326use crate :: rpc:: RpcApiContext ;
2427
@@ -32,10 +35,7 @@ fn request_hashes(versioned_hashes: &[[u8; 32]]) -> Result<Vec<H256>, ProblemJso
3235 Ok ( versioned_hashes. iter ( ) . map ( |h| H256 :: from ( * h) ) . collect ( ) )
3336}
3437
35- pub async fn blobs_v1 (
36- State ( ctx) : State < RpcApiContext > ,
37- Ssz ( req) : Ssz < VersionedHashList > ,
38- ) -> Response {
38+ pub async fn blobs_v1 ( State ( ctx) : State < RpcApiContext > , Ssz ( req) : Ssz < BlobsV1Request > ) -> Response {
3939 // Osaka gate (mirror JSON-RPC getBlobsV1, engine/blobs.rs): /blobs/v1 serves
4040 // whole-blob proofs and is only valid pre-Osaka. After Osaka a blob carries
4141 // cell proofs, so the `proofs[0]` below would be a cell proof rather than a
@@ -60,7 +60,7 @@ pub async fn blobs_v1(
6060 Err ( e) => return ProblemJson :: internal ( & format ! ( "storage: {e}" ) ) . into_response ( ) ,
6161 }
6262
63- let hashes = match request_hashes ( & req) {
63+ let hashes = match request_hashes ( & req. versioned_hashes ) {
6464 Ok ( h) => h,
6565 Err ( p) => return p. into_response ( ) ,
6666 } ;
@@ -92,19 +92,16 @@ pub async fn blobs_v1(
9292 entries. push ( entry) ;
9393 }
9494
95- match TryInto :: < BlobsV1Response > :: try_into ( entries ) {
96- Ok ( resp ) => SszBody ( resp ) . into_response ( ) ,
95+ match entries . try_into ( ) {
96+ Ok ( entries ) => SszBody ( BlobsV1Response { entries } ) . into_response ( ) ,
9797 Err ( _) => ProblemJson :: internal ( "blobs response exceeds MAX_BLOBS_REQUEST" ) . into_response ( ) ,
9898 }
9999}
100100
101101/// `/blobs/v2` — all-or-nothing (Osaka). If any requested blob is missing the
102102/// EL MUST return `204 No Content`, mirroring `engine_getBlobsV2`'s `null`.
103- pub async fn blobs_v2 (
104- State ( ctx) : State < RpcApiContext > ,
105- Ssz ( req) : Ssz < VersionedHashList > ,
106- ) -> Response {
107- let hashes = match request_hashes ( & req) {
103+ pub async fn blobs_v2 ( State ( ctx) : State < RpcApiContext > , Ssz ( req) : Ssz < BlobsV2Request > ) -> Response {
104+ let hashes = match request_hashes ( & req. versioned_hashes ) {
108105 Ok ( h) => h,
109106 Err ( p) => return p. into_response ( ) ,
110107 } ;
@@ -141,20 +138,17 @@ pub async fn blobs_v2(
141138 }
142139 }
143140
144- match TryInto :: < BlobsV2Response > :: try_into ( entries ) {
145- Ok ( resp ) => SszBody ( resp ) . into_response ( ) ,
141+ match entries . try_into ( ) {
142+ Ok ( entries ) => SszBody ( BlobsV2Response { entries } ) . into_response ( ) ,
146143 Err ( _) => ProblemJson :: internal ( "blobs response exceeds MAX_BLOBS_REQUEST" ) . into_response ( ) ,
147144 }
148145}
149146
150147/// `/blobs/v3` — partial responses (Osaka). Missing blobs surface as
151148/// `available == false` entries; `204 No Content` is reserved for "EL cannot
152149/// serve the request at all".
153- pub async fn blobs_v3 (
154- State ( ctx) : State < RpcApiContext > ,
155- Ssz ( req) : Ssz < VersionedHashList > ,
156- ) -> Response {
157- let hashes = match request_hashes ( & req) {
150+ pub async fn blobs_v3 ( State ( ctx) : State < RpcApiContext > , Ssz ( req) : Ssz < BlobsV2Request > ) -> Response {
151+ let hashes = match request_hashes ( & req. versioned_hashes ) {
158152 Ok ( h) => h,
159153 Err ( p) => return p. into_response ( ) ,
160154 } ;
@@ -186,8 +180,8 @@ pub async fn blobs_v3(
186180 entries. push ( entry) ;
187181 }
188182
189- match TryInto :: < BlobsV3Response > :: try_into ( entries ) {
190- Ok ( resp ) => SszBody ( resp ) . into_response ( ) ,
183+ match entries . try_into ( ) {
184+ Ok ( entries ) => SszBody ( BlobsV3Response { entries } ) . into_response ( ) ,
191185 Err ( _) => ProblemJson :: internal ( "blobs response exceeds MAX_BLOBS_REQUEST" ) . into_response ( ) ,
192186 }
193187}
0 commit comments