Upgrade Iroh native backend foundation

This commit is contained in:
Eric Wendland 2026-05-22 15:28:52 +02:00
commit 9d46dd4d0d
11 changed files with 1588 additions and 712 deletions

View file

@ -1045,10 +1045,7 @@ async fn peer_ping(node: &LocalNode, peer_node: &str) -> Result<ControlResponse,
.connect(node_addr, geth_iroh::ALPN_CONTROL)
.await
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
let alpn = conn
.alpn()
.map(display_alpn)
.unwrap_or_else(|| "unknown".to_owned());
let alpn = display_alpn(conn.alpn());
let (mut send, mut recv) = conn
.open_bi()
.await
@ -2178,14 +2175,16 @@ async fn handle_local_pipe_tcp_stream(
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
remote_send
.finish()
.map_err(|error| NodeError::IrohPeer(error.to_string()))
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
Ok::<(), NodeError>(())
};
let mut remote_recv = remote_recv;
let download = async {
tokio::io::copy(&mut remote_recv, &mut local_write)
.await
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
local_write.shutdown().await.map_err(NodeError::from)
local_write.shutdown().await.map_err(NodeError::from)?;
Ok::<(), NodeError>(())
};
tokio::try_join!(upload, download)?;
Ok(())
@ -2301,14 +2300,16 @@ async fn handle_local_pipe_unix_stream(
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
remote_send
.finish()
.map_err(|error| NodeError::IrohPeer(error.to_string()))
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
Ok::<(), NodeError>(())
};
let mut remote_recv = remote_recv;
let download = async {
tokio::io::copy(&mut remote_recv, &mut local_write)
.await
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
local_write.shutdown().await.map_err(NodeError::from)
local_write.shutdown().await.map_err(NodeError::from)?;
Ok::<(), NodeError>(())
};
tokio::try_join!(upload, download)?;
Ok(())
@ -2511,14 +2512,16 @@ async fn handle_local_ssh_proxy_stream(
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
remote_send
.finish()
.map_err(|error| NodeError::IrohPeer(error.to_string()))
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
Ok::<(), NodeError>(())
};
let mut remote_recv = remote_recv;
let download = async {
tokio::io::copy(&mut remote_recv, &mut local_write)
.await
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
local_write.shutdown().await.map_err(NodeError::from)
local_write.shutdown().await.map_err(NodeError::from)?;
Ok::<(), NodeError>(())
};
tokio::try_join!(upload, download)?;
Ok(())
@ -4437,22 +4440,16 @@ async fn handle_iroh_control_connection(
let conn = incoming
.await
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
let remote_endpoint_id = conn
.remote_node_id()
.map(|node_id| node_id.to_string())
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
let alpn = conn
.alpn()
.map(display_alpn)
.unwrap_or_else(|| "unknown".to_owned());
let remote_endpoint_id = conn.remote_id().to_string();
let alpn = display_alpn(conn.alpn());
let (mut send, mut recv) = conn
.accept_bi()
.await
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
if alpn == display_alpn(geth_iroh::ALPN_SSH_PROXY.to_vec()) {
if alpn == display_alpn(geth_iroh::ALPN_SSH_PROXY) {
return handle_ssh_proxy_wire_connection(node, remote_endpoint_id, send, recv).await;
}
if alpn == display_alpn(geth_iroh::ALPN_PIPE.to_vec()) {
if alpn == display_alpn(geth_iroh::ALPN_PIPE) {
return handle_pipe_wire_connection(node, remote_endpoint_id, send, recv).await;
}
let bytes = recv
@ -5946,10 +5943,10 @@ async fn handle_pipe_unix_wire_connection(
fn iroh_node_addr_from_candidate(
candidate: &EndpointCandidate,
) -> Result<iroh::NodeAddr, NodeError> {
let node_id = candidate
) -> Result<iroh::EndpointAddr, NodeError> {
let endpoint_id = candidate
.endpoint_id
.parse::<iroh::NodeId>()
.parse::<iroh::EndpointId>()
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
let direct_addresses = candidate
.direct_addresses
@ -5959,7 +5956,10 @@ fn iroh_node_addr_from_candidate(
.map_err(|error| NodeError::IrohPeer(error.to_string()))
})
.collect::<Result<Vec<_>, _>>()?;
let mut node_addr = iroh::NodeAddr::new(node_id).with_direct_addresses(direct_addresses);
let mut node_addr = iroh::EndpointAddr::new(endpoint_id);
for address in direct_addresses {
node_addr = node_addr.with_ip_addr(address);
}
if let Some(relay_url) = &candidate.relay_url {
node_addr = node_addr.with_relay_url(
relay_url
@ -6005,8 +6005,8 @@ fn restricted_admin_shell_output(node: &LocalNode, command: &str) -> Result<Stri
}
}
fn display_alpn(alpn: Vec<u8>) -> String {
String::from_utf8_lossy(&alpn).into_owned()
fn display_alpn(alpn: &[u8]) -> String {
String::from_utf8_lossy(alpn).into_owned()
}
pub fn handle_request(
@ -7661,33 +7661,21 @@ pub fn handle_request(
}
fn native_backend_statuses() -> Vec<NativeBackendStatus> {
let blocker = "pinned blocker: current daemon endpoint uses iroh 0.90.0; the Rust-1.85-compatible backend crates resolved from crates.io require iroh 0.95, so they cannot share the daemon-owned endpoint until geth performs a coordinated Iroh endpoint upgrade".to_owned();
vec![
NativeBackendStatus {
module: "cas".to_owned(),
current_backend: "iroh-control-alpn-bootstrap".to_owned(),
target_crate: "iroh-blobs".to_owned(),
target_version: "0.97.0".to_owned(),
status: "blocked".to_owned(),
blocker: blocker.clone(),
},
NativeBackendStatus {
module: "kv".to_owned(),
current_backend: "iroh-control-alpn-bootstrap".to_owned(),
target_crate: "iroh-docs".to_owned(),
target_version: "0.95.0".to_owned(),
status: "blocked".to_owned(),
blocker: blocker.clone(),
},
NativeBackendStatus {
module: "pubsub".to_owned(),
current_backend: "iroh-control-alpn-bootstrap".to_owned(),
target_crate: "iroh-gossip".to_owned(),
target_version: "0.95.0".to_owned(),
status: "blocked".to_owned(),
blocker,
},
]
geth_iroh::native_iroh_libraries()
.into_iter()
.map(|library| NativeBackendStatus {
module: library.module,
current_backend: "shared-iroh-endpoint-ready".to_owned(),
target_crate: library.crate_name,
target_version: library.crate_version,
status: "ready-to-wire".to_owned(),
blocker: format!(
"none; native ALPN {} is compiled against the daemon-owned iroh {} endpoint, but the module still needs its bootstrap control-path implementation replaced",
library.alpn,
geth_iroh::IROH_VERSION
),
})
.collect()
}
fn stored_resource_to_descriptor(stored: StoredResource) -> Result<ResourceDescriptor, NodeError> {