anvil/server/
beacon_handler.rs1use crate::eth::{
2 EthApi,
3 beacon::{BeaconError, BeaconResponse},
4};
5use alloy_eips::BlockId;
6use alloy_primitives::B256;
7use alloy_rpc_types_beacon::{
8 header::Header,
9 sidecar::{BlobData, GetBlobsResponse},
10};
11use axum::{
12 Json,
13 extract::{Path, Query, State},
14 response::{IntoResponse, Response},
15};
16use hyper::StatusCode;
17use std::{collections::HashMap, str::FromStr as _};
18
19pub async fn handle_get_blob_sidecars(
23 State(api): State<EthApi>,
24 Path(block_id): Path<String>,
25 Query(params): Query<HashMap<String, String>>,
26) -> Response {
27 let Ok(block_id) = BlockId::from_str(&block_id) else {
29 return BeaconError::invalid_block_id(block_id).into_response();
30 };
31
32 let indices: Vec<u64> = params
35 .get("indices")
36 .map(|s| s.split(',').filter_map(|idx| idx.trim().parse::<u64>().ok()).collect())
37 .unwrap_or_default();
38
39 match api.anvil_get_blob_sidecars_by_block_id(block_id) {
41 Ok(Some(sidecar)) => BeaconResponse::with_flags(
42 sidecar
43 .into_iter()
44 .filter(|blob_item| indices.is_empty() || indices.contains(&blob_item.index))
45 .map(|blob_item| BlobData {
46 index: blob_item.index,
47 blob: blob_item.blob,
48 kzg_commitment: blob_item.kzg_commitment,
49 kzg_proof: blob_item.kzg_proof,
50 signed_block_header: Header::default(), kzg_commitment_inclusion_proof: vec![], })
53 .collect::<Vec<_>>(),
54 false, false, )
57 .into_response(),
58 Ok(None) => BeaconError::block_not_found().into_response(),
59 Err(_) => BeaconError::internal_error().into_response(),
60 }
61}
62
63pub async fn handle_get_blobs(
67 State(api): State<EthApi>,
68 Path(block_id): Path<String>,
69 Query(versioned_hashes): Query<HashMap<String, String>>,
70) -> Response {
71 let Ok(block_id) = BlockId::from_str(&block_id) else {
73 return BeaconError::invalid_block_id(block_id).into_response();
74 };
75
76 let versioned_hashes: Vec<B256> = versioned_hashes
79 .get("versioned_hashes")
80 .map(|s| s.split(',').filter_map(|hash| B256::from_str(hash.trim()).ok()).collect())
81 .unwrap_or_default();
82
83 match api.anvil_get_blobs_by_block_id(block_id, versioned_hashes) {
85 Ok(Some(blobs)) => (
86 StatusCode::OK,
87 Json(GetBlobsResponse { execution_optimistic: false, finalized: false, data: blobs }),
88 )
89 .into_response(),
90 Ok(None) => BeaconError::block_not_found().into_response(),
91 Err(_) => BeaconError::internal_error().into_response(),
92 }
93}