Skip to content

Commit f584e3e

Browse files
committed
Add service layer and enhance peer information retrieval in API crate
- Introduced a new `service` module to handle asynchronous operations for fetching peer information and topology. - Updated the `Cargo.toml` to include `serde` as a dependency for serialization. - Modified the routing in `route.rs` to include a new endpoint for retrieving topology and refactored the existing peer retrieval logic. - Added a new struct `PeerInfoWithPeers` to encapsulate peer information along with their connections.
1 parent 5de1e3a commit f584e3e

4 files changed

Lines changed: 70 additions & 16 deletions

File tree

crates/api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2024"
66
[dependencies]
77
axum.workspace = true
88
clap.workspace = true
9+
serde.workspace = true
910
tokio.workspace = true
1011
k8s = { path = "../k8s" }
1112
provider = { path = "../provider" }

crates/api/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod route;
2+
mod service;
23
use clap::Parser;
34
use std::{error::Error, net::SocketAddr, result::Result, time::Duration};
45
use tracing::level_filters::LevelFilter;

crates/api/src/route.rs

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,31 @@ use std::time::Duration;
22

33
use axum::{Json, Router, extract::State, routing::get};
44
use k8s::Client;
5-
use provider::optimism::p2p::P2P;
6-
use rpc_types_optimism::p2p::PeerInfo;
5+
use rpc_types_optimism::p2p::{PeerDump, PeerInfo};
6+
use serde::{Deserialize, Serialize};
7+
8+
use crate::service;
79

810
#[derive(Clone)]
911
pub struct AppState {
1012
pub client: Client,
1113
pub timeout: Duration,
1214
}
1315

14-
pub async fn get_peers(State(state): State<AppState>) -> Json<Vec<PeerInfo>> {
16+
#[derive(Clone, Serialize, Deserialize)]
17+
pub struct PeerInfoWithPeers {
18+
#[serde(flatten)]
19+
pub info: PeerInfo,
20+
#[serde(flatten)]
21+
pub peers: PeerDump,
22+
}
23+
24+
pub async fn list_peers_info(State(state): State<AppState>) -> Json<Vec<PeerInfo>> {
1525
let endpoints = state.client.discover_rpc_endpoints().await.unwrap();
1626

1727
let handles: Vec<_> = endpoints
1828
.into_iter()
19-
.map(|e| {
20-
let timeout = state.timeout;
21-
tokio::spawn(async move {
22-
tokio::time::timeout(timeout, async {
23-
let p = provider::create_provider(&e);
24-
p.info().await
25-
})
26-
.await
27-
.ok()
28-
.and_then(|r| r.ok())
29-
})
30-
})
29+
.map(|e| tokio::spawn(service::info(e, state.timeout)))
3130
.collect();
3231

3332
let mut results = Vec::new();
@@ -40,8 +39,37 @@ pub async fn get_peers(State(state): State<AppState>) -> Json<Vec<PeerInfo>> {
4039
Json(results)
4140
}
4241

42+
pub async fn get_topology(State(state): State<AppState>) -> Json<Vec<PeerInfoWithPeers>> {
43+
let endpoints = state.client.discover_rpc_endpoints().await.unwrap();
44+
let timeout = state.timeout;
45+
46+
let handles: Vec<_> = endpoints
47+
.into_iter()
48+
.map({
49+
move |e| {
50+
let timeout = timeout;
51+
tokio::spawn(async move {
52+
let info = service::info(e.clone(), timeout).await;
53+
let peers = service::peers(e, true, timeout).await;
54+
(info, peers)
55+
})
56+
}
57+
})
58+
.collect();
59+
60+
let mut results = Vec::new();
61+
for handle in handles {
62+
if let Ok((Some(info), Some(peers))) = handle.await {
63+
results.push(PeerInfoWithPeers { info, peers });
64+
}
65+
}
66+
67+
Json(results)
68+
}
69+
4370
pub fn routes() -> Router<AppState> {
4471
Router::new()
4572
.route("/healthz", get(|| async { "OK" }))
46-
.route("/peers", get(get_peers))
73+
.route("/peers", get(list_peers_info))
74+
.route("/topology", get(get_topology))
4775
}

crates/api/src/service.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use std::time::Duration;
2+
3+
use provider::optimism::p2p::P2P;
4+
use rpc_types_optimism::p2p::{PeerDump, PeerInfo};
5+
6+
pub async fn info(url: String, timeout: Duration) -> Option<PeerInfo> {
7+
tokio::time::timeout(timeout, async {
8+
let p = provider::create_provider(&url);
9+
p.info().await
10+
})
11+
.await
12+
.ok()
13+
.and_then(|r| r.ok())
14+
}
15+
16+
pub async fn peers(url: String, connected: bool, timeout: Duration) -> Option<PeerDump> {
17+
tokio::time::timeout(timeout, async {
18+
let p = provider::create_provider(&url);
19+
p.peers(connected).await
20+
})
21+
.await
22+
.ok()
23+
.and_then(|r| r.ok())
24+
}

0 commit comments

Comments
 (0)