Add Iroh peer ping

This commit is contained in:
Eric Wendland 2026-05-18 12:09:50 +02:00
commit 679eeb48a3
15 changed files with 619 additions and 18 deletions

View file

@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::net::{SocketAddrV4, SocketAddrV6};
use std::path::{Path, PathBuf};
use std::time::Duration;
pub const ALPN_CONTROL: &[u8] = b"/geth/control/1";
pub const ALPN_KV: &[u8] = b"/geth/kv/1";
@ -203,6 +204,7 @@ impl GethRelayMode {
}
}
#[derive(Clone, Debug)]
pub struct GethIrohEndpoint {
endpoint: iroh::Endpoint,
status: EndpointStatus,
@ -219,11 +221,42 @@ impl GethIrohEndpoint {
self.endpoint.node_id().to_string()
}
#[must_use]
pub fn endpoint(&self) -> iroh::Endpoint {
self.endpoint.clone()
}
pub async fn node_addr_snapshot(&self) -> Result<GethNodeAddr, IrohError> {
use n0_watcher::Watcher;
let mut watcher = self.endpoint.node_addr();
let node_addr = tokio::time::timeout(Duration::from_secs(2), watcher.initialized())
.await
.map_err(|_| IrohError::NodeAddrTimeout)?
.map_err(|error| IrohError::NodeAddrUnavailable(error.to_string()))?;
Ok(GethNodeAddr {
endpoint_id: node_addr.node_id.to_string(),
relay_url: node_addr.relay_url.map(|url| url.to_string()),
direct_addresses: node_addr
.direct_addresses
.into_iter()
.map(|addr| addr.to_string())
.collect(),
})
}
pub async fn shutdown(&self) {
self.endpoint.close().await;
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct GethNodeAddr {
pub endpoint_id: String,
pub relay_url: Option<String>,
pub direct_addresses: Vec<String>,
}
pub async fn start_endpoint(config: &GethIrohConfig) -> Result<GethIrohEndpoint, IrohError> {
let secret_key = load_or_create_secret_key(&config.secret_key_path)?;
let mut builder = iroh::Endpoint::builder()
@ -319,6 +352,10 @@ pub enum IrohError {
InvalidRelayUrl { url: String, message: String },
#[error("failed to bind iroh endpoint: {0}")]
Bind(Box<iroh::endpoint::BindError>),
#[error("timed out waiting for iroh node address")]
NodeAddrTimeout,
#[error("iroh node address watcher is unavailable: {0}")]
NodeAddrUnavailable(String),
}
#[derive(Debug, thiserror::Error)]
@ -437,6 +474,9 @@ mod tests {
assert_eq!(status.endpoint_id, Some(endpoint.node_id()));
assert_eq!(status.relay_mode, "disabled");
assert!(!status.local_discovery);
let node_addr = endpoint.node_addr_snapshot().await.expect("node addr");
assert_eq!(node_addr.endpoint_id, endpoint.node_id());
assert!(!node_addr.direct_addresses.is_empty());
endpoint.shutdown().await;
}
Err(IrohError::Bind(error)) => {