Skip to content

Commit 766a28d

Browse files
committed
chore: implement split api, use exact when fetching blobs
1 parent a2259b9 commit 766a28d

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

crates/blobber/src/blobs/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub enum FetchError {
2626
/// Pylon client URL not set error.
2727
#[error("Pylon client URL not set")]
2828
PylonClientUrlNotSet,
29-
/// Blob count mismatch error - received different number of blobs than requested from the CL.
29+
/// Blob count mismatch from the consensus client.
3030
#[error("Blob count mismatch: expected {expected}, got {actual} from the consensus client")]
3131
BlobCountMismatch {
3232
/// Expected number of blobs.

crates/blobber/src/blobs/fetch.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ where
166166
Ok(blobs) = self.get_blobs_from_explorer(tx_hash) => {
167167
Ok(blobs)
168168
}
169-
Ok(blobs) = self.get_blobs_from_cl(slot, versioned_hashes) => {
169+
Ok(blobs) = self.get_blobs_from_cl_exact(slot, versioned_hashes) => {
170170
Ok(blobs)
171171
}
172172
Ok(blobs) = self.get_blobs_from_pylon(tx_hash) => {
@@ -207,8 +207,13 @@ where
207207
.map_err(Into::into)
208208
}
209209

210-
/// Queries the connected consensus client for the blob transaction
210+
/// Queries the consensus client for blobs at a given slot, filtering by
211+
/// versioned hashes (best-effort).
212+
///
213+
/// This method returns whatever blobs the consensus client provides, even
214+
/// if fewer than requested. Use this when partial blob results are acceptable.
211215
#[instrument(skip_all)]
216+
#[allow(dead_code)]
212217
async fn get_blobs_from_cl(
213218
&self,
214219
slot: usize,
@@ -218,6 +223,36 @@ where
218223
return Err(FetchError::ConsensusClientUrlNotSet);
219224
};
220225

226+
let mut url =
227+
url.join(&format!("/eth/v1/beacon/blobs/{slot}")).map_err(FetchError::UrlParse)?;
228+
229+
let versioned_hashes =
230+
versioned_hashes.iter().map(|hash| hash.to_string()).collect::<Vec<_>>().join(",");
231+
url.query_pairs_mut().append_pair("versioned_hashes", &versioned_hashes);
232+
233+
let response = self.client.get(url).header("accept", "application/json").send().await?;
234+
235+
let response: GetBlobsResponse = response.json().await?;
236+
237+
Ok(Arc::new(response.data).into())
238+
}
239+
240+
/// Queries the consensus client for blobs at a given slot, filtering by
241+
/// versioned hashes (exact match required).
242+
///
243+
/// This method enforces that the consensus client returns exactly the
244+
/// number of blobs requested. If the count doesn't match, returns
245+
/// [`FetchError::BlobCountMismatch`].
246+
#[instrument(skip_all)]
247+
async fn get_blobs_from_cl_exact(
248+
&self,
249+
slot: usize,
250+
versioned_hashes: &[B256],
251+
) -> FetchResult<Blobs> {
252+
let Some(url) = &self.cl_url else {
253+
return Err(FetchError::ConsensusClientUrlNotSet);
254+
};
255+
221256
let mut url =
222257
url.join(&format!("/eth/v1/beacon/blobs/{slot}")).map_err(FetchError::UrlParse)?;
223258

0 commit comments

Comments
 (0)