Add Iroh peer ping
This commit is contained in:
parent
8ab3ef004e
commit
679eeb48a3
15 changed files with 619 additions and 18 deletions
|
|
@ -8,9 +8,11 @@ license.workspace = true
|
|||
[dependencies]
|
||||
hex.workspace = true
|
||||
iroh.workspace = true
|
||||
n0-watcher.workspace = true
|
||||
rand_core.workspace = true
|
||||
serde.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile.workspace = true
|
||||
|
|
|
|||
|
|
@ -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)) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue