diff --git a/Cargo.lock b/Cargo.lock index 0c680d19b7..892fb0cf5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4042,8 +4042,7 @@ dependencies = [ [[package]] name = "quic-rpc" version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e56dc58272a3f9c151b1c3a6df0e3caca083fd843b337e60f706fae2d974b6b" +source = "git+https://github.com/n0-computer/quic-rpc?branch=boxed-futures-public-constructor#95dc615b36e416aab9bb7aa9c4e2df568e31fea4" dependencies = [ "anyhow", "bincode", diff --git a/iroh-cli/Cargo.toml b/iroh-cli/Cargo.toml index 360bf6c76d..a8e0b7a1f3 100644 --- a/iroh-cli/Cargo.toml +++ b/iroh-cli/Cargo.toml @@ -45,7 +45,7 @@ parking_lot = "0.12.1" pkarr = { version = "1.1.5", default-features = false } portable-atomic = "1" postcard = "1.0.8" -quic-rpc = { version = "0.10.2", features = ["flume-transport", "quinn-transport"] } +quic-rpc = { version = "0.10.2", features = ["flume-transport", "quinn-transport"], git = "https://github.com/n0-computer/quic-rpc", branch = "boxed-futures-public-constructor" } rand = "0.8.5" ratatui = "0.26.2" reqwest = { version = "0.12.4", default-features = false, features = ["json", "rustls-tls"] } diff --git a/iroh/Cargo.toml b/iroh/Cargo.toml index 307ec354ba..672859075d 100644 --- a/iroh/Cargo.toml +++ b/iroh/Cargo.toml @@ -37,7 +37,7 @@ iroh-docs = { version = "0.18.0", path = "../iroh-docs" } iroh-gossip = { version = "0.18.0", path = "../iroh-gossip" } parking_lot = "0.12.1" postcard = { version = "1", default-features = false, features = ["alloc", "use-std", "experimental-derive"] } -quic-rpc = { version = "0.10.2", default-features = false, features = ["flume-transport", "quinn-transport"] } +quic-rpc = { version = "0.10.2", default-features = false, features = ["flume-transport", "quinn-transport"], git = "https://github.com/n0-computer/quic-rpc", branch = "boxed-futures-public-constructor" } quinn = { package = "iroh-quinn", version = "0.10" } rand = "0.8" serde = { version = "1", features = ["derive"] } diff --git a/iroh/src/node/builder.rs b/iroh/src/node/builder.rs index d2917eb2ca..25b59bf1d4 100644 --- a/iroh/src/node/builder.rs +++ b/iroh/src/node/builder.rs @@ -21,11 +21,8 @@ use iroh_net::{ relay::RelayMode, Endpoint, }; -use quic_rpc::{ - transport::{ - flume::FlumeServerEndpoint, misc::DummyServerEndpoint, quinn::QuinnServerEndpoint, - }, - ServiceEndpoint, +use quic_rpc::transport::{ + boxed::BoxableServerEndpoint, flume::FlumeServerEndpoint, quinn::QuinnServerEndpoint, }; use serde::{Deserialize, Serialize}; use tokio_util::{sync::CancellationToken, task::LocalPoolHandle}; @@ -81,15 +78,17 @@ pub enum DocsStorage { /// The returned [`Node`] is awaitable to know when it finishes. It can be terminated /// using [`Node::shutdown`]. #[derive(derive_more::Debug)] -pub struct Builder +pub struct Builder where D: Map, - E: ServiceEndpoint, { storage: StorageConfig, bind_port: Option, secret_key: SecretKey, - rpc_endpoint: E, + rpc_endpoint: quic_rpc::transport::boxed::ServerEndpoint< + crate::rpc_protocol::Request, + crate::rpc_protocol::Response, + >, blobs_store: D, keylog: bool, relay_mode: RelayMode, @@ -145,6 +144,40 @@ impl From> for DiscoveryConfig { } } +#[derive(Debug, Default)] +pub struct DummyServerEndpoint; + +impl BoxableServerEndpoint + for DummyServerEndpoint +{ + fn clone_box( + &self, + ) -> Box> + { + Box::new(DummyServerEndpoint) + } + + fn accept_bi_boxed( + &self, + ) -> quic_rpc::transport::boxed::AcceptFuture< + crate::rpc_protocol::Request, + crate::rpc_protocol::Response, + > { + quic_rpc::transport::boxed::AcceptFuture::boxed(futures_lite::future::pending()) + } + + fn local_addr(&self) -> &[quic_rpc::transport::LocalAddr] { + &[] + } +} + +fn mk_external_rpc() -> quic_rpc::transport::boxed::ServerEndpoint< + crate::rpc_protocol::Request, + crate::rpc_protocol::Response, +> { + quic_rpc::transport::boxed::ServerEndpoint::new(DummyServerEndpoint::default()) +} + impl Default for Builder { fn default() -> Self { Self { @@ -155,7 +188,7 @@ impl Default for Builder { keylog: false, relay_mode: RelayMode::Default, dns_resolver: None, - rpc_endpoint: Default::default(), + rpc_endpoint: mk_external_rpc(), gc_policy: GcPolicy::Disabled, docs_storage: DocsStorage::Memory, node_discovery: Default::default(), @@ -181,7 +214,7 @@ impl Builder { keylog: false, relay_mode: RelayMode::Default, dns_resolver: None, - rpc_endpoint: Default::default(), + rpc_endpoint: mk_external_rpc(), gc_policy: GcPolicy::Disabled, docs_storage, node_discovery: Default::default(), @@ -192,16 +225,15 @@ impl Builder { } } -impl Builder +impl Builder where D: BaoStore, - E: ServiceEndpoint, { /// Persist all node data in the provided directory. pub async fn persist( self, root: impl AsRef, - ) -> Result> { + ) -> Result> { let root = root.as_ref(); let blob_dir = IrohPaths::BaoStoreDir.with_root(root); @@ -256,7 +288,13 @@ where } /// Configure rpc endpoint, changing the type of the builder to the new endpoint type. - pub fn rpc_endpoint>(self, value: E2) -> Builder { + pub fn rpc_endpoint( + self, + value: quic_rpc::transport::boxed::ServerEndpoint< + crate::rpc_protocol::Request, + crate::rpc_protocol::Response, + >, + ) -> Builder { // we can't use ..self here because the return type is different Builder { storage: self.storage, @@ -277,8 +315,9 @@ where } /// Configure the default iroh rpc endpoint. - pub async fn enable_rpc(self) -> Result>> { + pub async fn enable_rpc(self) -> Result> { let (ep, actual_rpc_port) = make_rpc_endpoint(&self.secret_key, DEFAULT_RPC_PORT)?; + let ep = quic_rpc::transport::boxed::ServerEndpoint::new(ep); if let StorageConfig::Persistent(ref root) = self.storage { // store rpc endpoint RpcStatus::store(root, actual_rpc_port).await?; @@ -406,7 +445,7 @@ where /// /// Returns an [`ProtocolBuilder`], on which custom protocols can be registered with /// [`ProtocolBuilder::accept`]. To spawn the node, call [`ProtocolBuilder::spawn`]. - pub async fn build(self) -> Result> { + pub async fn build(self) -> Result> { // Clone the blob store to shutdown in case of error. let blobs_store = self.blobs_store.clone(); match self.build_inner().await { @@ -418,7 +457,7 @@ where } } - async fn build_inner(self) -> Result> { + async fn build_inner(self) -> Result> { trace!("building node"); let lp = LocalPoolHandle::new(num_cpus::get()); let endpoint = { @@ -536,17 +575,21 @@ where /// Note that RPC calls performed with client returned from [`Self::client`] will not complete /// until the node is spawned. #[derive(derive_more::Debug)] -pub struct ProtocolBuilder { +pub struct ProtocolBuilder { inner: Arc>, internal_rpc: FlumeServerEndpoint, - external_rpc: E, + #[debug("external rpc")] + external_rpc: quic_rpc::transport::boxed::ServerEndpoint< + crate::rpc_protocol::Request, + crate::rpc_protocol::Response, + >, protocols: ProtocolMap, #[debug("callback")] gc_done_callback: Option>, gc_policy: GcPolicy, } -impl> ProtocolBuilder { +impl ProtocolBuilder { /// Registers a protocol handler for incoming connections. /// /// Use this to register custom protocols onto the iroh node. Whenever a new connection for diff --git a/iroh/tests/provide.rs b/iroh/tests/provide.rs index 7b9abf9648..7e8bb6b367 100644 --- a/iroh/tests/provide.rs +++ b/iroh/tests/provide.rs @@ -11,7 +11,6 @@ use futures_lite::FutureExt; use iroh::node::{Builder, DocsStorage}; use iroh_base::node_addr::AddrInfoOptions; use iroh_net::{defaults::default_relay_map, key::SecretKey, NodeAddr, NodeId}; -use quic_rpc::transport::misc::DummyServerEndpoint; use rand::RngCore; use bao_tree::{blake3, ChunkNum, ChunkRanges}; @@ -39,7 +38,7 @@ async fn dial(secret_key: SecretKey, peer: NodeAddr) -> anyhow::Result(db: D) -> Builder { +fn test_node(db: D) -> Builder { iroh::node::Builder::with_db_and_store(db, DocsStorage::Memory, iroh::node::StorageConfig::Mem) .bind_port(0) } diff --git a/iroh/tests/sync.rs b/iroh/tests/sync.rs index b2ff42fedd..1727a468e3 100644 --- a/iroh/tests/sync.rs +++ b/iroh/tests/sync.rs @@ -18,7 +18,6 @@ use iroh::{ net::key::{PublicKey, SecretKey}, node::{Builder, Node}, }; -use quic_rpc::transport::misc::DummyServerEndpoint; use rand::{CryptoRng, Rng, SeedableRng}; use tracing::{debug, error_span, info, Instrument}; use tracing_subscriber::{prelude::*, EnvFilter}; @@ -32,7 +31,7 @@ use iroh_net::relay::RelayMode; const TIMEOUT: Duration = Duration::from_secs(60); -fn test_node(secret_key: SecretKey) -> Builder { +fn test_node(secret_key: SecretKey) -> Builder { Node::memory() .secret_key(secret_key) .relay_mode(RelayMode::Disabled)