1use crate::{EthApi, IpcTask};
4use anvil_server::{ServerConfig, ipc::IpcEndpoint};
5use axum::{Router, routing::get};
6use futures::StreamExt;
7use handler::{HttpEthRpcHandler, PubSubEthRpcHandler};
8use std::{io, net::SocketAddr, pin::pin};
9use tokio::net::TcpListener;
10
11mod beacon_handler;
12pub mod error;
13mod handler;
14
15pub async fn serve(
20 addr: SocketAddr,
21 api: EthApi,
22 config: ServerConfig,
23) -> io::Result<impl Future<Output = io::Result<()>>> {
24 let tcp_listener = TcpListener::bind(addr).await?;
25 Ok(serve_on(tcp_listener, api, config))
26}
27
28pub async fn serve_on(
30 tcp_listener: TcpListener,
31 api: EthApi,
32 config: ServerConfig,
33) -> io::Result<()> {
34 axum::serve(tcp_listener, router(api, config).into_make_service()).await
35}
36
37pub fn router(api: EthApi, config: ServerConfig) -> Router {
40 let http = HttpEthRpcHandler::new(api.clone());
41 let ws = PubSubEthRpcHandler::new(api.clone());
42
43 let rpc_router = anvil_server::http_ws_router(config, http, ws);
45
46 let beacon_router = beacon_router(api);
48
49 rpc_router.merge(beacon_router)
51}
52
53fn beacon_router(api: EthApi) -> Router {
55 Router::new()
56 .route(
57 "/eth/v1/beacon/blob_sidecars/{block_id}",
58 get(beacon_handler::handle_get_blob_sidecars),
59 )
60 .route("/eth/v1/beacon/blobs/{block_id}", get(beacon_handler::handle_get_blobs))
61 .with_state(api)
62}
63
64#[track_caller]
70pub fn spawn_ipc(api: EthApi, path: String) -> IpcTask {
71 try_spawn_ipc(api, path).expect("failed to establish ipc connection")
72}
73
74pub fn try_spawn_ipc(api: EthApi, path: String) -> io::Result<IpcTask> {
76 let handler = PubSubEthRpcHandler::new(api);
77 let ipc = IpcEndpoint::new(handler, path);
78 let incoming = ipc.incoming()?;
79
80 let task = tokio::task::spawn(async move {
81 let mut incoming = pin!(incoming);
82 while let Some(stream) = incoming.next().await {
83 trace!(target: "ipc", "new ipc connection");
84 tokio::task::spawn(stream);
85 }
86 });
87
88 Ok(task)
89}