11//! /blobs/v{1..4} — blob retrieval from mempool, per execution-apis #793.
22//!
3- //! Response shape is `List[BlobV*Entry ]` where each entry carries an
4- //! `available` flag plus `contents` (zeroed when unavailable) . `/blobs/v2` is
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
55//! all-or-nothing: if any requested blob is missing the handler returns
66//! `204 No Content` instead of emitting unavailable entries. `/blobs/v3`
77//! surfaces missing blobs per entry. `/blobs/v4` requires per-cell data that
8- //! the mempool does not store, so it returns `204 No Content` ("EL cannot
9- //! serve this request at all").
8+ //! the mempool does not store, so it returns `204 No Content`.
109
1110use axum:: extract:: State ;
1211use axum:: http:: StatusCode ;
@@ -18,8 +17,8 @@ use crate::engine_rest::extractors::Ssz;
1817use crate :: engine_rest:: handlers:: capabilities:: BLOBS_MAX_COUNT ;
1918use crate :: engine_rest:: responses:: SszBody ;
2019use crate :: engine_rest:: types:: blobs:: {
21- BlobAndProofV1 , BlobAndProofV2 , BlobV1Entry , BlobV2Entry , BlobsRequest , BlobsRequestV4 ,
22- BlobsV1Response , BlobsV2Response , BlobsV3Response ,
20+ BlobAndProofV1 , BlobAndProofV2 , BlobV1Entry , BlobV2Entry , BlobsRequestV4 , BlobsV1Response ,
21+ BlobsV2Response , BlobsV3Response , VersionedHashList ,
2322} ;
2423use crate :: rpc:: RpcApiContext ;
2524
@@ -33,8 +32,11 @@ fn request_hashes(versioned_hashes: &[[u8; 32]]) -> Result<Vec<H256>, ProblemJso
3332 Ok ( versioned_hashes. iter ( ) . map ( |h| H256 :: from ( * h) ) . collect ( ) )
3433}
3534
36- pub async fn blobs_v1 ( State ( ctx) : State < RpcApiContext > , Ssz ( req) : Ssz < BlobsRequest > ) -> Response {
37- let hashes = match request_hashes ( & req. versioned_hashes ) {
35+ pub async fn blobs_v1 (
36+ State ( ctx) : State < RpcApiContext > ,
37+ Ssz ( req) : Ssz < VersionedHashList > ,
38+ ) -> Response {
39+ let hashes = match request_hashes ( & req) {
3840 Ok ( h) => h,
3941 Err ( p) => return p. into_response ( ) ,
4042 } ;
@@ -66,17 +68,19 @@ pub async fn blobs_v1(State(ctx): State<RpcApiContext>, Ssz(req): Ssz<BlobsReque
6668 entries. push ( entry) ;
6769 }
6870
69- match entries . try_into ( ) {
70- Ok ( entries ) => SszBody ( BlobsV1Response { entries } ) . into_response ( ) ,
71+ match TryInto :: < BlobsV1Response > :: try_into ( entries ) {
72+ Ok ( resp ) => SszBody ( resp ) . into_response ( ) ,
7173 Err ( _) => ProblemJson :: internal ( "blobs response exceeds MAX_BLOBS_REQUEST" ) . into_response ( ) ,
7274 }
7375}
7476
7577/// `/blobs/v2` — all-or-nothing (Osaka). If any requested blob is missing the
76- /// EL MUST return `204 No Content` (spec §`POST /blobs/v2`), mirroring
77- /// `engine_getBlobsV2`'s `null` response.
78- pub async fn blobs_v2 ( State ( ctx) : State < RpcApiContext > , Ssz ( req) : Ssz < BlobsRequest > ) -> Response {
79- let hashes = match request_hashes ( & req. versioned_hashes ) {
78+ /// EL MUST return `204 No Content`, mirroring `engine_getBlobsV2`'s `null`.
79+ pub async fn blobs_v2 (
80+ State ( ctx) : State < RpcApiContext > ,
81+ Ssz ( req) : Ssz < VersionedHashList > ,
82+ ) -> Response {
83+ let hashes = match request_hashes ( & req) {
8084 Ok ( h) => h,
8185 Err ( p) => return p. into_response ( ) ,
8286 } ;
@@ -113,17 +117,20 @@ pub async fn blobs_v2(State(ctx): State<RpcApiContext>, Ssz(req): Ssz<BlobsReque
113117 }
114118 }
115119
116- match entries . try_into ( ) {
117- Ok ( entries ) => SszBody ( BlobsV2Response { entries } ) . into_response ( ) ,
120+ match TryInto :: < BlobsV2Response > :: try_into ( entries ) {
121+ Ok ( resp ) => SszBody ( resp ) . into_response ( ) ,
118122 Err ( _) => ProblemJson :: internal ( "blobs response exceeds MAX_BLOBS_REQUEST" ) . into_response ( ) ,
119123 }
120124}
121125
122126/// `/blobs/v3` — partial responses (Osaka). Missing blobs surface as
123127/// `available == false` entries; `204 No Content` is reserved for "EL cannot
124128/// serve the request at all".
125- pub async fn blobs_v3 ( State ( ctx) : State < RpcApiContext > , Ssz ( req) : Ssz < BlobsRequest > ) -> Response {
126- let hashes = match request_hashes ( & req. versioned_hashes ) {
129+ pub async fn blobs_v3 (
130+ State ( ctx) : State < RpcApiContext > ,
131+ Ssz ( req) : Ssz < VersionedHashList > ,
132+ ) -> Response {
133+ let hashes = match request_hashes ( & req) {
127134 Ok ( h) => h,
128135 Err ( p) => return p. into_response ( ) ,
129136 } ;
@@ -155,8 +162,8 @@ pub async fn blobs_v3(State(ctx): State<RpcApiContext>, Ssz(req): Ssz<BlobsReque
155162 entries. push ( entry) ;
156163 }
157164
158- match entries . try_into ( ) {
159- Ok ( entries ) => SszBody ( BlobsV3Response { entries } ) . into_response ( ) ,
165+ match TryInto :: < BlobsV3Response > :: try_into ( entries ) {
166+ Ok ( resp ) => SszBody ( resp ) . into_response ( ) ,
160167 Err ( _) => ProblemJson :: internal ( "blobs response exceeds MAX_BLOBS_REQUEST" ) . into_response ( ) ,
161168 }
162169}
0 commit comments