From 3467da15488f27dd07573c5b2cfefa2c5970abfd Mon Sep 17 00:00:00 2001 From: Kasey Date: Tue, 3 Jan 2023 16:17:26 -0500 Subject: [PATCH 1/8] feat(rpc, api): add gossipsub methods to Api This commit represents the state of https://github.com/n0-computer/iroh/pull/669 before the repo changes. --- examples/embed/src/main.rs | 2 +- iroh-api/src/api.rs | 43 ++++- iroh-api/src/fs.rs | 1 + iroh-api/src/lib.rs | 6 +- iroh-api/src/p2p.rs | 109 +++++++++-- iroh-one/src/main.rs | 2 +- iroh-p2p/src/lib.rs | 1 + iroh-p2p/src/node.rs | 77 ++++---- iroh-p2p/src/rpc.rs | 88 ++++++--- iroh-resolver/src/lib.rs | 3 + iroh-rpc-client/src/lib.rs | 1 + iroh-rpc-client/src/network.rs | 23 ++- iroh-rpc-types/Cargo.toml | 2 +- iroh-rpc-types/src/gossipsub_event.rs | 55 ++++++ iroh-rpc-types/src/lib.rs | 2 + iroh-rpc-types/src/p2p.rs | 13 +- iroh-share/Cargo.toml | 2 + iroh-share/src/data.rs | 52 ++++++ iroh-share/src/iroh.rs | 19 ++ iroh-share/src/lib.rs | 57 +++++- iroh-share/src/main.rs | 252 ++++++++++++++++++-------- iroh-share/src/p2p_node.rs | 225 ----------------------- iroh-share/src/receiver.rs | 252 -------------------------- iroh-share/src/sender.rs | 189 ++++++------------- iroh-unixfs/src/content_loader.rs | 92 +++++++++- iroh/src/p2p.rs | 21 ++- 26 files changed, 778 insertions(+), 811 deletions(-) create mode 100644 iroh-rpc-types/src/gossipsub_event.rs create mode 100644 iroh-share/src/data.rs create mode 100644 iroh-share/src/iroh.rs delete mode 100644 iroh-share/src/p2p_node.rs diff --git a/examples/embed/src/main.rs b/examples/embed/src/main.rs index e00dc5d84..7fba0af91 100644 --- a/examples/embed/src/main.rs +++ b/examples/embed/src/main.rs @@ -17,7 +17,7 @@ async fn main() -> Result<()> { "/ip4/0.0.0.0/tcp/0".parse().unwrap(), "/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap(), ]; - let p2p = P2pService::new(p2p_config, dir, store.addr()).await?; + let (p2p,_network_events) = P2pService::new(p2p_config, dir, store.addr()).await?; // Note by default this is configured with an indexer, but not with http resolvers. let iroh = IrohBuilder::new().store(store).p2p(p2p).build().await?; diff --git a/iroh-api/src/api.rs b/iroh-api/src/api.rs index 947dd786c..40d0c2ad0 100644 --- a/iroh-api/src/api.rs +++ b/iroh-api/src/api.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::fmt; use std::path::{Path, PathBuf}; @@ -9,17 +9,17 @@ use anyhow::{ensure, Context, Result}; use cid::Cid; use futures::stream::BoxStream; use futures::{StreamExt, TryStreamExt}; -use iroh_resolver::resolver::Resolver; -use iroh_rpc_client::{Client, ClientStatus}; -use iroh_unixfs::{ - builder::Entry as UnixfsEntry, - content_loader::{FullLoader, FullLoaderConfig}, +use iroh_resolver::{ + resolver::Resolver, ContentLoader, FullLoader, FullLoaderConfig, LoaderFromProviders, }; +use iroh_rpc_client::{Client, ClientStatus}; +use iroh_unixfs::builder::Entry as UnixfsEntry; use iroh_util::{iroh_config_path, make_config}; use relative_path::RelativePathBuf; use tokio::io::{AsyncRead, AsyncReadExt}; use crate::store::add_blocks_to_store; +use crate::PeerId; /// API to interact with an iroh system. /// @@ -128,7 +128,36 @@ impl Api { ); tracing::debug!("get {:?}", ipfs_path); - let resolver = self.resolver.clone(); + self.get_with_resolver(ipfs_path, self.resolver.clone()) + } + + pub fn get_from( + &self, + ipfs_path: &IpfsPath, + peers: HashSet, + ) -> Result>> { + ensure!( + ipfs_path.cid().is_some(), + "IPFS path does not refer to a CID" + ); + + tracing::debug!("get {:?} from peers {:#?}", ipfs_path, peers); + // TODO(ramfox): path of least resistance to hack this together as POC. Might be the way + // was want to go, or, if it's bad news bears to have (potentially) more than one resolver, + // we can bake in passing down providers through a LoadConfig (or some similar name) that allows you to tune + // your actions down in the loader + let loader = LoaderFromProviders::new(self.client.clone(), peers); + // TODO(ramfox): is it okay to create these ad-hoc. If so, we probably shouldn't be storing + // one in general + let resolver = Resolver::new(loader); + self.get_with_resolver(ipfs_path, resolver) + } + + fn get_with_resolver( + &self, + ipfs_path: &IpfsPath, + resolver: Resolver, + ) -> Result>> { let results = resolver.resolve_recursive_with_paths(ipfs_path.clone()); let sub_path = ipfs_path.to_relative_string(); diff --git a/iroh-api/src/fs.rs b/iroh-api/src/fs.rs index 0732b95b8..d8fdee2a3 100644 --- a/iroh-api/src/fs.rs +++ b/iroh-api/src/fs.rs @@ -32,6 +32,7 @@ async fn save_get_stream( while let Some(block) = blocks.next().await { let (path, out) = block?; let full_path = path.to_path(root_path); + println!("full path: {:?}", full_path); match out { OutType::Dir => { tokio::fs::create_dir_all(full_path).await?; diff --git a/iroh-api/src/lib.rs b/iroh-api/src/lib.rs index 370bd21c9..14ef34f2f 100644 --- a/iroh-api/src/lib.rs +++ b/iroh-api/src/lib.rs @@ -3,11 +3,13 @@ pub use crate::api::OutType; pub use crate::config::Config; pub use crate::error::ApiError; pub use crate::p2p::P2p as P2pApi; -pub use crate::p2p::PeerIdOrAddr; +pub use crate::p2p::{peer_id_from_multiaddr, PeerIdOrAddr}; pub use bytes::Bytes; pub use cid::Cid; pub use iroh_resolver::resolver::Path as IpfsPath; -pub use iroh_rpc_client::{ClientStatus, Lookup, ServiceStatus, ServiceType, StatusType}; +pub use iroh_rpc_client::{ + ClientStatus, GossipsubEvent, Lookup, ServiceStatus, ServiceType, StatusType, +}; pub use iroh_unixfs::builder::{ Config as UnixfsConfig, DirectoryBuilder, Entry as UnixfsEntry, FileBuilder, SymlinkBuilder, }; diff --git a/iroh-api/src/p2p.rs b/iroh-api/src/p2p.rs index 82bb77ca8..8c5f918c8 100644 --- a/iroh-api/src/p2p.rs +++ b/iroh-api/src/p2p.rs @@ -1,10 +1,18 @@ -use crate::error::map_service_error; -use anyhow::Result; -use iroh_rpc_client::{Lookup, P2pClient}; -use libp2p::{multiaddr::Protocol, Multiaddr, PeerId}; use std::collections::HashMap; -#[derive(Debug)] +use anyhow::Result; +use bytes::Bytes; +use futures::stream::Stream; +use iroh_rpc_client::{GossipsubEvent, Lookup, P2pClient}; +use libp2p::{ + gossipsub::{MessageId, TopicHash}, + multiaddr::Protocol, + Multiaddr, PeerId, +}; + +use crate::error::map_service_error; + +#[derive(Debug, Clone)] pub struct P2p { client: P2pClient, } @@ -21,7 +29,27 @@ impl P2p { } pub async fn lookup_local(&self) -> Result { - self.client.lookup_local().await + self.client + .lookup_local() + .await + .map_err(|e| map_service_error("p2p", e)) + } + + /// The [`PeerId`] for this Iroh p2p nod + pub async fn peer_id(&self) -> Result { + self.client + .local_peer_id() + .await + .map_err(|e| map_service_error("p2p", e)) + } + + /// The list of [`Multiaddr`] that the Iroh p2p node is listening on + pub async fn addrs(&self) -> Result> { + self.client + .get_listening_addrs() + .await + .map(|(_, addrs)| addrs) + .map_err(|e| map_service_error("p2p", e)) } pub async fn lookup(&self, addr: &PeerIdOrAddr) -> Result { @@ -35,15 +63,15 @@ impl P2p { .map_err(|e| map_service_error("p2p", e)) } - pub async fn connect(&self, addr: &PeerIdOrAddr) -> Result<()> { - match addr { - PeerIdOrAddr::PeerId(peer_id) => self.client.connect(*peer_id, vec![]).await, - PeerIdOrAddr::Multiaddr(addr) => { - let peer_id = peer_id_from_multiaddr(addr)?; - self.client.connect(peer_id, vec![addr.clone()]).await - } - } - .map_err(|e| map_service_error("p2p", e)) + /// Connect to a peer using a [`PeerId`] and `Vec` of [`Multiaddr`] + /// + /// If there is an empty `Vec` of `Multiaddr`s, Iroh will attempt to find + /// the peer on the DHT using the `PeerId`. + pub async fn connect(&self, peer_id: PeerId, addrs: Vec) -> Result<()> { + self.client + .connect(peer_id, addrs) + .await + .map_err(|e| map_service_error("p2p", e)) } pub async fn peers(&self) -> Result>> { @@ -52,9 +80,58 @@ impl P2p { .await .map_err(|e| map_service_error("p2p", e)) } + + /// Subscribe to a pub/sub Topic + /// + /// We use Gossipsub as the pub/sub protocol. This method will subscribe you + /// to a Gossipsub topic and return a stream of [`GossipsubEvent`]s relevant + /// to that topic. + /// + /// Learn more about the Gossipsub protocol in the `libp2p-gossipsub` + /// [documentation](https://docs.rs/libp2p-gossipsub/latest/libp2p_gossipsub/). + pub async fn subscribe( + &self, + topic: String, + ) -> Result>> { + let topic = TopicHash::from_raw(topic); + self.client + .gossipsub_subscribe(topic) + .await + .map_err(|e| map_service_error("p2p", e)) + } + + /// Publish a message on a pub/sub Topic. + /// + /// We use Gossipsub as the pub/sub protocol. This method allows you to publish + /// a message on a given topic to anyone in your network that is subscribed to + /// that topic. + /// + /// Read the [`P2p::subscribe`] documentation for how to subscribe and receive + /// Gossipsub messages. + pub async fn publish(&self, topic: String, data: Bytes) -> Result { + let topic = TopicHash::from_raw(topic); + self.client + .gossipsub_publish(topic, data) + .await + .map_err(|e| map_service_error("p2p", e)) + } + + /// Explicitly add a peer to our pub/sub network. + /// + /// We use Gossipsub as our pub/sub protocol. + /// + /// We will attempt to stay connected and forward all relevant Gossipsub messages + /// to this peer. Read the [`P2p::subscribe`] and [`P2p::publish`] documentation + /// for how to subscribe, read, and publish messages. + pub async fn add_pubsub_peer(&self, peer_id: PeerId) -> Result<()> { + self.client + .gossipsub_add_explicit_peer(peer_id) + .await + .map_err(|e| map_service_error("p2p", e)) + } } -fn peer_id_from_multiaddr(addr: &Multiaddr) -> Result { +pub fn peer_id_from_multiaddr(addr: &Multiaddr) -> Result { match addr.iter().find(|p| matches!(*p, Protocol::P2p(_))) { Some(Protocol::P2p(peer_id)) => { PeerId::from_multihash(peer_id).map_err(|m| anyhow::anyhow!("Multiaddress contains invalid p2p multihash {:?}. Cannot derive a PeerId from this address.", m )) diff --git a/iroh-one/src/main.rs b/iroh-one/src/main.rs index 9f2e90c7f..c17db4784 100644 --- a/iroh-one/src/main.rs +++ b/iroh-one/src/main.rs @@ -46,7 +46,7 @@ async fn main() -> Result<()> { } } - let (store_rpc, p2p_rpc) = { + let (store_rpc, (_network_events, p2p_rpc)) = { let store_recv = Addr::new_mem(); let store_sender = store_recv.clone(); let p2p_recv = Addr::new_mem(); diff --git a/iroh-p2p/src/lib.rs b/iroh-p2p/src/lib.rs index 1cd7664cd..dbac614c9 100644 --- a/iroh-p2p/src/lib.rs +++ b/iroh-p2p/src/lib.rs @@ -11,5 +11,6 @@ mod swarm; pub use self::config::*; pub use self::keys::{DiskStorage, Keychain, MemoryStorage}; pub use self::node::*; +pub use iroh_rpc_types::{GossipsubEvent, GossipsubEventStream}; pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/iroh-p2p/src/node.rs b/iroh-p2p/src/node.rs index 7b9b128d0..bb5bc9cfe 100644 --- a/iroh-p2p/src/node.rs +++ b/iroh-p2p/src/node.rs @@ -10,7 +10,6 @@ use iroh_metrics::{core::MRecorder, inc, libp2p_metrics, p2p::P2PMetrics}; use iroh_rpc_client::Client as RpcClient; use iroh_rpc_types::p2p::P2pAddr; use libp2p::core::Multiaddr; -use libp2p::gossipsub::{GossipsubMessage, MessageId, TopicHash}; pub use libp2p::gossipsub::{IdentTopic, Topic}; use libp2p::identify::{Event as IdentifyEvent, Info as IdentifyInfo}; use libp2p::identity::Keypair; @@ -26,6 +25,7 @@ use libp2p::ping::Result as PingResult; use libp2p::swarm::dial_opts::{DialOpts, PeerCondition}; use libp2p::swarm::{ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, SwarmEvent}; use libp2p::{PeerId, Swarm}; +use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::oneshot::{self, Sender as OneShotSender}; use tokio::task::JoinHandle; @@ -38,6 +38,7 @@ use crate::keys::{Keychain, Storage}; use crate::providers::Providers; use crate::rpc::{P2p, ProviderRequestKey}; use crate::swarm::build_swarm; +use crate::GossipsubEvent; use crate::{ behaviour::{Event, NodeBehaviour}, rpc::{self, RpcMessage}, @@ -45,7 +46,7 @@ use crate::{ }; #[allow(clippy::large_enum_variant)] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum NetworkEvent { PeerConnected(PeerId), PeerDisconnected(PeerId), @@ -53,23 +54,6 @@ pub enum NetworkEvent { CancelLookupQuery(PeerId), } -#[derive(Debug, Clone)] -pub enum GossipsubEvent { - Subscribed { - peer_id: PeerId, - topic: TopicHash, - }, - Unsubscribed { - peer_id: PeerId, - topic: TopicHash, - }, - Message { - from: PeerId, - id: MessageId, - message: GossipsubMessage, - }, -} - pub struct Node { swarm: Swarm, net_receiver_in: Receiver, @@ -706,10 +690,12 @@ impl Node { message, } = e { + let topic = message.topic.clone(); self.emit_network_event(NetworkEvent::Gossipsub(GossipsubEvent::Message { from: propagation_source, id: message_id, message, + topic, })); } else if let libp2p::gossipsub::GossipsubEvent::Subscribed { peer_id, topic } = e { self.emit_network_event(NetworkEvent::Gossipsub(GossipsubEvent::Subscribed { @@ -978,7 +964,11 @@ impl Node { .map_err(|_| anyhow!("sender dropped"))?; } rpc::GossipsubMessage::Subscribe(response_channel, topic_hash) => { - let res = gossipsub.subscribe(&IdentTopic::new(topic_hash.into_string())); + let t = IdentTopic::new(topic_hash.into_string()); + let res = gossipsub + .subscribe(&t) + .map(|_| self.network_events()) + .map_err(|e| anyhow::Error::new(e)); response_channel .send(res) .map_err(|_| anyhow!("sender dropped"))?; @@ -1242,7 +1232,6 @@ mod tests { let client = RpcClient::new(cfg).await?; - let network_events = p2p.network_events(); let task = tokio::task::spawn(async move { p2p.run().await.unwrap() }); let client = client.try_p2p()?; @@ -1257,7 +1246,6 @@ mod tests { task, client, peer_id, - network_events, addr, dial_addr, }) @@ -1281,8 +1269,6 @@ mod tests { client: P2pClient, /// The node's peer_id peer_id: PeerId, - /// A channel to read the network events received by the node. - network_events: Receiver, /// The listening address for this node. addr: Multiaddr, /// A multiaddr that is a combination of the listening addr and peer_id. @@ -1435,10 +1421,11 @@ mod tests { #[tokio::test] async fn test_cancel_listen_for_identify() -> Result<()> { - let mut test_runner_a = TestRunnerBuilder::new().no_bootstrap().build().await?; + let test_runner_a = TestRunnerBuilder::new().no_bootstrap().build().await?; let peer_id: PeerId = "12D3KooWFma2D63TG9ToSiRsjFkoNm2tTihScTBAEdXxinYk5rwE" .parse() .unwrap(); + let mut network_events = test_runner_a.client.network_events().await?; test_runner_a .client .lookup(peer_id, None) @@ -1446,7 +1433,7 @@ mod tests { .unwrap_err(); // when lookup ends in error, we must ensure we // have canceled the lookup - let event = test_runner_a.network_events.recv().await.unwrap(); + let event = network_events.next().await.unwrap().unwrap(); if let NetworkEvent::CancelLookupQuery(got_peer_id) = event { assert_eq!(peer_id, got_peer_id); } else { @@ -1458,7 +1445,7 @@ mod tests { #[tokio::test] async fn test_gossipsub() -> Result<()> { - let mut test_runner_a = TestRunnerBuilder::new().no_bootstrap().build().await?; + let test_runner_a = TestRunnerBuilder::new().no_bootstrap().build().await?; // peer_id 12D3KooWLo6JTNKXfjkZtKf8ooLQoXVXUEeuu4YDY3CYqK6rxHXt let test_runner_b = TestRunnerBuilder::new() .no_bootstrap() @@ -1466,14 +1453,15 @@ mod tests { .build() .await?; let addrs_b = vec![test_runner_b.addr.clone()]; + let mut network_events_a = test_runner_a.client.network_events().await?; test_runner_a .client .connect(test_runner_b.peer_id, addrs_b) .await?; - match test_runner_a.network_events.recv().await { - Some(NetworkEvent::PeerConnected(peer_id)) => { + match network_events_a.next().await { + Some(Ok(NetworkEvent::PeerConnected(peer_id))) => { assert_eq!(test_runner_b.peer_id, peer_id); } Some(n) => { @@ -1489,7 +1477,7 @@ mod tests { assert_eq!(test_runner_b.peer_id, got_peer.0); // create topic - let topic = TopicHash::from_raw("test_topic"); + let topic = libp2p::gossipsub::TopicHash::from_raw("test_topic"); // subscribe both to same topic test_runner_a .client @@ -1500,11 +1488,11 @@ mod tests { .gossipsub_subscribe(topic.clone()) .await?; - match test_runner_a.network_events.recv().await { - Some(NetworkEvent::Gossipsub(GossipsubEvent::Subscribed { + match network_events_a.next().await { + Some(Ok(NetworkEvent::Gossipsub(GossipsubEvent::Subscribed { peer_id, topic: subscribed_topic, - })) => { + }))) => { assert_eq!(test_runner_b.peer_id, peer_id); assert_eq!(topic, subscribed_topic); } @@ -1541,8 +1529,10 @@ mod tests { .gossipsub_publish(topic.clone(), msg.clone()) .await?; - match test_runner_a.network_events.recv().await { - Some(NetworkEvent::Gossipsub(GossipsubEvent::Message { from, message, .. })) => { + match network_events_a.next().await { + Some(Ok(NetworkEvent::Gossipsub(GossipsubEvent::Message { + from, message, .. + }))) => { assert_eq!(test_runner_b.peer_id, from); assert_eq!(topic, message.topic); assert_eq!(test_runner_b.peer_id, message.source.unwrap()); @@ -1560,11 +1550,11 @@ mod tests { .client .gossipsub_unsubscribe(topic.clone()) .await?; - match test_runner_a.network_events.recv().await { - Some(NetworkEvent::Gossipsub(GossipsubEvent::Unsubscribed { + match network_events_a.next().await { + Some(Ok(NetworkEvent::Gossipsub(GossipsubEvent::Unsubscribed { peer_id, topic: unsubscribe_topic, - })) => { + }))) => { assert_eq!(test_runner_b.peer_id, peer_id); assert_eq!(topic, unsubscribe_topic); } @@ -1591,7 +1581,7 @@ mod tests { println!("peer_a: {:?}", test_runner_a.peer_id); // peer_id 12D3KooWLo6JTNKXfjkZtKf8ooLQoXVXUEeuu4YDY3CYqK6rxHXt - let mut test_runner_b = TestRunnerBuilder::new() + let test_runner_b = TestRunnerBuilder::new() .no_bootstrap() .with_seed(ChaCha8Rng::from_seed([0; 32])) .build() @@ -1608,6 +1598,7 @@ mod tests { println!("peer_c: {:?}", test_runner_c.peer_id); + let mut network_events_b = test_runner_b.client.network_events().await?; // connect a and c to b test_runner_a .client @@ -1615,8 +1606,8 @@ mod tests { .await?; // expect a network event showing a & b have connected - match test_runner_b.network_events.recv().await { - Some(NetworkEvent::PeerConnected(peer_id)) => { + match network_events_b.next().await { + Some(Ok(NetworkEvent::PeerConnected(peer_id))) => { assert_eq!(test_runner_a.peer_id, peer_id); } Some(n) => { @@ -1633,8 +1624,8 @@ mod tests { .await?; // expect a network event showing b & c have connected - match test_runner_b.network_events.recv().await { - Some(NetworkEvent::PeerConnected(peer_id)) => { + match network_events_b.next().await { + Some(Ok(NetworkEvent::PeerConnected(peer_id))) => { assert_eq!(test_runner_c.peer_id, peer_id); } Some(n) => { diff --git a/iroh-p2p/src/rpc.rs b/iroh-p2p/src/rpc.rs index 70b10e506..e568e79d3 100644 --- a/iroh-p2p/src/rpc.rs +++ b/iroh-p2p/src/rpc.rs @@ -4,7 +4,7 @@ use cid::Cid; use futures::StreamExt; use futures::{ stream::{BoxStream, Stream}, - TryFutureExt, + FutureExt, TryFutureExt, }; use iroh_bitswap::Block; use iroh_rpc_client::{ @@ -13,22 +13,19 @@ use iroh_rpc_client::{ use iroh_rpc_types::{ p2p::*, RpcError, RpcResult, VersionRequest, VersionResponse, WatchRequest, WatchResponse, }; -use libp2p::gossipsub::{ - error::{PublishError, SubscriptionError}, - MessageId, TopicHash, -}; +use libp2p::gossipsub::{error::PublishError, MessageId, TopicHash}; use libp2p::identify::Info as IdentifyInfo; use libp2p::kad::record::Key; use libp2p::Multiaddr; use libp2p::PeerId; use std::collections::{HashMap, HashSet}; use std::result; -use tokio::sync::mpsc::{channel, Sender}; +use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::oneshot; +use tokio_stream::wrappers::ReceiverStream; use tracing::{debug, info, trace}; -use super::node::DEFAULT_PROVIDER_LIMIT; -use crate::VERSION; +use crate::{GossipsubEvent, GossipsubEventStream, NetworkEvent, DEFAULT_PROVIDER_LIMIT, VERSION}; #[derive(Clone)] pub(crate) struct P2p { @@ -217,7 +214,7 @@ impl P2p { }; self.sender.send(msg).await?; - let r = tokio_stream::wrappers::ReceiverStream::new(r); + let r = ReceiverStream::new(r); let stream = r .map(|providers| { @@ -394,6 +391,54 @@ impl P2p { Ok(peer_info_from_lookup(lookup)) } + #[tracing::instrument(skip(self))] + fn gossipsub_subscribe(self, req: GossipsubSubscribeRequest) -> GossipsubEventStream { + async move { + self.gossipsub_subscribe_0(req) + .await + .expect("FIX THIS - NEEDS TO BE ABLE TO RETURN A RESULT") + } + .flatten_stream() + .boxed() + } + + #[tracing::instrument(skip(self))] + async fn gossipsub_subscribe_0( + self, + req: GossipsubSubscribeRequest, + ) -> Result>> { + let t = TopicHash::from_raw(req.topic_hash); + let (s, r) = oneshot::channel(); + self.sender + .send(RpcMessage::Gossipsub(GossipsubMessage::Subscribe( + s, + t.clone(), + ))) + .await?; + + let mut r = r.await??; + let stream = async_stream::stream! { + while let Some(network_event) = r.recv().await { + if let NetworkEvent::Gossipsub(event) = network_event { + match &event { + GossipsubEvent::Subscribed { topic, .. } | + GossipsubEvent::Unsubscribed {topic, .. } | + GossipsubEvent::Message { topic, .. } => { + println!("gossipsub event: {:#?}", event); + println!("in message topic {:#?}, expected topic {:#?}", topic, t); + if *topic == t { + println!("topic match!"); + yield Box::new(GossipsubSubscribeResponse {event}); + } + }, + }; + } + } + } + .boxed(); + Ok(stream) + } + #[tracing::instrument(skip(self, req))] async fn gossipsub_add_explicit_peer(self, req: GossipsubAddExplicitPeerRequest) -> Result<()> { let (s, r) = oneshot::channel(); @@ -485,24 +530,6 @@ impl P2p { Ok(()) } - #[tracing::instrument(skip(self, req))] - async fn gossipsub_subscribe( - self, - req: GossipsubSubscribeRequest, - ) -> Result { - let (s, r) = oneshot::channel(); - let msg = RpcMessage::Gossipsub(GossipsubMessage::Subscribe( - s, - TopicHash::from_raw(req.topic_hash), - )); - - self.sender.send(msg).await?; - - let was_subscribed = r.await?.context("subscribe error")?; - - Ok(GossipsubSubscribeResponse { was_subscribed }) - } - #[tracing::instrument(skip(self))] async fn gossipsub_topics(self, _: GossipsubTopicsRequest) -> Result { let (s, r) = oneshot::channel(); @@ -548,7 +575,7 @@ async fn dispatch(s: P2pServer, req: P2pRequest, chan: ServerSocket, GossipsubAllMeshPeers(req) => s.rpc_map_err(req, chan, target, P2p::gossipsub_all_mesh_peers).await, GossipsubPublish(req) => s.rpc_map_err(req, chan, target, P2p::gossipsub_publish).await, GossipsubRemoveExplicitPeer(req) => s.rpc_map_err(req, chan, target, P2p::gossipsub_remove_explicit_peer).await, - GossipsubSubscribe(req) => s.rpc_map_err(req, chan, target, P2p::gossipsub_subscribe).await, + GossipsubSubscribe(req) => s.server_streaming(req, chan, target, P2p::gossipsub_subscribe).await, GossipsubTopics(req) => s.rpc_map_err(req, chan, target, P2p::gossipsub_topics).await, GossipsubUnsubscribe(req) => s.rpc_map_err(req, chan, target, P2p::gossipsub_unsubscribe).await, StopSessionBitswap(req) => s.rpc_map_err(req, chan, target, P2p::stop_session_bitswap).await, @@ -668,7 +695,10 @@ pub enum GossipsubMessage { Bytes, ), RemoveExplicitPeer(oneshot::Sender<()>, PeerId), - Subscribe(oneshot::Sender>, TopicHash), + Subscribe( + oneshot::Sender>>, + TopicHash, + ), Topics(oneshot::Sender>), Unsubscribe(oneshot::Sender>, TopicHash), } diff --git a/iroh-resolver/src/lib.rs b/iroh-resolver/src/lib.rs index fe9fb5056..c805f798a 100644 --- a/iroh-resolver/src/lib.rs +++ b/iroh-resolver/src/lib.rs @@ -1,4 +1,7 @@ pub mod dns_resolver; pub mod resolver; +pub use iroh_unixfs::content_loader::{ + ContentLoader, FullLoader, FullLoaderConfig, LoaderFromProviders, +}; pub use resolver::{Path, PathType}; diff --git a/iroh-rpc-client/src/lib.rs b/iroh-rpc-client/src/lib.rs index b4181d5c0..ec99005c5 100644 --- a/iroh-rpc-client/src/lib.rs +++ b/iroh-rpc-client/src/lib.rs @@ -6,6 +6,7 @@ pub mod status; pub mod store; pub use self::config::Config; pub use client::Client; +pub use iroh_rpc_types::GossipsubEvent; use iroh_rpc_types::{gateway::GatewayService, p2p::P2pService, store::StoreService, Addr}; pub use network::{Lookup, P2pClient}; use quic_rpc::{ diff --git a/iroh-rpc-client/src/network.rs b/iroh-rpc-client/src/network.rs index 420d1f972..20908b9f3 100644 --- a/iroh-rpc-client/src/network.rs +++ b/iroh-rpc-client/src/network.rs @@ -3,7 +3,7 @@ use async_stream::stream; use bytes::Bytes; use cid::Cid; use futures::{Stream, StreamExt}; -use iroh_rpc_types::{p2p::*, VersionRequest, WatchRequest}; +use iroh_rpc_types::{p2p::*, GossipsubEvent, VersionRequest, WatchRequest}; use libp2p::gossipsub::{MessageId, TopicHash}; use libp2p::{Multiaddr, PeerId}; use std::collections::{HashMap, HashSet}; @@ -243,12 +243,21 @@ impl P2pClient { } #[tracing::instrument(skip(self))] - pub async fn gossipsub_subscribe(&self, topic: TopicHash) -> Result { - let req = GossipsubSubscribeRequest { - topic_hash: topic.to_string(), - }; - let res = self.client.rpc(req).await??; - Ok(res.was_subscribed) + pub async fn gossipsub_subscribe( + &self, + topic: TopicHash, + ) -> Result>> { + let res = self + .client + .server_streaming(GossipsubSubscribeRequest { + topic_hash: topic.to_string(), + }) + .await?; + let events = res.map(|e| { + let e = e?.event; + Ok(e) + }); + Ok(events) } #[tracing::instrument(skip(self))] diff --git a/iroh-rpc-types/Cargo.toml b/iroh-rpc-types/Cargo.toml index b29dffe8f..68ae6c21b 100644 --- a/iroh-rpc-types/Cargo.toml +++ b/iroh-rpc-types/Cargo.toml @@ -14,7 +14,7 @@ bytes = { workspace = true, features = ["serde"] } cid = { workspace = true, features = ["serde-codec"] } derive_more.workspace = true futures.workspace = true -libp2p = { workspace = true, features = ["serde"] } +libp2p = { workspace = true, features = ["serde", "gossipsub"] } quic-rpc.workspace = true serde.workspace = true serde-error.workspace = true diff --git a/iroh-rpc-types/src/gossipsub_event.rs b/iroh-rpc-types/src/gossipsub_event.rs new file mode 100644 index 000000000..21044d2f5 --- /dev/null +++ b/iroh-rpc-types/src/gossipsub_event.rs @@ -0,0 +1,55 @@ +use futures::stream::BoxStream; +use libp2p::{ + gossipsub::{GossipsubMessage, MessageId, TopicHash}, + PeerId, +}; +use serde::{Deserialize, Serialize}; + +use crate::p2p::GossipsubSubscribeResponse; + +pub type GossipsubEventStream = BoxStream<'static, Box>; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum GossipsubEvent { + Subscribed { + peer_id: PeerId, + #[serde(with = "TopicHashDef")] + topic: TopicHash, + }, + Unsubscribed { + peer_id: PeerId, + #[serde(with = "TopicHashDef")] + topic: TopicHash, + }, + Message { + from: PeerId, + id: MessageId, + #[serde(with = "GossipsubMessageDef")] + message: GossipsubMessage, + #[serde(with = "TopicHashDef")] + topic: TopicHash, + }, +} + +#[derive(Serialize, Deserialize)] +#[serde(remote = "TopicHash")] +struct TopicHashDef { + #[serde(getter = "TopicHash::to_string")] + hash: String, +} + +impl From for TopicHash { + fn from(t: TopicHashDef) -> Self { + TopicHash::from_raw(t.hash) + } +} + +#[derive(Serialize, Deserialize)] +#[serde(remote = "GossipsubMessage")] +struct GossipsubMessageDef { + source: Option, + data: Vec, + sequence_number: Option, + #[serde(with = "TopicHashDef")] + topic: TopicHash, +} diff --git a/iroh-rpc-types/src/lib.rs b/iroh-rpc-types/src/lib.rs index b930a6e43..bc0a0f49a 100644 --- a/iroh-rpc-types/src/lib.rs +++ b/iroh-rpc-types/src/lib.rs @@ -1,11 +1,13 @@ pub mod addr; pub mod gateway; +mod gossipsub_event; pub mod p2p; pub mod store; use std::fmt; pub use addr::Addr; +pub use gossipsub_event::{GossipsubEvent, GossipsubEventStream}; use serde::{Deserialize, Serialize}; diff --git a/iroh-rpc-types/src/p2p.rs b/iroh-rpc-types/src/p2p.rs index 3da8369ad..e076cc6c1 100644 --- a/iroh-rpc-types/src/p2p.rs +++ b/iroh-rpc-types/src/p2p.rs @@ -9,6 +9,7 @@ use quic_rpc::{ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; +use crate::GossipsubEvent; use crate::{RpcResult, VersionRequest, VersionResponse, WatchRequest, WatchResponse}; pub type P2pAddr = super::addr::Addr; @@ -193,7 +194,7 @@ pub struct GossipsubSubscribeRequest { #[derive(Serialize, Deserialize, Debug)] pub struct GossipsubSubscribeResponse { - pub was_subscribed: bool, + pub event: GossipsubEvent, } #[derive(Serialize, Deserialize, Debug)] @@ -258,7 +259,7 @@ pub enum P2pResponse { GossipsubPeers(RpcResult), GossipsubAllPeers(RpcResult), GossipsubPublish(RpcResult), - GossipsubSubscribe(RpcResult), + GossipsubSubscribe(Box), GossipsubTopics(RpcResult), GossipsubUnsubscribe(RpcResult), LocalPeerId(RpcResult), @@ -363,8 +364,12 @@ impl RpcMsg for GossipsubTopicsRequest { type Response = RpcResult; } -impl RpcMsg for GossipsubSubscribeRequest { - type Response = RpcResult; +impl Msg for GossipsubSubscribeRequest { + type Response = Box; + + type Update = Self; + + type Pattern = ServerStreaming; } impl RpcMsg for GossipsubUnsubscribeRequest { diff --git a/iroh-share/Cargo.toml b/iroh-share/Cargo.toml index cc5b41c8f..81912f0fc 100644 --- a/iroh-share/Cargo.toml +++ b/iroh-share/Cargo.toml @@ -19,6 +19,8 @@ futures.workspace = true iroh-metrics.workspace = true iroh-p2p.workspace = true iroh-resolver.workspace = true +iroh-embed.workspace = true +iroh-api.workspace = true iroh-rpc-client.workspace = true iroh-rpc-types.workspace = true iroh-store.workspace = true diff --git a/iroh-share/src/data.rs b/iroh-share/src/data.rs new file mode 100644 index 000000000..7c9a19e7f --- /dev/null +++ b/iroh-share/src/data.rs @@ -0,0 +1,52 @@ +use anyhow::{Context, Result}; +use futures::Stream; +use iroh_resolver::{ + resolver::{Out, OutPrettyReader, Resolver, UnixfsType}, + Path, +}; +use iroh_unixfs::{content_loader::ContentLoader, Link}; + +#[derive(Debug)] +pub struct Data { + resolver: Resolver, + root: Out, +} + +impl Data +where + C: ContentLoader, +{ + pub fn typ(&self) -> UnixfsType { + self.root.metadata().unixfs_type.unwrap() + } + + pub fn is_file(&self) -> bool { + self.typ() == UnixfsType::File + } + + pub fn is_dir(&self) -> bool { + self.typ() == UnixfsType::Dir + } + + pub fn read_dir(&self) -> Result> + '_>> { + self.root + .unixfs_read_dir(&self.resolver, Default::default()) + } + + pub fn pretty(self) -> Result> { + self.root.pretty(self.resolver, Default::default(), None) + } + + pub async fn read_file(&self, link: &Link) -> Result> { + let root = self + .resolver + .resolve(Path::from_cid(link.cid)) + .await + .context("resolve")?; + + Ok(Data { + resolver: self.resolver.clone(), + root, + }) + } +} diff --git a/iroh-share/src/iroh.rs b/iroh-share/src/iroh.rs new file mode 100644 index 000000000..b757c0181 --- /dev/null +++ b/iroh-share/src/iroh.rs @@ -0,0 +1,19 @@ +use std::path::Path; + +use anyhow::Result; +use iroh_embed::{Iroh, IrohBuilder, Libp2pConfig, P2pService, RocksStoreService}; + +pub async fn build(port: u16, db_path: &Path) -> Result { + let db_path = db_path.to_path_buf(); + let store = RocksStoreService::new(db_path.clone()).await?; + + let mut libp2p_config = Libp2pConfig::default(); + libp2p_config.listening_multiaddrs = vec![format!("/ip4/0.0.0.0/tcp/{port}").parse().unwrap()]; + libp2p_config.bootstrap_peers = Default::default(); // disable bootstrap for now + libp2p_config.relay_server = false; + libp2p_config.max_conns_in = 8; + libp2p_config.max_conns_out = 8; + + let (p2p,_network_events) = P2pService::new(libp2p_config, db_path, store.addr()).await?; + IrohBuilder::new().store(store).p2p(p2p).build().await +} diff --git a/iroh-share/src/lib.rs b/iroh-share/src/lib.rs index 720134553..8991eba02 100644 --- a/iroh-share/src/lib.rs +++ b/iroh-share/src/lib.rs @@ -1,17 +1,62 @@ -mod p2p_node; +mod data; +mod iroh; mod receiver; mod sender; use cid::Cid; +use libp2p::{Multiaddr, PeerId}; use serde::{Deserialize, Serialize}; -pub use crate::p2p_node::Ticket; -pub use crate::receiver::{ProgressEvent, Receiver, Transfer as ReceiverTransfer}; -pub use crate::sender::{Sender, Transfer as SenderTransfer}; +// pub use crate::receiver::{ProgressEvent, Receiver}; +// pub use crate::sender::Sender; +pub use crate::receiver::ProgressEvent; + +// TODO(ramfox): remove re export +pub use crate::iroh::build as build_iroh; + +use anyhow::Result; +use libp2p::gossipsub::{Sha256Topic, TopicHash}; +use rand::Rng; + +/// Ticket describing the peer, their addresses, and the topic +/// on which to discuss the data transfer +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct Ticket { + pub peer_id: PeerId, + pub addrs: Vec, + pub topic: String, +} + +impl Ticket { + pub fn new(peer_id: PeerId, addrs: Vec) -> Self { + let id: u64 = rand::thread_rng().gen(); + let topic = Sha256Topic::new(format!("iroh-share-{id}")) + .hash() + .to_string(); + Self { + peer_id, + addrs, + topic, + } + } + + pub fn topic_hash(&self) -> TopicHash { + TopicHash::from_raw(self.topic.clone()) + } + + pub fn as_bytes(&self) -> Vec { + bincode::serialize(self).expect("failed to serialize") + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + let ticket = bincode::deserialize(bytes)?; + Ok(ticket) + } +} /// Messages sent from the sender. #[derive(Debug, Clone, Serialize, Deserialize)] -enum SenderMessage { +pub enum SenderMessage { Start { /// The root Cid of the content. root: Cid, @@ -22,7 +67,7 @@ enum SenderMessage { /// Messages sent from the receiver. #[derive(Debug, Clone, Serialize, Deserialize)] -enum ReceiverMessage { +pub enum ReceiverMessage { /// Transfer was completed successfully. FinishOk, /// Transfer failed. diff --git a/iroh-share/src/main.rs b/iroh-share/src/main.rs index 027368d7f..7b4f050e0 100644 --- a/iroh-share/src/main.rs +++ b/iroh-share/src/main.rs @@ -1,12 +1,18 @@ use std::path::PathBuf; -use anyhow::{ensure, Context, Result}; +use anyhow::{anyhow, ensure, Result}; use clap::{Parser, Subcommand}; use futures::stream::StreamExt; -use iroh_share::{ProgressEvent, Receiver, Sender, Ticket}; -use tokio::io::AsyncWriteExt; +use iroh_p2p::GossipsubEvent; +use iroh_share::{ReceiverMessage, SenderMessage, Ticket}; +use iroh_unixfs::chunker::ChunkerConfig; +use rand::Rng; +use tracing::{debug, info, warn}; use tracing_subscriber::{fmt, prelude::*, EnvFilter}; +use iroh_api::{IpfsPath, UnixfsConfig, UnixfsEntry, DEFAULT_CHUNKS_SIZE}; +use libp2p::gossipsub::Sha256Topic; + #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] struct Args { @@ -46,37 +52,107 @@ async fn main() -> Result<()> { Commands::Send { path } => { println!("Sending: {}", path.display()); + ensure!(path.exists(), "provided file or directory does not exist"); + ensure!( + path.is_file() || path.is_dir(), + "currently only supports files or directories" + ); + // TODO: allow db specification let sender_dir = tempfile::tempdir().unwrap(); let sender_db = sender_dir.path().join("db"); - let port = 9990; - let sender = Sender::new(port, &sender_db) - .await - .context("failed to create sender")?; - - ensure!(path.exists(), "provided file does not exist"); - ensure!(path.is_file(), "currently only supports files"); - - // TODO: streaming read - let name = path - .file_name() - .ok_or_else(|| anyhow::anyhow!("missing file name"))?; - let name = name - .to_str() - .ok_or_else(|| anyhow::anyhow!("file name must be valid utf8"))?; - - let data = tokio::fs::read(&path).await?; - let sender_transfer = sender - .transfer_from_data(name, data.into()) - .await - .context("transfer")?; - - let ticket = sender_transfer.ticket(); + println!("Starting up Iroh services..."); + let iroh = iroh_share::build_iroh(9990, &sender_db).await?; + let entry = UnixfsEntry::from_path( + &path, + UnixfsConfig { + wrap: true, + chunker: Some(ChunkerConfig::Fixed(DEFAULT_CHUNKS_SIZE)), + }, + ) + .await?; + + let mut progress = iroh.api().add_stream(entry).await?; + let mut root = None; + let mut num_parts = 0; + while let Some(ev) = progress.next().await { + let (cid, _) = ev?; + root = Some(cid); + num_parts += 1; + } + + let root = root.unwrap(); + + let id: u64 = rand::thread_rng().gen(); + let topic_hash = Sha256Topic::new(format!("iroh-share-{id}")).hash(); + let th = topic_hash.clone(); + + let (done_sender, done_receiver) = futures::channel::oneshot::channel(); + + let mut events = iroh.api().p2p()?.subscribe(topic_hash.to_string()).await?; + let p2p = iroh.api().p2p()?; + let gossip_task_source = tokio::task::spawn(async move { + let mut current_peer = None; + while let Some(Ok(e)) = events.next().await { + match e { + GossipsubEvent::Subscribed { peer_id, topic } => { + if topic == th && current_peer.is_none() { + info!("connected to {}", peer_id); + current_peer = Some(peer_id); + + let start = + bincode::serialize(&SenderMessage::Start { root, num_parts }) + .expect("serialize failure"); + p2p.publish(topic.to_string(), start.into()).await.unwrap(); + } + } + GossipsubEvent::Message { from, message, .. } => { + println!("received message from {}", from); + debug!("received message from {}", from); + if let Some(current_peer) = current_peer { + if from == current_peer { + match bincode::deserialize(&message.data) { + Ok(ReceiverMessage::FinishOk) => { + println!("finished transfer"); + info!("finished transfer"); + done_sender.send(Ok(())).ok(); + break; + } + Ok(ReceiverMessage::FinishError(err)) => { + println!("transfer failed: {}", err); + info!("transfer failed: {}", err); + done_sender.send(Err(anyhow!("{}", err))).ok(); + break; + } + Err(err) => { + warn!("unexpected message: {:?}", err); + } + } + } + } + } + _ => {} + } + } + }); + + let peer_id = iroh.api().p2p()?.peer_id().await?; + let addrs = iroh.api().p2p()?.addrs().await?; + info!("Available addrs: {:?}", addrs); + + let ticket = Ticket { + peer_id, + addrs, + topic: topic_hash.to_string(), + }; + let ticket_bytes = ticket.as_bytes(); let ticket_str = multibase::encode(multibase::Base::Base64, &ticket_bytes); println!("Ticket:\n{ticket_str}\n"); - sender_transfer.done().await?; + done_receiver.await??; + iroh.stop().await?; + gossip_task_source.await?; } Commands::Receive { ticket, out } => { println!("Receiving"); @@ -88,57 +164,89 @@ async fn main() -> Result<()> { let sender_db = sender_dir.path().join("db"); let port = 9991; - let receiver = Receiver::new(port, &sender_db) - .await - .context("failed to create sender")?; - let mut receiver_transfer = receiver - .transfer_from_ticket(&ticket) - .await - .context("failed to read transfer")?; - let data = receiver_transfer.recv().await?; - let mut progress = receiver_transfer.progress()?; - - tokio::spawn(async move { - while let Some(ev) = progress.next().await { - match ev { - Ok(ProgressEvent::Piece { index, total }) => { - println!("transferred: {index}/{total}"); - } - Err(e) => { - eprintln!("transfer failed: {e}"); + let iroh = iroh_share::build_iroh(port, &sender_db).await?; + let addrs = ticket.addrs.clone(); + iroh.api().p2p()?.connect(ticket.peer_id, addrs).await?; + iroh.api().p2p()?.add_pubsub_peer(ticket.peer_id).await?; + let mut events = iroh.api().p2p()?.subscribe(ticket.topic.clone()).await?; + + let (root_sender, root_receiver) = futures::channel::oneshot::channel(); + let expected_sender = ticket.peer_id; + let gossipsub_task_source = tokio::task::spawn(async move { + let mut root_sender = Some(root_sender); + + while let Some(Ok(ev)) = events.next().await { + if let GossipsubEvent::Message { from, message, .. } = ev { + if from == expected_sender { + match bincode::deserialize(&message.data) { + Ok(SenderMessage::Start { root, .. }) => { + if let Some(root_sender) = root_sender.take() { + root_sender.send(root).ok(); + } + } + Err(err) => { + warn!("got unexpected message from {}: {:?}", from, err); + } + } + } else { + warn!("got message from unexpected sender: {:?}", from); } } } }); - - let mut out_dir = std::env::current_dir()?; - if let Some(out) = out { - out_dir = out_dir.join(out); - } - tokio::fs::create_dir_all(&out_dir) - .await - .with_context(|| format!("failed to create {}", out_dir.display()))?; - - let out = tokio::fs::canonicalize(out_dir).await?; - - let mut reader = data.read_dir()?.unwrap(); - while let Some(link) = reader.next().await { - let link = link?; - let file_content = data.read_file(&link).await?; - let path = out.join(link.name.unwrap_or_default()); - println!("Writing {}", path.display()); - let mut file = tokio::fs::File::create(&path) - .await - .with_context(|| format!("create file: {}", path.display()))?; - let mut content = file_content.pretty()?; - tokio::io::copy(&mut content, &mut file) - .await - .context("copy")?; - file.flush().await?; + let root = root_receiver.await?; + let mut peers = std::collections::HashSet::new(); + peers.insert(expected_sender); + let ipfs_path = IpfsPath::from_cid(root); + match iroh.api().get_from(&ipfs_path, peers) { + Ok(blocks) => { + let mut out_dir = std::env::current_dir()?; + if let Some(out) = out { + out_dir = out_dir.join(out); + } + println!("want to save to {:#?}", out_dir); + let msg = + match iroh_api::fs::write_get_stream(&ipfs_path, blocks, Some(&out_dir)) + .await + { + Ok(p) => { + println!("Received all data, written to: {}", p.to_str().unwrap()); + ReceiverMessage::FinishOk + } + Err(err) => { + println!("Error saving file(s): {err}"); + ReceiverMessage::FinishError(err.to_string()) + } + }; + iroh.api() + .p2p()? + .publish( + ticket.topic.clone(), + bincode::serialize(&msg) + .expect("failed to serialize message") + .into(), + ) + .await + .ok(); + } + Err(e) => { + let msg = ReceiverMessage::FinishError(e.to_string()); + iroh.api() + .p2p()? + .publish( + ticket.topic.clone(), + bincode::serialize(&msg) + .expect("failed to serialize message") + .into(), + ) + .await + .ok(); + println!("error with transfer {}", e); + } } - receiver_transfer.finish().await?; - println!("Received all data, written to: {}", out.display()); + iroh.stop().await?; + gossipsub_task_source.await?; } } diff --git a/iroh-share/src/p2p_node.rs b/iroh-share/src/p2p_node.rs deleted file mode 100644 index ec22d7b40..000000000 --- a/iroh-share/src/p2p_node.rs +++ /dev/null @@ -1,225 +0,0 @@ -use std::{collections::HashSet, path::Path, sync::Arc}; - -use anyhow::{ensure, Result}; -use async_trait::async_trait; -use cid::Cid; -use iroh_p2p::{config, Config, Keychain, MemoryStorage, NetworkEvent, Node}; -use iroh_resolver::resolver::Resolver; -use iroh_rpc_client::Client; -use iroh_rpc_types::Addr; -use iroh_unixfs::{ - content_loader::{ContentLoader, ContextId, LoaderContext, IROH_STORE}, - parse_links, LoadedCid, Source, -}; -use libp2p::{Multiaddr, PeerId}; -use serde::{Deserialize, Serialize}; -use tokio::sync::mpsc::Receiver; -use tokio::{sync::Mutex, task::JoinHandle}; -use tracing::{error, warn}; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct Ticket { - pub peer_id: PeerId, - pub addrs: Vec, - pub topic: String, -} - -impl Ticket { - pub fn as_bytes(&self) -> Vec { - bincode::serialize(self).expect("failed to serialize") - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - let ticket = bincode::deserialize(bytes)?; - Ok(ticket) - } -} - -#[derive(Debug)] -pub struct P2pNode { - p2p_task: JoinHandle<()>, - store_task: JoinHandle<()>, - rpc: Client, - resolver: Resolver, -} - -/// Wrapper struct to implement custom content loading -#[derive(Debug, Clone)] -pub struct Loader { - client: Client, - providers: Arc>>, -} - -impl Loader { - pub fn new(client: Client) -> Self { - Loader { - client, - providers: Arc::new(Mutex::new(HashSet::new())), - } - } - - pub fn providers(&self) -> &Arc>> { - &self.providers - } -} - -#[async_trait] -impl ContentLoader for Loader { - async fn load_cid(&self, cid: &Cid, _ctx: &LoaderContext) -> Result { - let cid = *cid; - let providers = self.providers.lock().await.clone(); - - match self.client.try_store()?.get(cid).await { - Ok(Some(data)) => { - return Ok(LoadedCid { - data, - source: Source::Store(IROH_STORE), - }); - } - Ok(None) => {} - Err(err) => { - warn!("failed to fetch data from store {}: {:?}", cid, err); - } - } - - ensure!(!providers.is_empty(), "no providers supplied"); - - // TODO: track context id - let res = self - .client - .try_p2p()? - .fetch_bitswap(0, cid, providers.clone()) - .await; - let bytes = match res { - Ok(bytes) => bytes, - Err(err) => { - error!("Bitswap error: {:#?}", err); - return Err(err); - } - }; - - let cloned = bytes.clone(); - let rpc = self.clone(); - { - let clone2 = cloned.clone(); - let links = - tokio::task::spawn_blocking(move || parse_links(&cid, &clone2).unwrap_or_default()) - .await - .unwrap_or_default(); - - rpc.client.try_store()?.put(cid, cloned, links).await?; - } - - Ok(LoadedCid { - data: bytes, - source: Source::Bitswap, - }) - } - - async fn stop_session(&self, ctx: ContextId) -> Result<()> { - self.client - .try_p2p()? - .stop_session_bitswap(ctx.into()) - .await?; - Ok(()) - } - - async fn has_cid(&self, cid: &Cid) -> Result { - Ok(self.client.try_store()?.has(*cid).await?) - } -} - -impl P2pNode { - pub async fn new(port: u16, db_path: &Path) -> Result<(Self, Receiver)> { - let rpc_p2p_addr_server = Addr::new_mem(); - let rpc_p2p_addr_client = rpc_p2p_addr_server.clone(); - let rpc_store_addr_server = Addr::new_mem(); - let rpc_store_addr_client = rpc_store_addr_server.clone(); - - let rpc_store_client_config = iroh_rpc_client::Config { - p2p_addr: Some(rpc_p2p_addr_client.clone()), - store_addr: Some(rpc_store_addr_client.clone()), - gateway_addr: None, - channels: Some(1), - }; - let rpc_p2p_client_config = iroh_rpc_client::Config { - p2p_addr: Some(rpc_p2p_addr_client.clone()), - store_addr: Some(rpc_store_addr_client.clone()), - gateway_addr: None, - channels: Some(1), - }; - let mut libp2p_config = config::Libp2pConfig::default(); - libp2p_config.listening_multiaddrs = - vec![format!("/ip4/0.0.0.0/tcp/{port}").parse().unwrap()]; - libp2p_config.mdns = false; - libp2p_config.kademlia = true; - libp2p_config.autonat = true; - libp2p_config.relay_client = true; - libp2p_config.bootstrap_peers = Default::default(); // disable bootstrap for now - libp2p_config.relay_server = false; - libp2p_config.max_conns_in = 8; - libp2p_config.max_conns_out = 8; - let config = Config { - libp2p: libp2p_config, - rpc_client: rpc_p2p_client_config.clone(), - key_store_path: db_path.parent().unwrap().to_path_buf(), - }; - - let rpc = Client::new(rpc_p2p_client_config).await?; - let loader = Loader::new(rpc.clone()); - let resolver = iroh_resolver::resolver::Resolver::new(loader); - - let store_config = iroh_store::Config { - path: db_path.to_path_buf(), - rpc_client: rpc_store_client_config, - }; - - let store = if store_config.path.exists() { - iroh_store::Store::open(store_config).await? - } else { - iroh_store::Store::create(store_config).await? - }; - - let kc = Keychain::::new(); - let mut p2p = Node::new(config, rpc_p2p_addr_server, kc).await?; - let events = p2p.network_events(); - - let p2p_task = tokio::task::spawn(async move { - if let Err(err) = p2p.run().await { - error!("{:?}", err); - } - }); - - let store_task = tokio::spawn(async move { - iroh_store::rpc::new(rpc_store_addr_server, store) - .await - .unwrap() - }); - - Ok(( - Self { - p2p_task, - store_task, - rpc, - resolver, - }, - events, - )) - } - - pub fn rpc(&self) -> &Client { - &self.rpc - } - - pub fn resolver(&self) -> &Resolver { - &self.resolver - } - - pub async fn close(self) -> Result<()> { - self.rpc.try_p2p().unwrap().shutdown().await?; - self.store_task.abort(); - self.p2p_task.await?; - self.store_task.await.ok(); - Ok(()) - } -} diff --git a/iroh-share/src/receiver.rs b/iroh-share/src/receiver.rs index a57b18165..c147ae651 100644 --- a/iroh-share/src/receiver.rs +++ b/iroh-share/src/receiver.rs @@ -1,256 +1,4 @@ -use anyhow::{anyhow, ensure, Context, Result}; -use futures::{ - channel::{oneshot::channel as oneshot, oneshot::Receiver as OneShotReceiver}, - Stream, StreamExt, -}; -use iroh_p2p::NetworkEvent; -use iroh_resolver::resolver::{Out, OutPrettyReader, OutType, Path, Resolver, UnixfsType}; -use iroh_unixfs::Link; -use libp2p::gossipsub::{GossipsubMessage, MessageId, TopicHash}; -use libp2p::PeerId; -use tokio::sync::mpsc::{channel, Receiver as ChannelReceiver}; -use tokio::task::JoinHandle; -use tokio_stream::wrappers::ReceiverStream; -use tracing::{debug, info, warn}; - -use crate::SenderMessage; -use crate::{ - p2p_node::{Loader, P2pNode, Ticket}, - ReceiverMessage, -}; - -#[derive(Debug)] -pub struct Receiver { - p2p: P2pNode, - gossip_messages: ChannelReceiver<(MessageId, PeerId, GossipsubMessage)>, - gossip_task: JoinHandle<()>, -} - -impl Receiver { - pub async fn new(port: u16, db_path: &std::path::Path) -> Result { - let (p2p, mut events) = P2pNode::new(port, db_path).await?; - let (s, r) = channel(1024); - - let gossip_task = tokio::task::spawn(async move { - while let Some(event) = events.recv().await { - if let NetworkEvent::Gossipsub(iroh_p2p::GossipsubEvent::Message { - from, - id, - message, - }) = event - { - s.try_send((id, from, message)).ok(); - } - } - }); - - Ok(Receiver { - p2p, - gossip_messages: r, - gossip_task, - }) - } - - pub async fn transfer_from_ticket(self, ticket: &Ticket) -> Result { - // Connect to the sender - info!("connecting"); - let Receiver { - p2p, - mut gossip_messages, - gossip_task, - } = self; - let p2p_rpc = p2p.rpc().try_p2p()?; - p2p_rpc - .connect(ticket.peer_id, ticket.addrs.clone()) - .await?; - p2p_rpc.gossipsub_add_explicit_peer(ticket.peer_id).await?; - let topic = TopicHash::from_raw(&ticket.topic); - p2p_rpc.gossipsub_subscribe(topic.clone()).await?; - - let expected_sender = ticket.peer_id; - let resolver = p2p.resolver().clone(); - let (progress_sender, progress_receiver) = channel(1024); - let (data_sender, data_receiver) = oneshot(); - - // add provider - resolver - .loader() - .providers() - .lock() - .await - .insert(expected_sender); - - let rpc = p2p.rpc().clone(); - - let gossip_task_source = tokio::task::spawn(async move { - let mut data_sender = Some(data_sender); - - while let Some((_id, from, message)) = gossip_messages.recv().await { - if from == expected_sender { - match bincode::deserialize(&message.data) { - Ok(SenderMessage::Start { root, num_parts }) => { - let results = resolver.resolve_recursive(Path::from_cid(root)); - tokio::pin!(results); - // root is the first - let mut index = 1; - let mut has_err = None; - while let Some(res) = results.next().await { - let msg = match &res { - Ok(_out) => Ok(ProgressEvent::Piece { - index, - total: num_parts, - }), - Err(err) => { - has_err = Some(err.to_string()); - Err(err.to_string()) - } - }; - debug!("progress {}/{}", index, num_parts); - progress_sender.send(msg).await.unwrap(); - - if let Some(data_sender) = data_sender.take() { - data_sender.send(res).ok(); - } - - // If there was an error abort. - if has_err.is_some() { - break; - } - index += 1; - } - info!("transfer completed"); - drop(progress_sender); - - // TODO: send finish message or error - let msg = if let Some(error) = has_err.take() { - ReceiverMessage::FinishError(error) - } else { - ReceiverMessage::FinishOk - }; - rpc.try_p2p() - .expect("missing p2p rpc") - .gossipsub_publish( - topic, - bincode::serialize(&msg) - .expect("failed to serialize") - .into(), - ) - .await - .ok(); - } - Err(err) => { - warn!("got unexpected message from {}: {:?}", from, err); - } - } - // we only receive a single iteration - break; - } else { - warn!("got message from unexpected sender: {:?}", from); - } - } - }); - - Ok(Transfer { - gossip_task, - gossip_task_source, - p2p, - data_receiver: Some(data_receiver), - progress_receiver: Some(progress_receiver), - }) - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub enum ProgressEvent { Piece { index: usize, total: usize }, } - -#[derive(Debug)] -pub struct Transfer { - p2p: P2pNode, - gossip_task: JoinHandle<()>, - gossip_task_source: JoinHandle<()>, - data_receiver: Option>>, - progress_receiver: Option>>, -} - -impl Transfer { - pub async fn recv(&mut self) -> Result { - let data_receiver = self - .data_receiver - .take() - .ok_or_else(|| anyhow!("recv must only be called once"))?; - let root = data_receiver.await??; - - ensure!( - root.metadata().typ == OutType::Unixfs, - "expected unixfs data" - ); - - Ok(Data { - resolver: self.p2p.resolver().clone(), - root, - }) - } - - pub fn progress( - &mut self, - ) -> Result>> { - let progress = self - .progress_receiver - .take() - .ok_or_else(|| anyhow!("progerss must only be called once"))?; - Ok(ReceiverStream::new(progress)) - } - - /// Finish and finalize the transfer. - pub async fn finish(self) -> Result<()> { - self.gossip_task.abort(); - self.gossip_task_source.await?; - self.p2p.close().await?; - - Ok(()) - } -} - -#[derive(Debug)] -pub struct Data { - resolver: Resolver, - root: Out, -} - -impl Data { - pub fn typ(&self) -> UnixfsType { - self.root.metadata().unixfs_type.unwrap() - } - - pub fn is_file(&self) -> bool { - self.typ() == UnixfsType::File - } - - pub fn is_dir(&self) -> bool { - self.typ() == UnixfsType::Dir - } - - pub fn read_dir(&self) -> Result> + '_>> { - self.root - .unixfs_read_dir(&self.resolver, Default::default()) - } - - pub fn pretty(self) -> Result> { - self.root.pretty(self.resolver, Default::default(), None) - } - - pub async fn read_file(&self, link: &Link) -> Result { - let root = self - .resolver - .resolve(Path::from_cid(link.cid)) - .await - .context("resolve")?; - - Ok(Data { - resolver: self.resolver.clone(), - root, - }) - } -} diff --git a/iroh-share/src/sender.rs b/iroh-share/src/sender.rs index 5b6174961..58d182f5e 100644 --- a/iroh-share/src/sender.rs +++ b/iroh-share/src/sender.rs @@ -1,93 +1,63 @@ use std::path::Path; -use anyhow::{anyhow, Context, Result}; -use bytes::Bytes; -use futures::channel::oneshot::{channel as oneshot, Receiver as OneShotReceiver}; -use futures::StreamExt; -use iroh_p2p::{GossipsubEvent, NetworkEvent}; -use iroh_unixfs::builder::{DirectoryBuilder, FileBuilder}; -use libp2p::gossipsub::Sha256Topic; -use rand::Rng; -use tokio::sync::mpsc::{channel, Receiver}; +use anyhow::{anyhow, Result}; +use futures::{channel::oneshot, stream::BoxStream, StreamExt}; +use iroh_api::{Cid, UnixfsEntry}; +use iroh_api::{GossipsubEvent, P2pApi}; +use iroh_embed::Iroh; use tokio::task::JoinHandle; use tracing::{debug, info, warn}; -use crate::{ - p2p_node::{P2pNode, Ticket}, - ReceiverMessage, SenderMessage, -}; +use crate::{iroh::build as build_iroh, ReceiverMessage, SenderMessage, Ticket}; -/// The sending part of the data transfer. -#[derive(Debug)] pub struct Sender { - p2p: P2pNode, - gossip_events: Receiver, - gossip_task: JoinHandle<()>, + iroh: Iroh, } -impl Sender { - pub async fn new(port: u16, db_path: &Path) -> Result { - let (p2p, mut events) = P2pNode::new(port, db_path).await?; - let (s, r) = channel(1024); - - let gossip_task = tokio::task::spawn(async move { - while let Some(event) = events.recv().await { - if let NetworkEvent::Gossipsub(e) = event { - // drop events if they are not processed - s.try_send(e).ok(); - } - } - }); +type EventStream = BoxStream<'static, Result>; +type ProgressStream = BoxStream<'static, Result<(Cid, u64)>>; - Ok(Sender { - p2p, - gossip_events: r, - gossip_task, - }) +impl Sender { + pub async fn new(database_path: &Path) -> Result { + let iroh = build_iroh(9990, database_path).await?; + Ok(Self { iroh }) } - pub async fn transfer_from_dir_builder( - self, - dir_builder: DirectoryBuilder, - ) -> Result { - let id = self.next_id(); - let Sender { - p2p, - mut gossip_events, - gossip_task, - } = self; - - let t = Sha256Topic::new(format!("iroh-share-{id}")); - let root_dir = dir_builder.build().await?; + pub async fn make_available(&self, entry: UnixfsEntry) -> Result { + self.iroh.api().add_stream(entry).await + } - let (done_sender, done_receiver) = oneshot(); + pub async fn transfer(&self, root: Cid, num_parts: usize) -> Result { + Transfer::new(self.iroh.api().p2p()?.clone(), root, num_parts).await + } +} - let p2p_rpc = p2p.rpc().try_p2p()?; - let store = p2p.rpc().try_store()?; - let (root, num_parts) = { - let parts = root_dir.encode(); - tokio::pin!(parts); - let mut num_parts = 0; - let mut root_cid = None; - while let Some(part) = parts.next().await { - let (cid, bytes, links) = part?.into_parts(); - num_parts += 1; - root_cid = Some(cid); - store.put(cid, bytes, links).await?; - } - (root_cid.unwrap(), num_parts) - }; +struct Transfer { + api: P2pApi, + ticket: Ticket, + // progress: TODO + event_task: JoinHandle<()>, + done: oneshot::Receiver>, +} - let topic_hash = t.hash(); - let th = topic_hash.clone(); +// make available progress +// transfer started +// transfer succeeded +// transfer failed - // subscribe to the topic, to receive responses - p2p_rpc.gossipsub_subscribe(topic_hash.clone()).await?; - let p2p2 = p2p_rpc.clone(); - let gossip_task_source = tokio::task::spawn(async move { +impl Transfer { + pub async fn new(api: P2pApi, root: Cid, num_parts: usize) -> Result { + let peer_id = api.peer_id().await?; + let addrs = api.addrs().await?; + let ticket = Ticket::new(peer_id, addrs); + let mut events = api.subscribe(ticket.topic.clone()).await?; + let th = ticket.topic_hash(); + let (done_sender, done_receiver) = futures::channel::oneshot::channel(); + let p2p = api.clone(); + let event_task = tokio::task::spawn(async move { let mut current_peer = None; - while let Some(event) = gossip_events.recv().await { - match event { + while let Some(Ok(e)) = events.next().await { + match e { GossipsubEvent::Subscribed { peer_id, topic } => { if topic == th && current_peer.is_none() { info!("connected to {}", peer_id); @@ -96,22 +66,23 @@ impl Sender { let start = bincode::serialize(&SenderMessage::Start { root, num_parts }) .expect("serialize failure"); - p2p2.gossipsub_publish(topic.clone(), start.into()) - .await - .unwrap(); + p2p.publish(topic.to_string(), start.into()).await.unwrap(); } } GossipsubEvent::Message { from, message, .. } => { + println!("received message from {}", from); debug!("received message from {}", from); if let Some(current_peer) = current_peer { if from == current_peer { match bincode::deserialize(&message.data) { Ok(ReceiverMessage::FinishOk) => { + println!("finished transfer"); info!("finished transfer"); done_sender.send(Ok(())).ok(); break; } Ok(ReceiverMessage::FinishError(err)) => { + println!("transfer failed: {}", err); info!("transfer failed: {}", err); done_sender.send(Err(anyhow!("{}", err))).ok(); break; @@ -128,71 +99,17 @@ impl Sender { } }); - let (peer_id, addrs) = p2p_rpc - .get_listening_addrs() - .await - .context("getting p2p info")?; - info!("Available addrs: {:?}", addrs); - let topic_string = topic_hash.to_string(); - - let ticket = Ticket { - peer_id, - addrs, - topic: topic_string, - }; - - Ok(Transfer { + Ok(Self { + api, ticket, - gossip_task_source, - done_receiver, - gossip_task, - p2p, + event_task, + done: done_receiver, }) } - pub async fn transfer_from_data( - self, - name: impl Into, - data: Bytes, - ) -> Result { - let name = name.into(); - // wrap in directory to preserve the name - let file = FileBuilder::new() - .name(name) - .content_bytes(data) - .build() - .await?; - let root_dir = DirectoryBuilder::new().add_file(file); - - self.transfer_from_dir_builder(root_dir).await - } - - fn next_id(&self) -> u64 { - rand::thread_rng().gen() - } -} - -#[derive(Debug)] -pub struct Transfer { - p2p: P2pNode, - ticket: Ticket, - done_receiver: OneShotReceiver>, - gossip_task: JoinHandle<()>, - gossip_task_source: JoinHandle<()>, -} - -impl Transfer { - pub fn ticket(&self) -> &Ticket { - &self.ticket - } - - /// Waits until the transfer is done. pub async fn done(self) -> Result<()> { - self.done_receiver.await??; - self.gossip_task.abort(); - self.gossip_task_source.await?; - self.p2p.close().await?; - + self.done.await??; + self.event_task.await?; Ok(()) } } diff --git a/iroh-unixfs/src/content_loader.rs b/iroh-unixfs/src/content_loader.rs index 0399253c7..124795416 100644 --- a/iroh-unixfs/src/content_loader.rs +++ b/iroh-unixfs/src/content_loader.rs @@ -4,18 +4,19 @@ use std::{ hash::BuildHasher, str::FromStr, sync::Arc, - sync::Mutex, }; -use anyhow::{anyhow, bail, Result}; +use anyhow::{anyhow, bail, ensure, Result}; use async_trait::async_trait; use bytes::Bytes; use cid::{multibase::Base, Cid}; use futures::future::Either; use iroh_rpc_client::Client; +use libp2p::PeerId; use rand::seq::SliceRandom; use reqwest::Url; -use tracing::{debug, info, trace, warn}; +use tokio::sync::Mutex; +use tracing::{debug, error, info, trace, warn}; use crate::{ indexer::{Indexer, IndexerUrl}, @@ -292,6 +293,91 @@ impl ContentLoader for FullLoader { self.client.try_store()?.has(*cid).await } } +/// Load content using only the specified providers +#[derive(Debug, Clone)] +pub struct LoaderFromProviders { + client: Client, + providers: Arc>>, +} + +impl LoaderFromProviders { + pub fn new(client: Client, providers: HashSet) -> Self { + Self { + client, + providers: Arc::new(Mutex::new(providers)), + } + } + + pub fn providers(&self) -> &Arc>> { + &self.providers + } +} + +#[async_trait] +impl ContentLoader for LoaderFromProviders { + async fn load_cid(&self, cid: &Cid, _ctx: &LoaderContext) -> Result { + let cid = *cid; + let providers = self.providers.lock().await.clone(); + + match self.client.try_store()?.get(cid).await { + Ok(Some(data)) => { + return Ok(LoadedCid { + data, + source: Source::Store(IROH_STORE), + }); + } + Ok(None) => {} + Err(err) => { + warn!("failed to fetch data from store {}: {:?}", cid, err); + } + } + + ensure!(!providers.is_empty(), "no providers supplied"); + + // TODO: track context id + let res = self + .client + .try_p2p()? + .fetch_bitswap(0, cid, providers.clone()) + .await; + let bytes = match res { + Ok(bytes) => bytes, + Err(err) => { + error!("Bitswap error: {:#?}", err); + return Err(err); + } + }; + + let cloned = bytes.clone(); + let rpc = self.clone(); + { + let clone2 = cloned.clone(); + let links = + tokio::task::spawn_blocking(move || parse_links(&cid, &clone2).unwrap_or_default()) + .await + .unwrap_or_default(); + + rpc.client.try_store()?.put(cid, cloned, links).await?; + } + + Ok(LoadedCid { + data: bytes, + source: Source::Bitswap, + }) + } + + async fn stop_session(&self, ctx: ContextId) -> Result<()> { + self.client + .try_p2p()? + .stop_session_bitswap(ctx.into()) + .await?; + Ok(()) + } + + async fn has_cid(&self, cid: &Cid) -> Result { + Ok(self.client.try_store()?.has(*cid).await?) + } +} #[derive(Debug, Clone)] pub struct LoaderContext { diff --git a/iroh/src/p2p.rs b/iroh/src/p2p.rs index f466d7f32..358592f4b 100644 --- a/iroh/src/p2p.rs +++ b/iroh/src/p2p.rs @@ -2,7 +2,7 @@ use crate::doc; use anyhow::{Error, Result}; use clap::{Args, Subcommand}; use crossterm::style::Stylize; -use iroh_api::{Lookup, Multiaddr, P2pApi, PeerId, PeerIdOrAddr}; +use iroh_api::{peer_id_from_multiaddr, Lookup, Multiaddr, P2pApi, PeerId, PeerIdOrAddr}; use std::{collections::HashMap, fmt::Display, str::FromStr}; #[derive(Args, Debug, Clone)] @@ -63,12 +63,21 @@ impl Display for PeerIdOrAddrArg { pub async fn run_command(p2p: &P2pApi, cmd: &P2p) -> Result<()> { match &cmd.command { - P2pCommands::Connect { addr } => match p2p.connect(&addr.0).await { - Ok(_) => { - println!("Connected to {addr}!"); + P2pCommands::Connect { addr } => { + let res = match &addr.0 { + PeerIdOrAddr::PeerId(peer_id) => p2p.connect(*peer_id, vec![]).await, + PeerIdOrAddr::Multiaddr(addr) => { + let peer_id = peer_id_from_multiaddr(addr)?; + p2p.connect(peer_id, vec![addr.clone()]).await + } + }; + match res { + Ok(_) => { + println!("Connected to {addr}!"); + } + Err(e) => return Err(e), } - Err(e) => return Err(e), - }, + } P2pCommands::Lookup { addr } => { let lookup = match addr { Some(addr) => p2p.lookup(&addr.0).await?, From a7971ae2bfb17487ef1e0a9c4263f46096baadaa Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Tue, 7 Mar 2023 15:08:50 -0700 Subject: [PATCH 2/8] refactor: cleans up PR to get it passing tests This change removes any changes that were not related to exposing gossipsub subscription events. Additionally it updates tests to pass using the new APIs. --- examples/embed/src/main.rs | 2 +- iroh-api/src/api.rs | 43 ++----- iroh-api/src/fs.rs | 1 - iroh-one/src/main.rs | 2 +- iroh-p2p/src/node.rs | 86 ++++++++----- iroh-p2p/src/rpc.rs | 3 - iroh-share/Cargo.toml | 2 - iroh-share/src/data.rs | 52 -------- iroh-share/src/iroh.rs | 19 --- iroh-share/src/lib.rs | 57 +-------- iroh-share/src/main.rs | 252 +++++++++++-------------------------- iroh-share/src/p2p_node.rs | 220 ++++++++++++++++++++++++++++++++ iroh-share/src/receiver.rs | 245 ++++++++++++++++++++++++++++++++++++ iroh-share/src/sender.rs | 165 ++++++++++++++++-------- 14 files changed, 717 insertions(+), 432 deletions(-) delete mode 100644 iroh-share/src/data.rs delete mode 100644 iroh-share/src/iroh.rs create mode 100644 iroh-share/src/p2p_node.rs diff --git a/examples/embed/src/main.rs b/examples/embed/src/main.rs index 7fba0af91..e00dc5d84 100644 --- a/examples/embed/src/main.rs +++ b/examples/embed/src/main.rs @@ -17,7 +17,7 @@ async fn main() -> Result<()> { "/ip4/0.0.0.0/tcp/0".parse().unwrap(), "/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap(), ]; - let (p2p,_network_events) = P2pService::new(p2p_config, dir, store.addr()).await?; + let p2p = P2pService::new(p2p_config, dir, store.addr()).await?; // Note by default this is configured with an indexer, but not with http resolvers. let iroh = IrohBuilder::new().store(store).p2p(p2p).build().await?; diff --git a/iroh-api/src/api.rs b/iroh-api/src/api.rs index 40d0c2ad0..947dd786c 100644 --- a/iroh-api/src/api.rs +++ b/iroh-api/src/api.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::fmt; use std::path::{Path, PathBuf}; @@ -9,17 +9,17 @@ use anyhow::{ensure, Context, Result}; use cid::Cid; use futures::stream::BoxStream; use futures::{StreamExt, TryStreamExt}; -use iroh_resolver::{ - resolver::Resolver, ContentLoader, FullLoader, FullLoaderConfig, LoaderFromProviders, -}; +use iroh_resolver::resolver::Resolver; use iroh_rpc_client::{Client, ClientStatus}; -use iroh_unixfs::builder::Entry as UnixfsEntry; +use iroh_unixfs::{ + builder::Entry as UnixfsEntry, + content_loader::{FullLoader, FullLoaderConfig}, +}; use iroh_util::{iroh_config_path, make_config}; use relative_path::RelativePathBuf; use tokio::io::{AsyncRead, AsyncReadExt}; use crate::store::add_blocks_to_store; -use crate::PeerId; /// API to interact with an iroh system. /// @@ -128,36 +128,7 @@ impl Api { ); tracing::debug!("get {:?}", ipfs_path); - self.get_with_resolver(ipfs_path, self.resolver.clone()) - } - - pub fn get_from( - &self, - ipfs_path: &IpfsPath, - peers: HashSet, - ) -> Result>> { - ensure!( - ipfs_path.cid().is_some(), - "IPFS path does not refer to a CID" - ); - - tracing::debug!("get {:?} from peers {:#?}", ipfs_path, peers); - // TODO(ramfox): path of least resistance to hack this together as POC. Might be the way - // was want to go, or, if it's bad news bears to have (potentially) more than one resolver, - // we can bake in passing down providers through a LoadConfig (or some similar name) that allows you to tune - // your actions down in the loader - let loader = LoaderFromProviders::new(self.client.clone(), peers); - // TODO(ramfox): is it okay to create these ad-hoc. If so, we probably shouldn't be storing - // one in general - let resolver = Resolver::new(loader); - self.get_with_resolver(ipfs_path, resolver) - } - - fn get_with_resolver( - &self, - ipfs_path: &IpfsPath, - resolver: Resolver, - ) -> Result>> { + let resolver = self.resolver.clone(); let results = resolver.resolve_recursive_with_paths(ipfs_path.clone()); let sub_path = ipfs_path.to_relative_string(); diff --git a/iroh-api/src/fs.rs b/iroh-api/src/fs.rs index d8fdee2a3..0732b95b8 100644 --- a/iroh-api/src/fs.rs +++ b/iroh-api/src/fs.rs @@ -32,7 +32,6 @@ async fn save_get_stream( while let Some(block) = blocks.next().await { let (path, out) = block?; let full_path = path.to_path(root_path); - println!("full path: {:?}", full_path); match out { OutType::Dir => { tokio::fs::create_dir_all(full_path).await?; diff --git a/iroh-one/src/main.rs b/iroh-one/src/main.rs index c17db4784..9f2e90c7f 100644 --- a/iroh-one/src/main.rs +++ b/iroh-one/src/main.rs @@ -46,7 +46,7 @@ async fn main() -> Result<()> { } } - let (store_rpc, (_network_events, p2p_rpc)) = { + let (store_rpc, p2p_rpc) = { let store_recv = Addr::new_mem(); let store_sender = store_recv.clone(); let p2p_recv = Addr::new_mem(); diff --git a/iroh-p2p/src/node.rs b/iroh-p2p/src/node.rs index bb5bc9cfe..32abbdbf7 100644 --- a/iroh-p2p/src/node.rs +++ b/iroh-p2p/src/node.rs @@ -1079,12 +1079,13 @@ mod tests { use crate::keys::{Keypair, MemoryStorage}; use bytes::Bytes; - use futures::TryStreamExt; + use futures::{future, TryStreamExt}; use rand::prelude::*; use rand_chacha::ChaCha8Rng; use ssh_key::private::Ed25519Keypair; use libp2p::{identity::Keypair as Libp2pKeypair, kad::record::Key}; + use tokio::task; use super::*; use anyhow::Result; @@ -1232,6 +1233,7 @@ mod tests { let client = RpcClient::new(cfg).await?; + let network_events = p2p.network_events(); let task = tokio::task::spawn(async move { p2p.run().await.unwrap() }); let client = client.try_p2p()?; @@ -1246,6 +1248,7 @@ mod tests { task, client, peer_id, + network_events, addr, dial_addr, }) @@ -1269,6 +1272,8 @@ mod tests { client: P2pClient, /// The node's peer_id peer_id: PeerId, + /// A channel to read the network events received by the node. + network_events: Receiver, /// The listening address for this node. addr: Multiaddr, /// A multiaddr that is a combination of the listening addr and peer_id. @@ -1421,11 +1426,10 @@ mod tests { #[tokio::test] async fn test_cancel_listen_for_identify() -> Result<()> { - let test_runner_a = TestRunnerBuilder::new().no_bootstrap().build().await?; + let mut test_runner_a = TestRunnerBuilder::new().no_bootstrap().build().await?; let peer_id: PeerId = "12D3KooWFma2D63TG9ToSiRsjFkoNm2tTihScTBAEdXxinYk5rwE" .parse() .unwrap(); - let mut network_events = test_runner_a.client.network_events().await?; test_runner_a .client .lookup(peer_id, None) @@ -1433,7 +1437,7 @@ mod tests { .unwrap_err(); // when lookup ends in error, we must ensure we // have canceled the lookup - let event = network_events.next().await.unwrap().unwrap(); + let event = test_runner_a.network_events.recv().await.unwrap(); if let NetworkEvent::CancelLookupQuery(got_peer_id) = event { assert_eq!(peer_id, got_peer_id); } else { @@ -1445,7 +1449,7 @@ mod tests { #[tokio::test] async fn test_gossipsub() -> Result<()> { - let test_runner_a = TestRunnerBuilder::new().no_bootstrap().build().await?; + let mut test_runner_a = TestRunnerBuilder::new().no_bootstrap().build().await?; // peer_id 12D3KooWLo6JTNKXfjkZtKf8ooLQoXVXUEeuu4YDY3CYqK6rxHXt let test_runner_b = TestRunnerBuilder::new() .no_bootstrap() @@ -1453,15 +1457,14 @@ mod tests { .build() .await?; let addrs_b = vec![test_runner_b.addr.clone()]; - let mut network_events_a = test_runner_a.client.network_events().await?; test_runner_a .client .connect(test_runner_b.peer_id, addrs_b) .await?; - match network_events_a.next().await { - Some(Ok(NetworkEvent::PeerConnected(peer_id))) => { + match test_runner_a.network_events.recv().await { + Some(NetworkEvent::PeerConnected(peer_id)) => { assert_eq!(test_runner_b.peer_id, peer_id); } Some(n) => { @@ -1479,28 +1482,35 @@ mod tests { // create topic let topic = libp2p::gossipsub::TopicHash::from_raw("test_topic"); // subscribe both to same topic - test_runner_a + let mut subscription_a = test_runner_a .client .gossipsub_subscribe(topic.clone()) .await?; - test_runner_b + let subscription_b = test_runner_b .client .gossipsub_subscribe(topic.clone()) .await?; - match network_events_a.next().await { - Some(Ok(NetworkEvent::Gossipsub(GossipsubEvent::Subscribed { + // Spawn a task to read all messages from b, but ignore them. + // This ensures the subscription request is actually processed. + task::spawn(subscription_b.for_each(|_| future::ready(()))); + + match subscription_a.next().await { + Some(Ok(GossipsubEvent::Subscribed { peer_id, topic: subscribed_topic, - }))) => { + })) => { assert_eq!(test_runner_b.peer_id, peer_id); assert_eq!(topic, subscribed_topic); } Some(n) => { - anyhow::bail!("unexpected network event: {:?}", n); + anyhow::bail!( + "unexpected network event, expecting a GossipsubEvent::Subscribed, got: {:?}", + n + ); } None => { - anyhow::bail!("expected NetworkEvent::Gossipsub(Subscribed), received no event"); + anyhow::bail!("expected GossipsubEvent::Subscribed, received no event"); } }; @@ -1529,20 +1539,24 @@ mod tests { .gossipsub_publish(topic.clone(), msg.clone()) .await?; - match network_events_a.next().await { - Some(Ok(NetworkEvent::Gossipsub(GossipsubEvent::Message { - from, message, .. - }))) => { + match subscription_a.next().await { + Some(Ok(GossipsubEvent::Message { from, message, .. })) => { assert_eq!(test_runner_b.peer_id, from); assert_eq!(topic, message.topic); assert_eq!(test_runner_b.peer_id, message.source.unwrap()); assert_eq!(msg.to_vec(), message.data); } - Some(n) => { - anyhow::bail!("unexpected network event: {:?}", n); + Some(Ok(n)) => { + anyhow::bail!( + "unexpected network event, expecting a GossipsubEvent::Message, got: {:?}", + n + ); + } + Some(Err(e)) => { + anyhow::bail!("unexpected network error: {:?}", e); } None => { - anyhow::bail!("expected NetworkEvent::Gossipsub(Message), received no event"); + anyhow::bail!("expected GossipsubEvent::Message, received no event"); } }; @@ -1550,16 +1564,23 @@ mod tests { .client .gossipsub_unsubscribe(topic.clone()) .await?; - match network_events_a.next().await { - Some(Ok(NetworkEvent::Gossipsub(GossipsubEvent::Unsubscribed { + + match subscription_a.next().await { + Some(Ok(GossipsubEvent::Unsubscribed { peer_id, topic: unsubscribe_topic, - }))) => { + })) => { assert_eq!(test_runner_b.peer_id, peer_id); assert_eq!(topic, unsubscribe_topic); } - Some(n) => { - anyhow::bail!("unexpected network event: {:?}", n); + Some(Ok(n)) => { + anyhow::bail!( + "unexpected network event, expecting a GossipsubEvent::Unsubscribed, got: {:?}", + n + ); + } + Some(Err(e)) => { + anyhow::bail!("unexpected network error: {:?}", e); } None => { anyhow::bail!("expected NetworkEvent::Gossipsub(Unsubscribed), received no event"); @@ -1581,7 +1602,7 @@ mod tests { println!("peer_a: {:?}", test_runner_a.peer_id); // peer_id 12D3KooWLo6JTNKXfjkZtKf8ooLQoXVXUEeuu4YDY3CYqK6rxHXt - let test_runner_b = TestRunnerBuilder::new() + let mut test_runner_b = TestRunnerBuilder::new() .no_bootstrap() .with_seed(ChaCha8Rng::from_seed([0; 32])) .build() @@ -1598,7 +1619,6 @@ mod tests { println!("peer_c: {:?}", test_runner_c.peer_id); - let mut network_events_b = test_runner_b.client.network_events().await?; // connect a and c to b test_runner_a .client @@ -1606,8 +1626,8 @@ mod tests { .await?; // expect a network event showing a & b have connected - match network_events_b.next().await { - Some(Ok(NetworkEvent::PeerConnected(peer_id))) => { + match test_runner_b.network_events.recv().await { + Some(NetworkEvent::PeerConnected(peer_id)) => { assert_eq!(test_runner_a.peer_id, peer_id); } Some(n) => { @@ -1624,8 +1644,8 @@ mod tests { .await?; // expect a network event showing b & c have connected - match network_events_b.next().await { - Some(Ok(NetworkEvent::PeerConnected(peer_id))) => { + match test_runner_b.network_events.recv().await { + Some(NetworkEvent::PeerConnected(peer_id)) => { assert_eq!(test_runner_c.peer_id, peer_id); } Some(n) => { diff --git a/iroh-p2p/src/rpc.rs b/iroh-p2p/src/rpc.rs index e568e79d3..d3fd76ed6 100644 --- a/iroh-p2p/src/rpc.rs +++ b/iroh-p2p/src/rpc.rs @@ -424,10 +424,7 @@ impl P2p { GossipsubEvent::Subscribed { topic, .. } | GossipsubEvent::Unsubscribed {topic, .. } | GossipsubEvent::Message { topic, .. } => { - println!("gossipsub event: {:#?}", event); - println!("in message topic {:#?}, expected topic {:#?}", topic, t); if *topic == t { - println!("topic match!"); yield Box::new(GossipsubSubscribeResponse {event}); } }, diff --git a/iroh-share/Cargo.toml b/iroh-share/Cargo.toml index 81912f0fc..cc5b41c8f 100644 --- a/iroh-share/Cargo.toml +++ b/iroh-share/Cargo.toml @@ -19,8 +19,6 @@ futures.workspace = true iroh-metrics.workspace = true iroh-p2p.workspace = true iroh-resolver.workspace = true -iroh-embed.workspace = true -iroh-api.workspace = true iroh-rpc-client.workspace = true iroh-rpc-types.workspace = true iroh-store.workspace = true diff --git a/iroh-share/src/data.rs b/iroh-share/src/data.rs deleted file mode 100644 index 7c9a19e7f..000000000 --- a/iroh-share/src/data.rs +++ /dev/null @@ -1,52 +0,0 @@ -use anyhow::{Context, Result}; -use futures::Stream; -use iroh_resolver::{ - resolver::{Out, OutPrettyReader, Resolver, UnixfsType}, - Path, -}; -use iroh_unixfs::{content_loader::ContentLoader, Link}; - -#[derive(Debug)] -pub struct Data { - resolver: Resolver, - root: Out, -} - -impl Data -where - C: ContentLoader, -{ - pub fn typ(&self) -> UnixfsType { - self.root.metadata().unixfs_type.unwrap() - } - - pub fn is_file(&self) -> bool { - self.typ() == UnixfsType::File - } - - pub fn is_dir(&self) -> bool { - self.typ() == UnixfsType::Dir - } - - pub fn read_dir(&self) -> Result> + '_>> { - self.root - .unixfs_read_dir(&self.resolver, Default::default()) - } - - pub fn pretty(self) -> Result> { - self.root.pretty(self.resolver, Default::default(), None) - } - - pub async fn read_file(&self, link: &Link) -> Result> { - let root = self - .resolver - .resolve(Path::from_cid(link.cid)) - .await - .context("resolve")?; - - Ok(Data { - resolver: self.resolver.clone(), - root, - }) - } -} diff --git a/iroh-share/src/iroh.rs b/iroh-share/src/iroh.rs deleted file mode 100644 index b757c0181..000000000 --- a/iroh-share/src/iroh.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::path::Path; - -use anyhow::Result; -use iroh_embed::{Iroh, IrohBuilder, Libp2pConfig, P2pService, RocksStoreService}; - -pub async fn build(port: u16, db_path: &Path) -> Result { - let db_path = db_path.to_path_buf(); - let store = RocksStoreService::new(db_path.clone()).await?; - - let mut libp2p_config = Libp2pConfig::default(); - libp2p_config.listening_multiaddrs = vec![format!("/ip4/0.0.0.0/tcp/{port}").parse().unwrap()]; - libp2p_config.bootstrap_peers = Default::default(); // disable bootstrap for now - libp2p_config.relay_server = false; - libp2p_config.max_conns_in = 8; - libp2p_config.max_conns_out = 8; - - let (p2p,_network_events) = P2pService::new(libp2p_config, db_path, store.addr()).await?; - IrohBuilder::new().store(store).p2p(p2p).build().await -} diff --git a/iroh-share/src/lib.rs b/iroh-share/src/lib.rs index 8991eba02..720134553 100644 --- a/iroh-share/src/lib.rs +++ b/iroh-share/src/lib.rs @@ -1,62 +1,17 @@ -mod data; -mod iroh; +mod p2p_node; mod receiver; mod sender; use cid::Cid; -use libp2p::{Multiaddr, PeerId}; use serde::{Deserialize, Serialize}; -// pub use crate::receiver::{ProgressEvent, Receiver}; -// pub use crate::sender::Sender; -pub use crate::receiver::ProgressEvent; - -// TODO(ramfox): remove re export -pub use crate::iroh::build as build_iroh; - -use anyhow::Result; -use libp2p::gossipsub::{Sha256Topic, TopicHash}; -use rand::Rng; - -/// Ticket describing the peer, their addresses, and the topic -/// on which to discuss the data transfer -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct Ticket { - pub peer_id: PeerId, - pub addrs: Vec, - pub topic: String, -} - -impl Ticket { - pub fn new(peer_id: PeerId, addrs: Vec) -> Self { - let id: u64 = rand::thread_rng().gen(); - let topic = Sha256Topic::new(format!("iroh-share-{id}")) - .hash() - .to_string(); - Self { - peer_id, - addrs, - topic, - } - } - - pub fn topic_hash(&self) -> TopicHash { - TopicHash::from_raw(self.topic.clone()) - } - - pub fn as_bytes(&self) -> Vec { - bincode::serialize(self).expect("failed to serialize") - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - let ticket = bincode::deserialize(bytes)?; - Ok(ticket) - } -} +pub use crate::p2p_node::Ticket; +pub use crate::receiver::{ProgressEvent, Receiver, Transfer as ReceiverTransfer}; +pub use crate::sender::{Sender, Transfer as SenderTransfer}; /// Messages sent from the sender. #[derive(Debug, Clone, Serialize, Deserialize)] -pub enum SenderMessage { +enum SenderMessage { Start { /// The root Cid of the content. root: Cid, @@ -67,7 +22,7 @@ pub enum SenderMessage { /// Messages sent from the receiver. #[derive(Debug, Clone, Serialize, Deserialize)] -pub enum ReceiverMessage { +enum ReceiverMessage { /// Transfer was completed successfully. FinishOk, /// Transfer failed. diff --git a/iroh-share/src/main.rs b/iroh-share/src/main.rs index 7b4f050e0..027368d7f 100644 --- a/iroh-share/src/main.rs +++ b/iroh-share/src/main.rs @@ -1,18 +1,12 @@ use std::path::PathBuf; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{ensure, Context, Result}; use clap::{Parser, Subcommand}; use futures::stream::StreamExt; -use iroh_p2p::GossipsubEvent; -use iroh_share::{ReceiverMessage, SenderMessage, Ticket}; -use iroh_unixfs::chunker::ChunkerConfig; -use rand::Rng; -use tracing::{debug, info, warn}; +use iroh_share::{ProgressEvent, Receiver, Sender, Ticket}; +use tokio::io::AsyncWriteExt; use tracing_subscriber::{fmt, prelude::*, EnvFilter}; -use iroh_api::{IpfsPath, UnixfsConfig, UnixfsEntry, DEFAULT_CHUNKS_SIZE}; -use libp2p::gossipsub::Sha256Topic; - #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] struct Args { @@ -52,107 +46,37 @@ async fn main() -> Result<()> { Commands::Send { path } => { println!("Sending: {}", path.display()); - ensure!(path.exists(), "provided file or directory does not exist"); - ensure!( - path.is_file() || path.is_dir(), - "currently only supports files or directories" - ); - // TODO: allow db specification let sender_dir = tempfile::tempdir().unwrap(); let sender_db = sender_dir.path().join("db"); - println!("Starting up Iroh services..."); - let iroh = iroh_share::build_iroh(9990, &sender_db).await?; - let entry = UnixfsEntry::from_path( - &path, - UnixfsConfig { - wrap: true, - chunker: Some(ChunkerConfig::Fixed(DEFAULT_CHUNKS_SIZE)), - }, - ) - .await?; - - let mut progress = iroh.api().add_stream(entry).await?; - let mut root = None; - let mut num_parts = 0; - while let Some(ev) = progress.next().await { - let (cid, _) = ev?; - root = Some(cid); - num_parts += 1; - } - - let root = root.unwrap(); - - let id: u64 = rand::thread_rng().gen(); - let topic_hash = Sha256Topic::new(format!("iroh-share-{id}")).hash(); - let th = topic_hash.clone(); - - let (done_sender, done_receiver) = futures::channel::oneshot::channel(); - - let mut events = iroh.api().p2p()?.subscribe(topic_hash.to_string()).await?; - let p2p = iroh.api().p2p()?; - let gossip_task_source = tokio::task::spawn(async move { - let mut current_peer = None; - while let Some(Ok(e)) = events.next().await { - match e { - GossipsubEvent::Subscribed { peer_id, topic } => { - if topic == th && current_peer.is_none() { - info!("connected to {}", peer_id); - current_peer = Some(peer_id); - - let start = - bincode::serialize(&SenderMessage::Start { root, num_parts }) - .expect("serialize failure"); - p2p.publish(topic.to_string(), start.into()).await.unwrap(); - } - } - GossipsubEvent::Message { from, message, .. } => { - println!("received message from {}", from); - debug!("received message from {}", from); - if let Some(current_peer) = current_peer { - if from == current_peer { - match bincode::deserialize(&message.data) { - Ok(ReceiverMessage::FinishOk) => { - println!("finished transfer"); - info!("finished transfer"); - done_sender.send(Ok(())).ok(); - break; - } - Ok(ReceiverMessage::FinishError(err)) => { - println!("transfer failed: {}", err); - info!("transfer failed: {}", err); - done_sender.send(Err(anyhow!("{}", err))).ok(); - break; - } - Err(err) => { - warn!("unexpected message: {:?}", err); - } - } - } - } - } - _ => {} - } - } - }); - - let peer_id = iroh.api().p2p()?.peer_id().await?; - let addrs = iroh.api().p2p()?.addrs().await?; - info!("Available addrs: {:?}", addrs); - - let ticket = Ticket { - peer_id, - addrs, - topic: topic_hash.to_string(), - }; - + let port = 9990; + let sender = Sender::new(port, &sender_db) + .await + .context("failed to create sender")?; + + ensure!(path.exists(), "provided file does not exist"); + ensure!(path.is_file(), "currently only supports files"); + + // TODO: streaming read + let name = path + .file_name() + .ok_or_else(|| anyhow::anyhow!("missing file name"))?; + let name = name + .to_str() + .ok_or_else(|| anyhow::anyhow!("file name must be valid utf8"))?; + + let data = tokio::fs::read(&path).await?; + let sender_transfer = sender + .transfer_from_data(name, data.into()) + .await + .context("transfer")?; + + let ticket = sender_transfer.ticket(); let ticket_bytes = ticket.as_bytes(); let ticket_str = multibase::encode(multibase::Base::Base64, &ticket_bytes); println!("Ticket:\n{ticket_str}\n"); - done_receiver.await??; - iroh.stop().await?; - gossip_task_source.await?; + sender_transfer.done().await?; } Commands::Receive { ticket, out } => { println!("Receiving"); @@ -164,89 +88,57 @@ async fn main() -> Result<()> { let sender_db = sender_dir.path().join("db"); let port = 9991; - let iroh = iroh_share::build_iroh(port, &sender_db).await?; - let addrs = ticket.addrs.clone(); - iroh.api().p2p()?.connect(ticket.peer_id, addrs).await?; - iroh.api().p2p()?.add_pubsub_peer(ticket.peer_id).await?; - let mut events = iroh.api().p2p()?.subscribe(ticket.topic.clone()).await?; - - let (root_sender, root_receiver) = futures::channel::oneshot::channel(); - let expected_sender = ticket.peer_id; - let gossipsub_task_source = tokio::task::spawn(async move { - let mut root_sender = Some(root_sender); - - while let Some(Ok(ev)) = events.next().await { - if let GossipsubEvent::Message { from, message, .. } = ev { - if from == expected_sender { - match bincode::deserialize(&message.data) { - Ok(SenderMessage::Start { root, .. }) => { - if let Some(root_sender) = root_sender.take() { - root_sender.send(root).ok(); - } - } - Err(err) => { - warn!("got unexpected message from {}: {:?}", from, err); - } - } - } else { - warn!("got message from unexpected sender: {:?}", from); + let receiver = Receiver::new(port, &sender_db) + .await + .context("failed to create sender")?; + let mut receiver_transfer = receiver + .transfer_from_ticket(&ticket) + .await + .context("failed to read transfer")?; + let data = receiver_transfer.recv().await?; + let mut progress = receiver_transfer.progress()?; + + tokio::spawn(async move { + while let Some(ev) = progress.next().await { + match ev { + Ok(ProgressEvent::Piece { index, total }) => { + println!("transferred: {index}/{total}"); + } + Err(e) => { + eprintln!("transfer failed: {e}"); } } } }); - let root = root_receiver.await?; - let mut peers = std::collections::HashSet::new(); - peers.insert(expected_sender); - let ipfs_path = IpfsPath::from_cid(root); - match iroh.api().get_from(&ipfs_path, peers) { - Ok(blocks) => { - let mut out_dir = std::env::current_dir()?; - if let Some(out) = out { - out_dir = out_dir.join(out); - } - println!("want to save to {:#?}", out_dir); - let msg = - match iroh_api::fs::write_get_stream(&ipfs_path, blocks, Some(&out_dir)) - .await - { - Ok(p) => { - println!("Received all data, written to: {}", p.to_str().unwrap()); - ReceiverMessage::FinishOk - } - Err(err) => { - println!("Error saving file(s): {err}"); - ReceiverMessage::FinishError(err.to_string()) - } - }; - iroh.api() - .p2p()? - .publish( - ticket.topic.clone(), - bincode::serialize(&msg) - .expect("failed to serialize message") - .into(), - ) - .await - .ok(); - } - Err(e) => { - let msg = ReceiverMessage::FinishError(e.to_string()); - iroh.api() - .p2p()? - .publish( - ticket.topic.clone(), - bincode::serialize(&msg) - .expect("failed to serialize message") - .into(), - ) - .await - .ok(); - println!("error with transfer {}", e); - } + + let mut out_dir = std::env::current_dir()?; + if let Some(out) = out { + out_dir = out_dir.join(out); + } + tokio::fs::create_dir_all(&out_dir) + .await + .with_context(|| format!("failed to create {}", out_dir.display()))?; + + let out = tokio::fs::canonicalize(out_dir).await?; + + let mut reader = data.read_dir()?.unwrap(); + while let Some(link) = reader.next().await { + let link = link?; + let file_content = data.read_file(&link).await?; + let path = out.join(link.name.unwrap_or_default()); + println!("Writing {}", path.display()); + let mut file = tokio::fs::File::create(&path) + .await + .with_context(|| format!("create file: {}", path.display()))?; + let mut content = file_content.pretty()?; + tokio::io::copy(&mut content, &mut file) + .await + .context("copy")?; + file.flush().await?; } - iroh.stop().await?; - gossipsub_task_source.await?; + receiver_transfer.finish().await?; + println!("Received all data, written to: {}", out.display()); } } diff --git a/iroh-share/src/p2p_node.rs b/iroh-share/src/p2p_node.rs new file mode 100644 index 000000000..4540abc83 --- /dev/null +++ b/iroh-share/src/p2p_node.rs @@ -0,0 +1,220 @@ +use std::{collections::HashSet, path::Path, sync::Arc}; + +use anyhow::{ensure, Result}; +use async_trait::async_trait; +use cid::Cid; +use iroh_p2p::{config, Config, Keychain, MemoryStorage, Node}; +use iroh_resolver::resolver::Resolver; +use iroh_rpc_client::Client; +use iroh_rpc_types::Addr; +use iroh_unixfs::{ + content_loader::{ContentLoader, ContextId, LoaderContext, IROH_STORE}, + parse_links, LoadedCid, Source, +}; +use libp2p::{Multiaddr, PeerId}; +use serde::{Deserialize, Serialize}; +use tokio::{sync::Mutex, task::JoinHandle}; +use tracing::{error, warn}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct Ticket { + pub peer_id: PeerId, + pub addrs: Vec, + pub topic: String, +} + +impl Ticket { + pub fn as_bytes(&self) -> Vec { + bincode::serialize(self).expect("failed to serialize") + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + let ticket = bincode::deserialize(bytes)?; + Ok(ticket) + } +} + +#[derive(Debug)] +pub struct P2pNode { + p2p_task: JoinHandle<()>, + store_task: JoinHandle<()>, + rpc: Client, + resolver: Resolver, +} + +/// Wrapper struct to implement custom content loading +#[derive(Debug, Clone)] +pub struct Loader { + client: Client, + providers: Arc>>, +} + +impl Loader { + pub fn new(client: Client) -> Self { + Loader { + client, + providers: Arc::new(Mutex::new(HashSet::new())), + } + } + + pub fn providers(&self) -> &Arc>> { + &self.providers + } +} + +#[async_trait] +impl ContentLoader for Loader { + async fn load_cid(&self, cid: &Cid, _ctx: &LoaderContext) -> Result { + let cid = *cid; + let providers = self.providers.lock().await.clone(); + + match self.client.try_store()?.get(cid).await { + Ok(Some(data)) => { + return Ok(LoadedCid { + data, + source: Source::Store(IROH_STORE), + }); + } + Ok(None) => {} + Err(err) => { + warn!("failed to fetch data from store {}: {:?}", cid, err); + } + } + + ensure!(!providers.is_empty(), "no providers supplied"); + + // TODO: track context id + let res = self + .client + .try_p2p()? + .fetch_bitswap(0, cid, providers.clone()) + .await; + let bytes = match res { + Ok(bytes) => bytes, + Err(err) => { + error!("Bitswap error: {:#?}", err); + return Err(err); + } + }; + + let cloned = bytes.clone(); + let rpc = self.clone(); + { + let clone2 = cloned.clone(); + let links = + tokio::task::spawn_blocking(move || parse_links(&cid, &clone2).unwrap_or_default()) + .await + .unwrap_or_default(); + + rpc.client.try_store()?.put(cid, cloned, links).await?; + } + + Ok(LoadedCid { + data: bytes, + source: Source::Bitswap, + }) + } + + async fn stop_session(&self, ctx: ContextId) -> Result<()> { + self.client + .try_p2p()? + .stop_session_bitswap(ctx.into()) + .await?; + Ok(()) + } + + async fn has_cid(&self, cid: &Cid) -> Result { + Ok(self.client.try_store()?.has(*cid).await?) + } +} + +impl P2pNode { + pub async fn new(port: u16, db_path: &Path) -> Result { + let rpc_p2p_addr_server = Addr::new_mem(); + let rpc_p2p_addr_client = rpc_p2p_addr_server.clone(); + let rpc_store_addr_server = Addr::new_mem(); + let rpc_store_addr_client = rpc_store_addr_server.clone(); + + let rpc_store_client_config = iroh_rpc_client::Config { + p2p_addr: Some(rpc_p2p_addr_client.clone()), + store_addr: Some(rpc_store_addr_client.clone()), + gateway_addr: None, + channels: Some(1), + }; + let rpc_p2p_client_config = iroh_rpc_client::Config { + p2p_addr: Some(rpc_p2p_addr_client.clone()), + store_addr: Some(rpc_store_addr_client.clone()), + gateway_addr: None, + channels: Some(1), + }; + let mut libp2p_config = config::Libp2pConfig::default(); + libp2p_config.listening_multiaddrs = + vec![format!("/ip4/0.0.0.0/tcp/{port}").parse().unwrap()]; + libp2p_config.mdns = false; + libp2p_config.kademlia = true; + libp2p_config.autonat = true; + libp2p_config.relay_client = true; + libp2p_config.bootstrap_peers = Default::default(); // disable bootstrap for now + libp2p_config.relay_server = false; + libp2p_config.max_conns_in = 8; + libp2p_config.max_conns_out = 8; + let config = Config { + libp2p: libp2p_config, + rpc_client: rpc_p2p_client_config.clone(), + key_store_path: db_path.parent().unwrap().to_path_buf(), + }; + + let rpc = Client::new(rpc_p2p_client_config).await?; + let loader = Loader::new(rpc.clone()); + let resolver = iroh_resolver::resolver::Resolver::new(loader); + + let store_config = iroh_store::Config { + path: db_path.to_path_buf(), + rpc_client: rpc_store_client_config, + }; + + let store = if store_config.path.exists() { + iroh_store::Store::open(store_config).await? + } else { + iroh_store::Store::create(store_config).await? + }; + + let kc = Keychain::::new(); + let mut p2p = Node::new(config, rpc_p2p_addr_server, kc).await?; + + let p2p_task = tokio::task::spawn(async move { + if let Err(err) = p2p.run().await { + error!("{:?}", err); + } + }); + + let store_task = tokio::spawn(async move { + iroh_store::rpc::new(rpc_store_addr_server, store) + .await + .unwrap() + }); + + Ok(Self { + p2p_task, + store_task, + rpc, + resolver, + }) + } + + pub fn rpc(&self) -> &Client { + &self.rpc + } + + pub fn resolver(&self) -> &Resolver { + &self.resolver + } + + pub async fn close(self) -> Result<()> { + self.rpc.try_p2p().unwrap().shutdown().await?; + self.store_task.abort(); + self.p2p_task.await?; + self.store_task.await.ok(); + Ok(()) + } +} diff --git a/iroh-share/src/receiver.rs b/iroh-share/src/receiver.rs index c147ae651..6c6b0a659 100644 --- a/iroh-share/src/receiver.rs +++ b/iroh-share/src/receiver.rs @@ -1,4 +1,249 @@ +use anyhow::{anyhow, ensure, Context, Result}; +use futures::{ + channel::{oneshot::channel as oneshot, oneshot::Receiver as OneShotReceiver}, + Stream, StreamExt, +}; +use iroh_resolver::resolver::{Out, OutPrettyReader, OutType, Path, Resolver, UnixfsType}; +use iroh_rpc_types::GossipsubEvent; +use iroh_unixfs::Link; +use libp2p::gossipsub::TopicHash; +use tokio::sync::mpsc::{channel, Receiver as ChannelReceiver}; +use tokio::task::JoinHandle; +use tokio_stream::wrappers::ReceiverStream; +use tracing::{debug, error, info, warn}; + +use crate::SenderMessage; +use crate::{ + p2p_node::{Loader, P2pNode, Ticket}, + ReceiverMessage, +}; + +#[derive(Debug)] +pub struct Receiver { + p2p: P2pNode, +} + +impl Receiver { + pub async fn new(port: u16, db_path: &std::path::Path) -> Result { + let p2p = P2pNode::new(port, db_path).await?; + + Ok(Receiver { p2p }) + } + + pub async fn transfer_from_ticket(self, ticket: &Ticket) -> Result { + // Connect to the sender + info!("connecting"); + let Receiver { p2p } = self; + let p2p_rpc = p2p.rpc().try_p2p()?; + p2p_rpc + .connect(ticket.peer_id, ticket.addrs.clone()) + .await?; + p2p_rpc.gossipsub_add_explicit_peer(ticket.peer_id).await?; + let topic = TopicHash::from_raw(&ticket.topic); + let mut subscription = p2p_rpc.gossipsub_subscribe(topic.clone()).await?; + + let expected_sender = ticket.peer_id; + let resolver = p2p.resolver().clone(); + let (progress_sender, progress_receiver) = channel(1024); + let (data_sender, data_receiver) = oneshot(); + + // add provider + resolver + .loader() + .providers() + .lock() + .await + .insert(expected_sender); + + let rpc = p2p.rpc().clone(); + + let gossip_task_source = tokio::task::spawn(async move { + let mut data_sender = Some(data_sender); + + loop { + match subscription.next().await { + Some(Ok(GossipsubEvent::Message { + id: _, + from, + message, + topic: _, + })) => { + if from == expected_sender { + match bincode::deserialize(&message.data) { + Ok(SenderMessage::Start { root, num_parts }) => { + let results = resolver.resolve_recursive(Path::from_cid(root)); + tokio::pin!(results); + // root is the first + let mut index = 1; + let mut has_err = None; + while let Some(res) = results.next().await { + let msg = match &res { + Ok(_out) => Ok(ProgressEvent::Piece { + index, + total: num_parts, + }), + Err(err) => { + has_err = Some(err.to_string()); + Err(err.to_string()) + } + }; + debug!("progress {}/{}", index, num_parts); + progress_sender.send(msg).await.unwrap(); + + if let Some(data_sender) = data_sender.take() { + data_sender.send(res).ok(); + } + + // If there was an error abort. + if has_err.is_some() { + break; + } + index += 1; + } + info!("transfer completed"); + drop(progress_sender); + + // TODO: send finish message or error + let msg = if let Some(error) = has_err.take() { + ReceiverMessage::FinishError(error) + } else { + ReceiverMessage::FinishOk + }; + rpc.try_p2p() + .expect("missing p2p rpc") + .gossipsub_publish( + topic, + bincode::serialize(&msg) + .expect("failed to serialize") + .into(), + ) + .await + .ok(); + } + Err(err) => { + warn!("got unexpected message from {}: {:?}", from, err); + } + } + // we only receive a single iteration + break; + } else { + warn!("got message from unexpected sender: {:?}", from); + } + } + // Ignore the subscribed messasges + Some(Ok(GossipsubEvent::Subscribed { .. })) => {} + // Ignore the unsubscribed messasges + Some(Ok(GossipsubEvent::Unsubscribed { .. })) => {} + Some(Err(e)) => { + error!("got unexpected error: {:?}", e); + break; + } + None => { + error!("expected subscription message got none"); + break; + } + } + } + }); + + Ok(Transfer { + gossip_task_source, + p2p, + data_receiver: Some(data_receiver), + progress_receiver: Some(progress_receiver), + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum ProgressEvent { Piece { index: usize, total: usize }, } + +#[derive(Debug)] +pub struct Transfer { + p2p: P2pNode, + gossip_task_source: JoinHandle<()>, + data_receiver: Option>>, + progress_receiver: Option>>, +} + +impl Transfer { + pub async fn recv(&mut self) -> Result { + let data_receiver = self + .data_receiver + .take() + .ok_or_else(|| anyhow!("recv must only be called once"))?; + let root = data_receiver.await??; + + ensure!( + root.metadata().typ == OutType::Unixfs, + "expected unixfs data" + ); + + Ok(Data { + resolver: self.p2p.resolver().clone(), + root, + }) + } + + pub fn progress( + &mut self, + ) -> Result>> { + let progress = self + .progress_receiver + .take() + .ok_or_else(|| anyhow!("progerss must only be called once"))?; + Ok(ReceiverStream::new(progress)) + } + + /// Finish and finalize the transfer. + pub async fn finish(self) -> Result<()> { + self.gossip_task_source.await?; + self.p2p.close().await?; + + Ok(()) + } +} + +#[derive(Debug)] +pub struct Data { + resolver: Resolver, + root: Out, +} + +impl Data { + pub fn typ(&self) -> UnixfsType { + self.root.metadata().unixfs_type.unwrap() + } + + pub fn is_file(&self) -> bool { + self.typ() == UnixfsType::File + } + + pub fn is_dir(&self) -> bool { + self.typ() == UnixfsType::Dir + } + + pub fn read_dir(&self) -> Result> + '_>> { + self.root + .unixfs_read_dir(&self.resolver, Default::default()) + } + + pub fn pretty(self) -> Result> { + self.root.pretty(self.resolver, Default::default(), None) + } + + pub async fn read_file(&self, link: &Link) -> Result { + let root = self + .resolver + .resolve(Path::from_cid(link.cid)) + .await + .context("resolve")?; + + Ok(Data { + resolver: self.resolver.clone(), + root, + }) + } +} diff --git a/iroh-share/src/sender.rs b/iroh-share/src/sender.rs index 58d182f5e..938310571 100644 --- a/iroh-share/src/sender.rs +++ b/iroh-share/src/sender.rs @@ -1,63 +1,72 @@ use std::path::Path; -use anyhow::{anyhow, Result}; -use futures::{channel::oneshot, stream::BoxStream, StreamExt}; -use iroh_api::{Cid, UnixfsEntry}; -use iroh_api::{GossipsubEvent, P2pApi}; -use iroh_embed::Iroh; +use anyhow::{anyhow, Context, Result}; +use bytes::Bytes; +use futures::channel::oneshot::{channel as oneshot, Receiver as OneShotReceiver}; +use futures::StreamExt; +use iroh_rpc_types::GossipsubEvent; +use iroh_unixfs::builder::{DirectoryBuilder, FileBuilder}; +use libp2p::gossipsub::Sha256Topic; +use rand::Rng; use tokio::task::JoinHandle; use tracing::{debug, info, warn}; -use crate::{iroh::build as build_iroh, ReceiverMessage, SenderMessage, Ticket}; +use crate::{ + p2p_node::{P2pNode, Ticket}, + ReceiverMessage, SenderMessage, +}; +/// The sending part of the data transfer. +#[derive(Debug)] pub struct Sender { - iroh: Iroh, + p2p: P2pNode, } -type EventStream = BoxStream<'static, Result>; -type ProgressStream = BoxStream<'static, Result<(Cid, u64)>>; - impl Sender { - pub async fn new(database_path: &Path) -> Result { - let iroh = build_iroh(9990, database_path).await?; - Ok(Self { iroh }) - } + pub async fn new(port: u16, db_path: &Path) -> Result { + let p2p = P2pNode::new(port, db_path).await?; - pub async fn make_available(&self, entry: UnixfsEntry) -> Result { - self.iroh.api().add_stream(entry).await + Ok(Sender { p2p }) } - pub async fn transfer(&self, root: Cid, num_parts: usize) -> Result { - Transfer::new(self.iroh.api().p2p()?.clone(), root, num_parts).await - } -} + pub async fn transfer_from_dir_builder( + self, + dir_builder: DirectoryBuilder, + ) -> Result { + let id = self.next_id(); + let Sender { p2p } = self; -struct Transfer { - api: P2pApi, - ticket: Ticket, - // progress: TODO - event_task: JoinHandle<()>, - done: oneshot::Receiver>, -} + let t = Sha256Topic::new(format!("iroh-share-{id}")); + let root_dir = dir_builder.build().await?; -// make available progress -// transfer started -// transfer succeeded -// transfer failed + let (done_sender, done_receiver) = oneshot(); -impl Transfer { - pub async fn new(api: P2pApi, root: Cid, num_parts: usize) -> Result { - let peer_id = api.peer_id().await?; - let addrs = api.addrs().await?; - let ticket = Ticket::new(peer_id, addrs); - let mut events = api.subscribe(ticket.topic.clone()).await?; - let th = ticket.topic_hash(); - let (done_sender, done_receiver) = futures::channel::oneshot::channel(); - let p2p = api.clone(); - let event_task = tokio::task::spawn(async move { + let p2p_rpc = p2p.rpc().try_p2p()?; + let store = p2p.rpc().try_store()?; + let (root, num_parts) = { + let parts = root_dir.encode(); + tokio::pin!(parts); + let mut num_parts = 0; + let mut root_cid = None; + while let Some(part) = parts.next().await { + let (cid, bytes, links) = part?.into_parts(); + num_parts += 1; + root_cid = Some(cid); + store.put(cid, bytes, links).await?; + } + (root_cid.unwrap(), num_parts) + }; + + let topic_hash = t.hash(); + let th = topic_hash.clone(); + + // subscribe to the topic, to receive responses + let mut subscription = p2p_rpc.gossipsub_subscribe(topic_hash.clone()).await?; + let p2p2 = p2p_rpc.clone(); + let gossip_task_source = tokio::task::spawn(async move { let mut current_peer = None; - while let Some(Ok(e)) = events.next().await { - match e { + while let Some(Ok(event)) = subscription.next().await { + match event { GossipsubEvent::Subscribed { peer_id, topic } => { if topic == th && current_peer.is_none() { info!("connected to {}", peer_id); @@ -66,23 +75,22 @@ impl Transfer { let start = bincode::serialize(&SenderMessage::Start { root, num_parts }) .expect("serialize failure"); - p2p.publish(topic.to_string(), start.into()).await.unwrap(); + p2p2.gossipsub_publish(topic.clone(), start.into()) + .await + .unwrap(); } } GossipsubEvent::Message { from, message, .. } => { - println!("received message from {}", from); debug!("received message from {}", from); if let Some(current_peer) = current_peer { if from == current_peer { match bincode::deserialize(&message.data) { Ok(ReceiverMessage::FinishOk) => { - println!("finished transfer"); info!("finished transfer"); done_sender.send(Ok(())).ok(); break; } Ok(ReceiverMessage::FinishError(err)) => { - println!("transfer failed: {}", err); info!("transfer failed: {}", err); done_sender.send(Err(anyhow!("{}", err))).ok(); break; @@ -99,17 +107,68 @@ impl Transfer { } }); - Ok(Self { - api, + let (peer_id, addrs) = p2p_rpc + .get_listening_addrs() + .await + .context("getting p2p info")?; + info!("Available addrs: {:?}", addrs); + let topic_string = topic_hash.to_string(); + + let ticket = Ticket { + peer_id, + addrs, + topic: topic_string, + }; + + Ok(Transfer { ticket, - event_task, - done: done_receiver, + gossip_task_source, + done_receiver, + p2p, }) } + pub async fn transfer_from_data( + self, + name: impl Into, + data: Bytes, + ) -> Result { + let name = name.into(); + // wrap in directory to preserve the name + let file = FileBuilder::new() + .name(name) + .content_bytes(data) + .build() + .await?; + let root_dir = DirectoryBuilder::new().add_file(file); + + self.transfer_from_dir_builder(root_dir).await + } + + fn next_id(&self) -> u64 { + rand::thread_rng().gen() + } +} + +#[derive(Debug)] +pub struct Transfer { + p2p: P2pNode, + ticket: Ticket, + done_receiver: OneShotReceiver>, + gossip_task_source: JoinHandle<()>, +} + +impl Transfer { + pub fn ticket(&self) -> &Ticket { + &self.ticket + } + + /// Waits until the transfer is done. pub async fn done(self) -> Result<()> { - self.done.await??; - self.event_task.await?; + self.done_receiver.await??; + self.gossip_task_source.await?; + self.p2p.close().await?; + Ok(()) } } From 3d22ba07c4ba50d319d8ea30f38a9bfe8a9f2270 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Wed, 8 Mar 2023 17:22:51 -0700 Subject: [PATCH 3/8] build: commit Cargo.lock --- .gitignore | 1 - Cargo.lock | 7654 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 7654 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 699c97053..d06223966 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /target /iroh_gateway/test_files/* .env -Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..aa6d67ee4 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7654 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", + "rand_core 0.6.4", +] + +[[package]] +name = "aes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" +dependencies = [ + "aes-soft", + "aesni", + "cipher 0.2.5", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" +dependencies = [ + "aead 0.3.2", + "aes 0.6.0", + "cipher 0.2.5", + "ctr 0.6.0", + "ghash 0.3.1", + "subtle", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead 0.4.3", + "aes 0.7.5", + "cipher 0.3.0", + "ctr 0.8.0", + "ghash 0.4.4", + "subtle", +] + +[[package]] +name = "aes-soft" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" +dependencies = [ + "cipher 0.2.5", + "opaque-debug", +] + +[[package]] +name = "aesni" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +dependencies = [ + "cipher 0.2.5", + "opaque-debug", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.8", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom 0.2.8", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anyhow" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +dependencies = [ + "backtrace", +] + +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "asn1-rs" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" +dependencies = [ + "asn1-rs-derive 0.1.0", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf6690c370453db30743b373a60ba498fc0d6d83b11f4abfd87a84a075db5dd4" +dependencies = [ + "asn1-rs-derive 0.4.0", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "asn1_der" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22d1f4b888c298a027c99dc9048015fac177587de20fc30232a057dfbe24a21" + +[[package]] +name = "async-broadcast" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d26004fe83b2d1cd3a97609b21e39f9a31535822210fe83205d2ce48866ea61" +dependencies = [ + "event-listener", + "futures-core", + "parking_lot 0.12.1", +] + +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-compression" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite 0.2.9", + "tokio", +] + +[[package]] +name = "async-io" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" +dependencies = [ + "async-lock", + "autocfg", + "concurrent-queue", + "futures-lite", + "libc", + "log", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "windows-sys", +] + +[[package]] +name = "async-lock" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" +dependencies = [ + "event-listener", + "futures-lite", +] + +[[package]] +name = "async-recursion" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b015a331cc64ebd1774ba119538573603427eaace0a1950c423ab971f903796" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "asynchronous-codec" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06a0daa378f5fd10634e44b0a29b2a87b890657658e072a30d6f26e57ddee182" +dependencies = [ + "bytes", + "futures-sink", + "futures-util", + "memchr", + "pin-project-lite 0.2.9", +] + +[[package]] +name = "atomic-waker" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5694b64066a2459918d8074c2ce0d5a88f409431994c2356617c8ae0c4721fc" +dependencies = [ + "async-trait", + "axum-core", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite 0.2.9", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cae3e661676ffbacb30f1a824089a8c9150e71017f7e1e38f2aa32009188d34" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "base64ct" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq 0.1.5", +] + +[[package]] +name = "blake2s_simd" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq 0.1.5", +] + +[[package]] +name = "blake3" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq 0.2.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-modes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +dependencies = [ + "block-padding", + "cipher 0.2.5", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "brotli" +version = "3.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]] +name = "by_address" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf8dba2868114ed769a1f2590fc9ae5eb331175b44313b6c9b922f8f7ca813d0" + +[[package]] +name = "bytecheck" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +dependencies = [ + "bytecheck_derive", + "ptr_meta", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +dependencies = [ + "serde", +] + +[[package]] +name = "bytesize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c58ec36aac5066d5ca17df51b3e70279f5670a72102f5752cb7e7c856adfc70" + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77df041dc383319cc661b428b6961a005db4d6808d5e12536931b1ca9556055" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", +] + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[package]] +name = "ccm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca1a8fbc20b50ac9673ff014abfb2b5f4085ee1a850d408f14a159c5853ac7" +dependencies = [ + "aead 0.3.2", + "cipher 0.2.5", + "subtle", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" +dependencies = [ + "aead 0.4.3", + "chacha20", + "cipher 0.3.0", + "poly1305", + "zeroize", +] + +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "num-integer", + "num-traits", + "serde", + "winapi", +] + +[[package]] +name = "ciborium" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" + +[[package]] +name = "ciborium-ll" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "cid" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b68e3193982cd54187d71afdb2a271ad4cf8af157858e9cb911b91321de143" +dependencies = [ + "core2", + "multibase", + "multihash 0.17.0", + "serde", + "serde_bytes", + "unsigned-varint", +] + +[[package]] +name = "cipher" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "clang-sys" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +dependencies = [ + "atty", + "bitflags", + "clap_lex 0.2.4", + "indexmap", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap" +version = "4.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex 0.3.1", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_mangen" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb258c6232b4d728d13d6072656627924c16707aae6267cd5a1ea05abff9a25c" +dependencies = [ + "clap 4.1.4", + "roff", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "concurrent-queue" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "config" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +dependencies = [ + "async-trait", + "json5", + "lazy_static", + "nom", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + +[[package]] +name = "console" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys", +] + +[[package]] +name = "console-api" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57ff02e8ad8e06ab9731d5dc72dc23bef9200778eae1a89d555d8c42e5d4a86" +dependencies = [ + "prost", + "prost-types", + "tonic", + "tracing-core", +] + +[[package]] +name = "console-subscriber" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a3a81dfaf6b66bce5d159eddae701e3a002f194d378cbf7be5f053c281d9be" +dependencies = [ + "console-api", + "crossbeam-channel", + "crossbeam-utils", + "futures", + "hdrhistogram", + "humantime", + "prost-types", + "serde", + "serde_json", + "thread_local", + "tokio", + "tokio-stream", + "tonic", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "const-oid" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "constant_time_eq" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "cpuid-bool" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +dependencies = [ + "anes", + "atty", + "cast", + "ciborium", + "clap 3.2.23", + "criterion-plot", + "futures", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "tokio", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" +dependencies = [ + "cfg-if", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.7.1", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags", + "crossterm_winapi", + "libc", + "mio", + "parking_lot 0.12.1", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" +dependencies = [ + "cipher 0.2.5", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher 0.3.0", +] + +[[package]] +name = "ctrlc" +version = "3.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1631ca6e3c59112501a9d87fd86f21591ff77acd31331e8a73f8d80a65bbdd71" +dependencies = [ + "nix 0.26.2", + "windows-sys", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da00a7a9a4eb92a0a0f8e75660926d48f0d0f3c537e455c457bcdaa1e16b1ac" +dependencies = [ + "cfg-if", + "fiat-crypto", + "packed_simd_2", + "platforms", + "subtle", + "zeroize", +] + +[[package]] +name = "cxx" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322296e2f2e5af4270b54df9e85a02ff037e271af20ba3e7fe1575515dc840b8" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "017a1385b05d631e7875b1f151c9f012d37b53491e2a87f65bff5c262b2111d8" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c26bbb078acf09bc1ecda02d4223f03bdd28bd4874edcb0379138efc499ce971" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357f40d1f06a24b60ae1fe122542c1fb05d28d32acb2aed064e84bc2ad1e252e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core 0.9.6", +] + +[[package]] +name = "data-encoding" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" + +[[package]] +name = "data-encoding-macro" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" +dependencies = [ + "data-encoding", + "syn", +] + +[[package]] +name = "deadqueue" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a2561fd313df162315935989dceb8c99db4ee1933358270a57a3cfb8c957f3" +dependencies = [ + "crossbeam-queue", + "tokio", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" +dependencies = [ + "asn1-rs 0.3.1", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der-parser" +version = "8.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d4bc9b0db0a0df9ae64634ac5bdefb7afcb534e182275ca0beadbe486701c1" +dependencies = [ + "asn1-rs 0.5.1", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" +dependencies = [ + "derive_builder_core", + "syn", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "dialoguer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af3c796f3b0b408d9fd581611b47fa850821fcb84aa640b83a3c1a5be2d691f2" +dependencies = [ + "console", + "shell-words", + "tempfile", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.3", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "displaydoc" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + +[[package]] +name = "dtoa" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00704156a7de8df8da0911424e30c2049957b0a714542a44e05fe693dd85313" + +[[package]] +name = "duct" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ae3fc31835f74c2a7ceda3aeede378b0ae2e74c8f1c36559fcc9ae2a4e7d3e" +dependencies = [ + "libc", + "once_cell", + "os_pipe", + "shared_child", +] + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest 0.10.6", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-as-inner" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastmurmur3" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d922f481ae01f2a3f1fff7b9e0e789f18f0c755a38ec983a3e6f37762cdcc2a2" + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "libz-sys", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin 0.9.4", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_extra" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" + +[[package]] +name = "futures" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" + +[[package]] +name = "futures-executor" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite 0.2.9", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" +dependencies = [ + "futures-io", + "rustls 0.20.8", + "webpki 0.22.0", +] + +[[package]] +name = "futures-sink" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" + +[[package]] +name = "futures-task" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite 0.2.9", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" +dependencies = [ + "opaque-debug", + "polyval 0.4.5", +] + +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval 0.5.3", +] + +[[package]] +name = "gimli" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" + +[[package]] +name = "git-version" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b0decc02f4636b9ccad390dcbe77b722a77efedfa393caf8379a51d5c61899" +dependencies = [ + "git-version-macro", + "proc-macro-hack", +] + +[[package]] +name = "git-version-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "handlebars" +version = "4.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "035ef95d03713f2c347a72547b7cd38cbc9af7cd51e6099fb62d586d4a6dee3a" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hdrhistogram" +version = "7.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +dependencies = [ + "base64 0.13.1", + "byteorder", + "flate2", + "nom", + "num-traits", +] + +[[package]] +name = "headers" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +dependencies = [ + "base64 0.13.1", + "bitflags", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "hex_fmt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac 0.10.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite 0.2.9", +] + +[[package]] +name = "http-range-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" + +[[package]] +name = "http-serde" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e272971f774ba29341db2f686255ff8a979365a26fb9e4277f6b6d9ec0cdd5e" +dependencies = [ + "http", + "serde", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm 0.2.6", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite 0.2.9", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +dependencies = [ + "http", + "hyper", + "rustls 0.20.8", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite 0.2.9", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if-addrs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "if-watch" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba7abdbb86e485125dad06c2691e1e393bf3b08c7b743b43aa162a00fd39062e" +dependencies = [ + "async-io", + "core-foundation", + "fnv", + "futures", + "if-addrs", + "ipnet", + "log", + "rtnetlink", + "system-configuration", + "tokio", + "windows", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + +[[package]] +name = "indicatif" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cef509aa9bc73864d6756f0d34d35504af3cf0844373afe9b8669a5b8005a729" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" +dependencies = [ + "async-trait", + "tokio", +] + +[[package]] +name = "interceptor" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8a11ae2da61704edada656798b61c94b35ecac2c58eb955156987d5e6be90b" +dependencies = [ + "async-trait", + "bytes", + "log", + "rand 0.8.5", + "rtcp", + "rtp", + "thiserror", + "tokio", + "waitgroup", + "webrtc-srtp", + "webrtc-util", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "ipconfig" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" +dependencies = [ + "socket2", + "widestring", + "winapi", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" + +[[package]] +name = "iroh" +version = "0.2.0" +dependencies = [ + "anyhow", + "async-stream", + "clap 4.1.4", + "config", + "console", + "crossterm", + "futures", + "git-version", + "indicatif", + "iroh-api", + "iroh-localops", + "iroh-metrics", + "iroh-rpc-client", + "iroh-unixfs", + "iroh-util", + "relative-path", + "serde", + "sysinfo 0.27.7", + "tokio", + "tracing", + "which", +] + +[[package]] +name = "iroh-api" +version = "0.2.0" +dependencies = [ + "anyhow", + "async-stream", + "async-trait", + "bytes", + "cid", + "config", + "criterion", + "futures", + "iroh-metrics", + "iroh-resolver", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-store", + "iroh-unixfs", + "iroh-util", + "libp2p", + "relative-path", + "serde", + "tempfile", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "iroh-bitswap" +version = "0.2.0" +dependencies = [ + "ahash 0.8.3", + "anyhow", + "async-broadcast", + "async-channel", + "async-stream", + "async-trait", + "asynchronous-codec", + "bytes", + "cid", + "criterion", + "deadqueue", + "derivative", + "futures", + "iroh-metrics", + "iroh-util", + "keyed_priority_queue", + "libp2p", + "multihash 0.17.0", + "names", + "num_enum", + "once_cell", + "prost", + "prost-build", + "rand 0.8.5", + "smallvec", + "thiserror", + "tokio", + "tokio-context", + "tokio-stream", + "tokio-util", + "tracing", + "tracing-subscriber", + "unsigned-varint", + "wasm-timer", +] + +[[package]] +name = "iroh-car" +version = "0.2.0" +dependencies = [ + "cid", + "futures", + "integer-encoding", + "libipld", + "libipld-cbor", + "multihash 0.17.0", + "thiserror", + "tokio", +] + +[[package]] +name = "iroh-embed" +version = "0.2.0" +dependencies = [ + "anyhow", + "futures", + "iroh-api", + "iroh-gateway", + "iroh-metrics", + "iroh-one", + "iroh-p2p", + "iroh-resolver", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-store", + "iroh-unixfs", + "reqwest", + "testdir", + "tokio", + "tokio-test", +] + +[[package]] +name = "iroh-example-embed" +version = "0.2.0" +dependencies = [ + "anyhow", + "futures-util", + "iroh-api", + "iroh-embed", + "testdir", + "tokio", +] + +[[package]] +name = "iroh-example-importer" +version = "0.2.0" +dependencies = [ + "anyhow", + "bytes", + "bytesize", + "clap 4.1.4", + "futures", + "indicatif", + "iroh-car", + "iroh-resolver", + "iroh-rpc-client", + "iroh-unixfs", + "iroh-util", + "par-stream", + "tokio", +] + +[[package]] +name = "iroh-gateway" +version = "0.2.0" +dependencies = [ + "anyhow", + "async-recursion", + "async-stream", + "async-trait", + "axum", + "bytes", + "cid", + "clap 4.1.4", + "config", + "futures", + "git-version", + "handlebars", + "headers", + "hex", + "hex-literal", + "http", + "http-body", + "http-serde", + "hyper", + "iroh-car", + "iroh-metrics", + "iroh-resolver", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-store", + "iroh-unixfs", + "iroh-util", + "libp2p", + "mime", + "mime_classifier", + "mime_guess", + "names", + "once_cell", + "opentelemetry", + "phf", + "rand 0.8.5", + "reqwest", + "serde", + "serde_json", + "serde_qs", + "sha2 0.10.6", + "tempfile", + "testdir", + "time", + "tokio", + "tokio-util", + "toml", + "tower", + "tower-http", + "tower-layer", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", + "url", + "urlencoding", +] + +[[package]] +name = "iroh-localops" +version = "0.2.0" +dependencies = [ + "anyhow", + "nix 0.26.2", +] + +[[package]] +name = "iroh-metrics" +version = "0.2.0" +dependencies = [ + "async-trait", + "config", + "console-subscriber", + "iroh-util", + "lazy_static", + "libp2p", + "names", + "opentelemetry", + "opentelemetry-otlp", + "paste", + "prometheus-client", + "reqwest", + "serde", + "tokio", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "iroh-one" +version = "0.2.0" +dependencies = [ + "anyhow", + "async-trait", + "axum", + "bytes", + "cid", + "clap 4.1.4", + "config", + "futures", + "headers", + "http", + "http-serde", + "hyper", + "iroh-gateway", + "iroh-metrics", + "iroh-p2p", + "iroh-resolver", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-store", + "iroh-unixfs", + "iroh-util", + "reqwest", + "serde", + "tempfile", + "tokio", + "tracing", +] + +[[package]] +name = "iroh-p2p" +version = "0.2.0" +dependencies = [ + "ahash 0.8.3", + "anyhow", + "async-stream", + "async-trait", + "asynchronous-codec", + "bytes", + "cid", + "clap 4.1.4", + "config", + "criterion", + "futures", + "futures-util", + "git-version", + "iroh-bitswap", + "iroh-metrics", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-util", + "lazy_static", + "libp2p", + "lru", + "names", + "rand 0.8.5", + "rand_chacha 0.3.1", + "serde", + "smallvec", + "ssh-key", + "tempfile", + "tokio", + "tokio-stream", + "toml", + "tracing", + "tracing-subscriber", + "zeroize", +] + +[[package]] +name = "iroh-resolver" +version = "0.2.0" +dependencies = [ + "anyhow", + "async-channel", + "async-recursion", + "async-stream", + "async-trait", + "bs58", + "bytes", + "cid", + "fnv", + "futures", + "iroh-car", + "iroh-metrics", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-store", + "iroh-unixfs", + "iroh-util", + "libipld", + "libp2p", + "proptest", + "rand 0.8.5", + "rand_chacha 0.3.1", + "ruzstd", + "serde", + "tokio", + "tracing", + "trust-dns-resolver", +] + +[[package]] +name = "iroh-rpc-client" +version = "0.2.0" +dependencies = [ + "anyhow", + "async-stream", + "bytes", + "cid", + "config", + "futures", + "hyper", + "iroh-metrics", + "iroh-rpc-types", + "iroh-util", + "libp2p", + "quic-rpc", + "serde", + "tokio", + "tokio-stream", + "toml", + "tracing", +] + +[[package]] +name = "iroh-rpc-types" +version = "0.2.0" +dependencies = [ + "anyhow", + "bytes", + "cid", + "derive_more", + "futures", + "libp2p", + "quic-rpc", + "serde", + "serde-error", + "serde_with", + "tokio", +] + +[[package]] +name = "iroh-share" +version = "0.2.0" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "bytes", + "cid", + "clap 4.1.4", + "futures", + "iroh-metrics", + "iroh-p2p", + "iroh-resolver", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-store", + "iroh-unixfs", + "iroh-util", + "libp2p", + "multibase", + "rand 0.8.5", + "serde", + "tempfile", + "tokio", + "tokio-stream", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "iroh-store" +version = "0.2.0" +dependencies = [ + "ahash 0.8.3", + "anyhow", + "async-stream", + "async-trait", + "bytecheck", + "bytes", + "cid", + "clap 4.1.4", + "config", + "criterion", + "ctrlc", + "futures", + "git-version", + "iroh-metrics", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-util", + "libipld", + "multihash 0.17.0", + "names", + "opentelemetry", + "rayon", + "rkyv", + "rocksdb", + "serde", + "smallvec", + "tempfile", + "tokio", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "iroh-unixfs" +version = "0.2.0" +dependencies = [ + "anyhow", + "async-channel", + "async-recursion", + "async-stream", + "async-trait", + "base64 0.20.0", + "bytes", + "cid", + "config", + "criterion", + "fastmurmur3", + "futures", + "iroh-metrics", + "iroh-rpc-client", + "iroh-rpc-types", + "iroh-store", + "iroh-util", + "libipld", + "libp2p", + "multihash 0.17.0", + "num_enum", + "once_cell", + "proptest", + "prost", + "prost-build", + "rand 0.8.5", + "reqwest", + "serde", + "serde_json", + "tempfile", + "tokio", + "tokio-util", + "tracing", + "unsigned-varint", + "url", +] + +[[package]] +name = "iroh-util" +version = "0.2.0" +dependencies = [ + "anyhow", + "cid", + "config", + "ctrlc", + "dirs-next", + "futures", + "humansize", + "nix 0.26.2", + "rlimit", + "serde", + "sysinfo 0.27.7", + "temp-env", + "testdir", + "thiserror", + "toml", + "tracing", +] + +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" + +[[package]] +name = "jobserver" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keyed_priority_queue" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d63b6407b66fc81fc539dccf3ddecb669f393c5101b6a2be3976c95099a06e8" +dependencies = [ + "indexmap", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "libipld" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20e38e0ad9a2fd600476691fa0780421931a198279985e398a3a0851903e1b2" +dependencies = [ + "fnv", + "libipld-cbor", + "libipld-cbor-derive", + "libipld-core", + "libipld-json", + "libipld-macro", + "libipld-pb", + "log", + "multihash 0.17.0", + "thiserror", +] + +[[package]] +name = "libipld-cbor" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b75370e27e0745910a9991c83f365cdae58027acf0502aa7987ac538a8a4744" +dependencies = [ + "byteorder", + "libipld-core", + "thiserror", +] + +[[package]] +name = "libipld-cbor-derive" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4515686b6bffd663a1fbdd87408ced5b612751910a9e309042e9efef9dbdb324" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "libipld-core" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7a704ba3b25dee9e7a2361fae2c7c19defae2a92e69ae96ffb203996705cd7c" +dependencies = [ + "anyhow", + "cid", + "core2", + "multibase", + "multihash 0.17.0", + "thiserror", +] + +[[package]] +name = "libipld-json" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc549d7c70f9a401031fcb6d3bf7eccfe91bcad938f7485f71ee8ba9f79c1e79" +dependencies = [ + "libipld-core", + "multihash 0.17.0", + "serde", + "serde_json", +] + +[[package]] +name = "libipld-macro" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c7ccd89e54f2796cf3f99aabeea7a7751d418df504926544f28348d3c890c7" +dependencies = [ + "libipld-core", +] + +[[package]] +name = "libipld-pb" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd84ee8b7e283c81b28ecf46e07c31a524a2cd35ec4e87833733a18218c17ccb" +dependencies = [ + "libipld-core", + "prost", + "thiserror", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + +[[package]] +name = "libm" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "libp2p" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e0a0d2f693675f49ded13c5d510c48b78069e23cbd9108d7ccd59f6dc568819" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "getrandom 0.2.8", + "instant", + "libp2p-autonat", + "libp2p-core", + "libp2p-dcutr", + "libp2p-dns", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-kad", + "libp2p-mdns", + "libp2p-metrics", + "libp2p-mplex", + "libp2p-noise", + "libp2p-ping", + "libp2p-quic", + "libp2p-relay", + "libp2p-request-response", + "libp2p-swarm", + "libp2p-tcp", + "libp2p-webrtc", + "libp2p-websocket", + "libp2p-yamux", + "multiaddr", + "parking_lot 0.12.1", + "pin-project", + "smallvec", +] + +[[package]] +name = "libp2p-autonat" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "705aa16b15f8438eea368b06cb0461ac885df35152b25ec31dfade1179a687cd" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-request-response", + "libp2p-swarm", + "log", + "prost", + "prost-build", + "rand 0.8.5", +] + +[[package]] +name = "libp2p-core" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a8fcd392ff67af6cc3f03b1426c41f7f26b6b9aff2dc632c1c56dd649e571f" +dependencies = [ + "asn1_der", + "bs58", + "ed25519-dalek", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "log", + "multiaddr", + "multihash 0.16.3", + "multistream-select", + "once_cell", + "parking_lot 0.12.1", + "pin-project", + "prost", + "prost-build", + "rand 0.8.5", + "ring", + "rw-stream-sink", + "sec1", + "serde", + "sha2 0.10.6", + "smallvec", + "thiserror", + "unsigned-varint", + "void", + "zeroize", +] + +[[package]] +name = "libp2p-dcutr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c642470f6ca6301cb607806c7c045b1e70010659422ec775367fc334147fa28a" +dependencies = [ + "asynchronous-codec", + "bytes", + "either", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-swarm", + "log", + "prost", + "prost-build", + "prost-codec", + "thiserror", + "void", +] + +[[package]] +name = "libp2p-dns" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e42a271c1b49f789b92f7fc87749fa79ce5c7bdc88cbdfacb818a4bca47fec5" +dependencies = [ + "futures", + "libp2p-core", + "log", + "parking_lot 0.12.1", + "smallvec", + "trust-dns-resolver", +] + +[[package]] +name = "libp2p-gossipsub" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a173171c71c29bb156f98886c7c4824596de3903dadf01e2e79d2ccdcf38cd9f" +dependencies = [ + "asynchronous-codec", + "base64 0.13.1", + "byteorder", + "bytes", + "fnv", + "futures", + "hex_fmt", + "instant", + "libp2p-core", + "libp2p-swarm", + "log", + "prometheus-client", + "prost", + "prost-build", + "prost-codec", + "rand 0.8.5", + "regex", + "serde", + "sha2 0.10.6", + "smallvec", + "thiserror", + "unsigned-varint", + "wasm-timer", +] + +[[package]] +name = "libp2p-identify" +version = "0.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c052d0026f4817b44869bfb6810f4e1112f43aec8553f2cb38881c524b563abf" +dependencies = [ + "asynchronous-codec", + "futures", + "futures-timer", + "libp2p-core", + "libp2p-swarm", + "log", + "lru", + "prost", + "prost-build", + "prost-codec", + "smallvec", + "thiserror", + "void", +] + +[[package]] +name = "libp2p-kad" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2766dcd2be8c87d5e1f35487deb22d765f49c6ae1251b3633efe3b25698bd3d2" +dependencies = [ + "arrayvec", + "asynchronous-codec", + "bytes", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-swarm", + "log", + "prost", + "prost-build", + "rand 0.8.5", + "serde", + "sha2 0.10.6", + "smallvec", + "thiserror", + "uint", + "unsigned-varint", + "void", +] + +[[package]] +name = "libp2p-mdns" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f378264aade9872d6ccd315c0accc18be3a35d15fc1b9c36e5b6f983b62b5b" +dependencies = [ + "data-encoding", + "futures", + "if-watch", + "libp2p-core", + "libp2p-swarm", + "log", + "rand 0.8.5", + "smallvec", + "socket2", + "tokio", + "trust-dns-proto", + "void", +] + +[[package]] +name = "libp2p-metrics" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad8a64f29da86005c86a4d2728b8a0719e9b192f4092b609fd8790acb9dec55" +dependencies = [ + "libp2p-core", + "libp2p-dcutr", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-kad", + "libp2p-ping", + "libp2p-relay", + "libp2p-swarm", + "prometheus-client", +] + +[[package]] +name = "libp2p-mplex" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03805b44107aa013e7cbbfa5627b31c36cbedfdfb00603c0311998882bc4bace" +dependencies = [ + "asynchronous-codec", + "bytes", + "futures", + "libp2p-core", + "log", + "nohash-hasher", + "parking_lot 0.12.1", + "rand 0.8.5", + "smallvec", + "unsigned-varint", +] + +[[package]] +name = "libp2p-noise" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a978cb57efe82e892ec6f348a536bfbd9fee677adbe5689d7a93ad3a9bffbf2e" +dependencies = [ + "bytes", + "curve25519-dalek 3.2.0", + "futures", + "libp2p-core", + "log", + "once_cell", + "prost", + "prost-build", + "rand 0.8.5", + "sha2 0.10.6", + "snow", + "static_assertions", + "thiserror", + "x25519-dalek 1.1.1", + "zeroize", +] + +[[package]] +name = "libp2p-ping" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "929fcace45a112536e22b3dcfd4db538723ef9c3cb79f672b98be2cc8e25f37f" +dependencies = [ + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-swarm", + "log", + "rand 0.8.5", + "void", +] + +[[package]] +name = "libp2p-quic" +version = "0.7.0-alpha" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e7c867e95c8130667b24409d236d37598270e6da69b3baf54213ba31ffca59" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "if-watch", + "libp2p-core", + "libp2p-tls", + "log", + "parking_lot 0.12.1", + "quinn-proto", + "rand 0.8.5", + "rustls 0.20.8", + "thiserror", + "tokio", +] + +[[package]] +name = "libp2p-relay" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffb67f6b6cce19cfeab9b10b77fbff756a66a1c143cba7deb8c3f964fadcb59" +dependencies = [ + "asynchronous-codec", + "bytes", + "either", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-swarm", + "log", + "pin-project", + "prost", + "prost-build", + "prost-codec", + "rand 0.8.5", + "smallvec", + "static_assertions", + "thiserror", + "void", +] + +[[package]] +name = "libp2p-request-response" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3236168796727bfcf4927f766393415361e2c644b08bedb6a6b13d957c9a4884" +dependencies = [ + "async-trait", + "bytes", + "futures", + "instant", + "libp2p-core", + "libp2p-swarm", + "log", + "rand 0.8.5", + "smallvec", + "unsigned-varint", +] + +[[package]] +name = "libp2p-swarm" +version = "0.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a35472fe3276b3855c00f1c032ea8413615e030256429ad5349cdf67c6e1a0" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-swarm-derive", + "log", + "pin-project", + "rand 0.8.5", + "smallvec", + "thiserror", + "tokio", + "void", +] + +[[package]] +name = "libp2p-swarm-derive" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d527d5827582abd44a6d80c07ff8b50b4ee238a8979e05998474179e79dc400" +dependencies = [ + "heck", + "quote", + "syn", +] + +[[package]] +name = "libp2p-tcp" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b257baf6df8f2df39678b86c578961d48cc8b68642a12f0f763f56c8e5858d" +dependencies = [ + "futures", + "futures-timer", + "if-watch", + "libc", + "libp2p-core", + "log", + "socket2", + "tokio", +] + +[[package]] +name = "libp2p-tls" +version = "0.1.0-alpha" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7905ce0d040576634e8a3229a7587cc8beab83f79db6023800f1792895defa8" +dependencies = [ + "futures", + "futures-rustls", + "libp2p-core", + "rcgen 0.10.0", + "ring", + "rustls 0.20.8", + "thiserror", + "webpki 0.22.0", + "x509-parser 0.14.0", + "yasna", +] + +[[package]] +name = "libp2p-webrtc" +version = "0.4.0-alpha" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb6cd86dd68cba72308ea05de1cebf3ba0ae6e187c40548167955d4e3970f6a" +dependencies = [ + "async-trait", + "asynchronous-codec", + "bytes", + "futures", + "futures-timer", + "hex", + "if-watch", + "libp2p-core", + "libp2p-noise", + "log", + "multihash 0.16.3", + "prost", + "prost-build", + "prost-codec", + "rand 0.8.5", + "rcgen 0.9.3", + "serde", + "stun", + "thiserror", + "tinytemplate", + "tokio", + "tokio-util", + "webrtc", +] + +[[package]] +name = "libp2p-websocket" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d705506030d5c0aaf2882437c70dab437605f21c5f9811978f694e6917a3b54" +dependencies = [ + "either", + "futures", + "futures-rustls", + "libp2p-core", + "log", + "parking_lot 0.12.1", + "quicksink", + "rw-stream-sink", + "soketto", + "url", + "webpki-roots", +] + +[[package]] +name = "libp2p-yamux" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f63594a0aa818642d9d4915c791945053877253f08a3626f13416b5cd928a29" +dependencies = [ + "futures", + "libp2p-core", + "log", + "parking_lot 0.12.1", + "thiserror", + "yamux", +] + +[[package]] +name = "librocksdb-sys" +version = "0.8.0+7.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611804e4666a25136fcc5f8cf425ab4d26c7f74ea245ffe92ea23b85b6420b5d" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "zstd-sys", +] + +[[package]] +name = "libz-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lru" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6e8aaa3f231bb4bd57b84b2d5dc3ae7f350265df8aa96492e0bc394a1571909" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matchit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_classifier" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e817cb34c89e147fcfbb8a4e88e4c1c064c1c9fcdab80191f94b55921b3cbbd4" +dependencies = [ + "mime", + "serde", +] + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", +] + +[[package]] +name = "multiaddr" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aebdb21e90f81d13ed01dc84123320838e53963c2ca94b60b305d3fa64f31e" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "multibase", + "multihash 0.16.3", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c346cf9999c631f002d8f977c4eaeaa0e6386f16007202308d0b3757522c2cc" +dependencies = [ + "core2", + "digest 0.10.6", + "multihash-derive", + "serde", + "serde-big-array", + "sha2 0.10.6", + "unsigned-varint", +] + +[[package]] +name = "multihash" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", + "core2", + "digest 0.10.6", + "multihash-derive", + "serde", + "serde-big-array", + "sha2 0.10.6", + "sha3", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "multistream-select" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8552ab875c1313b97b8d20cb857b9fd63e2d1d6a0a1b53ce9821e575405f27a" +dependencies = [ + "bytes", + "futures", + "log", + "pin-project", + "smallvec", + "unsigned-varint", +] + +[[package]] +name = "names" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.8", +] + +[[package]] +name = "netlink-packet-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" +dependencies = [ + "anyhow", + "byteorder", + "libc", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" +dependencies = [ + "anyhow", + "bitflags", + "byteorder", + "libc", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-utils" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" +dependencies = [ + "anyhow", + "byteorder", + "paste", + "thiserror", +] + +[[package]] +name = "netlink-proto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror", + "tokio", +] + +[[package]] +name = "netlink-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "260e21fbb6f3d253a14df90eb0000a6066780a15dd901a7519ce02d77a94985b" +dependencies = [ + "bytes", + "futures", + "libc", + "log", + "tokio", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", + "static_assertions", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "ntapi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" +dependencies = [ + "byteorder", + "lazy_static", + "libm 0.2.6", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", + "libm 0.2.6", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d829733185c1ca374f17e52b762f24f535ec625d2cc1f070e34c8a9068f341b" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2be1598bf1c313dcdd12092e3f1920f463462525a21b7b4e11b4168353d0123e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.30.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +dependencies = [ + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" +dependencies = [ + "asn1-rs 0.3.1", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs 0.5.1", +] + +[[package]] +name = "once_cell" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d6c3d7288a106c0a363e4b0e8d308058d56902adefb16f4936f417ffef086e" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c928609d087790fc936a1067bdc310ae702bdf3b090c3f281b713622c8bbde" +dependencies = [ + "async-trait", + "futures", + "futures-util", + "http", + "opentelemetry", + "opentelemetry-proto", + "prost", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61a2f56df5574508dd86aaca016c917489e589ece4141df1b5e349af8d66c28" +dependencies = [ + "futures", + "futures-util", + "opentelemetry", + "prost", + "tonic", + "tonic-build", +] + +[[package]] +name = "opentelemetry_api" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22" +dependencies = [ + "fnv", + "futures-channel", + "futures-util", + "indexmap", + "js-sys", + "once_cell", + "pin-project-lite 0.2.9", + "thiserror", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113" +dependencies = [ + "async-trait", + "crossbeam-channel", + "dashmap", + "fnv", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "percent-encoding", + "rand 0.8.5", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "ordered-multimap" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +dependencies = [ + "dlv-list", + "hashbrown", +] + +[[package]] +name = "os_pipe" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a252f1f8c11e84b3ab59d7a488e48e4478a93937e027076638c49536204639" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa", + "elliptic-curve", + "sha2 0.10.6", +] + +[[package]] +name = "p384" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +dependencies = [ + "ecdsa", + "elliptic-curve", + "sha2 0.10.6", +] + +[[package]] +name = "packed_simd_2" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" +dependencies = [ + "cfg-if", + "libm 0.1.4", +] + +[[package]] +name = "par-stream" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ef8c7bc0cbc89c3d02fb0cce36f609e8707150bd38c1cbce79c6b7906f4099a" +dependencies = [ + "by_address", + "crossbeam", + "dashmap", + "derivative", + "flume", + "futures", + "num_cpus", + "once_cell", + "parking_lot 0.12.1", + "pin-project", + "tokio", +] + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.6", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "paste" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pest" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ab62d2fa33726dbe6321cc97ef96d8cde531e3eeaf858a058de53a8a6d40d8f" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf026e2d0581559db66d837fe5242320f525d85c76283c61f4d51a1238d65ea" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b27bd18aa01d91c8ed2b61ea23406a676b42d82609c6e2581fba42f0c15f17f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f02b677c1859756359fc9983c2e56a0237f18624a3789528804406b7e915e5d" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.6", +] + +[[package]] +name = "petgraph" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +dependencies = [ + "der", + "pkcs8", + "spki", + "zeroize", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "platforms" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" + +[[package]] +name = "plotters" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" + +[[package]] +name = "plotters-svg" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "polling" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "log", + "wepoll-ffi", + "windows-sys", +] + +[[package]] +name = "poly1305" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" +dependencies = [ + "cpuid-bool", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus-client" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83cd1b99916654a69008fd66b4f9397fbe08e6e51dfe23d4417acf5d3b8cb87c" +dependencies = [ + "dtoa", + "itoa", + "parking_lot 0.12.1", + "prometheus-client-derive-text-encode", +] + +[[package]] +name = "prometheus-client-derive-text-encode" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66a455fbcb954c1a7decf3c586e860fd7889cddf4b8e164be736dbac95a953cd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proptest" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0d9cc07f18492d879586c92b485def06bc850da3118075cd45d50e9c95b0e5" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.1", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", +] + +[[package]] +name = "prost" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f8ad728fb08fe212df3c05169e940fbb6d9d16a877ddde14644a983ba2012e" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn", + "tempfile", + "which", +] + +[[package]] +name = "prost-codec" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc34979ff898b6e141106178981ce2596c387ea6e62533facfc61a37fc879c0" +dependencies = [ + "asynchronous-codec", + "bytes", + "prost", + "thiserror", + "unsigned-varint", +] + +[[package]] +name = "prost-derive" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" +dependencies = [ + "bytes", + "prost", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "quic-rpc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26426ee18cda93ddaf265f73715d90cbf8259d943e13438f89beb093286688b6" +dependencies = [ + "bincode", + "bytes", + "flume", + "futures", + "hyper", + "pin-project", + "serde", + "tokio", + "tracing", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quicksink" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project-lite 0.1.12", +] + +[[package]] +name = "quinn-proto" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4ced82a24bb281af338b9e8f94429b6eca01b4e66d899f40031f074e74c9" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls 0.20.8", + "slab", + "thiserror", + "tinyvec", + "tracing", + "webpki 0.22.0", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.8", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "rcgen" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" +dependencies = [ + "pem", + "ring", + "time", + "x509-parser 0.13.2", + "yasna", +] + +[[package]] +name = "rcgen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +dependencies = [ + "pem", + "ring", + "time", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.8", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "relative-path" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3bf6b372449361333ac1f498b7edae4dd5e70dccd7c0c2a7c7bce8f05ede648" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" +dependencies = [ + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite 0.2.9", + "rustls 0.20.8", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error 1.2.3", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac 0.12.1", + "zeroize", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rkyv" +version = "0.7.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +dependencies = [ + "bytecheck", + "hashbrown", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rlimit" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a29d87a652dc4d43c586328706bb5cdff211f3f39a530f240b53f7221dab8e" +dependencies = [ + "libc", +] + +[[package]] +name = "rocksdb" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9562ea1d70c0cc63a34a22d977753b50cca91cc6b6527750463bd5dd8697bc" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "roff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" + +[[package]] +name = "ron" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" +dependencies = [ + "base64 0.13.1", + "bitflags", + "serde", +] + +[[package]] +name = "rsa" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" +dependencies = [ + "byteorder", + "digest 0.10.6", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "smallvec", + "subtle", + "zeroize", +] + +[[package]] +name = "rtcp" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1919efd6d4a6a85d13388f9487549bb8e359f17198cc03ffd72f79b553873691" +dependencies = [ + "bytes", + "thiserror", + "webrtc-util", +] + +[[package]] +name = "rtnetlink" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" +dependencies = [ + "futures", + "log", + "netlink-packet-route", + "netlink-proto", + "nix 0.24.3", + "thiserror", + "tokio", +] + +[[package]] +name = "rtp" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a095411ff00eed7b12e4c6a118ba984d113e1079582570d56a5ee723f11f80" +dependencies = [ + "async-trait", + "bytes", + "rand 0.8.5", + "serde", + "thiserror", + "webrtc-util", +] + +[[package]] +name = "rust-ini" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.1", + "log", + "ring", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct 0.7.0", + "webpki 0.22.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +dependencies = [ + "base64 0.21.0", +] + +[[package]] +name = "rustversion" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ruzstd" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffae8df4aa221781b715c27bbed0fac16b6f1e2643efb7af8a24dfc78d444493" +dependencies = [ + "byteorder", + "thiserror", + "twox-hash", +] + +[[package]] +name = "rw-stream-sink" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" +dependencies = [ + "futures", + "pin-project", + "static_assertions", +] + +[[package]] +name = "ryu" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sdp" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d22a5ef407871893fd72b4562ee15e4742269b173959db4b8df6f538c414e13" +dependencies = [ + "rand 0.8.5", + "substring", + "thiserror", + "url", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-big-array" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd31f59f6fe2b0c055371bb2f16d7f0aa7d8881676c04a55b1596d1a17cd10a4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-error" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e988182713aeed6a619a88bca186f6d6407483485ffe44c869ee264f8eabd13f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b04f22b563c91331a10074bda3dd5492e3cc39d56bd557e91c0af42b6c7341" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_qs" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cac3f1e2ca2fe333923a1ae72caca910b98ed0630bb35ef6f8c8517d6e81afa" +dependencies = [ + "percent-encoding", + "serde", + "thiserror", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d904179146de381af4c93d3af6ca4984b3152db687dacb9c3c35e86f39809c" +dependencies = [ + "base64 0.13.1", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1966009f3c05f095697c537312f5415d1e3ed31ce0a56942bac4c771c5c335e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "sha3" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +dependencies = [ + "digest 0.10.6", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared_child" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "signal-hook" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.6", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "snow" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774d05a3edae07ce6d68ea6984f3c05e9bba8927e3dd591e3b479e5b03213d0d" +dependencies = [ + "aes-gcm 0.9.4", + "blake2", + "chacha20poly1305", + "curve25519-dalek 4.0.0-rc.0", + "rand_core 0.6.4", + "ring", + "rustc_version", + "sha2 0.10.6", + "subtle", +] + +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "flate2", + "futures", + "httparse", + "log", + "rand 0.8.5", + "sha-1", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "ssh-encoding" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19cfdc32e0199062113edf41f344fbf784b8205a94600233c84eb838f45191e1" +dependencies = [ + "base64ct", + "pem-rfc7468", + "sha2 0.10.6", +] + +[[package]] +name = "ssh-key" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288d8f5562af5a3be4bda308dd374b2c807b940ac370b5efa1c99311da91d9a1" +dependencies = [ + "ed25519-dalek", + "p256", + "p384", + "rand_core 0.6.4", + "rsa", + "sec1", + "sha2 0.10.6", + "signature", + "ssh-encoding", + "zeroize", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "stun" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7e94b1ec00bad60e6410e058b52f1c66de3dc5fe4d62d09b3e52bb7d3b73e25" +dependencies = [ + "base64 0.13.1", + "crc", + "lazy_static", + "md-5", + "rand 0.8.5", + "ring", + "subtle", + "thiserror", + "tokio", + "url", + "webrtc-util", +] + +[[package]] +name = "substring" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +dependencies = [ + "autocfg", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "sysinfo" +version = "0.26.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c18a6156d1f27a9592ee18c1a846ca8dd5c258b7179fc193ae87c74ebb666f5" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "winapi", +] + +[[package]] +name = "sysinfo" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975fe381e0ecba475d4acff52466906d95b153a40324956552e027b2a9eaa89e" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi", +] + +[[package]] +name = "system-configuration" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75182f12f490e953596550b65ee31bda7c8e043d9386174b353bda50838c3fd" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "temp-env" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a30d48359f77fbb6af3d7b928cc2d092e1dc90b44f397e979ef08ae15733ed65" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "testdir" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23029d5d16b0351859485c6849252f00bf0ebc98098a9efd954853c3533720c7" +dependencies = [ + "anyhow", + "backtrace", + "cargo_metadata", + "once_cell", + "sysinfo 0.26.9", + "whoami", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite 0.2.9", + "signal-hook-registry", + "socket2", + "tokio-macros", + "tracing", + "windows-sys", +] + +[[package]] +name = "tokio-context" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf0b8394dd5ca9a1b726c629390154c19222dfd7467a4b56f1ced90adee3958" +dependencies = [ + "tokio", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite 0.2.9", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.8", + "tokio", + "webpki 0.22.0", +] + +[[package]] +name = "tokio-stream" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +dependencies = [ + "futures-core", + "pin-project-lite 0.2.9", + "tokio", +] + +[[package]] +name = "tokio-test" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53474327ae5e166530d17f2d956afcb4f8a004de581b3cae10f12006bc8163e3" +dependencies = [ + "async-stream", + "bytes", + "futures-core", + "tokio", + "tokio-stream", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite 0.2.9", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project", + "pin-project-lite 0.2.9", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "async-compression", + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite 0.2.9", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite 0.2.9", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ebb87a95ea13271332df069020513ab70bdb5637ca42d6e492dc3bbbad48de" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trust-dns-proto" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" +dependencies = [ + "async-trait", + "bytes", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "h2", + "http", + "idna 0.2.3", + "ipnet", + "lazy_static", + "rand 0.8.5", + "rustls 0.20.8", + "rustls-pemfile", + "serde", + "smallvec", + "socket2", + "thiserror", + "tinyvec", + "tokio", + "tokio-rustls", + "tracing", + "url", + "webpki 0.22.0", + "webpki-roots", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lazy_static", + "lru-cache", + "parking_lot 0.12.1", + "resolv-conf", + "rustls 0.20.8", + "serde", + "smallvec", + "thiserror", + "tokio", + "tokio-rustls", + "tracing", + "trust-dns-proto", + "webpki-roots", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "turn" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4712ee30d123ec7ae26d1e1b218395a16c87cdbaf4b3925d170d684af62ea5e8" +dependencies = [ + "async-trait", + "base64 0.13.1", + "futures", + "log", + "md-5", + "rand 0.8.5", + "ring", + "stun", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "unsigned-varint" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" +dependencies = [ + "asynchronous-codec", + "bytes", + "futures-io", + "futures-util", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna 0.3.0", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" + +[[package]] +name = "uuid" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +dependencies = [ + "getrandom 0.2.8", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "waitgroup" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292" +dependencies = [ + "atomic-waker", +] + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki 0.22.0", +] + +[[package]] +name = "webrtc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3bc9049bdb2cea52f5fd4f6f728184225bdb867ed0dc2410eab6df5bdd67bb" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "hex", + "interceptor", + "lazy_static", + "log", + "rand 0.8.5", + "rcgen 0.9.3", + "regex", + "ring", + "rtcp", + "rtp", + "rustls 0.19.1", + "sdp", + "serde", + "serde_json", + "sha2 0.10.6", + "stun", + "thiserror", + "time", + "tokio", + "turn", + "url", + "waitgroup", + "webrtc-data", + "webrtc-dtls", + "webrtc-ice", + "webrtc-mdns", + "webrtc-media", + "webrtc-sctp", + "webrtc-srtp", + "webrtc-util", +] + +[[package]] +name = "webrtc-data" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef36a4d12baa6e842582fe9ec16a57184ba35e1a09308307b67d43ec8883100" +dependencies = [ + "bytes", + "derive_builder", + "log", + "thiserror", + "tokio", + "webrtc-sctp", + "webrtc-util", +] + +[[package]] +name = "webrtc-dtls" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7021987ae0a2ed6c8cd33f68e98e49bb6e74ffe9543310267b48a1bbe3900e5f" +dependencies = [ + "aes 0.6.0", + "aes-gcm 0.8.0", + "async-trait", + "bincode", + "block-modes", + "byteorder", + "ccm", + "curve25519-dalek 3.2.0", + "der-parser 8.1.0", + "elliptic-curve", + "hkdf", + "hmac 0.10.1", + "log", + "oid-registry 0.6.1", + "p256", + "p384", + "rand 0.8.5", + "rand_core 0.6.4", + "rcgen 0.9.3", + "ring", + "rustls 0.19.1", + "sec1", + "serde", + "sha-1", + "sha2 0.9.9", + "signature", + "subtle", + "thiserror", + "tokio", + "webpki 0.21.4", + "webrtc-util", + "x25519-dalek 2.0.0-pre.1", + "x509-parser 0.13.2", +] + +[[package]] +name = "webrtc-ice" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494483fbb2f5492620871fdc78b084aed8807377f6e3fe88b2e49f0a9c9c41d7" +dependencies = [ + "arc-swap", + "async-trait", + "crc", + "log", + "rand 0.8.5", + "serde", + "serde_json", + "stun", + "thiserror", + "tokio", + "turn", + "url", + "uuid", + "waitgroup", + "webrtc-mdns", + "webrtc-util", +] + +[[package]] +name = "webrtc-mdns" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" +dependencies = [ + "log", + "socket2", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-media" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a3c157a040324e5049bcbd644ffc9079e6738fa2cfab2bcff64e5cc4c00d7" +dependencies = [ + "byteorder", + "bytes", + "derive_builder", + "displaydoc", + "rand 0.8.5", + "rtp", + "thiserror", + "webrtc-util", +] + +[[package]] +name = "webrtc-sctp" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d47adcd9427eb3ede33d5a7f3424038f63c965491beafcc20bc650a2f6679c0" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "crc", + "log", + "rand 0.8.5", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-srtp" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6183edc4c1c6c0175f8812eefdce84dfa0aea9c3ece71c2bf6ddd3c964de3da5" +dependencies = [ + "aead 0.4.3", + "aes 0.7.5", + "aes-gcm 0.9.4", + "async-trait", + "byteorder", + "bytes", + "ctr 0.8.0", + "hmac 0.11.0", + "log", + "rtcp", + "rtp", + "sha-1", + "subtle", + "thiserror", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-util" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" +dependencies = [ + "async-trait", + "bitflags", + "bytes", + "cc", + "ipnet", + "lazy_static", + "libc", + "log", + "nix 0.24.3", + "rand 0.8.5", + "thiserror", + "tokio", + "winapi", +] + +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "whoami" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45dbc71f0cdca27dc261a9bd37ddec174e4a0af2b900b890f378460f745426e3" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45296b64204227616fdbf2614cefa4c236b98ee64dfaaaa435207ed99fe7829f" +dependencies = [ + "windows_aarch64_msvc 0.34.0", + "windows_i686_gnu 0.34.0", + "windows_i686_msvc 0.34.0", + "windows_x86_64_gnu 0.34.0", + "windows_x86_64_msvc 0.34.0", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek 3.2.0", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" +dependencies = [ + "curve25519-dalek 3.2.0", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "x509-parser" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" +dependencies = [ + "asn1-rs 0.3.1", + "base64 0.13.1", + "data-encoding", + "der-parser 7.0.0", + "lazy_static", + "nom", + "oid-registry 0.4.0", + "ring", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "x509-parser" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +dependencies = [ + "asn1-rs 0.5.1", + "base64 0.13.1", + "data-encoding", + "der-parser 8.1.0", + "lazy_static", + "nom", + "oid-registry 0.6.1", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "xtask" +version = "0.2.0" +dependencies = [ + "anyhow", + "clap 4.1.4", + "clap_mangen", + "dirs-next", + "iroh", + "xtaskops", +] + +[[package]] +name = "xtaskops" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1c4a13a4331477d0e57b7f09fb70a5e2c30c6da35eb56f1bac157aa76152d4a" +dependencies = [ + "anyhow", + "clap 3.2.23", + "derive_builder", + "dialoguer", + "duct", + "fs_extra", + "glob", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "yamux" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d9ba232399af1783a58d8eb26f6b5006fbefe2dc9ef36bd283324792d03ea5" +dependencies = [ + "futures", + "log", + "nohash-hasher", + "parking_lot 0.12.1", + "rand 0.8.5", + "static_assertions", +] + +[[package]] +name = "yasna" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aed2e7a52e3744ab4d0c05c20aa065258e84c49fd4226f5191b2ed29712710b4" +dependencies = [ + "time", +] + +[[package]] +name = "zeroize" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zstd-sys" +version = "2.0.6+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a3f9792c0c3dc6c165840a75f47ae1f4da402c2d006881129579f6597e801b" +dependencies = [ + "cc", + "libc", + "pkg-config", +] From b67789f0fe305a2f2dd2899f9588441d0152cf84 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Thu, 9 Mar 2023 08:20:18 -0700 Subject: [PATCH 4/8] fix: clippy warnings --- iroh-p2p/src/node.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iroh-p2p/src/node.rs b/iroh-p2p/src/node.rs index 32abbdbf7..63114767d 100644 --- a/iroh-p2p/src/node.rs +++ b/iroh-p2p/src/node.rs @@ -968,7 +968,7 @@ impl Node { let res = gossipsub .subscribe(&t) .map(|_| self.network_events()) - .map_err(|e| anyhow::Error::new(e)); + .map_err(anyhow::Error::new); response_channel .send(res) .map_err(|_| anyhow!("sender dropped"))?; From 7e27934904584a595bacd455bf0b7400b22716be Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Thu, 9 Mar 2023 10:02:32 -0700 Subject: [PATCH 5/8] fix: remove irrelvant content loader changes --- iroh-resolver/src/lib.rs | 3 - iroh-unixfs/src/content_loader.rs | 92 +------------------------------ 2 files changed, 3 insertions(+), 92 deletions(-) diff --git a/iroh-resolver/src/lib.rs b/iroh-resolver/src/lib.rs index c805f798a..fe9fb5056 100644 --- a/iroh-resolver/src/lib.rs +++ b/iroh-resolver/src/lib.rs @@ -1,7 +1,4 @@ pub mod dns_resolver; pub mod resolver; -pub use iroh_unixfs::content_loader::{ - ContentLoader, FullLoader, FullLoaderConfig, LoaderFromProviders, -}; pub use resolver::{Path, PathType}; diff --git a/iroh-unixfs/src/content_loader.rs b/iroh-unixfs/src/content_loader.rs index 124795416..0399253c7 100644 --- a/iroh-unixfs/src/content_loader.rs +++ b/iroh-unixfs/src/content_loader.rs @@ -4,19 +4,18 @@ use std::{ hash::BuildHasher, str::FromStr, sync::Arc, + sync::Mutex, }; -use anyhow::{anyhow, bail, ensure, Result}; +use anyhow::{anyhow, bail, Result}; use async_trait::async_trait; use bytes::Bytes; use cid::{multibase::Base, Cid}; use futures::future::Either; use iroh_rpc_client::Client; -use libp2p::PeerId; use rand::seq::SliceRandom; use reqwest::Url; -use tokio::sync::Mutex; -use tracing::{debug, error, info, trace, warn}; +use tracing::{debug, info, trace, warn}; use crate::{ indexer::{Indexer, IndexerUrl}, @@ -293,91 +292,6 @@ impl ContentLoader for FullLoader { self.client.try_store()?.has(*cid).await } } -/// Load content using only the specified providers -#[derive(Debug, Clone)] -pub struct LoaderFromProviders { - client: Client, - providers: Arc>>, -} - -impl LoaderFromProviders { - pub fn new(client: Client, providers: HashSet) -> Self { - Self { - client, - providers: Arc::new(Mutex::new(providers)), - } - } - - pub fn providers(&self) -> &Arc>> { - &self.providers - } -} - -#[async_trait] -impl ContentLoader for LoaderFromProviders { - async fn load_cid(&self, cid: &Cid, _ctx: &LoaderContext) -> Result { - let cid = *cid; - let providers = self.providers.lock().await.clone(); - - match self.client.try_store()?.get(cid).await { - Ok(Some(data)) => { - return Ok(LoadedCid { - data, - source: Source::Store(IROH_STORE), - }); - } - Ok(None) => {} - Err(err) => { - warn!("failed to fetch data from store {}: {:?}", cid, err); - } - } - - ensure!(!providers.is_empty(), "no providers supplied"); - - // TODO: track context id - let res = self - .client - .try_p2p()? - .fetch_bitswap(0, cid, providers.clone()) - .await; - let bytes = match res { - Ok(bytes) => bytes, - Err(err) => { - error!("Bitswap error: {:#?}", err); - return Err(err); - } - }; - - let cloned = bytes.clone(); - let rpc = self.clone(); - { - let clone2 = cloned.clone(); - let links = - tokio::task::spawn_blocking(move || parse_links(&cid, &clone2).unwrap_or_default()) - .await - .unwrap_or_default(); - - rpc.client.try_store()?.put(cid, cloned, links).await?; - } - - Ok(LoadedCid { - data: bytes, - source: Source::Bitswap, - }) - } - - async fn stop_session(&self, ctx: ContextId) -> Result<()> { - self.client - .try_p2p()? - .stop_session_bitswap(ctx.into()) - .await?; - Ok(()) - } - - async fn has_cid(&self, cid: &Cid) -> Result { - Ok(self.client.try_store()?.has(*cid).await?) - } -} #[derive(Debug, Clone)] pub struct LoaderContext { From adff99707accbec0460854d2033c48fceb09e499 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Thu, 9 Mar 2023 10:18:19 -0700 Subject: [PATCH 6/8] fix: remove duplicate topic from RPC messages The topic was inside the both the message event and the message data. It now only lives within the message data section. This avoids ambiguity of knowing which topic to use and keeping them synchronized. --- iroh-p2p/src/node.rs | 2 -- iroh-p2p/src/rpc.rs | 2 +- iroh-rpc-types/src/gossipsub_event.rs | 2 -- iroh-share/src/receiver.rs | 1 - 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/iroh-p2p/src/node.rs b/iroh-p2p/src/node.rs index 63114767d..7cb95d126 100644 --- a/iroh-p2p/src/node.rs +++ b/iroh-p2p/src/node.rs @@ -690,12 +690,10 @@ impl Node { message, } = e { - let topic = message.topic.clone(); self.emit_network_event(NetworkEvent::Gossipsub(GossipsubEvent::Message { from: propagation_source, id: message_id, message, - topic, })); } else if let libp2p::gossipsub::GossipsubEvent::Subscribed { peer_id, topic } = e { self.emit_network_event(NetworkEvent::Gossipsub(GossipsubEvent::Subscribed { diff --git a/iroh-p2p/src/rpc.rs b/iroh-p2p/src/rpc.rs index d3fd76ed6..2f9ce3538 100644 --- a/iroh-p2p/src/rpc.rs +++ b/iroh-p2p/src/rpc.rs @@ -423,7 +423,7 @@ impl P2p { match &event { GossipsubEvent::Subscribed { topic, .. } | GossipsubEvent::Unsubscribed {topic, .. } | - GossipsubEvent::Message { topic, .. } => { + GossipsubEvent::Message { message: libp2p::gossipsub::GossipsubMessage{ topic , .. }, .. } => { if *topic == t { yield Box::new(GossipsubSubscribeResponse {event}); } diff --git a/iroh-rpc-types/src/gossipsub_event.rs b/iroh-rpc-types/src/gossipsub_event.rs index 21044d2f5..db3f50213 100644 --- a/iroh-rpc-types/src/gossipsub_event.rs +++ b/iroh-rpc-types/src/gossipsub_event.rs @@ -26,8 +26,6 @@ pub enum GossipsubEvent { id: MessageId, #[serde(with = "GossipsubMessageDef")] message: GossipsubMessage, - #[serde(with = "TopicHashDef")] - topic: TopicHash, }, } diff --git a/iroh-share/src/receiver.rs b/iroh-share/src/receiver.rs index 6c6b0a659..d2be3aaa2 100644 --- a/iroh-share/src/receiver.rs +++ b/iroh-share/src/receiver.rs @@ -66,7 +66,6 @@ impl Receiver { id: _, from, message, - topic: _, })) => { if from == expected_sender { match bincode::deserialize(&message.data) { From 930a8648155958a78214e034edb0c64236e45ac4 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Thu, 9 Mar 2023 14:19:58 -0700 Subject: [PATCH 7/8] fix: fix clippy issue --- iroh-bitswap/src/lib.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/iroh-bitswap/src/lib.rs b/iroh-bitswap/src/lib.rs index ae1b3f1ba..ff77292dd 100644 --- a/iroh-bitswap/src/lib.rs +++ b/iroh-bitswap/src/lib.rs @@ -77,21 +77,16 @@ pub struct Bitswap { _workers: Arc>>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] enum PeerState { Connected(ConnectionId), Responsive(ConnectionId, ProtocolId), Unresponsive, + #[default] Disconnected, DialFailure(Instant), } -impl Default for PeerState { - fn default() -> Self { - PeerState::Disconnected - } -} - impl PeerState { fn is_connected(self) -> bool { matches!(self, PeerState::Connected(_) | PeerState::Responsive(_, _)) From 25ff9e4b9a78c03a09401a427b44980adef35f2f Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Fri, 10 Mar 2023 08:17:28 -0700 Subject: [PATCH 8/8] fix: remove uneeded ser/de implementations on NetworkEvent --- iroh-p2p/src/node.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iroh-p2p/src/node.rs b/iroh-p2p/src/node.rs index 7cb95d126..e4f7335ad 100644 --- a/iroh-p2p/src/node.rs +++ b/iroh-p2p/src/node.rs @@ -25,7 +25,6 @@ use libp2p::ping::Result as PingResult; use libp2p::swarm::dial_opts::{DialOpts, PeerCondition}; use libp2p::swarm::{ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, SwarmEvent}; use libp2p::{PeerId, Swarm}; -use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::oneshot::{self, Sender as OneShotSender}; use tokio::task::JoinHandle; @@ -46,7 +45,7 @@ use crate::{ }; #[allow(clippy::large_enum_variant)] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone)] pub enum NetworkEvent { PeerConnected(PeerId), PeerDisconnected(PeerId),