├── src ├── compat │ ├── mod.rs │ ├── bitswap_pb.proto │ ├── prefix.rs │ ├── protocol.rs │ └── message.rs ├── lib.rs ├── stats.rs ├── protocol.rs ├── query.rs └── behaviour.rs ├── Cargo.toml ├── .gitignore ├── README.md ├── .github └── workflows │ └── ci.yml └── Cargo.lock /src/compat/mod.rs: -------------------------------------------------------------------------------- 1 | mod message; 2 | mod prefix; 3 | mod protocol; 4 | 5 | pub use message::CompatMessage; 6 | pub use protocol::{CompatProtocol, InboundMessage}; 7 | 8 | fn other(e: E) -> std::io::Error { 9 | std::io::Error::new(std::io::ErrorKind::Other, e) 10 | } 11 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Bitswap protocol implementation 2 | #![deny(missing_docs)] 3 | #![deny(warnings)] 4 | #![allow(clippy::derive_partial_eq_without_eq)] 5 | 6 | mod behaviour; 7 | #[cfg(feature = "compat")] 8 | mod compat; 9 | mod protocol; 10 | mod query; 11 | mod stats; 12 | 13 | pub use crate::behaviour::{Bitswap, BitswapConfig, BitswapEvent, BitswapStore, Channel}; 14 | pub use crate::query::QueryId; 15 | -------------------------------------------------------------------------------- /src/compat/bitswap_pb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package bitswap_pb; 4 | 5 | message Message { 6 | 7 | message Wantlist { 8 | enum WantType { 9 | Block = 0; 10 | Have = 1; 11 | } 12 | 13 | message Entry { 14 | bytes block = 1; // the block cid (cidV0 in bitswap 1.0.0, cidV1 in bitswap 1.1.0) 15 | int32 priority = 2; // the priority (normalized). default to 1 16 | bool cancel = 3; // whether this revokes an entry 17 | WantType wantType = 4; // Note: defaults to enum 0, ie Block 18 | bool sendDontHave = 5; // Note: defaults to false 19 | } 20 | 21 | repeated Entry entries = 1; // a list of wantlist entries 22 | bool full = 2; // whether this is the full wantlist. default to false 23 | } 24 | 25 | message Block { 26 | bytes prefix = 1; // CID prefix (cid version, multicodec and multihash prefix (type + length) 27 | bytes data = 2; 28 | } 29 | 30 | enum BlockPresenceType { 31 | Have = 0; 32 | DontHave = 1; 33 | } 34 | message BlockPresence { 35 | bytes cid = 1; 36 | BlockPresenceType type = 2; 37 | } 38 | 39 | Wantlist wantlist = 1; 40 | repeated bytes blocks = 2; // used to send Blocks in bitswap 1.0.0 41 | repeated Block payload = 3; // used to send Blocks in bitswap 1.1.0 42 | repeated BlockPresence blockPresences = 4; 43 | int32 pendingBytes = 5; 44 | } 45 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libp2p-bitswap" 3 | version = "0.25.0" 4 | authors = ["David Craven "] 5 | edition = "2018" 6 | description = "Implementation of the ipfs bitswap protocol." 7 | license = "MIT OR Apache-2.0" 8 | repository = "https://github.com/ipfs-rust/libp2p-bitswap" 9 | 10 | [features] 11 | compat = ["prost", "prost-build"] 12 | 13 | [build-dependencies] 14 | prost-build = { version = "0.11", optional = true } 15 | 16 | [dependencies] 17 | async-trait = "0.1.52" 18 | fnv = "1.0.7" 19 | futures = "0.3.19" 20 | lazy_static = "1.4.0" 21 | libipld = { version = "0.15.0", default-features = false } 22 | libp2p = { version = "0.50.0", features = ["request-response"] } 23 | prometheus = "0.13.0" 24 | prost = { version = "0.11", optional = true } 25 | thiserror = "1.0.30" 26 | tracing = "0.1.29" 27 | unsigned-varint = { version = "0.7.1", features = ["futures", "std"] } 28 | 29 | [dev-dependencies] 30 | async-std = { version = "1.10.0", features = ["attributes"] } 31 | env_logger = "0.9.0" 32 | libipld = { version = "0.15.0", default-features = false, features = ["dag-cbor"] } 33 | libp2p = { version = "0.50.0", features = ["tcp", "noise", "yamux", "rsa", "async-std"] } 34 | multihash = { version = "0.17.0", default-features = false, features = ["blake3", "sha2"] } 35 | tracing-subscriber = { version = "0.3.5", features = ["env-filter", "tracing-log"] } 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/rust,osx,visualstudiocode 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=rust,osx,visualstudiocode 3 | 4 | ### OSX ### 5 | # General 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | 10 | # Icon must end with two \r 11 | Icon 12 | 13 | 14 | # Thumbnails 15 | ._* 16 | 17 | # Files that might appear in the root of a volume 18 | .DocumentRevisions-V100 19 | .fseventsd 20 | .Spotlight-V100 21 | .TemporaryItems 22 | .Trashes 23 | .VolumeIcon.icns 24 | .com.apple.timemachine.donotpresent 25 | 26 | # Directories potentially created on remote AFP share 27 | .AppleDB 28 | .AppleDesktop 29 | Network Trash Folder 30 | Temporary Items 31 | .apdisk 32 | 33 | ### Rust ### 34 | # Generated by Cargo 35 | # will have compiled files and executables 36 | debug/ 37 | target/ 38 | 39 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 40 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 41 | # Cargo.lock 42 | 43 | # These are backup files generated by rustfmt 44 | **/*.rs.bk 45 | 46 | # MSVC Windows builds of rustc generate these, which store debugging information 47 | *.pdb 48 | 49 | ### VisualStudioCode ### 50 | .vscode/* 51 | !.vscode/settings.json 52 | !.vscode/tasks.json 53 | !.vscode/launch.json 54 | !.vscode/extensions.json 55 | !.vscode/*.code-snippets 56 | 57 | # Local History for Visual Studio Code 58 | .history/ 59 | 60 | # Built Visual Studio Code Extensions 61 | *.vsix 62 | 63 | ### VisualStudioCode Patch ### 64 | # Ignore all local history of files 65 | .history 66 | .ionide 67 | 68 | # End of https://www.toptal.com/developers/gitignore/api/rust,osx,visualstudiocode -------------------------------------------------------------------------------- /src/compat/prefix.rs: -------------------------------------------------------------------------------- 1 | use crate::compat::other; 2 | use libipld::cid::{Cid, Version}; 3 | use libipld::multihash::{Code, MultihashDigest}; 4 | use std::convert::TryFrom; 5 | use std::io::Result; 6 | use unsigned_varint::{decode as varint_decode, encode as varint_encode}; 7 | 8 | /// Prefix represents all metadata of a CID, without the actual content. 9 | #[derive(PartialEq, Eq, Clone, Debug)] 10 | pub struct Prefix { 11 | /// The version of CID. 12 | pub version: Version, 13 | /// The codec of CID. 14 | pub codec: u64, 15 | /// The multihash type of CID. 16 | pub mh_type: u64, 17 | /// The multihash length of CID. 18 | pub mh_len: usize, 19 | } 20 | 21 | impl Prefix { 22 | /// Create a new prefix from encoded bytes. 23 | pub fn new(data: &[u8]) -> Result { 24 | let (raw_version, remain) = varint_decode::u64(data).map_err(other)?; 25 | let version = Version::try_from(raw_version).map_err(other)?; 26 | let (codec, remain) = varint_decode::u64(remain).map_err(other)?; 27 | let (mh_type, remain) = varint_decode::u64(remain).map_err(other)?; 28 | let (mh_len, _remain) = varint_decode::usize(remain).map_err(other)?; 29 | Ok(Prefix { 30 | version, 31 | codec, 32 | mh_type, 33 | mh_len, 34 | }) 35 | } 36 | 37 | /// Convert the prefix to encoded bytes. 38 | pub fn to_bytes(&self) -> Vec { 39 | let mut res = Vec::with_capacity(4); 40 | let mut buf = varint_encode::u64_buffer(); 41 | let version = varint_encode::u64(self.version.into(), &mut buf); 42 | res.extend_from_slice(version); 43 | let mut buf = varint_encode::u64_buffer(); 44 | let codec = varint_encode::u64(self.codec, &mut buf); 45 | res.extend_from_slice(codec); 46 | let mut buf = varint_encode::u64_buffer(); 47 | let mh_type = varint_encode::u64(self.mh_type, &mut buf); 48 | res.extend_from_slice(mh_type); 49 | let mut buf = varint_encode::u64_buffer(); 50 | let mh_len = varint_encode::u64(self.mh_len as u64, &mut buf); 51 | res.extend_from_slice(mh_len); 52 | res 53 | } 54 | 55 | /// Create a CID out of the prefix and some data that will be hashed 56 | pub fn to_cid(&self, data: &[u8]) -> Result { 57 | let mh = Code::try_from(self.mh_type).map_err(other)?.digest(data); 58 | Cid::new(self.version, self.codec, mh).map_err(other) 59 | } 60 | } 61 | 62 | impl From<&Cid> for Prefix { 63 | fn from(cid: &Cid) -> Self { 64 | Self { 65 | version: cid.version(), 66 | codec: cid.codec(), 67 | mh_type: cid.hash().code(), 68 | mh_len: cid.hash().digest().len(), 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/stats.rs: -------------------------------------------------------------------------------- 1 | use lazy_static::lazy_static; 2 | use prometheus::{HistogramOpts, HistogramVec, IntCounter, IntCounterVec, Opts}; 3 | 4 | lazy_static! { 5 | pub static ref REQUESTS_TOTAL: IntCounterVec = IntCounterVec::new( 6 | Opts::new( 7 | "bitswap_requests_total", 8 | "Number of bitswap requests labelled by type and result.", 9 | ), 10 | &["type"], 11 | ) 12 | .unwrap(); 13 | pub static ref REQUEST_DURATION_SECONDS: HistogramVec = HistogramVec::new( 14 | HistogramOpts::new( 15 | "bitswap_request_duration_seconds", 16 | "Duration of bitswap requests labelled by request type", 17 | ), 18 | &["type"], 19 | ) 20 | .unwrap(); 21 | pub static ref REQUESTS_CANCELED: IntCounter = IntCounter::new( 22 | "bitswap_requests_canceled_total", 23 | "Number of canceled requests", 24 | ) 25 | .unwrap(); 26 | pub static ref BLOCK_NOT_FOUND: IntCounter = IntCounter::new( 27 | "bitswap_block_not_found_total", 28 | "Number of block not found errors.", 29 | ) 30 | .unwrap(); 31 | pub static ref PROVIDERS_TOTAL: IntCounter = IntCounter::new( 32 | "bitswap_providers_total", 33 | r#"Number of providers total. Using the number of provider requests, the average 34 | number of providers per request can be computed."# 35 | ) 36 | .unwrap(); 37 | pub static ref MISSING_BLOCKS_TOTAL: IntCounter = IntCounter::new( 38 | "bitswap_missing_blocks_total", 39 | r#"Number of missing blocks total. Using the number of missing blocks requests, the 40 | average number of missing blocks per request can be computed."# 41 | ) 42 | .unwrap(); 43 | pub static ref RECEIVED_BLOCK_BYTES: IntCounter = 44 | IntCounter::new("bitswap_received_block_bytes", "Number of received bytes.",).unwrap(); 45 | pub static ref RECEIVED_INVALID_BLOCK_BYTES: IntCounter = IntCounter::new( 46 | "bitswap_received_invalid_block_bytes", 47 | "Number of received bytes that didn't match the hash.", 48 | ) 49 | .unwrap(); 50 | pub static ref SENT_BLOCK_BYTES: IntCounter = 51 | IntCounter::new("bitswap_sent_block_bytes", "Number of sent block bytes.",).unwrap(); 52 | pub static ref RESPONSES_TOTAL: IntCounterVec = IntCounterVec::new( 53 | Opts::new( 54 | "bitswap_responses_total", 55 | "Number of bitswap responses sent to peers.", 56 | ), 57 | &["type"], 58 | ) 59 | .unwrap(); 60 | pub static ref THROTTLED_INBOUND: IntCounter = IntCounter::new( 61 | "bitswap_throttled_too_many_inbound_total", 62 | "Number of too many inbound events.", 63 | ) 64 | .unwrap(); 65 | pub static ref THROTTLED_OUTBOUND: IntCounter = IntCounter::new( 66 | "bitswap_throttled_resume_send_total", 67 | "Number of resume send events.", 68 | ) 69 | .unwrap(); 70 | pub static ref OUTBOUND_FAILURE: IntCounterVec = IntCounterVec::new( 71 | Opts::new( 72 | "bitswap_outbound_failures_total", 73 | "Number of outbound failures.", 74 | ), 75 | &["type"], 76 | ) 77 | .unwrap(); 78 | pub static ref INBOUND_FAILURE: IntCounterVec = IntCounterVec::new( 79 | Opts::new( 80 | "bitswap_inbound_failures_total", 81 | "Number of inbound failures.", 82 | ), 83 | &["type"], 84 | ) 85 | .unwrap(); 86 | } 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Crates.io](https://img.shields.io/crates/v/libp2p-bitswap.svg)](https://crates.io/crates/libp2p-bitswap) 2 | [![docs.rs](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/libp2p-bitswap) 3 | 4 | # libp2p-bitswap 5 | 6 | Implementation of the bitswap protocol. 7 | 8 | ## Efficiently syncing dags of blocks 9 | 10 | Bitswap is a very simple protocol. It was adapted and simplified for ipfs-embed. The message 11 | format can be represented by the following enums. 12 | 13 | ```rust 14 | pub enum BitswapRequest { 15 | Have(Cid), 16 | Block(Cid), 17 | } 18 | 19 | pub enum BitswapResponse { 20 | Have(bool), 21 | Block(Vec), 22 | } 23 | ``` 24 | 25 | The mechanism for locating providers can be abstracted. A dht can be plugged in or a centralized 26 | db query. The bitswap api looks as follows: 27 | 28 | ```rust 29 | #[derive(Debug)] 30 | pub enum BitswapEvent { 31 | /// Received a block from a peer. Includes the number of known missing blocks for a 32 | /// sync query. When a block is received and missing blocks is not empty the counter 33 | /// is increased. If missing blocks is empty the counter is decremented. 34 | Progress(QueryId, usize), 35 | /// A get or sync query completed. 36 | Complete(QueryId, Result<()>), 37 | } 38 | 39 | pub trait BitswapStore: Send + Sync + 'static { 40 | /// The store params. 41 | type Params: StoreParams; 42 | /// A have query needs to know if the block store contains the block. 43 | fn contains(&mut self, cid: &Cid) -> Result; 44 | /// A block query needs to retrieve the block from the store. 45 | fn get(&mut self, cid: &Cid) -> Result>>; 46 | /// A block response needs to insert the block into the store. 47 | fn insert(&mut self, block: &Block) -> Result<()>; 48 | /// A sync query needs a list of missing blocks to make progress. 49 | fn missing_blocks(&mut self, cid: &Cid) -> Result>; 50 | } 51 | 52 | pub struct BitswapConfig { 53 | /// Timeout of a request. 54 | pub request_timeout: Duration, 55 | /// Time a connection is kept alive. 56 | pub connection_keep_alive: Duration, 57 | } 58 | 59 | impl Bitswap

{ 60 | /// Creates a new `Bitswap` behaviour. 61 | pub fn new(config: BitswapConfig) -> Self; 62 | 63 | /// Adds an address for a peer. 64 | pub fn add_address(&mut self, peer_id: &PeerId, addr: Multiaddr); 65 | 66 | /// Removes an address for a peer. 67 | pub fn remove_address(&mut self, peer_id: &PeerId, addr: &Multiaddr); 68 | 69 | /// Starts a get query with an initial guess of providers. 70 | pub fn get(&mut self, cid: Cid, peers: impl Iterator) -> QueryId; 71 | 72 | /// Starts a sync query with an the initial set of missing blocks. 73 | pub fn sync(&mut self, cid: Cid, peers: Vec, missing: impl Iterator) -> QueryId; 74 | 75 | /// Cancels an in progress query. Returns true if a query was cancelled. 76 | pub fn cancel(&mut self, id: QueryId) -> bool; 77 | 78 | /// Register bitswap stats in a prometheus registry. 79 | pub fn register_metrics(&self, registry: &Registry) -> Result<()>; 80 | } 81 | ``` 82 | 83 | So what happens when you create a get request? First all the providers in the initial set 84 | are queried with the have request. As an optimization, in every batch of queries a block 85 | request is sent instead. If the get query finds a block it returns a query complete. If the 86 | block wasn't found in the initial set, a `Providers` event is emitted. This is where 87 | the bitswap consumer tries to locate providers by for example performing a dht lookup. After 88 | the locating of providers completes, it is signaled by calling `inject_providers`. The query 89 | manager then performs bitswap requests using the new provider set which results in the block 90 | being found or a `BlockNotFound` error. 91 | 92 | Often we want to sync an entire dag of blocks. We can efficiently sync dags of blocks by adding 93 | a sync query that runs get queries in parallel for all the references of a block. The set of 94 | providers that had a block is used as the initial set in a reference query. 95 | 96 | ## License 97 | 98 | MIT OR Apache-2.0 99 | -------------------------------------------------------------------------------- /src/compat/protocol.rs: -------------------------------------------------------------------------------- 1 | use crate::compat::{other, CompatMessage}; 2 | use futures::future::BoxFuture; 3 | use futures::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; 4 | use libp2p::core::{upgrade, InboundUpgrade, OutboundUpgrade, UpgradeInfo}; 5 | use std::{io, iter}; 6 | 7 | // 2MB Block Size according to the specs at https://github.com/ipfs/specs/blob/main/BITSWAP.md 8 | const MAX_BUF_SIZE: usize = 2_097_152; 9 | 10 | #[derive(Clone, Debug, Default)] 11 | pub struct CompatProtocol; 12 | 13 | impl UpgradeInfo for CompatProtocol { 14 | type Info = &'static [u8]; 15 | type InfoIter = iter::Once; 16 | 17 | fn protocol_info(&self) -> Self::InfoIter { 18 | iter::once(b"/ipfs/bitswap/1.2.0") 19 | } 20 | } 21 | 22 | impl InboundUpgrade for CompatProtocol 23 | where 24 | TSocket: AsyncRead + AsyncWrite + Send + Unpin + 'static, 25 | { 26 | type Output = InboundMessage; 27 | type Error = io::Error; 28 | type Future = BoxFuture<'static, Result>; 29 | 30 | fn upgrade_inbound(self, mut socket: TSocket, _info: Self::Info) -> Self::Future { 31 | Box::pin(async move { 32 | tracing::trace!("upgrading inbound"); 33 | let packet = upgrade::read_length_prefixed(&mut socket, MAX_BUF_SIZE) 34 | .await 35 | .map_err(|err| { 36 | tracing::debug!(%err, "inbound upgrade error"); 37 | other(err) 38 | })?; 39 | socket.close().await?; 40 | tracing::trace!("inbound upgrade done, closing"); 41 | let message = CompatMessage::from_bytes(&packet).map_err(|e| { 42 | tracing::debug!(%e, "inbound upgrade error"); 43 | e 44 | })?; 45 | tracing::trace!("inbound upgrade closed"); 46 | Ok(InboundMessage(message)) 47 | }) 48 | } 49 | } 50 | 51 | impl UpgradeInfo for CompatMessage { 52 | type Info = &'static [u8]; 53 | type InfoIter = iter::Once; 54 | 55 | fn protocol_info(&self) -> Self::InfoIter { 56 | iter::once(b"/ipfs/bitswap/1.2.0") 57 | } 58 | } 59 | 60 | impl OutboundUpgrade for CompatMessage 61 | where 62 | TSocket: AsyncRead + AsyncWrite + Send + Unpin + 'static, 63 | { 64 | type Output = (); 65 | type Error = io::Error; 66 | type Future = BoxFuture<'static, Result>; 67 | 68 | fn upgrade_outbound(self, mut socket: TSocket, _info: Self::Info) -> Self::Future { 69 | Box::pin(async move { 70 | let bytes = self.to_bytes()?; 71 | upgrade::write_length_prefixed(&mut socket, bytes).await?; 72 | socket.close().await?; 73 | Ok(()) 74 | }) 75 | } 76 | } 77 | 78 | #[derive(Debug)] 79 | pub struct InboundMessage(pub Vec); 80 | 81 | impl From<()> for InboundMessage { 82 | fn from(_: ()) -> Self { 83 | Self(Default::default()) 84 | } 85 | } 86 | 87 | #[cfg(test)] 88 | mod tests { 89 | use super::*; 90 | use crate::protocol::{BitswapRequest, RequestType}; 91 | use async_std::net::{TcpListener, TcpStream}; 92 | use futures::prelude::*; 93 | use libipld::Cid; 94 | use libp2p::core::upgrade; 95 | 96 | #[async_std::test] 97 | async fn test_upgrade() { 98 | let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); 99 | let listener_addr = listener.local_addr().unwrap(); 100 | 101 | let server = async move { 102 | let incoming = listener.incoming().into_future().await.0.unwrap().unwrap(); 103 | upgrade::apply_inbound(incoming, CompatProtocol) 104 | .await 105 | .unwrap(); 106 | }; 107 | 108 | let client = async move { 109 | let stream = TcpStream::connect(&listener_addr).await.unwrap(); 110 | upgrade::apply_outbound( 111 | stream, 112 | CompatMessage::Request(BitswapRequest { 113 | ty: RequestType::Have, 114 | cid: Cid::default(), 115 | }), 116 | upgrade::Version::V1, 117 | ) 118 | .await 119 | .unwrap(); 120 | }; 121 | 122 | future::select(Box::pin(server), Box::pin(client)).await; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/compat/message.rs: -------------------------------------------------------------------------------- 1 | use crate::compat::other; 2 | use crate::compat::prefix::Prefix; 3 | use crate::protocol::{BitswapRequest, BitswapResponse, RequestType}; 4 | use libipld::Cid; 5 | use prost::Message; 6 | use std::convert::TryFrom; 7 | use std::io; 8 | 9 | mod bitswap_pb { 10 | include!(concat!(env!("OUT_DIR"), "/bitswap_pb.rs")); 11 | } 12 | 13 | #[derive(Clone, Debug, Eq, PartialEq)] 14 | pub enum CompatMessage { 15 | Request(BitswapRequest), 16 | Response(Cid, BitswapResponse), 17 | } 18 | 19 | impl CompatMessage { 20 | pub fn to_bytes(&self) -> io::Result> { 21 | let mut msg = bitswap_pb::Message::default(); 22 | match self { 23 | CompatMessage::Request(BitswapRequest { ty, cid }) => { 24 | let mut wantlist = bitswap_pb::message::Wantlist::default(); 25 | let entry = bitswap_pb::message::wantlist::Entry { 26 | block: cid.to_bytes(), 27 | want_type: match ty { 28 | RequestType::Have => bitswap_pb::message::wantlist::WantType::Have, 29 | RequestType::Block => bitswap_pb::message::wantlist::WantType::Block, 30 | } as _, 31 | send_dont_have: true, 32 | cancel: false, 33 | priority: 1, 34 | }; 35 | wantlist.entries.push(entry); 36 | msg.wantlist = Some(wantlist); 37 | } 38 | CompatMessage::Response(cid, BitswapResponse::Have(have)) => { 39 | let block_presence = bitswap_pb::message::BlockPresence { 40 | cid: cid.to_bytes(), 41 | r#type: if *have { 42 | bitswap_pb::message::BlockPresenceType::Have 43 | } else { 44 | bitswap_pb::message::BlockPresenceType::DontHave 45 | } as _, 46 | }; 47 | msg.block_presences.push(block_presence); 48 | } 49 | CompatMessage::Response(cid, BitswapResponse::Block(bytes)) => { 50 | let payload = bitswap_pb::message::Block { 51 | prefix: Prefix::from(cid).to_bytes(), 52 | data: bytes.to_vec(), 53 | }; 54 | msg.payload.push(payload); 55 | } 56 | } 57 | let mut bytes = Vec::with_capacity(msg.encoded_len()); 58 | msg.encode(&mut bytes).map_err(other)?; 59 | Ok(bytes) 60 | } 61 | 62 | pub fn from_bytes(bytes: &[u8]) -> io::Result> { 63 | let msg = bitswap_pb::Message::decode(bytes)?; 64 | let mut parts = vec![]; 65 | for entry in msg.wantlist.unwrap_or_default().entries { 66 | if !entry.send_dont_have { 67 | tracing::error!("message hasn't set `send_dont_have`: skipping"); 68 | continue; 69 | } 70 | let cid = Cid::try_from(entry.block).map_err(other)?; 71 | let ty = match entry.want_type { 72 | ty if bitswap_pb::message::wantlist::WantType::Have as i32 == ty => { 73 | RequestType::Have 74 | } 75 | ty if bitswap_pb::message::wantlist::WantType::Block as i32 == ty => { 76 | RequestType::Block 77 | } 78 | _ => { 79 | tracing::error!("invalid request type: skipping"); 80 | continue; 81 | } 82 | }; 83 | parts.push(CompatMessage::Request(BitswapRequest { ty, cid })); 84 | } 85 | for payload in msg.payload { 86 | let prefix = Prefix::new(&payload.prefix)?; 87 | let cid = prefix.to_cid(&payload.data)?; 88 | parts.push(CompatMessage::Response( 89 | cid, 90 | BitswapResponse::Block(payload.data.to_vec()), 91 | )); 92 | } 93 | for presence in msg.block_presences { 94 | let cid = Cid::try_from(presence.cid).map_err(other)?; 95 | let have = match presence.r#type { 96 | ty if bitswap_pb::message::BlockPresenceType::Have as i32 == ty => true, 97 | ty if bitswap_pb::message::BlockPresenceType::DontHave as i32 == ty => false, 98 | _ => { 99 | tracing::error!("invalid block presence type: skipping"); 100 | continue; 101 | } 102 | }; 103 | parts.push(CompatMessage::Response(cid, BitswapResponse::Have(have))); 104 | } 105 | Ok(parts) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | 3 | name: libp2p-bitswap 4 | 5 | jobs: 6 | ci: 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | toolchain: 11 | - rust: stable 12 | #- rust: nightly 13 | platform: 14 | - target: x86_64-unknown-linux-gnu 15 | host: ubuntu-latest 16 | cross: false 17 | 18 | - target: x86_64-apple-darwin 19 | host: macos-latest 20 | cross: false 21 | 22 | - target: x86_64-pc-windows-msvc 23 | host: windows-latest 24 | cross: false 25 | 26 | - target: armv7-linux-androideabi 27 | host: ubuntu-latest 28 | cross: true 29 | - target: aarch64-linux-android 30 | host: ubuntu-latest 31 | cross: true 32 | 33 | - target: aarch64-apple-ios 34 | host: macos-latest 35 | cross: true 36 | 37 | # - target: wasm32-unknown-unknown 38 | # host: ubuntu-latest 39 | # cross: true 40 | env: 41 | RUST_BACKTRACE: 1 42 | RUST_LOG: debug 43 | CARGO_INCREMENTAL: 0 44 | LLVM_CONFIG_PATH: /usr/local/opt/llvm/bin/llvm-config 45 | NDK_HOME: /usr/local/lib/android/sdk/ndk-bundle 46 | 47 | runs-on: ${{ matrix.platform.host }} 48 | steps: 49 | - name: Checkout sources 50 | uses: actions/checkout@v3 51 | 52 | - name: Cache cargo folder 53 | uses: actions/cache@v3 54 | with: 55 | path: | 56 | ~/.cargo/bin/ 57 | ~/.cargo/registry/index/ 58 | ~/.cargo/registry/cache/ 59 | ~/.cargo/git/db/ 60 | target/ 61 | key: ${{ matrix.platform.target }}-cargo-${{ hashFiles('**/Cargo.lock') }} 62 | 63 | - name: Install Protoc 64 | uses: arduino/setup-protoc@v1 65 | with: 66 | repo-token: ${{ secrets.GITHUB_TOKEN }} 67 | 68 | - name: Install dependencies ubuntu 69 | if: matrix.platform.host == 'ubuntu-latest' 70 | run: sudo apt-get install llvm-dev 71 | 72 | - name: Install dependencies macos 73 | if: matrix.platform.host == 'macos-latest' 74 | run: brew install llvm 75 | 76 | - name: Install dependencies windows 77 | if: matrix.platform.host == 'windows-latest' 78 | run: choco install llvm 79 | 80 | - name: Install rust toolchain 81 | uses: actions-rs/toolchain@v1 82 | with: 83 | profile: minimal 84 | toolchain: ${{ matrix.toolchain.rust }} 85 | target: ${{ matrix.platform.target }} 86 | 87 | - name: Install cargo-apk 88 | if: contains(matrix.platform.target, 'android') 89 | uses: baptiste0928/cargo-install@bf6758885262d0e6f61089a9d8c8790d3ac3368f # v1.3.0 90 | with: 91 | crate: cargo-apk 92 | 93 | - name: Build 94 | if: contains(matrix.platform.target, 'android') == false 95 | uses: actions-rs/cargo@v1 96 | with: 97 | command: build 98 | args: --all --target ${{ matrix.platform.target }} 99 | 100 | - name: Build android 101 | if: contains(matrix.platform.target, 'android') 102 | uses: actions-rs/cargo@v1 103 | with: 104 | command: apk 105 | args: -- build --target ${{ matrix.platform.target }} 106 | 107 | - name: Rust tests 108 | if: matrix.platform.cross == false 109 | uses: actions-rs/cargo@v1 110 | with: 111 | command: test 112 | args: --all 113 | 114 | - name: Rust tests (compat feature) 115 | if: matrix.platform.cross == false 116 | uses: actions-rs/cargo@v1 117 | with: 118 | command: test 119 | args: --all --all-features 120 | 121 | lint-rust: 122 | runs-on: ubuntu-latest 123 | steps: 124 | - name: Checkout sources 125 | uses: actions/checkout@v3 126 | 127 | - name: Cache cargo folder 128 | uses: actions/cache@v3 129 | with: 130 | path: | 131 | ~/.cargo/bin/ 132 | ~/.cargo/registry/index/ 133 | ~/.cargo/registry/cache/ 134 | ~/.cargo/git/db/ 135 | target/ 136 | key: cargo-${{ hashFiles('**/Cargo.lock') }} 137 | 138 | - name: Install rust toolchain 139 | uses: actions-rs/toolchain@v1 140 | with: 141 | toolchain: stable 142 | profile: minimal 143 | components: clippy, rustfmt 144 | 145 | - name: Install Protoc 146 | uses: arduino/setup-protoc@v1 147 | with: 148 | repo-token: ${{ secrets.GITHUB_TOKEN }} 149 | 150 | - name: cargo fmt 151 | uses: actions-rs/cargo@v1 152 | with: 153 | command: fmt 154 | args: --all -- --check 155 | 156 | - name: cargo clippy 157 | uses: actions-rs/cargo@v1 158 | with: 159 | command: clippy 160 | args: --workspace --examples --tests -- -D warnings 161 | -------------------------------------------------------------------------------- /src/protocol.rs: -------------------------------------------------------------------------------- 1 | use async_trait::async_trait; 2 | use futures::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; 3 | use libipld::cid::Cid; 4 | use libipld::store::StoreParams; 5 | use libp2p::request_response::{ProtocolName, RequestResponseCodec}; 6 | use std::convert::TryFrom; 7 | use std::io::{self, Write}; 8 | use std::marker::PhantomData; 9 | use thiserror::Error; 10 | use unsigned_varint::{aio, io::ReadError}; 11 | 12 | // version codec hash size (u64 varint is max 10 bytes) + digest 13 | const MAX_CID_SIZE: usize = 4 * 10 + 64; 14 | 15 | #[derive(Clone, Debug)] 16 | pub struct BitswapProtocol; 17 | 18 | impl ProtocolName for BitswapProtocol { 19 | fn protocol_name(&self) -> &[u8] { 20 | b"/ipfs-embed/bitswap/1.0.0" 21 | } 22 | } 23 | 24 | #[derive(Clone)] 25 | pub struct BitswapCodec

{ 26 | _marker: PhantomData

, 27 | buffer: Vec, 28 | } 29 | 30 | impl Default for BitswapCodec

{ 31 | fn default() -> Self { 32 | let capacity = usize::max(P::MAX_BLOCK_SIZE, MAX_CID_SIZE) + 1; 33 | debug_assert!(capacity <= u32::MAX as usize); 34 | Self { 35 | _marker: PhantomData, 36 | buffer: Vec::with_capacity(capacity), 37 | } 38 | } 39 | } 40 | 41 | #[async_trait] 42 | impl RequestResponseCodec for BitswapCodec

{ 43 | type Protocol = BitswapProtocol; 44 | type Request = BitswapRequest; 45 | type Response = BitswapResponse; 46 | 47 | async fn read_request(&mut self, _: &Self::Protocol, io: &mut T) -> io::Result 48 | where 49 | T: AsyncRead + Send + Unpin, 50 | { 51 | let msg_len = u32_to_usize(aio::read_u32(&mut *io).await.map_err(|e| match e { 52 | ReadError::Io(e) => e, 53 | err => other(err), 54 | })?); 55 | if msg_len > MAX_CID_SIZE + 1 { 56 | return Err(invalid_data(MessageTooLarge(msg_len))); 57 | } 58 | self.buffer.resize(msg_len, 0); 59 | io.read_exact(&mut self.buffer).await?; 60 | let request = BitswapRequest::from_bytes(&self.buffer).map_err(invalid_data)?; 61 | Ok(request) 62 | } 63 | 64 | async fn read_response( 65 | &mut self, 66 | _: &Self::Protocol, 67 | io: &mut T, 68 | ) -> io::Result 69 | where 70 | T: AsyncRead + Send + Unpin, 71 | { 72 | let msg_len = u32_to_usize(aio::read_u32(&mut *io).await.map_err(|e| match e { 73 | ReadError::Io(e) => e, 74 | err => other(err), 75 | })?); 76 | if msg_len > P::MAX_BLOCK_SIZE + 1 { 77 | return Err(invalid_data(MessageTooLarge(msg_len))); 78 | } 79 | self.buffer.resize(msg_len, 0); 80 | io.read_exact(&mut self.buffer).await?; 81 | let response = BitswapResponse::from_bytes(&self.buffer).map_err(invalid_data)?; 82 | Ok(response) 83 | } 84 | 85 | async fn write_request( 86 | &mut self, 87 | _: &Self::Protocol, 88 | io: &mut T, 89 | req: Self::Request, 90 | ) -> io::Result<()> 91 | where 92 | T: AsyncWrite + Send + Unpin, 93 | { 94 | self.buffer.clear(); 95 | req.write_to(&mut self.buffer)?; 96 | if self.buffer.len() > MAX_CID_SIZE + 1 { 97 | return Err(invalid_data(MessageTooLarge(self.buffer.len()))); 98 | } 99 | let mut buf = unsigned_varint::encode::u32_buffer(); 100 | let msg_len = unsigned_varint::encode::u32(self.buffer.len() as u32, &mut buf); 101 | io.write_all(msg_len).await?; 102 | io.write_all(&self.buffer).await?; 103 | Ok(()) 104 | } 105 | 106 | async fn write_response( 107 | &mut self, 108 | _: &Self::Protocol, 109 | io: &mut T, 110 | res: Self::Response, 111 | ) -> io::Result<()> 112 | where 113 | T: AsyncWrite + Send + Unpin, 114 | { 115 | self.buffer.clear(); 116 | res.write_to(&mut self.buffer)?; 117 | if self.buffer.len() > P::MAX_BLOCK_SIZE + 1 { 118 | return Err(invalid_data(MessageTooLarge(self.buffer.len()))); 119 | } 120 | let mut buf = unsigned_varint::encode::u32_buffer(); 121 | let msg_len = unsigned_varint::encode::u32(self.buffer.len() as u32, &mut buf); 122 | io.write_all(msg_len).await?; 123 | io.write_all(&self.buffer).await?; 124 | Ok(()) 125 | } 126 | } 127 | 128 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 129 | pub enum RequestType { 130 | Have, 131 | Block, 132 | } 133 | 134 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 135 | pub struct BitswapRequest { 136 | pub ty: RequestType, 137 | pub cid: Cid, 138 | } 139 | 140 | impl BitswapRequest { 141 | pub fn write_to(&self, w: &mut W) -> io::Result<()> { 142 | match self { 143 | BitswapRequest { 144 | ty: RequestType::Have, 145 | cid, 146 | } => { 147 | w.write_all(&[0])?; 148 | cid.write_bytes(&mut *w).map_err(other)?; 149 | } 150 | BitswapRequest { 151 | ty: RequestType::Block, 152 | cid, 153 | } => { 154 | w.write_all(&[1])?; 155 | cid.write_bytes(&mut *w).map_err(other)?; 156 | } 157 | } 158 | Ok(()) 159 | } 160 | 161 | pub fn from_bytes(bytes: &[u8]) -> io::Result { 162 | let ty = match bytes[0] { 163 | 0 => RequestType::Have, 164 | 1 => RequestType::Block, 165 | c => return Err(invalid_data(UnknownMessageType(c))), 166 | }; 167 | let cid = Cid::try_from(&bytes[1..]).map_err(invalid_data)?; 168 | Ok(Self { ty, cid }) 169 | } 170 | } 171 | 172 | #[derive(Clone, Debug, Eq, PartialEq)] 173 | pub enum BitswapResponse { 174 | Have(bool), 175 | Block(Vec), 176 | } 177 | 178 | impl BitswapResponse { 179 | pub fn write_to(&self, w: &mut W) -> io::Result<()> { 180 | match self { 181 | BitswapResponse::Have(have) => { 182 | if *have { 183 | w.write_all(&[0])?; 184 | } else { 185 | w.write_all(&[2])?; 186 | } 187 | } 188 | BitswapResponse::Block(data) => { 189 | w.write_all(&[1])?; 190 | w.write_all(data)?; 191 | } 192 | }; 193 | Ok(()) 194 | } 195 | 196 | pub fn from_bytes(bytes: &[u8]) -> io::Result { 197 | let res = match bytes[0] { 198 | 0 | 2 => BitswapResponse::Have(bytes[0] == 0), 199 | 1 => BitswapResponse::Block(bytes[1..].to_vec()), 200 | c => return Err(invalid_data(UnknownMessageType(c))), 201 | }; 202 | Ok(res) 203 | } 204 | } 205 | 206 | fn invalid_data(e: E) -> io::Error { 207 | io::Error::new(io::ErrorKind::InvalidData, e) 208 | } 209 | 210 | fn other(e: E) -> io::Error { 211 | io::Error::new(io::ErrorKind::Other, e) 212 | } 213 | 214 | #[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))] 215 | fn u32_to_usize(n: u32) -> usize { 216 | n as usize 217 | } 218 | 219 | #[derive(Debug, Error)] 220 | #[error("unknown message type {0}")] 221 | pub struct UnknownMessageType(u8); 222 | 223 | #[derive(Debug, Error)] 224 | #[error("message too large {0}")] 225 | pub struct MessageTooLarge(usize); 226 | 227 | #[cfg(test)] 228 | pub(crate) mod tests { 229 | use super::*; 230 | use libipld::multihash::Code; 231 | use multihash::MultihashDigest; 232 | 233 | pub fn create_cid(bytes: &[u8]) -> Cid { 234 | let digest = Code::Blake3_256.digest(bytes); 235 | Cid::new_v1(0x55, digest) 236 | } 237 | 238 | #[test] 239 | fn test_request_encode_decode() { 240 | let requests = [ 241 | BitswapRequest { 242 | ty: RequestType::Have, 243 | cid: create_cid(&b"have_request"[..]), 244 | }, 245 | BitswapRequest { 246 | ty: RequestType::Block, 247 | cid: create_cid(&b"block_request"[..]), 248 | }, 249 | ]; 250 | let mut buf = Vec::with_capacity(MAX_CID_SIZE + 1); 251 | for request in &requests { 252 | buf.clear(); 253 | request.write_to(&mut buf).unwrap(); 254 | assert_eq!(&BitswapRequest::from_bytes(&buf).unwrap(), request); 255 | } 256 | } 257 | 258 | #[test] 259 | fn test_response_encode_decode() { 260 | let responses = [ 261 | BitswapResponse::Have(true), 262 | BitswapResponse::Have(false), 263 | BitswapResponse::Block(b"block_response".to_vec()), 264 | ]; 265 | let mut buf = Vec::with_capacity(13 + 1); 266 | for response in &responses { 267 | buf.clear(); 268 | response.write_to(&mut buf).unwrap(); 269 | assert_eq!(&BitswapResponse::from_bytes(&buf).unwrap(), response); 270 | } 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /src/query.rs: -------------------------------------------------------------------------------- 1 | use crate::stats::{REQUESTS_TOTAL, REQUEST_DURATION_SECONDS}; 2 | use fnv::{FnvHashMap, FnvHashSet}; 3 | use libipld::Cid; 4 | use libp2p::PeerId; 5 | use prometheus::HistogramTimer; 6 | use std::collections::VecDeque; 7 | 8 | /// Query id. 9 | #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 10 | pub struct QueryId(u64); 11 | 12 | impl std::fmt::Display for QueryId { 13 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 14 | self.0.fmt(f) 15 | } 16 | } 17 | 18 | /// Request. 19 | #[derive(Debug, Eq, PartialEq)] 20 | pub enum Request { 21 | /// Have query. 22 | Have(PeerId, Cid), 23 | /// Block query. 24 | Block(PeerId, Cid), 25 | /// Missing blocks query. 26 | MissingBlocks(Cid), 27 | } 28 | 29 | impl std::fmt::Display for Request { 30 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 31 | match self { 32 | Self::Have(_, _) => write!(f, "have"), 33 | Self::Block(_, _) => write!(f, "block"), 34 | Self::MissingBlocks(_) => write!(f, "missing-blocks"), 35 | } 36 | } 37 | } 38 | 39 | /// Response. 40 | #[derive(Debug)] 41 | pub enum Response { 42 | /// Have query. 43 | Have(PeerId, bool), 44 | /// Block query. 45 | Block(PeerId, bool), 46 | /// Missing blocks query. 47 | MissingBlocks(Vec), 48 | } 49 | 50 | impl std::fmt::Display for Response { 51 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 52 | match self { 53 | Self::Have(_, have) => write!(f, "have {}", have), 54 | Self::Block(_, block) => write!(f, "block {}", block), 55 | Self::MissingBlocks(missing) => write!(f, "missing-blocks {}", missing.len()), 56 | } 57 | } 58 | } 59 | 60 | /// Event emitted by a query. 61 | #[derive(Debug)] 62 | pub enum QueryEvent { 63 | /// A subquery to run. 64 | Request(QueryId, Request), 65 | /// A progress event. 66 | Progress(QueryId, usize), 67 | /// Complete event. 68 | Complete(QueryId, Result<(), Cid>), 69 | } 70 | 71 | #[derive(Debug)] 72 | pub struct Header { 73 | /// Query id. 74 | pub id: QueryId, 75 | /// Root query id. 76 | pub root: QueryId, 77 | /// Parent. 78 | pub parent: Option, 79 | /// Cid. 80 | pub cid: Cid, 81 | /// Timer. 82 | pub timer: HistogramTimer, 83 | /// Type. 84 | pub label: &'static str, 85 | } 86 | 87 | impl Drop for Header { 88 | fn drop(&mut self) { 89 | REQUESTS_TOTAL.with_label_values(&[self.label]).inc(); 90 | } 91 | } 92 | 93 | /// Query. 94 | #[derive(Debug)] 95 | struct Query { 96 | /// Header. 97 | hdr: Header, 98 | /// State. 99 | state: State, 100 | } 101 | 102 | #[derive(Debug)] 103 | enum State { 104 | None, 105 | Get(GetState), 106 | Sync(SyncState), 107 | } 108 | 109 | #[derive(Debug, Default)] 110 | struct GetState { 111 | have: FnvHashSet, 112 | block: Option, 113 | providers: Vec, 114 | } 115 | 116 | #[derive(Debug, Default)] 117 | struct SyncState { 118 | missing: FnvHashSet, 119 | children: FnvHashSet, 120 | providers: Vec, 121 | } 122 | 123 | enum Transition { 124 | Next(S), 125 | Complete(C), 126 | } 127 | 128 | #[derive(Default)] 129 | pub struct QueryManager { 130 | id_counter: u64, 131 | queries: FnvHashMap, 132 | events: VecDeque, 133 | } 134 | 135 | impl QueryManager { 136 | /// Start a new subquery. 137 | fn start_query( 138 | &mut self, 139 | root: QueryId, 140 | parent: Option, 141 | cid: Cid, 142 | req: Request, 143 | label: &'static str, 144 | ) -> QueryId { 145 | let timer = REQUEST_DURATION_SECONDS 146 | .with_label_values(&[label]) 147 | .start_timer(); 148 | let id = QueryId(self.id_counter); 149 | self.id_counter += 1; 150 | let query = Query { 151 | hdr: Header { 152 | id, 153 | root, 154 | parent, 155 | cid, 156 | timer, 157 | label, 158 | }, 159 | state: State::None, 160 | }; 161 | self.queries.insert(id, query); 162 | tracing::trace!("{} {} {}", root, id, req); 163 | self.events.push_back(QueryEvent::Request(id, req)); 164 | id 165 | } 166 | 167 | /// Starts a new have query to ask a peer if it has a block. 168 | fn have(&mut self, root: QueryId, parent: QueryId, peer_id: PeerId, cid: Cid) -> QueryId { 169 | self.start_query(root, Some(parent), cid, Request::Have(peer_id, cid), "have") 170 | } 171 | 172 | /// Starts a new block query to request a block from a peer. 173 | fn block(&mut self, root: QueryId, parent: QueryId, peer_id: PeerId, cid: Cid) -> QueryId { 174 | self.start_query( 175 | root, 176 | Some(parent), 177 | cid, 178 | Request::Block(peer_id, cid), 179 | "block", 180 | ) 181 | } 182 | 183 | /// Starts a query to determine the missing blocks of a dag. 184 | fn missing_blocks(&mut self, parent: QueryId, cid: Cid) -> QueryId { 185 | self.start_query( 186 | parent, 187 | Some(parent), 188 | cid, 189 | Request::MissingBlocks(cid), 190 | "missing-blocks", 191 | ) 192 | } 193 | 194 | /// Starts a query to locate and retrieve a block. Panics if no providers are supplied. 195 | pub fn get( 196 | &mut self, 197 | parent: Option, 198 | cid: Cid, 199 | providers: impl Iterator, 200 | ) -> QueryId { 201 | let timer = REQUEST_DURATION_SECONDS 202 | .with_label_values(&["get"]) 203 | .start_timer(); 204 | let id = QueryId(self.id_counter); 205 | self.id_counter += 1; 206 | let root = parent.unwrap_or(id); 207 | tracing::trace!("{} {} get", root, id); 208 | let mut state = GetState::default(); 209 | for peer in providers { 210 | if state.block.is_none() { 211 | state.block = Some(self.block(root, id, peer, cid)); 212 | } else { 213 | state.have.insert(self.have(root, id, peer, cid)); 214 | } 215 | } 216 | assert!(state.block.is_some()); 217 | let query = Query { 218 | hdr: Header { 219 | id, 220 | root, 221 | parent, 222 | cid, 223 | timer, 224 | label: "get", 225 | }, 226 | state: State::Get(state), 227 | }; 228 | self.queries.insert(id, query); 229 | id 230 | } 231 | 232 | /// Starts a query to recursively retrieve a dag. The missing blocks are the first 233 | /// blocks that need to be retrieved. 234 | pub fn sync( 235 | &mut self, 236 | cid: Cid, 237 | providers: Vec, 238 | missing: impl Iterator, 239 | ) -> QueryId { 240 | let timer = REQUEST_DURATION_SECONDS 241 | .with_label_values(&["sync"]) 242 | .start_timer(); 243 | let id = QueryId(self.id_counter); 244 | self.id_counter += 1; 245 | tracing::trace!("{} {} sync", id, id); 246 | let mut state = SyncState::default(); 247 | for cid in missing { 248 | state 249 | .missing 250 | .insert(self.get(Some(id), cid, providers.iter().copied())); 251 | } 252 | if state.missing.is_empty() { 253 | state.children.insert(self.missing_blocks(id, cid)); 254 | } 255 | state.providers = providers; 256 | let query = Query { 257 | hdr: Header { 258 | id, 259 | root: id, 260 | parent: None, 261 | cid, 262 | timer, 263 | label: "sync", 264 | }, 265 | state: State::Sync(state), 266 | }; 267 | self.queries.insert(id, query); 268 | id 269 | } 270 | 271 | /// Cancels an in progress query. 272 | pub fn cancel(&mut self, root: QueryId) -> bool { 273 | let query = if let Some(query) = self.queries.remove(&root) { 274 | query 275 | } else { 276 | return false; 277 | }; 278 | let queries = &self.queries; 279 | self.events.retain(|event| { 280 | let (id, req) = match event { 281 | QueryEvent::Request(id, req) => (id, req), 282 | QueryEvent::Progress(id, _) => return *id != root, 283 | QueryEvent::Complete(_, _) => return true, 284 | }; 285 | if queries.get(id).map(|q| q.hdr.root) != Some(root) { 286 | return true; 287 | } 288 | tracing::trace!("{} {} {} cancel", root, id, req); 289 | false 290 | }); 291 | match query.state { 292 | State::Get(_) => { 293 | tracing::trace!("{} {} get cancel", root, root); 294 | true 295 | } 296 | State::Sync(state) => { 297 | for id in state.missing { 298 | tracing::trace!("{} {} get cancel", root, id); 299 | self.queries.remove(&id); 300 | } 301 | tracing::trace!("{} {} sync cancel", root, root); 302 | true 303 | } 304 | State::None => { 305 | self.queries.insert(root, query); 306 | false 307 | } 308 | } 309 | } 310 | 311 | /// Advances a get query state machine using a transition function. 312 | fn get_query(&mut self, id: QueryId, f: F) 313 | where 314 | F: FnOnce(&mut Self, &Header, GetState) -> Transition>, 315 | { 316 | if let Some(mut parent) = self.queries.remove(&id) { 317 | let state = if let State::Get(state) = parent.state { 318 | state 319 | } else { 320 | return; 321 | }; 322 | match f(self, &parent.hdr, state) { 323 | Transition::Next(state) => { 324 | parent.state = State::Get(state); 325 | self.queries.insert(id, parent); 326 | } 327 | Transition::Complete(res) => { 328 | match res { 329 | Ok(()) => tracing::trace!("{} {} get ok", parent.hdr.root, parent.hdr.id), 330 | Err(_) => tracing::trace!("{} {} get err", parent.hdr.root, parent.hdr.id), 331 | } 332 | self.recv_get(parent.hdr, res); 333 | } 334 | } 335 | } 336 | } 337 | 338 | /// Advances a sync query state machine using a transition function. 339 | fn sync_query(&mut self, id: QueryId, f: F) 340 | where 341 | F: FnOnce(&mut Self, &Header, SyncState) -> Transition>, 342 | { 343 | if let Some(mut parent) = self.queries.remove(&id) { 344 | let state = if let State::Sync(state) = parent.state { 345 | state 346 | } else { 347 | return; 348 | }; 349 | match f(self, &parent.hdr, state) { 350 | Transition::Next(state) => { 351 | parent.state = State::Sync(state); 352 | self.queries.insert(id, parent); 353 | } 354 | Transition::Complete(res) => { 355 | if res.is_ok() { 356 | tracing::trace!("{} {} sync ok", parent.hdr.root, parent.hdr.id); 357 | } else { 358 | tracing::trace!("{} {} sync err", parent.hdr.root, parent.hdr.id); 359 | } 360 | self.recv_sync(parent.hdr, res); 361 | } 362 | } 363 | } 364 | } 365 | 366 | /// Processes the response of a have query. 367 | /// 368 | /// Marks the in progress query as complete and updates the set of peers that have 369 | /// a block. If there isn't an in progress block query a new block query will be 370 | /// started. If no block query can be started either a provider query is started or 371 | /// the get query is marked as complete with a block-not-found error. 372 | fn recv_have(&mut self, query: Header, peer_id: PeerId, have: bool) { 373 | self.get_query(query.parent.unwrap(), |mgr, parent, mut state| { 374 | state.have.remove(&query.id); 375 | if state.block == Some(query.id) { 376 | state.block = None; 377 | } 378 | if have { 379 | state.providers.push(peer_id); 380 | } 381 | if state.block.is_none() && !state.providers.is_empty() { 382 | state.block = Some(mgr.block( 383 | parent.root, 384 | parent.id, 385 | state.providers.pop().unwrap(), 386 | query.cid, 387 | )); 388 | } 389 | if state.have.is_empty() && state.block.is_none() && state.providers.is_empty() { 390 | if state.providers.is_empty() { 391 | return Transition::Complete(Err(query.cid)); 392 | } else { 393 | return Transition::Complete(Ok(())); 394 | } 395 | } 396 | Transition::Next(state) 397 | }); 398 | } 399 | 400 | /// Processes the response of a block query. 401 | /// 402 | /// Either completes the get query or processes it like a have query response. 403 | fn recv_block(&mut self, query: Header, peer_id: PeerId, block: bool) { 404 | if block { 405 | self.get_query(query.parent.unwrap(), |_mgr, _parent, mut state| { 406 | state.providers.push(peer_id); 407 | Transition::Complete(Ok(())) 408 | }); 409 | } else { 410 | self.recv_have(query, peer_id, block); 411 | } 412 | } 413 | 414 | /// Processes the response of a missing blocks query. 415 | /// 416 | /// Starts a get query for each missing block. If there are no in progress queries 417 | /// the sync query is marked as complete. 418 | fn recv_missing_blocks(&mut self, query: Header, missing: Vec) { 419 | let mut num_missing = 0; 420 | let num_missing_ref = &mut num_missing; 421 | self.sync_query(query.parent.unwrap(), |mgr, parent, mut state| { 422 | state.children.remove(&query.id); 423 | for cid in missing { 424 | state.missing.insert(mgr.get( 425 | Some(parent.root), 426 | cid, 427 | state.providers.iter().copied(), 428 | )); 429 | } 430 | *num_missing_ref = state.missing.len(); 431 | if state.missing.is_empty() && state.children.is_empty() { 432 | Transition::Complete(Ok(())) 433 | } else { 434 | Transition::Next(state) 435 | } 436 | }); 437 | if num_missing != 0 { 438 | self.events 439 | .push_back(QueryEvent::Progress(query.root, num_missing)); 440 | } 441 | } 442 | 443 | /// Processes the response of a get query. 444 | /// 445 | /// If it is part of a sync query a new missing blocks query is started. Otherwise 446 | /// the get query emits a `complete` event. 447 | fn recv_get(&mut self, query: Header, res: Result<(), Cid>) { 448 | if let Some(id) = query.parent { 449 | self.sync_query(id, |mgr, parent, mut state| { 450 | state.missing.remove(&query.id); 451 | if res.is_err() { 452 | Transition::Complete(res) 453 | } else { 454 | state 455 | .children 456 | .insert(mgr.missing_blocks(parent.root, query.cid)); 457 | Transition::Next(state) 458 | } 459 | }); 460 | } else { 461 | self.events.push_back(QueryEvent::Complete(query.id, res)); 462 | } 463 | } 464 | 465 | /// Processes the response of a sync query. 466 | /// 467 | /// The sync query emits a `complete` event. 468 | fn recv_sync(&mut self, query: Header, res: Result<(), Cid>) { 469 | self.events.push_back(QueryEvent::Complete(query.id, res)); 470 | } 471 | 472 | /// Dispatches the response to a query handler. 473 | pub fn inject_response(&mut self, id: QueryId, res: Response) { 474 | let query = if let Some(query) = self.queries.remove(&id) { 475 | query.hdr 476 | } else { 477 | return; 478 | }; 479 | tracing::trace!("{} {} {}", query.root, query.id, res); 480 | match res { 481 | Response::Have(peer, have) => { 482 | self.recv_have(query, peer, have); 483 | } 484 | Response::Block(peer, block) => { 485 | self.recv_block(query, peer, block); 486 | } 487 | Response::MissingBlocks(cids) => { 488 | self.recv_missing_blocks(query, cids); 489 | } 490 | } 491 | } 492 | 493 | /// Returns the header of a query. 494 | pub fn query_info(&self, id: QueryId) -> Option<&Header> { 495 | self.queries.get(&id).map(|q| &q.hdr) 496 | } 497 | 498 | /// Retrieves the next query event. 499 | pub fn next(&mut self) -> Option { 500 | self.events.pop_front() 501 | } 502 | } 503 | 504 | #[cfg(test)] 505 | mod tests { 506 | use super::*; 507 | use tracing_subscriber::fmt::TestWriter; 508 | 509 | fn tracing_try_init() { 510 | tracing_subscriber::fmt() 511 | .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) 512 | .with_writer(TestWriter::new()) 513 | .try_init() 514 | .ok(); 515 | } 516 | 517 | fn gen_peers(n: usize) -> Vec { 518 | let mut peers = Vec::with_capacity(n); 519 | for _ in 0..n { 520 | peers.push(PeerId::random()); 521 | } 522 | peers 523 | } 524 | 525 | fn assert_request(event: Option, req: Request) -> QueryId { 526 | if let Some(QueryEvent::Request(id, req2)) = event { 527 | assert_eq!(req2, req); 528 | id 529 | } else { 530 | panic!("{:?} is not a request", event); 531 | } 532 | } 533 | 534 | fn assert_complete(event: Option, id: QueryId, res: Result<(), Cid>) { 535 | if let Some(QueryEvent::Complete(id2, res2)) = event { 536 | assert_eq!(id, id2); 537 | assert_eq!(res, res2); 538 | } else { 539 | panic!("{:?} is not a complete event", event); 540 | } 541 | } 542 | 543 | #[test] 544 | fn test_get_query_block_not_found() { 545 | let mut mgr = QueryManager::default(); 546 | let initial_set = gen_peers(3); 547 | let cid = Cid::default(); 548 | 549 | let id = mgr.get(None, cid, initial_set.iter().copied()); 550 | 551 | let id1 = assert_request(mgr.next(), Request::Block(initial_set[0], cid)); 552 | let id2 = assert_request(mgr.next(), Request::Have(initial_set[1], cid)); 553 | let id3 = assert_request(mgr.next(), Request::Have(initial_set[2], cid)); 554 | 555 | mgr.inject_response(id1, Response::Have(initial_set[0], false)); 556 | mgr.inject_response(id2, Response::Have(initial_set[1], false)); 557 | mgr.inject_response(id3, Response::Have(initial_set[2], false)); 558 | 559 | assert_complete(mgr.next(), id, Err(cid)); 560 | } 561 | 562 | #[test] 563 | fn test_cid_query_block_found() { 564 | let mut mgr = QueryManager::default(); 565 | let initial_set = gen_peers(3); 566 | let cid = Cid::default(); 567 | 568 | let id = mgr.get(None, cid, initial_set.iter().copied()); 569 | 570 | let id1 = assert_request(mgr.next(), Request::Block(initial_set[0], cid)); 571 | let id2 = assert_request(mgr.next(), Request::Have(initial_set[1], cid)); 572 | let id3 = assert_request(mgr.next(), Request::Have(initial_set[2], cid)); 573 | 574 | mgr.inject_response(id1, Response::Block(initial_set[0], true)); 575 | mgr.inject_response(id2, Response::Have(initial_set[1], false)); 576 | mgr.inject_response(id3, Response::Have(initial_set[2], false)); 577 | 578 | assert_complete(mgr.next(), id, Ok(())); 579 | } 580 | 581 | #[test] 582 | fn test_get_query_gets_from_spare_if_block_request_fails() { 583 | let mut mgr = QueryManager::default(); 584 | let initial_set = gen_peers(3); 585 | let cid = Cid::default(); 586 | 587 | let id = mgr.get(None, cid, initial_set.iter().copied()); 588 | 589 | let id1 = assert_request(mgr.next(), Request::Block(initial_set[0], cid)); 590 | let id2 = assert_request(mgr.next(), Request::Have(initial_set[1], cid)); 591 | let id3 = assert_request(mgr.next(), Request::Have(initial_set[2], cid)); 592 | 593 | mgr.inject_response(id1, Response::Block(initial_set[0], false)); 594 | mgr.inject_response(id2, Response::Have(initial_set[1], true)); 595 | mgr.inject_response(id3, Response::Have(initial_set[2], false)); 596 | 597 | let id1 = assert_request(mgr.next(), Request::Block(initial_set[1], cid)); 598 | mgr.inject_response(id1, Response::Block(initial_set[1], true)); 599 | 600 | assert_complete(mgr.next(), id, Ok(())); 601 | } 602 | 603 | #[test] 604 | fn test_get_query_gets_from_spare_if_block_request_fails_after_have_is_received() { 605 | let mut mgr = QueryManager::default(); 606 | let initial_set = gen_peers(3); 607 | let cid = Cid::default(); 608 | 609 | let id = mgr.get(None, cid, initial_set.iter().copied()); 610 | 611 | let id1 = assert_request(mgr.next(), Request::Block(initial_set[0], cid)); 612 | let id2 = assert_request(mgr.next(), Request::Have(initial_set[1], cid)); 613 | let id3 = assert_request(mgr.next(), Request::Have(initial_set[2], cid)); 614 | 615 | mgr.inject_response(id1, Response::Block(initial_set[0], false)); 616 | mgr.inject_response(id2, Response::Have(initial_set[1], true)); 617 | mgr.inject_response(id3, Response::Have(initial_set[2], true)); 618 | 619 | let id1 = assert_request(mgr.next(), Request::Block(initial_set[1], cid)); 620 | mgr.inject_response(id1, Response::Block(initial_set[1], false)); 621 | 622 | let id1 = assert_request(mgr.next(), Request::Block(initial_set[2], cid)); 623 | mgr.inject_response(id1, Response::Block(initial_set[2], true)); 624 | 625 | assert_complete(mgr.next(), id, Ok(())); 626 | } 627 | 628 | #[test] 629 | fn test_sync_query() { 630 | tracing_try_init(); 631 | let mut mgr = QueryManager::default(); 632 | let providers = gen_peers(3); 633 | let cid = Cid::default(); 634 | 635 | let id = mgr.sync(cid, providers.clone(), std::iter::once(cid)); 636 | 637 | let id1 = assert_request(mgr.next(), Request::Block(providers[0], cid)); 638 | let id2 = assert_request(mgr.next(), Request::Have(providers[1], cid)); 639 | let id3 = assert_request(mgr.next(), Request::Have(providers[2], cid)); 640 | 641 | mgr.inject_response(id1, Response::Block(providers[0], true)); 642 | mgr.inject_response(id2, Response::Have(providers[1], false)); 643 | mgr.inject_response(id3, Response::Have(providers[2], false)); 644 | 645 | let id1 = assert_request(mgr.next(), Request::MissingBlocks(cid)); 646 | mgr.inject_response(id1, Response::MissingBlocks(vec![])); 647 | 648 | assert_complete(mgr.next(), id, Ok(())); 649 | } 650 | 651 | #[test] 652 | fn test_sync_query_empty() { 653 | tracing_try_init(); 654 | let mut mgr = QueryManager::default(); 655 | let cid = Cid::default(); 656 | let id = mgr.sync(cid, vec![], std::iter::empty()); 657 | let id1 = assert_request(mgr.next(), Request::MissingBlocks(cid)); 658 | mgr.inject_response(id1, Response::MissingBlocks(vec![])); 659 | assert_complete(mgr.next(), id, Ok(())); 660 | } 661 | } 662 | -------------------------------------------------------------------------------- /src/behaviour.rs: -------------------------------------------------------------------------------- 1 | //! Handles the `/ipfs/bitswap/1.0.0` and `/ipfs/bitswap/1.1.0` protocols. This 2 | //! allows exchanging IPFS blocks. 3 | //! 4 | //! # Usage 5 | //! 6 | //! The `Bitswap` struct implements the `NetworkBehaviour` trait. When used, it 7 | //! will allow providing and reciving IPFS blocks. 8 | #[cfg(feature = "compat")] 9 | use crate::compat::{CompatMessage, CompatProtocol, InboundMessage}; 10 | use crate::protocol::{ 11 | BitswapCodec, BitswapProtocol, BitswapRequest, BitswapResponse, RequestType, 12 | }; 13 | use crate::query::{QueryEvent, QueryId, QueryManager, Request, Response}; 14 | use crate::stats::*; 15 | use fnv::FnvHashMap; 16 | #[cfg(feature = "compat")] 17 | use fnv::FnvHashSet; 18 | use futures::{ 19 | channel::mpsc, 20 | stream::{Stream, StreamExt}, 21 | task::{Context, Poll}, 22 | }; 23 | use libipld::{error::BlockNotFound, store::StoreParams, Block, Cid, Result}; 24 | #[cfg(feature = "compat")] 25 | use libp2p::core::either::EitherOutput; 26 | use libp2p::core::{connection::ConnectionId, Multiaddr, PeerId}; 27 | use libp2p::swarm::derive_prelude::{ConnectionClosed, DialFailure, FromSwarm, ListenFailure}; 28 | #[cfg(feature = "compat")] 29 | use libp2p::swarm::{ConnectionHandlerSelect, NotifyHandler, OneShotHandler}; 30 | use libp2p::{ 31 | request_response::{ 32 | InboundFailure, OutboundFailure, ProtocolSupport, RequestId, RequestResponse, 33 | RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, 34 | }, 35 | swarm::{ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters}, 36 | }; 37 | use prometheus::Registry; 38 | use std::{pin::Pin, time::Duration}; 39 | 40 | /// Bitswap response channel. 41 | pub type Channel = ResponseChannel; 42 | 43 | /// Event emitted by the bitswap behaviour. 44 | #[derive(Debug)] 45 | pub enum BitswapEvent { 46 | /// Received a block from a peer. Includes the number of known missing blocks for a 47 | /// sync query. When a block is received and missing blocks is not empty the counter 48 | /// is increased. If missing blocks is empty the counter is decremented. 49 | Progress(QueryId, usize), 50 | /// A get or sync query completed. 51 | Complete(QueryId, Result<()>), 52 | } 53 | 54 | /// Trait implemented by a block store. 55 | pub trait BitswapStore: Send + Sync + 'static { 56 | /// The store params. 57 | type Params: StoreParams; 58 | /// A have query needs to know if the block store contains the block. 59 | fn contains(&mut self, cid: &Cid) -> Result; 60 | /// A block query needs to retrieve the block from the store. 61 | fn get(&mut self, cid: &Cid) -> Result>>; 62 | /// A block response needs to insert the block into the store. 63 | fn insert(&mut self, block: &Block) -> Result<()>; 64 | /// A sync query needs a list of missing blocks to make progress. 65 | fn missing_blocks(&mut self, cid: &Cid) -> Result>; 66 | } 67 | 68 | /// Bitswap configuration. 69 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 70 | pub struct BitswapConfig { 71 | /// Timeout of a request. 72 | pub request_timeout: Duration, 73 | /// Time a connection is kept alive. 74 | pub connection_keep_alive: Duration, 75 | } 76 | 77 | impl BitswapConfig { 78 | /// Creates a new `BitswapConfig`. 79 | pub fn new() -> Self { 80 | Self { 81 | request_timeout: Duration::from_secs(10), 82 | connection_keep_alive: Duration::from_secs(10), 83 | } 84 | } 85 | } 86 | 87 | impl Default for BitswapConfig { 88 | fn default() -> Self { 89 | Self::new() 90 | } 91 | } 92 | 93 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 94 | enum BitswapId { 95 | Bitswap(RequestId), 96 | #[cfg(feature = "compat")] 97 | Compat(Cid), 98 | } 99 | 100 | enum BitswapChannel { 101 | Bitswap(Channel), 102 | #[cfg(feature = "compat")] 103 | Compat(PeerId, Cid), 104 | } 105 | 106 | /// Network behaviour that handles sending and receiving blocks. 107 | pub struct Bitswap { 108 | /// Inner behaviour. 109 | inner: RequestResponse>, 110 | /// Query manager. 111 | query_manager: QueryManager, 112 | /// Requests. 113 | requests: FnvHashMap, 114 | /// Db request channel. 115 | db_tx: mpsc::UnboundedSender>, 116 | /// Db response channel. 117 | db_rx: mpsc::UnboundedReceiver, 118 | /// Compat peers. 119 | #[cfg(feature = "compat")] 120 | compat: FnvHashSet, 121 | } 122 | 123 | impl Bitswap

{ 124 | /// Creates a new `Bitswap` behaviour. 125 | pub fn new>(config: BitswapConfig, store: S) -> Self { 126 | let mut rr_config = RequestResponseConfig::default(); 127 | rr_config.set_connection_keep_alive(config.connection_keep_alive); 128 | rr_config.set_request_timeout(config.request_timeout); 129 | let protocols = std::iter::once((BitswapProtocol, ProtocolSupport::Full)); 130 | let inner = RequestResponse::new(BitswapCodec::

::default(), protocols, rr_config); 131 | let (db_tx, db_rx) = start_db_thread(store); 132 | Self { 133 | inner, 134 | query_manager: Default::default(), 135 | requests: Default::default(), 136 | db_tx, 137 | db_rx, 138 | #[cfg(feature = "compat")] 139 | compat: Default::default(), 140 | } 141 | } 142 | 143 | /// Adds an address for a peer. 144 | pub fn add_address(&mut self, peer_id: &PeerId, addr: Multiaddr) { 145 | self.inner.add_address(peer_id, addr); 146 | } 147 | 148 | /// Removes an address for a peer. 149 | pub fn remove_address(&mut self, peer_id: &PeerId, addr: &Multiaddr) { 150 | self.inner.remove_address(peer_id, addr); 151 | } 152 | 153 | /// Starts a get query with an initial guess of providers. 154 | pub fn get(&mut self, cid: Cid, peers: impl Iterator) -> QueryId { 155 | self.query_manager.get(None, cid, peers) 156 | } 157 | 158 | /// Starts a sync query with an the initial set of missing blocks. 159 | pub fn sync( 160 | &mut self, 161 | cid: Cid, 162 | peers: Vec, 163 | missing: impl Iterator, 164 | ) -> QueryId { 165 | self.query_manager.sync(cid, peers, missing) 166 | } 167 | 168 | /// Cancels an in progress query. Returns true if a query was cancelled. 169 | pub fn cancel(&mut self, id: QueryId) -> bool { 170 | let res = self.query_manager.cancel(id); 171 | if res { 172 | REQUESTS_CANCELED.inc(); 173 | } 174 | res 175 | } 176 | 177 | /// Registers prometheus metrics. 178 | pub fn register_metrics(&self, registry: &Registry) -> Result<()> { 179 | registry.register(Box::new(REQUESTS_TOTAL.clone()))?; 180 | registry.register(Box::new(REQUEST_DURATION_SECONDS.clone()))?; 181 | registry.register(Box::new(REQUESTS_CANCELED.clone()))?; 182 | registry.register(Box::new(BLOCK_NOT_FOUND.clone()))?; 183 | registry.register(Box::new(PROVIDERS_TOTAL.clone()))?; 184 | registry.register(Box::new(MISSING_BLOCKS_TOTAL.clone()))?; 185 | registry.register(Box::new(RECEIVED_BLOCK_BYTES.clone()))?; 186 | registry.register(Box::new(RECEIVED_INVALID_BLOCK_BYTES.clone()))?; 187 | registry.register(Box::new(SENT_BLOCK_BYTES.clone()))?; 188 | registry.register(Box::new(RESPONSES_TOTAL.clone()))?; 189 | registry.register(Box::new(THROTTLED_INBOUND.clone()))?; 190 | registry.register(Box::new(THROTTLED_OUTBOUND.clone()))?; 191 | registry.register(Box::new(OUTBOUND_FAILURE.clone()))?; 192 | registry.register(Box::new(INBOUND_FAILURE.clone()))?; 193 | Ok(()) 194 | } 195 | } 196 | 197 | enum DbRequest { 198 | Bitswap(BitswapChannel, BitswapRequest), 199 | Insert(Block

), 200 | MissingBlocks(QueryId, Cid), 201 | } 202 | 203 | enum DbResponse { 204 | Bitswap(BitswapChannel, BitswapResponse), 205 | MissingBlocks(QueryId, Result>), 206 | } 207 | 208 | fn start_db_thread( 209 | mut store: S, 210 | ) -> ( 211 | mpsc::UnboundedSender>, 212 | mpsc::UnboundedReceiver, 213 | ) { 214 | let (tx, requests) = mpsc::unbounded(); 215 | let (responses, rx) = mpsc::unbounded(); 216 | std::thread::spawn(move || { 217 | let mut requests: mpsc::UnboundedReceiver> = requests; 218 | while let Some(request) = futures::executor::block_on(requests.next()) { 219 | match request { 220 | DbRequest::Bitswap(channel, request) => { 221 | let response = match request.ty { 222 | RequestType::Have => { 223 | let have = store.contains(&request.cid).ok().unwrap_or_default(); 224 | if have { 225 | RESPONSES_TOTAL.with_label_values(&["have"]).inc(); 226 | } else { 227 | RESPONSES_TOTAL.with_label_values(&["dont_have"]).inc(); 228 | } 229 | tracing::trace!("have {}", have); 230 | BitswapResponse::Have(have) 231 | } 232 | RequestType::Block => { 233 | let block = store.get(&request.cid).ok().unwrap_or_default(); 234 | if let Some(data) = block { 235 | RESPONSES_TOTAL.with_label_values(&["block"]).inc(); 236 | SENT_BLOCK_BYTES.inc_by(data.len() as u64); 237 | tracing::trace!("block {}", data.len()); 238 | BitswapResponse::Block(data) 239 | } else { 240 | RESPONSES_TOTAL.with_label_values(&["dont_have"]).inc(); 241 | tracing::trace!("have false"); 242 | BitswapResponse::Have(false) 243 | } 244 | } 245 | }; 246 | responses 247 | .unbounded_send(DbResponse::Bitswap(channel, response)) 248 | .ok(); 249 | } 250 | DbRequest::Insert(block) => { 251 | if let Err(err) = store.insert(&block) { 252 | tracing::error!("error inserting blocks {}", err); 253 | } 254 | } 255 | DbRequest::MissingBlocks(id, cid) => { 256 | let res = store.missing_blocks(&cid); 257 | responses 258 | .unbounded_send(DbResponse::MissingBlocks(id, res)) 259 | .ok(); 260 | } 261 | } 262 | } 263 | }); 264 | (tx, rx) 265 | } 266 | 267 | impl Bitswap

{ 268 | /// Processes an incoming bitswap request. 269 | fn inject_request(&mut self, channel: BitswapChannel, request: BitswapRequest) { 270 | self.db_tx 271 | .unbounded_send(DbRequest::Bitswap(channel, request)) 272 | .ok(); 273 | } 274 | 275 | /// Processes an incoming bitswap response. 276 | fn inject_response(&mut self, id: BitswapId, peer: PeerId, response: BitswapResponse) { 277 | if let Some(id) = self.requests.remove(&id) { 278 | match response { 279 | BitswapResponse::Have(have) => { 280 | self.query_manager 281 | .inject_response(id, Response::Have(peer, have)); 282 | } 283 | BitswapResponse::Block(data) => { 284 | if let Some(info) = self.query_manager.query_info(id) { 285 | let len = data.len(); 286 | if let Ok(block) = Block::new(info.cid, data) { 287 | RECEIVED_BLOCK_BYTES.inc_by(len as u64); 288 | self.db_tx.unbounded_send(DbRequest::Insert(block)).ok(); 289 | self.query_manager 290 | .inject_response(id, Response::Block(peer, true)); 291 | } else { 292 | tracing::error!("received invalid block"); 293 | RECEIVED_INVALID_BLOCK_BYTES.inc_by(len as u64); 294 | self.query_manager 295 | .inject_response(id, Response::Block(peer, false)); 296 | } 297 | } 298 | } 299 | } 300 | } 301 | } 302 | 303 | fn inject_outbound_failure( 304 | &mut self, 305 | peer: &PeerId, 306 | request_id: RequestId, 307 | error: &OutboundFailure, 308 | ) { 309 | tracing::debug!( 310 | "bitswap outbound failure {} {} {:?}", 311 | peer, 312 | request_id, 313 | error 314 | ); 315 | match error { 316 | OutboundFailure::DialFailure => { 317 | OUTBOUND_FAILURE.with_label_values(&["dial_failure"]).inc(); 318 | } 319 | OutboundFailure::Timeout => { 320 | OUTBOUND_FAILURE.with_label_values(&["timeout"]).inc(); 321 | } 322 | OutboundFailure::ConnectionClosed => { 323 | OUTBOUND_FAILURE 324 | .with_label_values(&["connection_closed"]) 325 | .inc(); 326 | } 327 | OutboundFailure::UnsupportedProtocols => { 328 | OUTBOUND_FAILURE 329 | .with_label_values(&["unsupported_protocols"]) 330 | .inc(); 331 | } 332 | } 333 | } 334 | 335 | fn inject_inbound_failure( 336 | &mut self, 337 | peer: &PeerId, 338 | request_id: RequestId, 339 | error: &InboundFailure, 340 | ) { 341 | tracing::error!( 342 | "bitswap inbound failure {} {} {:?}", 343 | peer, 344 | request_id, 345 | error 346 | ); 347 | match error { 348 | InboundFailure::Timeout => { 349 | INBOUND_FAILURE.with_label_values(&["timeout"]).inc(); 350 | } 351 | InboundFailure::ConnectionClosed => { 352 | INBOUND_FAILURE 353 | .with_label_values(&["connection_closed"]) 354 | .inc(); 355 | } 356 | InboundFailure::UnsupportedProtocols => { 357 | INBOUND_FAILURE 358 | .with_label_values(&["unsupported_protocols"]) 359 | .inc(); 360 | } 361 | InboundFailure::ResponseOmission => { 362 | INBOUND_FAILURE 363 | .with_label_values(&["response_omission"]) 364 | .inc(); 365 | } 366 | } 367 | } 368 | } 369 | 370 | impl NetworkBehaviour for Bitswap

{ 371 | #[cfg(not(feature = "compat"))] 372 | type ConnectionHandler = 373 | > as NetworkBehaviour>::ConnectionHandler; 374 | 375 | #[cfg(feature = "compat")] 376 | #[allow(clippy::type_complexity)] 377 | type ConnectionHandler = ConnectionHandlerSelect< 378 | > as NetworkBehaviour>::ConnectionHandler, 379 | OneShotHandler, 380 | >; 381 | type OutEvent = BitswapEvent; 382 | 383 | fn new_handler(&mut self) -> Self::ConnectionHandler { 384 | #[cfg(not(feature = "compat"))] 385 | return self.inner.new_handler(); 386 | #[cfg(feature = "compat")] 387 | ConnectionHandler::select(self.inner.new_handler(), OneShotHandler::default()) 388 | } 389 | 390 | fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { 391 | self.inner.addresses_of_peer(peer_id) 392 | } 393 | 394 | fn on_swarm_event(&mut self, event: FromSwarm) { 395 | match event { 396 | FromSwarm::ConnectionEstablished(ev) => self 397 | .inner 398 | .on_swarm_event(FromSwarm::ConnectionEstablished(ev)), 399 | FromSwarm::ConnectionClosed(ConnectionClosed { 400 | peer_id, 401 | connection_id, 402 | endpoint, 403 | handler, 404 | remaining_established, 405 | }) => { 406 | #[cfg(feature = "compat")] 407 | if remaining_established == 0 { 408 | self.compat.remove(&peer_id); 409 | } 410 | #[cfg(feature = "compat")] 411 | let (handler, _oneshot) = handler.into_inner(); 412 | self.inner 413 | .on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { 414 | peer_id, 415 | connection_id, 416 | endpoint, 417 | handler, 418 | remaining_established, 419 | })); 420 | } 421 | FromSwarm::DialFailure(DialFailure { 422 | peer_id, 423 | handler, 424 | error, 425 | }) => { 426 | #[cfg(feature = "compat")] 427 | let (handler, _oneshot) = handler.into_inner(); 428 | self.inner 429 | .on_swarm_event(FromSwarm::DialFailure(DialFailure { 430 | peer_id, 431 | handler, 432 | error, 433 | })); 434 | } 435 | FromSwarm::AddressChange(ev) => self.inner.on_swarm_event(FromSwarm::AddressChange(ev)), 436 | FromSwarm::ListenFailure(ListenFailure { 437 | local_addr, 438 | send_back_addr, 439 | handler, 440 | }) => { 441 | #[cfg(feature = "compat")] 442 | let (handler, _oneshot) = handler.into_inner(); 443 | self.inner 444 | .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { 445 | local_addr, 446 | send_back_addr, 447 | handler, 448 | })); 449 | } 450 | FromSwarm::NewListener(ev) => self.inner.on_swarm_event(FromSwarm::NewListener(ev)), 451 | FromSwarm::NewListenAddr(ev) => self.inner.on_swarm_event(FromSwarm::NewListenAddr(ev)), 452 | FromSwarm::ExpiredListenAddr(ev) => { 453 | self.inner.on_swarm_event(FromSwarm::ExpiredListenAddr(ev)) 454 | } 455 | FromSwarm::ListenerError(ev) => self.inner.on_swarm_event(FromSwarm::ListenerError(ev)), 456 | FromSwarm::ListenerClosed(ev) => { 457 | self.inner.on_swarm_event(FromSwarm::ListenerClosed(ev)) 458 | } 459 | FromSwarm::NewExternalAddr(ev) => { 460 | self.inner.on_swarm_event(FromSwarm::NewExternalAddr(ev)) 461 | } 462 | FromSwarm::ExpiredExternalAddr(ev) => self 463 | .inner 464 | .on_swarm_event(FromSwarm::ExpiredExternalAddr(ev)), 465 | } 466 | } 467 | 468 | fn on_connection_handler_event( 469 | &mut self, 470 | peer_id: PeerId, 471 | conn: ConnectionId, 472 | event: ::OutEvent, 473 | ) { 474 | tracing::trace!(?event, "on_connection_handler_event"); 475 | #[cfg(not(feature = "compat"))] 476 | return self.inner.on_connection_handler_event(peer_id, conn, event); 477 | #[cfg(feature = "compat")] 478 | match event { 479 | EitherOutput::First(event) => { 480 | self.inner.on_connection_handler_event(peer_id, conn, event) 481 | } 482 | EitherOutput::Second(msg) => { 483 | for msg in msg.0 { 484 | match msg { 485 | CompatMessage::Request(req) => { 486 | tracing::trace!("received compat request"); 487 | self.inject_request(BitswapChannel::Compat(peer_id, req.cid), req); 488 | } 489 | CompatMessage::Response(cid, res) => { 490 | tracing::trace!("received compat response"); 491 | self.inject_response(BitswapId::Compat(cid), peer_id, res); 492 | } 493 | } 494 | } 495 | } 496 | } 497 | } 498 | 499 | fn poll( 500 | &mut self, 501 | cx: &mut Context, 502 | pp: &mut impl PollParameters, 503 | ) -> Poll> { 504 | let mut exit = false; 505 | while !exit { 506 | exit = true; 507 | while let Poll::Ready(Some(response)) = Pin::new(&mut self.db_rx).poll_next(cx) { 508 | exit = false; 509 | match response { 510 | DbResponse::Bitswap(channel, response) => match channel { 511 | BitswapChannel::Bitswap(channel) => { 512 | self.inner.send_response(channel, response).ok(); 513 | } 514 | #[cfg(feature = "compat")] 515 | BitswapChannel::Compat(peer_id, cid) => { 516 | let compat = CompatMessage::Response(cid, response); 517 | return Poll::Ready(NetworkBehaviourAction::NotifyHandler { 518 | peer_id, 519 | handler: NotifyHandler::Any, 520 | event: EitherOutput::Second(compat), 521 | }); 522 | } 523 | }, 524 | DbResponse::MissingBlocks(id, res) => match res { 525 | Ok(missing) => { 526 | MISSING_BLOCKS_TOTAL.inc_by(missing.len() as u64); 527 | self.query_manager 528 | .inject_response(id, Response::MissingBlocks(missing)); 529 | } 530 | Err(err) => { 531 | self.query_manager.cancel(id); 532 | let event = BitswapEvent::Complete(id, Err(err)); 533 | return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); 534 | } 535 | }, 536 | } 537 | } 538 | while let Some(query) = self.query_manager.next() { 539 | exit = false; 540 | match query { 541 | QueryEvent::Request(id, req) => match req { 542 | Request::Have(peer_id, cid) => { 543 | let req = BitswapRequest { 544 | ty: RequestType::Have, 545 | cid, 546 | }; 547 | let rid = self.inner.send_request(&peer_id, req); 548 | self.requests.insert(BitswapId::Bitswap(rid), id); 549 | } 550 | Request::Block(peer_id, cid) => { 551 | let req = BitswapRequest { 552 | ty: RequestType::Block, 553 | cid, 554 | }; 555 | let rid = self.inner.send_request(&peer_id, req); 556 | self.requests.insert(BitswapId::Bitswap(rid), id); 557 | } 558 | Request::MissingBlocks(cid) => { 559 | self.db_tx 560 | .unbounded_send(DbRequest::MissingBlocks(id, cid)) 561 | .ok(); 562 | } 563 | }, 564 | QueryEvent::Progress(id, missing) => { 565 | let event = BitswapEvent::Progress(id, missing); 566 | return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); 567 | } 568 | QueryEvent::Complete(id, res) => { 569 | if res.is_err() { 570 | BLOCK_NOT_FOUND.inc(); 571 | } 572 | let event = BitswapEvent::Complete( 573 | id, 574 | res.map_err(|cid| BlockNotFound(cid).into()), 575 | ); 576 | return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); 577 | } 578 | } 579 | } 580 | while let Poll::Ready(event) = self.inner.poll(cx, pp) { 581 | exit = false; 582 | let event = match event { 583 | NetworkBehaviourAction::GenerateEvent(event) => event, 584 | NetworkBehaviourAction::Dial { opts, handler } => { 585 | #[cfg(feature = "compat")] 586 | let handler = ConnectionHandler::select(handler, Default::default()); 587 | return Poll::Ready(NetworkBehaviourAction::Dial { opts, handler }); 588 | } 589 | NetworkBehaviourAction::NotifyHandler { 590 | peer_id, 591 | handler, 592 | event, 593 | } => { 594 | return Poll::Ready(NetworkBehaviourAction::NotifyHandler { 595 | peer_id, 596 | handler, 597 | #[cfg(not(feature = "compat"))] 598 | event, 599 | #[cfg(feature = "compat")] 600 | event: EitherOutput::First(event), 601 | }); 602 | } 603 | NetworkBehaviourAction::ReportObservedAddr { address, score } => { 604 | return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { 605 | address, 606 | score, 607 | }); 608 | } 609 | NetworkBehaviourAction::CloseConnection { 610 | peer_id, 611 | connection, 612 | } => { 613 | return Poll::Ready(NetworkBehaviourAction::CloseConnection { 614 | peer_id, 615 | connection, 616 | }); 617 | } 618 | }; 619 | match event { 620 | RequestResponseEvent::Message { peer, message } => match message { 621 | RequestResponseMessage::Request { 622 | request_id: _, 623 | request, 624 | channel, 625 | } => self.inject_request(BitswapChannel::Bitswap(channel), request), 626 | RequestResponseMessage::Response { 627 | request_id, 628 | response, 629 | } => self.inject_response(BitswapId::Bitswap(request_id), peer, response), 630 | }, 631 | RequestResponseEvent::ResponseSent { .. } => {} 632 | RequestResponseEvent::OutboundFailure { 633 | peer, 634 | request_id, 635 | error, 636 | } => { 637 | self.inject_outbound_failure(&peer, request_id, &error); 638 | #[cfg(feature = "compat")] 639 | if let OutboundFailure::UnsupportedProtocols = error { 640 | if let Some(id) = self.requests.remove(&BitswapId::Bitswap(request_id)) 641 | { 642 | if let Some(info) = self.query_manager.query_info(id) { 643 | let ty = match info.label { 644 | "have" => RequestType::Have, 645 | "block" => RequestType::Block, 646 | _ => unreachable!(), 647 | }; 648 | let request = BitswapRequest { ty, cid: info.cid }; 649 | self.requests.insert(BitswapId::Compat(info.cid), id); 650 | tracing::trace!("adding compat peer {}", peer); 651 | self.compat.insert(peer); 652 | return Poll::Ready(NetworkBehaviourAction::NotifyHandler { 653 | peer_id: peer, 654 | handler: NotifyHandler::Any, 655 | event: EitherOutput::Second(CompatMessage::Request( 656 | request, 657 | )), 658 | }); 659 | } 660 | } 661 | } 662 | if let Some(id) = self.requests.remove(&BitswapId::Bitswap(request_id)) { 663 | self.query_manager 664 | .inject_response(id, Response::Have(peer, false)); 665 | } 666 | } 667 | RequestResponseEvent::InboundFailure { 668 | peer, 669 | request_id, 670 | error, 671 | } => { 672 | self.inject_inbound_failure(&peer, request_id, &error); 673 | } 674 | } 675 | } 676 | } 677 | Poll::Pending 678 | } 679 | } 680 | 681 | #[cfg(test)] 682 | mod tests { 683 | use super::*; 684 | use async_std::task; 685 | use futures::prelude::*; 686 | use libipld::block::Block; 687 | use libipld::cbor::DagCborCodec; 688 | use libipld::ipld; 689 | use libipld::ipld::Ipld; 690 | use libipld::multihash::Code; 691 | use libipld::store::DefaultParams; 692 | use libp2p::core::muxing::StreamMuxerBox; 693 | use libp2p::core::transport::Boxed; 694 | use libp2p::identity; 695 | use libp2p::noise::{Keypair, NoiseConfig, X25519Spec}; 696 | use libp2p::swarm::SwarmEvent; 697 | use libp2p::tcp::{self, async_io}; 698 | use libp2p::yamux::YamuxConfig; 699 | use libp2p::{PeerId, Swarm, Transport}; 700 | use std::sync::{Arc, Mutex}; 701 | use std::time::Duration; 702 | use tracing_subscriber::fmt::TestWriter; 703 | 704 | fn tracing_try_init() { 705 | tracing_subscriber::fmt() 706 | .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) 707 | .with_writer(TestWriter::new()) 708 | .try_init() 709 | .ok(); 710 | } 711 | 712 | fn mk_transport() -> (PeerId, Boxed<(PeerId, StreamMuxerBox)>) { 713 | let id_key = identity::Keypair::generate_ed25519(); 714 | let peer_id = id_key.public().to_peer_id(); 715 | let dh_key = Keypair::::new() 716 | .into_authentic(&id_key) 717 | .unwrap(); 718 | let noise = NoiseConfig::xx(dh_key).into_authenticated(); 719 | 720 | let transport = async_io::Transport::new(tcp::Config::new().nodelay(true)) 721 | .upgrade(libp2p::core::upgrade::Version::V1) 722 | .authenticate(noise) 723 | .multiplex(YamuxConfig::default()) 724 | .timeout(Duration::from_secs(20)) 725 | .boxed(); 726 | (peer_id, transport) 727 | } 728 | 729 | fn create_block(ipld: Ipld) -> Block { 730 | Block::encode(DagCborCodec, Code::Blake3_256, &ipld).unwrap() 731 | } 732 | 733 | #[derive(Clone, Default)] 734 | struct Store(Arc>>>); 735 | 736 | impl BitswapStore for Store { 737 | type Params = DefaultParams; 738 | fn contains(&mut self, cid: &Cid) -> Result { 739 | Ok(self.0.lock().unwrap().contains_key(cid)) 740 | } 741 | fn get(&mut self, cid: &Cid) -> Result>> { 742 | Ok(self.0.lock().unwrap().get(cid).cloned()) 743 | } 744 | fn insert(&mut self, block: &Block) -> Result<()> { 745 | self.0 746 | .lock() 747 | .unwrap() 748 | .insert(*block.cid(), block.data().to_vec()); 749 | Ok(()) 750 | } 751 | fn missing_blocks(&mut self, cid: &Cid) -> Result> { 752 | let mut stack = vec![*cid]; 753 | let mut missing = vec![]; 754 | while let Some(cid) = stack.pop() { 755 | if let Some(data) = self.get(&cid)? { 756 | let block = Block::::new_unchecked(cid, data); 757 | block.references(&mut stack)?; 758 | } else { 759 | missing.push(cid); 760 | } 761 | } 762 | Ok(missing) 763 | } 764 | } 765 | 766 | struct Peer { 767 | peer_id: PeerId, 768 | addr: Multiaddr, 769 | store: Store, 770 | swarm: Swarm>, 771 | } 772 | 773 | impl Peer { 774 | fn new() -> Self { 775 | let (peer_id, trans) = mk_transport(); 776 | let store = Store::default(); 777 | let mut swarm = Swarm::with_async_std_executor( 778 | trans, 779 | Bitswap::new(BitswapConfig::new(), store.clone()), 780 | peer_id, 781 | ); 782 | Swarm::listen_on(&mut swarm, "/ip4/127.0.0.1/tcp/0".parse().unwrap()).unwrap(); 783 | while swarm.next().now_or_never().is_some() {} 784 | let addr = Swarm::listeners(&swarm).next().unwrap().clone(); 785 | Self { 786 | peer_id, 787 | addr, 788 | store, 789 | swarm, 790 | } 791 | } 792 | 793 | fn add_address(&mut self, peer: &Peer) { 794 | self.swarm 795 | .behaviour_mut() 796 | .add_address(&peer.peer_id, peer.addr.clone()); 797 | } 798 | 799 | fn store(&mut self) -> impl std::ops::DerefMut>> + '_ { 800 | self.store.0.lock().unwrap() 801 | } 802 | 803 | fn swarm(&mut self) -> &mut Swarm> { 804 | &mut self.swarm 805 | } 806 | 807 | fn spawn(mut self, name: &'static str) -> PeerId { 808 | let peer_id = self.peer_id; 809 | task::spawn(async move { 810 | loop { 811 | let event = self.swarm.next().await; 812 | tracing::debug!("{}: {:?}", name, event); 813 | } 814 | }); 815 | peer_id 816 | } 817 | 818 | async fn next(&mut self) -> Option { 819 | loop { 820 | let ev = self.swarm.next().await?; 821 | if let SwarmEvent::Behaviour(event) = ev { 822 | return Some(event); 823 | } 824 | } 825 | } 826 | } 827 | 828 | fn assert_progress(event: Option, id: QueryId, missing: usize) { 829 | if let Some(BitswapEvent::Progress(id2, missing2)) = event { 830 | assert_eq!(id2, id); 831 | assert_eq!(missing2, missing); 832 | } else { 833 | panic!("{:?} is not a progress event", event); 834 | } 835 | } 836 | 837 | fn assert_complete_ok(event: Option, id: QueryId) { 838 | if let Some(BitswapEvent::Complete(id2, Ok(()))) = event { 839 | assert_eq!(id2, id); 840 | } else { 841 | panic!("{:?} is not a complete event", event); 842 | } 843 | } 844 | 845 | #[async_std::test] 846 | async fn test_bitswap_get() { 847 | tracing_try_init(); 848 | let mut peer1 = Peer::new(); 849 | let mut peer2 = Peer::new(); 850 | peer2.add_address(&peer1); 851 | 852 | let block = create_block(ipld!(&b"hello world"[..])); 853 | peer1.store().insert(*block.cid(), block.data().to_vec()); 854 | let peer1 = peer1.spawn("peer1"); 855 | 856 | let id = peer2 857 | .swarm() 858 | .behaviour_mut() 859 | .get(*block.cid(), std::iter::once(peer1)); 860 | 861 | assert_complete_ok(peer2.next().await, id); 862 | } 863 | 864 | #[async_std::test] 865 | async fn test_bitswap_cancel_get() { 866 | tracing_try_init(); 867 | let mut peer1 = Peer::new(); 868 | let mut peer2 = Peer::new(); 869 | peer2.add_address(&peer1); 870 | 871 | let block = create_block(ipld!(&b"hello world"[..])); 872 | peer1.store().insert(*block.cid(), block.data().to_vec()); 873 | let peer1 = peer1.spawn("peer1"); 874 | 875 | let id = peer2 876 | .swarm() 877 | .behaviour_mut() 878 | .get(*block.cid(), std::iter::once(peer1)); 879 | peer2.swarm().behaviour_mut().cancel(id); 880 | let res = peer2.next().now_or_never(); 881 | println!("{:?}", res); 882 | assert!(res.is_none()); 883 | } 884 | 885 | #[async_std::test] 886 | async fn test_bitswap_sync() { 887 | tracing_try_init(); 888 | let mut peer1 = Peer::new(); 889 | let mut peer2 = Peer::new(); 890 | peer2.add_address(&peer1); 891 | 892 | let b0 = create_block(ipld!({ 893 | "n": 0, 894 | })); 895 | let b1 = create_block(ipld!({ 896 | "prev": b0.cid(), 897 | "n": 1, 898 | })); 899 | let b2 = create_block(ipld!({ 900 | "prev": b1.cid(), 901 | "n": 2, 902 | })); 903 | peer1.store().insert(*b0.cid(), b0.data().to_vec()); 904 | peer1.store().insert(*b1.cid(), b1.data().to_vec()); 905 | peer1.store().insert(*b2.cid(), b2.data().to_vec()); 906 | let peer1 = peer1.spawn("peer1"); 907 | 908 | let id = 909 | peer2 910 | .swarm() 911 | .behaviour_mut() 912 | .sync(*b2.cid(), vec![peer1], std::iter::once(*b2.cid())); 913 | 914 | assert_progress(peer2.next().await, id, 1); 915 | assert_progress(peer2.next().await, id, 1); 916 | 917 | assert_complete_ok(peer2.next().await, id); 918 | } 919 | 920 | #[async_std::test] 921 | async fn test_bitswap_cancel_sync() { 922 | tracing_try_init(); 923 | let mut peer1 = Peer::new(); 924 | let mut peer2 = Peer::new(); 925 | peer2.add_address(&peer1); 926 | 927 | let block = create_block(ipld!(&b"hello world"[..])); 928 | peer1.store().insert(*block.cid(), block.data().to_vec()); 929 | let peer1 = peer1.spawn("peer1"); 930 | 931 | let id = peer2.swarm().behaviour_mut().sync( 932 | *block.cid(), 933 | vec![peer1], 934 | std::iter::once(*block.cid()), 935 | ); 936 | peer2.swarm().behaviour_mut().cancel(id); 937 | let res = peer2.next().now_or_never(); 938 | println!("{:?}", res); 939 | assert!(res.is_none()); 940 | } 941 | 942 | #[cfg(feature = "compat")] 943 | #[async_std::test] 944 | async fn compat_test() { 945 | tracing_try_init(); 946 | let cid: Cid = "QmP8njGuyiw9cjkhwHD9nZhyBTHufXFanAvZgcy9xYoWiB" 947 | .parse() 948 | .unwrap(); 949 | let peer_id: PeerId = "12D3KooWC1EaEEpghwnPdd89LaPTKEweD1PRLz4aRBkJEA9UiUuS" 950 | .parse() 951 | .unwrap(); 952 | let multiaddr: Multiaddr = "/ip4/95.217.194.97/tcp/8008".parse().unwrap(); 953 | 954 | let mut peer = Peer::new(); 955 | peer.swarm() 956 | .behaviour_mut() 957 | .add_address(&peer_id, multiaddr); 958 | let id = peer 959 | .swarm() 960 | .behaviour_mut() 961 | .get(cid, std::iter::once(peer_id)); 962 | assert_complete_ok(peer.next().await, id); 963 | } 964 | } 965 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aead" 7 | version = "0.4.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" 10 | dependencies = [ 11 | "generic-array", 12 | ] 13 | 14 | [[package]] 15 | name = "aes" 16 | version = "0.7.5" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" 19 | dependencies = [ 20 | "cfg-if", 21 | "cipher", 22 | "cpufeatures", 23 | "opaque-debug", 24 | ] 25 | 26 | [[package]] 27 | name = "aes-gcm" 28 | version = "0.9.4" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" 31 | dependencies = [ 32 | "aead", 33 | "aes", 34 | "cipher", 35 | "ctr", 36 | "ghash", 37 | "subtle", 38 | ] 39 | 40 | [[package]] 41 | name = "aho-corasick" 42 | version = "0.7.20" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" 45 | dependencies = [ 46 | "memchr", 47 | ] 48 | 49 | [[package]] 50 | name = "anyhow" 51 | version = "1.0.66" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" 54 | 55 | [[package]] 56 | name = "arrayref" 57 | version = "0.3.6" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 60 | 61 | [[package]] 62 | name = "arrayvec" 63 | version = "0.7.2" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 66 | 67 | [[package]] 68 | name = "asn1-rs" 69 | version = "0.5.1" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "cf6690c370453db30743b373a60ba498fc0d6d83b11f4abfd87a84a075db5dd4" 72 | dependencies = [ 73 | "asn1-rs-derive", 74 | "asn1-rs-impl", 75 | "displaydoc", 76 | "nom", 77 | "num-traits", 78 | "rusticata-macros", 79 | "thiserror", 80 | "time", 81 | ] 82 | 83 | [[package]] 84 | name = "asn1-rs-derive" 85 | version = "0.4.0" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" 88 | dependencies = [ 89 | "proc-macro2", 90 | "quote", 91 | "syn", 92 | "synstructure", 93 | ] 94 | 95 | [[package]] 96 | name = "asn1-rs-impl" 97 | version = "0.1.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" 100 | dependencies = [ 101 | "proc-macro2", 102 | "quote", 103 | "syn", 104 | ] 105 | 106 | [[package]] 107 | name = "asn1_der" 108 | version = "0.7.5" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "e22d1f4b888c298a027c99dc9048015fac177587de20fc30232a057dfbe24a21" 111 | 112 | [[package]] 113 | name = "async-attributes" 114 | version = "1.1.2" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" 117 | dependencies = [ 118 | "quote", 119 | "syn", 120 | ] 121 | 122 | [[package]] 123 | name = "async-channel" 124 | version = "1.8.0" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" 127 | dependencies = [ 128 | "concurrent-queue", 129 | "event-listener", 130 | "futures-core", 131 | ] 132 | 133 | [[package]] 134 | name = "async-executor" 135 | version = "1.5.0" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" 138 | dependencies = [ 139 | "async-lock", 140 | "async-task", 141 | "concurrent-queue", 142 | "fastrand", 143 | "futures-lite", 144 | "slab", 145 | ] 146 | 147 | [[package]] 148 | name = "async-fs" 149 | version = "1.6.0" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" 152 | dependencies = [ 153 | "async-lock", 154 | "autocfg", 155 | "blocking", 156 | "futures-lite", 157 | ] 158 | 159 | [[package]] 160 | name = "async-global-executor" 161 | version = "2.3.1" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" 164 | dependencies = [ 165 | "async-channel", 166 | "async-executor", 167 | "async-io", 168 | "async-lock", 169 | "blocking", 170 | "futures-lite", 171 | "once_cell", 172 | ] 173 | 174 | [[package]] 175 | name = "async-io" 176 | version = "1.12.0" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" 179 | dependencies = [ 180 | "async-lock", 181 | "autocfg", 182 | "concurrent-queue", 183 | "futures-lite", 184 | "libc", 185 | "log", 186 | "parking", 187 | "polling", 188 | "slab", 189 | "socket2", 190 | "waker-fn", 191 | "windows-sys", 192 | ] 193 | 194 | [[package]] 195 | name = "async-lock" 196 | version = "2.6.0" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" 199 | dependencies = [ 200 | "event-listener", 201 | "futures-lite", 202 | ] 203 | 204 | [[package]] 205 | name = "async-net" 206 | version = "1.7.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" 209 | dependencies = [ 210 | "async-io", 211 | "autocfg", 212 | "blocking", 213 | "futures-lite", 214 | ] 215 | 216 | [[package]] 217 | name = "async-process" 218 | version = "1.6.0" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "6381ead98388605d0d9ff86371043b5aa922a3905824244de40dc263a14fcba4" 221 | dependencies = [ 222 | "async-io", 223 | "async-lock", 224 | "autocfg", 225 | "blocking", 226 | "cfg-if", 227 | "event-listener", 228 | "futures-lite", 229 | "libc", 230 | "signal-hook", 231 | "windows-sys", 232 | ] 233 | 234 | [[package]] 235 | name = "async-std" 236 | version = "1.12.0" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" 239 | dependencies = [ 240 | "async-attributes", 241 | "async-channel", 242 | "async-global-executor", 243 | "async-io", 244 | "async-lock", 245 | "async-process", 246 | "crossbeam-utils", 247 | "futures-channel", 248 | "futures-core", 249 | "futures-io", 250 | "futures-lite", 251 | "gloo-timers", 252 | "kv-log-macro", 253 | "log", 254 | "memchr", 255 | "once_cell", 256 | "pin-project-lite", 257 | "pin-utils", 258 | "slab", 259 | "wasm-bindgen-futures", 260 | ] 261 | 262 | [[package]] 263 | name = "async-std-resolver" 264 | version = "0.22.0" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "6ba50e24d9ee0a8950d3d03fc6d0dd10aa14b5de3b101949b4e160f7fee7c723" 267 | dependencies = [ 268 | "async-std", 269 | "async-trait", 270 | "futures-io", 271 | "futures-util", 272 | "pin-utils", 273 | "socket2", 274 | "trust-dns-resolver", 275 | ] 276 | 277 | [[package]] 278 | name = "async-task" 279 | version = "4.3.0" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" 282 | 283 | [[package]] 284 | name = "async-trait" 285 | version = "0.1.59" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" 288 | dependencies = [ 289 | "proc-macro2", 290 | "quote", 291 | "syn", 292 | ] 293 | 294 | [[package]] 295 | name = "atomic-waker" 296 | version = "1.0.0" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" 299 | 300 | [[package]] 301 | name = "atty" 302 | version = "0.2.14" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 305 | dependencies = [ 306 | "hermit-abi", 307 | "libc", 308 | "winapi", 309 | ] 310 | 311 | [[package]] 312 | name = "autocfg" 313 | version = "1.1.0" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 316 | 317 | [[package]] 318 | name = "base-x" 319 | version = "0.2.11" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" 322 | 323 | [[package]] 324 | name = "base16ct" 325 | version = "0.1.1" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" 328 | 329 | [[package]] 330 | name = "base64" 331 | version = "0.13.1" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 334 | 335 | [[package]] 336 | name = "base64ct" 337 | version = "1.5.3" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" 340 | 341 | [[package]] 342 | name = "bitflags" 343 | version = "1.3.2" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 346 | 347 | [[package]] 348 | name = "blake2" 349 | version = "0.10.5" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "b12e5fd123190ce1c2e559308a94c9bacad77907d4c6005d9e58fe1a0689e55e" 352 | dependencies = [ 353 | "digest 0.10.6", 354 | ] 355 | 356 | [[package]] 357 | name = "blake3" 358 | version = "1.3.3" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" 361 | dependencies = [ 362 | "arrayref", 363 | "arrayvec", 364 | "cc", 365 | "cfg-if", 366 | "constant_time_eq", 367 | ] 368 | 369 | [[package]] 370 | name = "block-buffer" 371 | version = "0.9.0" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 374 | dependencies = [ 375 | "generic-array", 376 | ] 377 | 378 | [[package]] 379 | name = "block-buffer" 380 | version = "0.10.3" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" 383 | dependencies = [ 384 | "generic-array", 385 | ] 386 | 387 | [[package]] 388 | name = "blocking" 389 | version = "1.3.0" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8" 392 | dependencies = [ 393 | "async-channel", 394 | "async-lock", 395 | "async-task", 396 | "atomic-waker", 397 | "fastrand", 398 | "futures-lite", 399 | ] 400 | 401 | [[package]] 402 | name = "bs58" 403 | version = "0.4.0" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 406 | 407 | [[package]] 408 | name = "bumpalo" 409 | version = "3.11.1" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" 412 | 413 | [[package]] 414 | name = "byteorder" 415 | version = "1.4.3" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 418 | 419 | [[package]] 420 | name = "bytes" 421 | version = "1.3.0" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" 424 | 425 | [[package]] 426 | name = "cc" 427 | version = "1.0.78" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" 430 | 431 | [[package]] 432 | name = "cfg-if" 433 | version = "1.0.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 436 | 437 | [[package]] 438 | name = "chacha20" 439 | version = "0.8.2" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" 442 | dependencies = [ 443 | "cfg-if", 444 | "cipher", 445 | "cpufeatures", 446 | "zeroize", 447 | ] 448 | 449 | [[package]] 450 | name = "chacha20poly1305" 451 | version = "0.9.1" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" 454 | dependencies = [ 455 | "aead", 456 | "chacha20", 457 | "cipher", 458 | "poly1305", 459 | "zeroize", 460 | ] 461 | 462 | [[package]] 463 | name = "cid" 464 | version = "0.9.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "b9b68e3193982cd54187d71afdb2a271ad4cf8af157858e9cb911b91321de143" 467 | dependencies = [ 468 | "core2", 469 | "multibase", 470 | "multihash 0.17.0", 471 | "serde", 472 | "unsigned-varint", 473 | ] 474 | 475 | [[package]] 476 | name = "cipher" 477 | version = "0.3.0" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" 480 | dependencies = [ 481 | "generic-array", 482 | ] 483 | 484 | [[package]] 485 | name = "concurrent-queue" 486 | version = "2.0.0" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" 489 | dependencies = [ 490 | "crossbeam-utils", 491 | ] 492 | 493 | [[package]] 494 | name = "const-oid" 495 | version = "0.9.1" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" 498 | 499 | [[package]] 500 | name = "constant_time_eq" 501 | version = "0.2.4" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" 504 | 505 | [[package]] 506 | name = "core-foundation" 507 | version = "0.9.3" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 510 | dependencies = [ 511 | "core-foundation-sys", 512 | "libc", 513 | ] 514 | 515 | [[package]] 516 | name = "core-foundation-sys" 517 | version = "0.8.3" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 520 | 521 | [[package]] 522 | name = "core2" 523 | version = "0.4.0" 524 | source = "registry+https://github.com/rust-lang/crates.io-index" 525 | checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" 526 | dependencies = [ 527 | "memchr", 528 | ] 529 | 530 | [[package]] 531 | name = "cpufeatures" 532 | version = "0.2.5" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 535 | dependencies = [ 536 | "libc", 537 | ] 538 | 539 | [[package]] 540 | name = "crossbeam-utils" 541 | version = "0.8.14" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" 544 | dependencies = [ 545 | "cfg-if", 546 | ] 547 | 548 | [[package]] 549 | name = "crypto-common" 550 | version = "0.1.6" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 553 | dependencies = [ 554 | "generic-array", 555 | "typenum", 556 | ] 557 | 558 | [[package]] 559 | name = "ctor" 560 | version = "0.1.26" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" 563 | dependencies = [ 564 | "quote", 565 | "syn", 566 | ] 567 | 568 | [[package]] 569 | name = "ctr" 570 | version = "0.8.0" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" 573 | dependencies = [ 574 | "cipher", 575 | ] 576 | 577 | [[package]] 578 | name = "curve25519-dalek" 579 | version = "3.2.0" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" 582 | dependencies = [ 583 | "byteorder", 584 | "digest 0.9.0", 585 | "rand_core 0.5.1", 586 | "subtle", 587 | "zeroize", 588 | ] 589 | 590 | [[package]] 591 | name = "curve25519-dalek" 592 | version = "4.0.0-pre.5" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "67bc65846be335cb20f4e52d49a437b773a2c1fdb42b19fc84e79e6f6771536f" 595 | dependencies = [ 596 | "cfg-if", 597 | "fiat-crypto", 598 | "packed_simd_2", 599 | "platforms", 600 | "subtle", 601 | "zeroize", 602 | ] 603 | 604 | [[package]] 605 | name = "data-encoding" 606 | version = "2.3.3" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" 609 | 610 | [[package]] 611 | name = "data-encoding-macro" 612 | version = "0.1.12" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" 615 | dependencies = [ 616 | "data-encoding", 617 | "data-encoding-macro-internal", 618 | ] 619 | 620 | [[package]] 621 | name = "data-encoding-macro-internal" 622 | version = "0.1.10" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" 625 | dependencies = [ 626 | "data-encoding", 627 | "syn", 628 | ] 629 | 630 | [[package]] 631 | name = "der" 632 | version = "0.6.1" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" 635 | dependencies = [ 636 | "const-oid", 637 | "zeroize", 638 | ] 639 | 640 | [[package]] 641 | name = "der-parser" 642 | version = "8.1.0" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "42d4bc9b0db0a0df9ae64634ac5bdefb7afcb534e182275ca0beadbe486701c1" 645 | dependencies = [ 646 | "asn1-rs", 647 | "displaydoc", 648 | "nom", 649 | "num-bigint", 650 | "num-traits", 651 | "rusticata-macros", 652 | ] 653 | 654 | [[package]] 655 | name = "digest" 656 | version = "0.9.0" 657 | source = "registry+https://github.com/rust-lang/crates.io-index" 658 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 659 | dependencies = [ 660 | "generic-array", 661 | ] 662 | 663 | [[package]] 664 | name = "digest" 665 | version = "0.10.6" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 668 | dependencies = [ 669 | "block-buffer 0.10.3", 670 | "crypto-common", 671 | "subtle", 672 | ] 673 | 674 | [[package]] 675 | name = "displaydoc" 676 | version = "0.2.3" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" 679 | dependencies = [ 680 | "proc-macro2", 681 | "quote", 682 | "syn", 683 | ] 684 | 685 | [[package]] 686 | name = "ed25519" 687 | version = "1.5.2" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" 690 | dependencies = [ 691 | "signature", 692 | ] 693 | 694 | [[package]] 695 | name = "ed25519-dalek" 696 | version = "1.0.1" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" 699 | dependencies = [ 700 | "curve25519-dalek 3.2.0", 701 | "ed25519", 702 | "rand 0.7.3", 703 | "serde", 704 | "sha2 0.9.9", 705 | "zeroize", 706 | ] 707 | 708 | [[package]] 709 | name = "either" 710 | version = "1.8.0" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" 713 | 714 | [[package]] 715 | name = "enum-as-inner" 716 | version = "0.5.1" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" 719 | dependencies = [ 720 | "heck", 721 | "proc-macro2", 722 | "quote", 723 | "syn", 724 | ] 725 | 726 | [[package]] 727 | name = "env_logger" 728 | version = "0.9.3" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" 731 | dependencies = [ 732 | "atty", 733 | "humantime", 734 | "log", 735 | "regex", 736 | "termcolor", 737 | ] 738 | 739 | [[package]] 740 | name = "event-listener" 741 | version = "2.5.3" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 744 | 745 | [[package]] 746 | name = "fastrand" 747 | version = "1.8.0" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" 750 | dependencies = [ 751 | "instant", 752 | ] 753 | 754 | [[package]] 755 | name = "fiat-crypto" 756 | version = "0.1.17" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" 759 | 760 | [[package]] 761 | name = "fixedbitset" 762 | version = "0.4.2" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 765 | 766 | [[package]] 767 | name = "fnv" 768 | version = "1.0.7" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 771 | 772 | [[package]] 773 | name = "form_urlencoded" 774 | version = "1.1.0" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 777 | dependencies = [ 778 | "percent-encoding", 779 | ] 780 | 781 | [[package]] 782 | name = "futures" 783 | version = "0.3.25" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" 786 | dependencies = [ 787 | "futures-channel", 788 | "futures-core", 789 | "futures-executor", 790 | "futures-io", 791 | "futures-sink", 792 | "futures-task", 793 | "futures-util", 794 | ] 795 | 796 | [[package]] 797 | name = "futures-channel" 798 | version = "0.3.25" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" 801 | dependencies = [ 802 | "futures-core", 803 | "futures-sink", 804 | ] 805 | 806 | [[package]] 807 | name = "futures-core" 808 | version = "0.3.25" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" 811 | 812 | [[package]] 813 | name = "futures-executor" 814 | version = "0.3.25" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" 817 | dependencies = [ 818 | "futures-core", 819 | "futures-task", 820 | "futures-util", 821 | "num_cpus", 822 | ] 823 | 824 | [[package]] 825 | name = "futures-io" 826 | version = "0.3.25" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" 829 | 830 | [[package]] 831 | name = "futures-lite" 832 | version = "1.12.0" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" 835 | dependencies = [ 836 | "fastrand", 837 | "futures-core", 838 | "futures-io", 839 | "memchr", 840 | "parking", 841 | "pin-project-lite", 842 | "waker-fn", 843 | ] 844 | 845 | [[package]] 846 | name = "futures-macro" 847 | version = "0.3.25" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" 850 | dependencies = [ 851 | "proc-macro2", 852 | "quote", 853 | "syn", 854 | ] 855 | 856 | [[package]] 857 | name = "futures-rustls" 858 | version = "0.22.2" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" 861 | dependencies = [ 862 | "futures-io", 863 | "rustls", 864 | "webpki", 865 | ] 866 | 867 | [[package]] 868 | name = "futures-sink" 869 | version = "0.3.25" 870 | source = "registry+https://github.com/rust-lang/crates.io-index" 871 | checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" 872 | 873 | [[package]] 874 | name = "futures-task" 875 | version = "0.3.25" 876 | source = "registry+https://github.com/rust-lang/crates.io-index" 877 | checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" 878 | 879 | [[package]] 880 | name = "futures-timer" 881 | version = "3.0.2" 882 | source = "registry+https://github.com/rust-lang/crates.io-index" 883 | checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" 884 | 885 | [[package]] 886 | name = "futures-util" 887 | version = "0.3.25" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" 890 | dependencies = [ 891 | "futures-channel", 892 | "futures-core", 893 | "futures-io", 894 | "futures-macro", 895 | "futures-sink", 896 | "futures-task", 897 | "memchr", 898 | "pin-project-lite", 899 | "pin-utils", 900 | "slab", 901 | ] 902 | 903 | [[package]] 904 | name = "generic-array" 905 | version = "0.14.6" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 908 | dependencies = [ 909 | "typenum", 910 | "version_check", 911 | ] 912 | 913 | [[package]] 914 | name = "getrandom" 915 | version = "0.1.16" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 918 | dependencies = [ 919 | "cfg-if", 920 | "libc", 921 | "wasi 0.9.0+wasi-snapshot-preview1", 922 | ] 923 | 924 | [[package]] 925 | name = "getrandom" 926 | version = "0.2.8" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" 929 | dependencies = [ 930 | "cfg-if", 931 | "libc", 932 | "wasi 0.11.0+wasi-snapshot-preview1", 933 | ] 934 | 935 | [[package]] 936 | name = "ghash" 937 | version = "0.4.4" 938 | source = "registry+https://github.com/rust-lang/crates.io-index" 939 | checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" 940 | dependencies = [ 941 | "opaque-debug", 942 | "polyval", 943 | ] 944 | 945 | [[package]] 946 | name = "gloo-timers" 947 | version = "0.2.5" 948 | source = "registry+https://github.com/rust-lang/crates.io-index" 949 | checksum = "98c4a8d6391675c6b2ee1a6c8d06e8e2d03605c44cec1270675985a4c2a5500b" 950 | dependencies = [ 951 | "futures-channel", 952 | "futures-core", 953 | "js-sys", 954 | "wasm-bindgen", 955 | ] 956 | 957 | [[package]] 958 | name = "hashbrown" 959 | version = "0.12.3" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 962 | 963 | [[package]] 964 | name = "heck" 965 | version = "0.4.0" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 968 | 969 | [[package]] 970 | name = "hermit-abi" 971 | version = "0.1.19" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 974 | dependencies = [ 975 | "libc", 976 | ] 977 | 978 | [[package]] 979 | name = "hostname" 980 | version = "0.3.1" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" 983 | dependencies = [ 984 | "libc", 985 | "match_cfg", 986 | "winapi", 987 | ] 988 | 989 | [[package]] 990 | name = "humantime" 991 | version = "2.1.0" 992 | source = "registry+https://github.com/rust-lang/crates.io-index" 993 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 994 | 995 | [[package]] 996 | name = "idna" 997 | version = "0.2.3" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" 1000 | dependencies = [ 1001 | "matches", 1002 | "unicode-bidi", 1003 | "unicode-normalization", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "idna" 1008 | version = "0.3.0" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 1011 | dependencies = [ 1012 | "unicode-bidi", 1013 | "unicode-normalization", 1014 | ] 1015 | 1016 | [[package]] 1017 | name = "if-addrs" 1018 | version = "0.7.0" 1019 | source = "registry+https://github.com/rust-lang/crates.io-index" 1020 | checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" 1021 | dependencies = [ 1022 | "libc", 1023 | "winapi", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "if-watch" 1028 | version = "3.0.0" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "ba7abdbb86e485125dad06c2691e1e393bf3b08c7b743b43aa162a00fd39062e" 1031 | dependencies = [ 1032 | "async-io", 1033 | "core-foundation", 1034 | "fnv", 1035 | "futures", 1036 | "if-addrs", 1037 | "ipnet", 1038 | "log", 1039 | "rtnetlink", 1040 | "smol", 1041 | "system-configuration", 1042 | "windows", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "indexmap" 1047 | version = "1.9.2" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" 1050 | dependencies = [ 1051 | "autocfg", 1052 | "hashbrown", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "instant" 1057 | version = "0.1.12" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 1060 | dependencies = [ 1061 | "cfg-if", 1062 | ] 1063 | 1064 | [[package]] 1065 | name = "ipconfig" 1066 | version = "0.3.1" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" 1069 | dependencies = [ 1070 | "socket2", 1071 | "widestring", 1072 | "winapi", 1073 | "winreg", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "ipnet" 1078 | version = "2.7.0" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" 1081 | 1082 | [[package]] 1083 | name = "itertools" 1084 | version = "0.10.5" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 1087 | dependencies = [ 1088 | "either", 1089 | ] 1090 | 1091 | [[package]] 1092 | name = "itoa" 1093 | version = "1.0.4" 1094 | source = "registry+https://github.com/rust-lang/crates.io-index" 1095 | checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" 1096 | 1097 | [[package]] 1098 | name = "js-sys" 1099 | version = "0.3.60" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" 1102 | dependencies = [ 1103 | "wasm-bindgen", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "kv-log-macro" 1108 | version = "1.0.7" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" 1111 | dependencies = [ 1112 | "log", 1113 | ] 1114 | 1115 | [[package]] 1116 | name = "lazy_static" 1117 | version = "1.4.0" 1118 | source = "registry+https://github.com/rust-lang/crates.io-index" 1119 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1120 | 1121 | [[package]] 1122 | name = "libc" 1123 | version = "0.2.138" 1124 | source = "registry+https://github.com/rust-lang/crates.io-index" 1125 | checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" 1126 | 1127 | [[package]] 1128 | name = "libipld" 1129 | version = "0.15.0" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "a20e38e0ad9a2fd600476691fa0780421931a198279985e398a3a0851903e1b2" 1132 | dependencies = [ 1133 | "fnv", 1134 | "libipld-cbor", 1135 | "libipld-core", 1136 | "libipld-macro", 1137 | "log", 1138 | "multihash 0.17.0", 1139 | "thiserror", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "libipld-cbor" 1144 | version = "0.15.0" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "4b75370e27e0745910a9991c83f365cdae58027acf0502aa7987ac538a8a4744" 1147 | dependencies = [ 1148 | "byteorder", 1149 | "libipld-core", 1150 | "thiserror", 1151 | ] 1152 | 1153 | [[package]] 1154 | name = "libipld-core" 1155 | version = "0.15.0" 1156 | source = "registry+https://github.com/rust-lang/crates.io-index" 1157 | checksum = "b7a704ba3b25dee9e7a2361fae2c7c19defae2a92e69ae96ffb203996705cd7c" 1158 | dependencies = [ 1159 | "anyhow", 1160 | "cid", 1161 | "core2", 1162 | "multibase", 1163 | "multihash 0.17.0", 1164 | "thiserror", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "libipld-macro" 1169 | version = "0.15.0" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "d4c7ccd89e54f2796cf3f99aabeea7a7751d418df504926544f28348d3c890c7" 1172 | dependencies = [ 1173 | "libipld-core", 1174 | ] 1175 | 1176 | [[package]] 1177 | name = "libm" 1178 | version = "0.1.4" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" 1181 | 1182 | [[package]] 1183 | name = "libp2p" 1184 | version = "0.50.0" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "2e0a0d2f693675f49ded13c5d510c48b78069e23cbd9108d7ccd59f6dc568819" 1187 | dependencies = [ 1188 | "bytes", 1189 | "futures", 1190 | "futures-timer", 1191 | "getrandom 0.2.8", 1192 | "instant", 1193 | "libp2p-core", 1194 | "libp2p-dns", 1195 | "libp2p-mdns", 1196 | "libp2p-noise", 1197 | "libp2p-quic", 1198 | "libp2p-request-response", 1199 | "libp2p-swarm", 1200 | "libp2p-tcp", 1201 | "libp2p-yamux", 1202 | "multiaddr", 1203 | "parking_lot", 1204 | "pin-project", 1205 | "smallvec", 1206 | ] 1207 | 1208 | [[package]] 1209 | name = "libp2p-bitswap" 1210 | version = "0.25.0" 1211 | dependencies = [ 1212 | "async-std", 1213 | "async-trait", 1214 | "env_logger", 1215 | "fnv", 1216 | "futures", 1217 | "lazy_static", 1218 | "libipld", 1219 | "libp2p", 1220 | "multihash 0.17.0", 1221 | "prometheus", 1222 | "prost", 1223 | "prost-build", 1224 | "thiserror", 1225 | "tracing", 1226 | "tracing-subscriber", 1227 | "unsigned-varint", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "libp2p-core" 1232 | version = "0.38.0" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "b6a8fcd392ff67af6cc3f03b1426c41f7f26b6b9aff2dc632c1c56dd649e571f" 1235 | dependencies = [ 1236 | "asn1_der", 1237 | "bs58", 1238 | "ed25519-dalek", 1239 | "either", 1240 | "fnv", 1241 | "futures", 1242 | "futures-timer", 1243 | "instant", 1244 | "log", 1245 | "multiaddr", 1246 | "multihash 0.16.3", 1247 | "multistream-select", 1248 | "once_cell", 1249 | "parking_lot", 1250 | "pin-project", 1251 | "prost", 1252 | "prost-build", 1253 | "rand 0.8.5", 1254 | "ring", 1255 | "rw-stream-sink", 1256 | "sec1", 1257 | "sha2 0.10.6", 1258 | "smallvec", 1259 | "thiserror", 1260 | "unsigned-varint", 1261 | "void", 1262 | "zeroize", 1263 | ] 1264 | 1265 | [[package]] 1266 | name = "libp2p-dns" 1267 | version = "0.38.0" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | checksum = "8e42a271c1b49f789b92f7fc87749fa79ce5c7bdc88cbdfacb818a4bca47fec5" 1270 | dependencies = [ 1271 | "async-std-resolver", 1272 | "futures", 1273 | "libp2p-core", 1274 | "log", 1275 | "parking_lot", 1276 | "smallvec", 1277 | "trust-dns-resolver", 1278 | ] 1279 | 1280 | [[package]] 1281 | name = "libp2p-mdns" 1282 | version = "0.42.0" 1283 | source = "registry+https://github.com/rust-lang/crates.io-index" 1284 | checksum = "04f378264aade9872d6ccd315c0accc18be3a35d15fc1b9c36e5b6f983b62b5b" 1285 | dependencies = [ 1286 | "async-io", 1287 | "data-encoding", 1288 | "futures", 1289 | "if-watch", 1290 | "libp2p-core", 1291 | "libp2p-swarm", 1292 | "log", 1293 | "rand 0.8.5", 1294 | "smallvec", 1295 | "socket2", 1296 | "trust-dns-proto", 1297 | "void", 1298 | ] 1299 | 1300 | [[package]] 1301 | name = "libp2p-noise" 1302 | version = "0.41.0" 1303 | source = "registry+https://github.com/rust-lang/crates.io-index" 1304 | checksum = "a978cb57efe82e892ec6f348a536bfbd9fee677adbe5689d7a93ad3a9bffbf2e" 1305 | dependencies = [ 1306 | "bytes", 1307 | "curve25519-dalek 3.2.0", 1308 | "futures", 1309 | "libp2p-core", 1310 | "log", 1311 | "once_cell", 1312 | "prost", 1313 | "prost-build", 1314 | "rand 0.8.5", 1315 | "sha2 0.10.6", 1316 | "snow", 1317 | "static_assertions", 1318 | "thiserror", 1319 | "x25519-dalek", 1320 | "zeroize", 1321 | ] 1322 | 1323 | [[package]] 1324 | name = "libp2p-quic" 1325 | version = "0.7.0-alpha" 1326 | source = "registry+https://github.com/rust-lang/crates.io-index" 1327 | checksum = "01e7c867e95c8130667b24409d236d37598270e6da69b3baf54213ba31ffca59" 1328 | dependencies = [ 1329 | "async-std", 1330 | "bytes", 1331 | "futures", 1332 | "futures-timer", 1333 | "if-watch", 1334 | "libp2p-core", 1335 | "libp2p-tls", 1336 | "log", 1337 | "parking_lot", 1338 | "quinn-proto", 1339 | "rand 0.8.5", 1340 | "rustls", 1341 | "thiserror", 1342 | ] 1343 | 1344 | [[package]] 1345 | name = "libp2p-request-response" 1346 | version = "0.23.0" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "3236168796727bfcf4927f766393415361e2c644b08bedb6a6b13d957c9a4884" 1349 | dependencies = [ 1350 | "async-trait", 1351 | "bytes", 1352 | "futures", 1353 | "instant", 1354 | "libp2p-core", 1355 | "libp2p-swarm", 1356 | "log", 1357 | "rand 0.8.5", 1358 | "smallvec", 1359 | "unsigned-varint", 1360 | ] 1361 | 1362 | [[package]] 1363 | name = "libp2p-swarm" 1364 | version = "0.41.1" 1365 | source = "registry+https://github.com/rust-lang/crates.io-index" 1366 | checksum = "b2a35472fe3276b3855c00f1c032ea8413615e030256429ad5349cdf67c6e1a0" 1367 | dependencies = [ 1368 | "async-std", 1369 | "either", 1370 | "fnv", 1371 | "futures", 1372 | "futures-timer", 1373 | "instant", 1374 | "libp2p-core", 1375 | "log", 1376 | "pin-project", 1377 | "rand 0.8.5", 1378 | "smallvec", 1379 | "thiserror", 1380 | "void", 1381 | ] 1382 | 1383 | [[package]] 1384 | name = "libp2p-tcp" 1385 | version = "0.38.0" 1386 | source = "registry+https://github.com/rust-lang/crates.io-index" 1387 | checksum = "b4b257baf6df8f2df39678b86c578961d48cc8b68642a12f0f763f56c8e5858d" 1388 | dependencies = [ 1389 | "async-io", 1390 | "futures", 1391 | "futures-timer", 1392 | "if-watch", 1393 | "libc", 1394 | "libp2p-core", 1395 | "log", 1396 | "socket2", 1397 | ] 1398 | 1399 | [[package]] 1400 | name = "libp2p-tls" 1401 | version = "0.1.0-alpha" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "f7905ce0d040576634e8a3229a7587cc8beab83f79db6023800f1792895defa8" 1404 | dependencies = [ 1405 | "futures", 1406 | "futures-rustls", 1407 | "libp2p-core", 1408 | "rcgen", 1409 | "ring", 1410 | "rustls", 1411 | "thiserror", 1412 | "webpki", 1413 | "x509-parser", 1414 | "yasna", 1415 | ] 1416 | 1417 | [[package]] 1418 | name = "libp2p-yamux" 1419 | version = "0.42.0" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "4f63594a0aa818642d9d4915c791945053877253f08a3626f13416b5cd928a29" 1422 | dependencies = [ 1423 | "futures", 1424 | "libp2p-core", 1425 | "log", 1426 | "parking_lot", 1427 | "thiserror", 1428 | "yamux", 1429 | ] 1430 | 1431 | [[package]] 1432 | name = "linked-hash-map" 1433 | version = "0.5.6" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 1436 | 1437 | [[package]] 1438 | name = "lock_api" 1439 | version = "0.4.9" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 1442 | dependencies = [ 1443 | "autocfg", 1444 | "scopeguard", 1445 | ] 1446 | 1447 | [[package]] 1448 | name = "log" 1449 | version = "0.4.17" 1450 | source = "registry+https://github.com/rust-lang/crates.io-index" 1451 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 1452 | dependencies = [ 1453 | "cfg-if", 1454 | "value-bag", 1455 | ] 1456 | 1457 | [[package]] 1458 | name = "lru-cache" 1459 | version = "0.1.2" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" 1462 | dependencies = [ 1463 | "linked-hash-map", 1464 | ] 1465 | 1466 | [[package]] 1467 | name = "match_cfg" 1468 | version = "0.1.0" 1469 | source = "registry+https://github.com/rust-lang/crates.io-index" 1470 | checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" 1471 | 1472 | [[package]] 1473 | name = "matchers" 1474 | version = "0.1.0" 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" 1476 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 1477 | dependencies = [ 1478 | "regex-automata", 1479 | ] 1480 | 1481 | [[package]] 1482 | name = "matches" 1483 | version = "0.1.9" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" 1486 | 1487 | [[package]] 1488 | name = "memchr" 1489 | version = "2.5.0" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 1492 | 1493 | [[package]] 1494 | name = "minimal-lexical" 1495 | version = "0.2.1" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1498 | 1499 | [[package]] 1500 | name = "mio" 1501 | version = "0.8.5" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" 1504 | dependencies = [ 1505 | "libc", 1506 | "log", 1507 | "wasi 0.11.0+wasi-snapshot-preview1", 1508 | "windows-sys", 1509 | ] 1510 | 1511 | [[package]] 1512 | name = "multiaddr" 1513 | version = "0.16.0" 1514 | source = "registry+https://github.com/rust-lang/crates.io-index" 1515 | checksum = "a4aebdb21e90f81d13ed01dc84123320838e53963c2ca94b60b305d3fa64f31e" 1516 | dependencies = [ 1517 | "arrayref", 1518 | "byteorder", 1519 | "data-encoding", 1520 | "multibase", 1521 | "multihash 0.16.3", 1522 | "percent-encoding", 1523 | "serde", 1524 | "static_assertions", 1525 | "unsigned-varint", 1526 | "url", 1527 | ] 1528 | 1529 | [[package]] 1530 | name = "multibase" 1531 | version = "0.9.1" 1532 | source = "registry+https://github.com/rust-lang/crates.io-index" 1533 | checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" 1534 | dependencies = [ 1535 | "base-x", 1536 | "data-encoding", 1537 | "data-encoding-macro", 1538 | ] 1539 | 1540 | [[package]] 1541 | name = "multihash" 1542 | version = "0.16.3" 1543 | source = "registry+https://github.com/rust-lang/crates.io-index" 1544 | checksum = "1c346cf9999c631f002d8f977c4eaeaa0e6386f16007202308d0b3757522c2cc" 1545 | dependencies = [ 1546 | "core2", 1547 | "digest 0.10.6", 1548 | "multihash-derive", 1549 | "sha2 0.10.6", 1550 | "unsigned-varint", 1551 | ] 1552 | 1553 | [[package]] 1554 | name = "multihash" 1555 | version = "0.17.0" 1556 | source = "registry+https://github.com/rust-lang/crates.io-index" 1557 | checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" 1558 | dependencies = [ 1559 | "blake3", 1560 | "core2", 1561 | "digest 0.10.6", 1562 | "multihash-derive", 1563 | "sha2 0.10.6", 1564 | "unsigned-varint", 1565 | ] 1566 | 1567 | [[package]] 1568 | name = "multihash-derive" 1569 | version = "0.8.1" 1570 | source = "registry+https://github.com/rust-lang/crates.io-index" 1571 | checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" 1572 | dependencies = [ 1573 | "proc-macro-crate", 1574 | "proc-macro-error", 1575 | "proc-macro2", 1576 | "quote", 1577 | "syn", 1578 | "synstructure", 1579 | ] 1580 | 1581 | [[package]] 1582 | name = "multimap" 1583 | version = "0.8.3" 1584 | source = "registry+https://github.com/rust-lang/crates.io-index" 1585 | checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" 1586 | 1587 | [[package]] 1588 | name = "multistream-select" 1589 | version = "0.12.1" 1590 | source = "registry+https://github.com/rust-lang/crates.io-index" 1591 | checksum = "c8552ab875c1313b97b8d20cb857b9fd63e2d1d6a0a1b53ce9821e575405f27a" 1592 | dependencies = [ 1593 | "bytes", 1594 | "futures", 1595 | "log", 1596 | "pin-project", 1597 | "smallvec", 1598 | "unsigned-varint", 1599 | ] 1600 | 1601 | [[package]] 1602 | name = "netlink-packet-core" 1603 | version = "0.4.2" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" 1606 | dependencies = [ 1607 | "anyhow", 1608 | "byteorder", 1609 | "libc", 1610 | "netlink-packet-utils", 1611 | ] 1612 | 1613 | [[package]] 1614 | name = "netlink-packet-route" 1615 | version = "0.12.0" 1616 | source = "registry+https://github.com/rust-lang/crates.io-index" 1617 | checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" 1618 | dependencies = [ 1619 | "anyhow", 1620 | "bitflags", 1621 | "byteorder", 1622 | "libc", 1623 | "netlink-packet-core", 1624 | "netlink-packet-utils", 1625 | ] 1626 | 1627 | [[package]] 1628 | name = "netlink-packet-utils" 1629 | version = "0.5.1" 1630 | source = "registry+https://github.com/rust-lang/crates.io-index" 1631 | checksum = "25af9cf0dc55498b7bd94a1508af7a78706aa0ab715a73c5169273e03c84845e" 1632 | dependencies = [ 1633 | "anyhow", 1634 | "byteorder", 1635 | "paste", 1636 | "thiserror", 1637 | ] 1638 | 1639 | [[package]] 1640 | name = "netlink-proto" 1641 | version = "0.10.0" 1642 | source = "registry+https://github.com/rust-lang/crates.io-index" 1643 | checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" 1644 | dependencies = [ 1645 | "bytes", 1646 | "futures", 1647 | "log", 1648 | "netlink-packet-core", 1649 | "netlink-sys", 1650 | "thiserror", 1651 | "tokio", 1652 | ] 1653 | 1654 | [[package]] 1655 | name = "netlink-sys" 1656 | version = "0.8.3" 1657 | source = "registry+https://github.com/rust-lang/crates.io-index" 1658 | checksum = "92b654097027250401127914afb37cb1f311df6610a9891ff07a757e94199027" 1659 | dependencies = [ 1660 | "async-io", 1661 | "bytes", 1662 | "futures", 1663 | "libc", 1664 | "log", 1665 | ] 1666 | 1667 | [[package]] 1668 | name = "nix" 1669 | version = "0.24.3" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" 1672 | dependencies = [ 1673 | "bitflags", 1674 | "cfg-if", 1675 | "libc", 1676 | ] 1677 | 1678 | [[package]] 1679 | name = "nohash-hasher" 1680 | version = "0.2.0" 1681 | source = "registry+https://github.com/rust-lang/crates.io-index" 1682 | checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" 1683 | 1684 | [[package]] 1685 | name = "nom" 1686 | version = "7.1.1" 1687 | source = "registry+https://github.com/rust-lang/crates.io-index" 1688 | checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" 1689 | dependencies = [ 1690 | "memchr", 1691 | "minimal-lexical", 1692 | ] 1693 | 1694 | [[package]] 1695 | name = "nu-ansi-term" 1696 | version = "0.46.0" 1697 | source = "registry+https://github.com/rust-lang/crates.io-index" 1698 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1699 | dependencies = [ 1700 | "overload", 1701 | "winapi", 1702 | ] 1703 | 1704 | [[package]] 1705 | name = "num-bigint" 1706 | version = "0.4.3" 1707 | source = "registry+https://github.com/rust-lang/crates.io-index" 1708 | checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" 1709 | dependencies = [ 1710 | "autocfg", 1711 | "num-integer", 1712 | "num-traits", 1713 | ] 1714 | 1715 | [[package]] 1716 | name = "num-integer" 1717 | version = "0.1.45" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 1720 | dependencies = [ 1721 | "autocfg", 1722 | "num-traits", 1723 | ] 1724 | 1725 | [[package]] 1726 | name = "num-traits" 1727 | version = "0.2.15" 1728 | source = "registry+https://github.com/rust-lang/crates.io-index" 1729 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 1730 | dependencies = [ 1731 | "autocfg", 1732 | ] 1733 | 1734 | [[package]] 1735 | name = "num_cpus" 1736 | version = "1.14.0" 1737 | source = "registry+https://github.com/rust-lang/crates.io-index" 1738 | checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" 1739 | dependencies = [ 1740 | "hermit-abi", 1741 | "libc", 1742 | ] 1743 | 1744 | [[package]] 1745 | name = "oid-registry" 1746 | version = "0.6.1" 1747 | source = "registry+https://github.com/rust-lang/crates.io-index" 1748 | checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" 1749 | dependencies = [ 1750 | "asn1-rs", 1751 | ] 1752 | 1753 | [[package]] 1754 | name = "once_cell" 1755 | version = "1.16.0" 1756 | source = "registry+https://github.com/rust-lang/crates.io-index" 1757 | checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" 1758 | 1759 | [[package]] 1760 | name = "opaque-debug" 1761 | version = "0.3.0" 1762 | source = "registry+https://github.com/rust-lang/crates.io-index" 1763 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 1764 | 1765 | [[package]] 1766 | name = "overload" 1767 | version = "0.1.1" 1768 | source = "registry+https://github.com/rust-lang/crates.io-index" 1769 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1770 | 1771 | [[package]] 1772 | name = "packed_simd_2" 1773 | version = "0.3.8" 1774 | source = "registry+https://github.com/rust-lang/crates.io-index" 1775 | checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" 1776 | dependencies = [ 1777 | "cfg-if", 1778 | "libm", 1779 | ] 1780 | 1781 | [[package]] 1782 | name = "parking" 1783 | version = "2.0.0" 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" 1785 | checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" 1786 | 1787 | [[package]] 1788 | name = "parking_lot" 1789 | version = "0.12.1" 1790 | source = "registry+https://github.com/rust-lang/crates.io-index" 1791 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1792 | dependencies = [ 1793 | "lock_api", 1794 | "parking_lot_core", 1795 | ] 1796 | 1797 | [[package]] 1798 | name = "parking_lot_core" 1799 | version = "0.9.5" 1800 | source = "registry+https://github.com/rust-lang/crates.io-index" 1801 | checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" 1802 | dependencies = [ 1803 | "cfg-if", 1804 | "libc", 1805 | "redox_syscall", 1806 | "smallvec", 1807 | "windows-sys", 1808 | ] 1809 | 1810 | [[package]] 1811 | name = "paste" 1812 | version = "1.0.10" 1813 | source = "registry+https://github.com/rust-lang/crates.io-index" 1814 | checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b" 1815 | 1816 | [[package]] 1817 | name = "pem" 1818 | version = "1.1.0" 1819 | source = "registry+https://github.com/rust-lang/crates.io-index" 1820 | checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4" 1821 | dependencies = [ 1822 | "base64", 1823 | ] 1824 | 1825 | [[package]] 1826 | name = "percent-encoding" 1827 | version = "2.2.0" 1828 | source = "registry+https://github.com/rust-lang/crates.io-index" 1829 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 1830 | 1831 | [[package]] 1832 | name = "petgraph" 1833 | version = "0.6.2" 1834 | source = "registry+https://github.com/rust-lang/crates.io-index" 1835 | checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" 1836 | dependencies = [ 1837 | "fixedbitset", 1838 | "indexmap", 1839 | ] 1840 | 1841 | [[package]] 1842 | name = "pin-project" 1843 | version = "1.0.12" 1844 | source = "registry+https://github.com/rust-lang/crates.io-index" 1845 | checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" 1846 | dependencies = [ 1847 | "pin-project-internal", 1848 | ] 1849 | 1850 | [[package]] 1851 | name = "pin-project-internal" 1852 | version = "1.0.12" 1853 | source = "registry+https://github.com/rust-lang/crates.io-index" 1854 | checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" 1855 | dependencies = [ 1856 | "proc-macro2", 1857 | "quote", 1858 | "syn", 1859 | ] 1860 | 1861 | [[package]] 1862 | name = "pin-project-lite" 1863 | version = "0.2.9" 1864 | source = "registry+https://github.com/rust-lang/crates.io-index" 1865 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 1866 | 1867 | [[package]] 1868 | name = "pin-utils" 1869 | version = "0.1.0" 1870 | source = "registry+https://github.com/rust-lang/crates.io-index" 1871 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1872 | 1873 | [[package]] 1874 | name = "pkcs8" 1875 | version = "0.9.0" 1876 | source = "registry+https://github.com/rust-lang/crates.io-index" 1877 | checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" 1878 | dependencies = [ 1879 | "der", 1880 | "spki", 1881 | ] 1882 | 1883 | [[package]] 1884 | name = "platforms" 1885 | version = "3.0.2" 1886 | source = "registry+https://github.com/rust-lang/crates.io-index" 1887 | checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" 1888 | 1889 | [[package]] 1890 | name = "polling" 1891 | version = "2.5.2" 1892 | source = "registry+https://github.com/rust-lang/crates.io-index" 1893 | checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" 1894 | dependencies = [ 1895 | "autocfg", 1896 | "cfg-if", 1897 | "libc", 1898 | "log", 1899 | "wepoll-ffi", 1900 | "windows-sys", 1901 | ] 1902 | 1903 | [[package]] 1904 | name = "poly1305" 1905 | version = "0.7.2" 1906 | source = "registry+https://github.com/rust-lang/crates.io-index" 1907 | checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" 1908 | dependencies = [ 1909 | "cpufeatures", 1910 | "opaque-debug", 1911 | "universal-hash", 1912 | ] 1913 | 1914 | [[package]] 1915 | name = "polyval" 1916 | version = "0.5.3" 1917 | source = "registry+https://github.com/rust-lang/crates.io-index" 1918 | checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" 1919 | dependencies = [ 1920 | "cfg-if", 1921 | "cpufeatures", 1922 | "opaque-debug", 1923 | "universal-hash", 1924 | ] 1925 | 1926 | [[package]] 1927 | name = "ppv-lite86" 1928 | version = "0.2.17" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1931 | 1932 | [[package]] 1933 | name = "prettyplease" 1934 | version = "0.1.21" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "c142c0e46b57171fe0c528bee8c5b7569e80f0c17e377cd0e30ea57dbc11bb51" 1937 | dependencies = [ 1938 | "proc-macro2", 1939 | "syn", 1940 | ] 1941 | 1942 | [[package]] 1943 | name = "proc-macro-crate" 1944 | version = "1.1.3" 1945 | source = "registry+https://github.com/rust-lang/crates.io-index" 1946 | checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" 1947 | dependencies = [ 1948 | "thiserror", 1949 | "toml", 1950 | ] 1951 | 1952 | [[package]] 1953 | name = "proc-macro-error" 1954 | version = "1.0.4" 1955 | source = "registry+https://github.com/rust-lang/crates.io-index" 1956 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1957 | dependencies = [ 1958 | "proc-macro-error-attr", 1959 | "proc-macro2", 1960 | "quote", 1961 | "syn", 1962 | "version_check", 1963 | ] 1964 | 1965 | [[package]] 1966 | name = "proc-macro-error-attr" 1967 | version = "1.0.4" 1968 | source = "registry+https://github.com/rust-lang/crates.io-index" 1969 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1970 | dependencies = [ 1971 | "proc-macro2", 1972 | "quote", 1973 | "version_check", 1974 | ] 1975 | 1976 | [[package]] 1977 | name = "proc-macro2" 1978 | version = "1.0.47" 1979 | source = "registry+https://github.com/rust-lang/crates.io-index" 1980 | checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" 1981 | dependencies = [ 1982 | "unicode-ident", 1983 | ] 1984 | 1985 | [[package]] 1986 | name = "prometheus" 1987 | version = "0.13.3" 1988 | source = "registry+https://github.com/rust-lang/crates.io-index" 1989 | checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" 1990 | dependencies = [ 1991 | "cfg-if", 1992 | "fnv", 1993 | "lazy_static", 1994 | "memchr", 1995 | "parking_lot", 1996 | "protobuf", 1997 | "thiserror", 1998 | ] 1999 | 2000 | [[package]] 2001 | name = "prost" 2002 | version = "0.11.3" 2003 | source = "registry+https://github.com/rust-lang/crates.io-index" 2004 | checksum = "c0b18e655c21ff5ac2084a5ad0611e827b3f92badf79f4910b5a5c58f4d87ff0" 2005 | dependencies = [ 2006 | "bytes", 2007 | "prost-derive", 2008 | ] 2009 | 2010 | [[package]] 2011 | name = "prost-build" 2012 | version = "0.11.4" 2013 | source = "registry+https://github.com/rust-lang/crates.io-index" 2014 | checksum = "276470f7f281b0ed53d2ae42dd52b4a8d08853a3c70e7fe95882acbb98a6ae94" 2015 | dependencies = [ 2016 | "bytes", 2017 | "heck", 2018 | "itertools", 2019 | "lazy_static", 2020 | "log", 2021 | "multimap", 2022 | "petgraph", 2023 | "prettyplease", 2024 | "prost", 2025 | "prost-types", 2026 | "regex", 2027 | "syn", 2028 | "tempfile", 2029 | "which", 2030 | ] 2031 | 2032 | [[package]] 2033 | name = "prost-derive" 2034 | version = "0.11.2" 2035 | source = "registry+https://github.com/rust-lang/crates.io-index" 2036 | checksum = "164ae68b6587001ca506d3bf7f1000bfa248d0e1217b618108fba4ec1d0cc306" 2037 | dependencies = [ 2038 | "anyhow", 2039 | "itertools", 2040 | "proc-macro2", 2041 | "quote", 2042 | "syn", 2043 | ] 2044 | 2045 | [[package]] 2046 | name = "prost-types" 2047 | version = "0.11.2" 2048 | source = "registry+https://github.com/rust-lang/crates.io-index" 2049 | checksum = "747761bc3dc48f9a34553bf65605cf6cb6288ba219f3450b4275dbd81539551a" 2050 | dependencies = [ 2051 | "bytes", 2052 | "prost", 2053 | ] 2054 | 2055 | [[package]] 2056 | name = "protobuf" 2057 | version = "2.28.0" 2058 | source = "registry+https://github.com/rust-lang/crates.io-index" 2059 | checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" 2060 | 2061 | [[package]] 2062 | name = "quick-error" 2063 | version = "1.2.3" 2064 | source = "registry+https://github.com/rust-lang/crates.io-index" 2065 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 2066 | 2067 | [[package]] 2068 | name = "quinn-proto" 2069 | version = "0.9.2" 2070 | source = "registry+https://github.com/rust-lang/crates.io-index" 2071 | checksum = "72ef4ced82a24bb281af338b9e8f94429b6eca01b4e66d899f40031f074e74c9" 2072 | dependencies = [ 2073 | "bytes", 2074 | "rand 0.8.5", 2075 | "ring", 2076 | "rustc-hash", 2077 | "rustls", 2078 | "slab", 2079 | "thiserror", 2080 | "tinyvec", 2081 | "tracing", 2082 | "webpki", 2083 | ] 2084 | 2085 | [[package]] 2086 | name = "quote" 2087 | version = "1.0.21" 2088 | source = "registry+https://github.com/rust-lang/crates.io-index" 2089 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 2090 | dependencies = [ 2091 | "proc-macro2", 2092 | ] 2093 | 2094 | [[package]] 2095 | name = "rand" 2096 | version = "0.7.3" 2097 | source = "registry+https://github.com/rust-lang/crates.io-index" 2098 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 2099 | dependencies = [ 2100 | "getrandom 0.1.16", 2101 | "libc", 2102 | "rand_chacha 0.2.2", 2103 | "rand_core 0.5.1", 2104 | "rand_hc", 2105 | ] 2106 | 2107 | [[package]] 2108 | name = "rand" 2109 | version = "0.8.5" 2110 | source = "registry+https://github.com/rust-lang/crates.io-index" 2111 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 2112 | dependencies = [ 2113 | "libc", 2114 | "rand_chacha 0.3.1", 2115 | "rand_core 0.6.4", 2116 | ] 2117 | 2118 | [[package]] 2119 | name = "rand_chacha" 2120 | version = "0.2.2" 2121 | source = "registry+https://github.com/rust-lang/crates.io-index" 2122 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 2123 | dependencies = [ 2124 | "ppv-lite86", 2125 | "rand_core 0.5.1", 2126 | ] 2127 | 2128 | [[package]] 2129 | name = "rand_chacha" 2130 | version = "0.3.1" 2131 | source = "registry+https://github.com/rust-lang/crates.io-index" 2132 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 2133 | dependencies = [ 2134 | "ppv-lite86", 2135 | "rand_core 0.6.4", 2136 | ] 2137 | 2138 | [[package]] 2139 | name = "rand_core" 2140 | version = "0.5.1" 2141 | source = "registry+https://github.com/rust-lang/crates.io-index" 2142 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 2143 | dependencies = [ 2144 | "getrandom 0.1.16", 2145 | ] 2146 | 2147 | [[package]] 2148 | name = "rand_core" 2149 | version = "0.6.4" 2150 | source = "registry+https://github.com/rust-lang/crates.io-index" 2151 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 2152 | dependencies = [ 2153 | "getrandom 0.2.8", 2154 | ] 2155 | 2156 | [[package]] 2157 | name = "rand_hc" 2158 | version = "0.2.0" 2159 | source = "registry+https://github.com/rust-lang/crates.io-index" 2160 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 2161 | dependencies = [ 2162 | "rand_core 0.5.1", 2163 | ] 2164 | 2165 | [[package]] 2166 | name = "rcgen" 2167 | version = "0.10.0" 2168 | source = "registry+https://github.com/rust-lang/crates.io-index" 2169 | checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" 2170 | dependencies = [ 2171 | "pem", 2172 | "ring", 2173 | "time", 2174 | "yasna", 2175 | ] 2176 | 2177 | [[package]] 2178 | name = "redox_syscall" 2179 | version = "0.2.16" 2180 | source = "registry+https://github.com/rust-lang/crates.io-index" 2181 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 2182 | dependencies = [ 2183 | "bitflags", 2184 | ] 2185 | 2186 | [[package]] 2187 | name = "regex" 2188 | version = "1.7.0" 2189 | source = "registry+https://github.com/rust-lang/crates.io-index" 2190 | checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" 2191 | dependencies = [ 2192 | "aho-corasick", 2193 | "memchr", 2194 | "regex-syntax", 2195 | ] 2196 | 2197 | [[package]] 2198 | name = "regex-automata" 2199 | version = "0.1.10" 2200 | source = "registry+https://github.com/rust-lang/crates.io-index" 2201 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 2202 | dependencies = [ 2203 | "regex-syntax", 2204 | ] 2205 | 2206 | [[package]] 2207 | name = "regex-syntax" 2208 | version = "0.6.28" 2209 | source = "registry+https://github.com/rust-lang/crates.io-index" 2210 | checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" 2211 | 2212 | [[package]] 2213 | name = "remove_dir_all" 2214 | version = "0.5.3" 2215 | source = "registry+https://github.com/rust-lang/crates.io-index" 2216 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 2217 | dependencies = [ 2218 | "winapi", 2219 | ] 2220 | 2221 | [[package]] 2222 | name = "resolv-conf" 2223 | version = "0.7.0" 2224 | source = "registry+https://github.com/rust-lang/crates.io-index" 2225 | checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" 2226 | dependencies = [ 2227 | "hostname", 2228 | "quick-error", 2229 | ] 2230 | 2231 | [[package]] 2232 | name = "ring" 2233 | version = "0.16.20" 2234 | source = "registry+https://github.com/rust-lang/crates.io-index" 2235 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 2236 | dependencies = [ 2237 | "cc", 2238 | "libc", 2239 | "once_cell", 2240 | "spin", 2241 | "untrusted", 2242 | "web-sys", 2243 | "winapi", 2244 | ] 2245 | 2246 | [[package]] 2247 | name = "rtnetlink" 2248 | version = "0.10.1" 2249 | source = "registry+https://github.com/rust-lang/crates.io-index" 2250 | checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" 2251 | dependencies = [ 2252 | "async-global-executor", 2253 | "futures", 2254 | "log", 2255 | "netlink-packet-route", 2256 | "netlink-proto", 2257 | "nix", 2258 | "thiserror", 2259 | ] 2260 | 2261 | [[package]] 2262 | name = "rustc-hash" 2263 | version = "1.1.0" 2264 | source = "registry+https://github.com/rust-lang/crates.io-index" 2265 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 2266 | 2267 | [[package]] 2268 | name = "rustc_version" 2269 | version = "0.4.0" 2270 | source = "registry+https://github.com/rust-lang/crates.io-index" 2271 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 2272 | dependencies = [ 2273 | "semver", 2274 | ] 2275 | 2276 | [[package]] 2277 | name = "rusticata-macros" 2278 | version = "4.1.0" 2279 | source = "registry+https://github.com/rust-lang/crates.io-index" 2280 | checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" 2281 | dependencies = [ 2282 | "nom", 2283 | ] 2284 | 2285 | [[package]] 2286 | name = "rustls" 2287 | version = "0.20.7" 2288 | source = "registry+https://github.com/rust-lang/crates.io-index" 2289 | checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" 2290 | dependencies = [ 2291 | "log", 2292 | "ring", 2293 | "sct", 2294 | "webpki", 2295 | ] 2296 | 2297 | [[package]] 2298 | name = "rw-stream-sink" 2299 | version = "0.3.0" 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" 2301 | checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" 2302 | dependencies = [ 2303 | "futures", 2304 | "pin-project", 2305 | "static_assertions", 2306 | ] 2307 | 2308 | [[package]] 2309 | name = "scopeguard" 2310 | version = "1.1.0" 2311 | source = "registry+https://github.com/rust-lang/crates.io-index" 2312 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 2313 | 2314 | [[package]] 2315 | name = "sct" 2316 | version = "0.7.0" 2317 | source = "registry+https://github.com/rust-lang/crates.io-index" 2318 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 2319 | dependencies = [ 2320 | "ring", 2321 | "untrusted", 2322 | ] 2323 | 2324 | [[package]] 2325 | name = "sec1" 2326 | version = "0.3.0" 2327 | source = "registry+https://github.com/rust-lang/crates.io-index" 2328 | checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" 2329 | dependencies = [ 2330 | "base16ct", 2331 | "der", 2332 | "generic-array", 2333 | "pkcs8", 2334 | "zeroize", 2335 | ] 2336 | 2337 | [[package]] 2338 | name = "semver" 2339 | version = "1.0.14" 2340 | source = "registry+https://github.com/rust-lang/crates.io-index" 2341 | checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" 2342 | 2343 | [[package]] 2344 | name = "serde" 2345 | version = "1.0.150" 2346 | source = "registry+https://github.com/rust-lang/crates.io-index" 2347 | checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" 2348 | 2349 | [[package]] 2350 | name = "sha2" 2351 | version = "0.9.9" 2352 | source = "registry+https://github.com/rust-lang/crates.io-index" 2353 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 2354 | dependencies = [ 2355 | "block-buffer 0.9.0", 2356 | "cfg-if", 2357 | "cpufeatures", 2358 | "digest 0.9.0", 2359 | "opaque-debug", 2360 | ] 2361 | 2362 | [[package]] 2363 | name = "sha2" 2364 | version = "0.10.6" 2365 | source = "registry+https://github.com/rust-lang/crates.io-index" 2366 | checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" 2367 | dependencies = [ 2368 | "cfg-if", 2369 | "cpufeatures", 2370 | "digest 0.10.6", 2371 | ] 2372 | 2373 | [[package]] 2374 | name = "sharded-slab" 2375 | version = "0.1.4" 2376 | source = "registry+https://github.com/rust-lang/crates.io-index" 2377 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 2378 | dependencies = [ 2379 | "lazy_static", 2380 | ] 2381 | 2382 | [[package]] 2383 | name = "signal-hook" 2384 | version = "0.3.14" 2385 | source = "registry+https://github.com/rust-lang/crates.io-index" 2386 | checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" 2387 | dependencies = [ 2388 | "libc", 2389 | "signal-hook-registry", 2390 | ] 2391 | 2392 | [[package]] 2393 | name = "signal-hook-registry" 2394 | version = "1.4.0" 2395 | source = "registry+https://github.com/rust-lang/crates.io-index" 2396 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 2397 | dependencies = [ 2398 | "libc", 2399 | ] 2400 | 2401 | [[package]] 2402 | name = "signature" 2403 | version = "1.6.4" 2404 | source = "registry+https://github.com/rust-lang/crates.io-index" 2405 | checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" 2406 | 2407 | [[package]] 2408 | name = "slab" 2409 | version = "0.4.7" 2410 | source = "registry+https://github.com/rust-lang/crates.io-index" 2411 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 2412 | dependencies = [ 2413 | "autocfg", 2414 | ] 2415 | 2416 | [[package]] 2417 | name = "smallvec" 2418 | version = "1.10.0" 2419 | source = "registry+https://github.com/rust-lang/crates.io-index" 2420 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 2421 | 2422 | [[package]] 2423 | name = "smol" 2424 | version = "1.3.0" 2425 | source = "registry+https://github.com/rust-lang/crates.io-index" 2426 | checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" 2427 | dependencies = [ 2428 | "async-channel", 2429 | "async-executor", 2430 | "async-fs", 2431 | "async-io", 2432 | "async-lock", 2433 | "async-net", 2434 | "async-process", 2435 | "blocking", 2436 | "futures-lite", 2437 | ] 2438 | 2439 | [[package]] 2440 | name = "snow" 2441 | version = "0.9.0" 2442 | source = "registry+https://github.com/rust-lang/crates.io-index" 2443 | checksum = "774d05a3edae07ce6d68ea6984f3c05e9bba8927e3dd591e3b479e5b03213d0d" 2444 | dependencies = [ 2445 | "aes-gcm", 2446 | "blake2", 2447 | "chacha20poly1305", 2448 | "curve25519-dalek 4.0.0-pre.5", 2449 | "rand_core 0.6.4", 2450 | "ring", 2451 | "rustc_version", 2452 | "sha2 0.10.6", 2453 | "subtle", 2454 | ] 2455 | 2456 | [[package]] 2457 | name = "socket2" 2458 | version = "0.4.7" 2459 | source = "registry+https://github.com/rust-lang/crates.io-index" 2460 | checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" 2461 | dependencies = [ 2462 | "libc", 2463 | "winapi", 2464 | ] 2465 | 2466 | [[package]] 2467 | name = "spin" 2468 | version = "0.5.2" 2469 | source = "registry+https://github.com/rust-lang/crates.io-index" 2470 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 2471 | 2472 | [[package]] 2473 | name = "spki" 2474 | version = "0.6.0" 2475 | source = "registry+https://github.com/rust-lang/crates.io-index" 2476 | checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" 2477 | dependencies = [ 2478 | "base64ct", 2479 | "der", 2480 | ] 2481 | 2482 | [[package]] 2483 | name = "static_assertions" 2484 | version = "1.1.0" 2485 | source = "registry+https://github.com/rust-lang/crates.io-index" 2486 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 2487 | 2488 | [[package]] 2489 | name = "subtle" 2490 | version = "2.4.1" 2491 | source = "registry+https://github.com/rust-lang/crates.io-index" 2492 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 2493 | 2494 | [[package]] 2495 | name = "syn" 2496 | version = "1.0.105" 2497 | source = "registry+https://github.com/rust-lang/crates.io-index" 2498 | checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" 2499 | dependencies = [ 2500 | "proc-macro2", 2501 | "quote", 2502 | "unicode-ident", 2503 | ] 2504 | 2505 | [[package]] 2506 | name = "synstructure" 2507 | version = "0.12.6" 2508 | source = "registry+https://github.com/rust-lang/crates.io-index" 2509 | checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" 2510 | dependencies = [ 2511 | "proc-macro2", 2512 | "quote", 2513 | "syn", 2514 | "unicode-xid", 2515 | ] 2516 | 2517 | [[package]] 2518 | name = "system-configuration" 2519 | version = "0.5.0" 2520 | source = "registry+https://github.com/rust-lang/crates.io-index" 2521 | checksum = "d75182f12f490e953596550b65ee31bda7c8e043d9386174b353bda50838c3fd" 2522 | dependencies = [ 2523 | "bitflags", 2524 | "core-foundation", 2525 | "system-configuration-sys", 2526 | ] 2527 | 2528 | [[package]] 2529 | name = "system-configuration-sys" 2530 | version = "0.5.0" 2531 | source = "registry+https://github.com/rust-lang/crates.io-index" 2532 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" 2533 | dependencies = [ 2534 | "core-foundation-sys", 2535 | "libc", 2536 | ] 2537 | 2538 | [[package]] 2539 | name = "tempfile" 2540 | version = "3.3.0" 2541 | source = "registry+https://github.com/rust-lang/crates.io-index" 2542 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 2543 | dependencies = [ 2544 | "cfg-if", 2545 | "fastrand", 2546 | "libc", 2547 | "redox_syscall", 2548 | "remove_dir_all", 2549 | "winapi", 2550 | ] 2551 | 2552 | [[package]] 2553 | name = "termcolor" 2554 | version = "1.1.3" 2555 | source = "registry+https://github.com/rust-lang/crates.io-index" 2556 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 2557 | dependencies = [ 2558 | "winapi-util", 2559 | ] 2560 | 2561 | [[package]] 2562 | name = "thiserror" 2563 | version = "1.0.37" 2564 | source = "registry+https://github.com/rust-lang/crates.io-index" 2565 | checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" 2566 | dependencies = [ 2567 | "thiserror-impl", 2568 | ] 2569 | 2570 | [[package]] 2571 | name = "thiserror-impl" 2572 | version = "1.0.37" 2573 | source = "registry+https://github.com/rust-lang/crates.io-index" 2574 | checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" 2575 | dependencies = [ 2576 | "proc-macro2", 2577 | "quote", 2578 | "syn", 2579 | ] 2580 | 2581 | [[package]] 2582 | name = "thread_local" 2583 | version = "1.1.4" 2584 | source = "registry+https://github.com/rust-lang/crates.io-index" 2585 | checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" 2586 | dependencies = [ 2587 | "once_cell", 2588 | ] 2589 | 2590 | [[package]] 2591 | name = "time" 2592 | version = "0.3.17" 2593 | source = "registry+https://github.com/rust-lang/crates.io-index" 2594 | checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" 2595 | dependencies = [ 2596 | "itoa", 2597 | "serde", 2598 | "time-core", 2599 | "time-macros", 2600 | ] 2601 | 2602 | [[package]] 2603 | name = "time-core" 2604 | version = "0.1.0" 2605 | source = "registry+https://github.com/rust-lang/crates.io-index" 2606 | checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" 2607 | 2608 | [[package]] 2609 | name = "time-macros" 2610 | version = "0.2.6" 2611 | source = "registry+https://github.com/rust-lang/crates.io-index" 2612 | checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" 2613 | dependencies = [ 2614 | "time-core", 2615 | ] 2616 | 2617 | [[package]] 2618 | name = "tinyvec" 2619 | version = "1.6.0" 2620 | source = "registry+https://github.com/rust-lang/crates.io-index" 2621 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 2622 | dependencies = [ 2623 | "tinyvec_macros", 2624 | ] 2625 | 2626 | [[package]] 2627 | name = "tinyvec_macros" 2628 | version = "0.1.0" 2629 | source = "registry+https://github.com/rust-lang/crates.io-index" 2630 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 2631 | 2632 | [[package]] 2633 | name = "tokio" 2634 | version = "1.23.0" 2635 | source = "registry+https://github.com/rust-lang/crates.io-index" 2636 | checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" 2637 | dependencies = [ 2638 | "autocfg", 2639 | "bytes", 2640 | "libc", 2641 | "memchr", 2642 | "mio", 2643 | "num_cpus", 2644 | "pin-project-lite", 2645 | "socket2", 2646 | "windows-sys", 2647 | ] 2648 | 2649 | [[package]] 2650 | name = "toml" 2651 | version = "0.5.10" 2652 | source = "registry+https://github.com/rust-lang/crates.io-index" 2653 | checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" 2654 | dependencies = [ 2655 | "serde", 2656 | ] 2657 | 2658 | [[package]] 2659 | name = "tracing" 2660 | version = "0.1.37" 2661 | source = "registry+https://github.com/rust-lang/crates.io-index" 2662 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 2663 | dependencies = [ 2664 | "cfg-if", 2665 | "pin-project-lite", 2666 | "tracing-attributes", 2667 | "tracing-core", 2668 | ] 2669 | 2670 | [[package]] 2671 | name = "tracing-attributes" 2672 | version = "0.1.23" 2673 | source = "registry+https://github.com/rust-lang/crates.io-index" 2674 | checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" 2675 | dependencies = [ 2676 | "proc-macro2", 2677 | "quote", 2678 | "syn", 2679 | ] 2680 | 2681 | [[package]] 2682 | name = "tracing-core" 2683 | version = "0.1.30" 2684 | source = "registry+https://github.com/rust-lang/crates.io-index" 2685 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 2686 | dependencies = [ 2687 | "once_cell", 2688 | "valuable", 2689 | ] 2690 | 2691 | [[package]] 2692 | name = "tracing-log" 2693 | version = "0.1.3" 2694 | source = "registry+https://github.com/rust-lang/crates.io-index" 2695 | checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" 2696 | dependencies = [ 2697 | "lazy_static", 2698 | "log", 2699 | "tracing-core", 2700 | ] 2701 | 2702 | [[package]] 2703 | name = "tracing-subscriber" 2704 | version = "0.3.16" 2705 | source = "registry+https://github.com/rust-lang/crates.io-index" 2706 | checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" 2707 | dependencies = [ 2708 | "matchers", 2709 | "nu-ansi-term", 2710 | "once_cell", 2711 | "regex", 2712 | "sharded-slab", 2713 | "smallvec", 2714 | "thread_local", 2715 | "tracing", 2716 | "tracing-core", 2717 | "tracing-log", 2718 | ] 2719 | 2720 | [[package]] 2721 | name = "trust-dns-proto" 2722 | version = "0.22.0" 2723 | source = "registry+https://github.com/rust-lang/crates.io-index" 2724 | checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" 2725 | dependencies = [ 2726 | "async-trait", 2727 | "cfg-if", 2728 | "data-encoding", 2729 | "enum-as-inner", 2730 | "futures-channel", 2731 | "futures-io", 2732 | "futures-util", 2733 | "idna 0.2.3", 2734 | "ipnet", 2735 | "lazy_static", 2736 | "rand 0.8.5", 2737 | "smallvec", 2738 | "socket2", 2739 | "thiserror", 2740 | "tinyvec", 2741 | "tokio", 2742 | "tracing", 2743 | "url", 2744 | ] 2745 | 2746 | [[package]] 2747 | name = "trust-dns-resolver" 2748 | version = "0.22.0" 2749 | source = "registry+https://github.com/rust-lang/crates.io-index" 2750 | checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" 2751 | dependencies = [ 2752 | "cfg-if", 2753 | "futures-util", 2754 | "ipconfig", 2755 | "lazy_static", 2756 | "lru-cache", 2757 | "parking_lot", 2758 | "resolv-conf", 2759 | "smallvec", 2760 | "thiserror", 2761 | "tracing", 2762 | "trust-dns-proto", 2763 | ] 2764 | 2765 | [[package]] 2766 | name = "typenum" 2767 | version = "1.16.0" 2768 | source = "registry+https://github.com/rust-lang/crates.io-index" 2769 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 2770 | 2771 | [[package]] 2772 | name = "unicode-bidi" 2773 | version = "0.3.8" 2774 | source = "registry+https://github.com/rust-lang/crates.io-index" 2775 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 2776 | 2777 | [[package]] 2778 | name = "unicode-ident" 2779 | version = "1.0.5" 2780 | source = "registry+https://github.com/rust-lang/crates.io-index" 2781 | checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" 2782 | 2783 | [[package]] 2784 | name = "unicode-normalization" 2785 | version = "0.1.22" 2786 | source = "registry+https://github.com/rust-lang/crates.io-index" 2787 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 2788 | dependencies = [ 2789 | "tinyvec", 2790 | ] 2791 | 2792 | [[package]] 2793 | name = "unicode-xid" 2794 | version = "0.2.4" 2795 | source = "registry+https://github.com/rust-lang/crates.io-index" 2796 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 2797 | 2798 | [[package]] 2799 | name = "universal-hash" 2800 | version = "0.4.1" 2801 | source = "registry+https://github.com/rust-lang/crates.io-index" 2802 | checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" 2803 | dependencies = [ 2804 | "generic-array", 2805 | "subtle", 2806 | ] 2807 | 2808 | [[package]] 2809 | name = "unsigned-varint" 2810 | version = "0.7.1" 2811 | source = "registry+https://github.com/rust-lang/crates.io-index" 2812 | checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" 2813 | dependencies = [ 2814 | "futures-io", 2815 | "futures-util", 2816 | ] 2817 | 2818 | [[package]] 2819 | name = "untrusted" 2820 | version = "0.7.1" 2821 | source = "registry+https://github.com/rust-lang/crates.io-index" 2822 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 2823 | 2824 | [[package]] 2825 | name = "url" 2826 | version = "2.3.1" 2827 | source = "registry+https://github.com/rust-lang/crates.io-index" 2828 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 2829 | dependencies = [ 2830 | "form_urlencoded", 2831 | "idna 0.3.0", 2832 | "percent-encoding", 2833 | ] 2834 | 2835 | [[package]] 2836 | name = "valuable" 2837 | version = "0.1.0" 2838 | source = "registry+https://github.com/rust-lang/crates.io-index" 2839 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 2840 | 2841 | [[package]] 2842 | name = "value-bag" 2843 | version = "1.0.0-alpha.9" 2844 | source = "registry+https://github.com/rust-lang/crates.io-index" 2845 | checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" 2846 | dependencies = [ 2847 | "ctor", 2848 | "version_check", 2849 | ] 2850 | 2851 | [[package]] 2852 | name = "version_check" 2853 | version = "0.9.4" 2854 | source = "registry+https://github.com/rust-lang/crates.io-index" 2855 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2856 | 2857 | [[package]] 2858 | name = "void" 2859 | version = "1.0.2" 2860 | source = "registry+https://github.com/rust-lang/crates.io-index" 2861 | checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 2862 | 2863 | [[package]] 2864 | name = "waker-fn" 2865 | version = "1.1.0" 2866 | source = "registry+https://github.com/rust-lang/crates.io-index" 2867 | checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" 2868 | 2869 | [[package]] 2870 | name = "wasi" 2871 | version = "0.9.0+wasi-snapshot-preview1" 2872 | source = "registry+https://github.com/rust-lang/crates.io-index" 2873 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2874 | 2875 | [[package]] 2876 | name = "wasi" 2877 | version = "0.11.0+wasi-snapshot-preview1" 2878 | source = "registry+https://github.com/rust-lang/crates.io-index" 2879 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2880 | 2881 | [[package]] 2882 | name = "wasm-bindgen" 2883 | version = "0.2.83" 2884 | source = "registry+https://github.com/rust-lang/crates.io-index" 2885 | checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" 2886 | dependencies = [ 2887 | "cfg-if", 2888 | "wasm-bindgen-macro", 2889 | ] 2890 | 2891 | [[package]] 2892 | name = "wasm-bindgen-backend" 2893 | version = "0.2.83" 2894 | source = "registry+https://github.com/rust-lang/crates.io-index" 2895 | checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" 2896 | dependencies = [ 2897 | "bumpalo", 2898 | "log", 2899 | "once_cell", 2900 | "proc-macro2", 2901 | "quote", 2902 | "syn", 2903 | "wasm-bindgen-shared", 2904 | ] 2905 | 2906 | [[package]] 2907 | name = "wasm-bindgen-futures" 2908 | version = "0.4.33" 2909 | source = "registry+https://github.com/rust-lang/crates.io-index" 2910 | checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" 2911 | dependencies = [ 2912 | "cfg-if", 2913 | "js-sys", 2914 | "wasm-bindgen", 2915 | "web-sys", 2916 | ] 2917 | 2918 | [[package]] 2919 | name = "wasm-bindgen-macro" 2920 | version = "0.2.83" 2921 | source = "registry+https://github.com/rust-lang/crates.io-index" 2922 | checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" 2923 | dependencies = [ 2924 | "quote", 2925 | "wasm-bindgen-macro-support", 2926 | ] 2927 | 2928 | [[package]] 2929 | name = "wasm-bindgen-macro-support" 2930 | version = "0.2.83" 2931 | source = "registry+https://github.com/rust-lang/crates.io-index" 2932 | checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" 2933 | dependencies = [ 2934 | "proc-macro2", 2935 | "quote", 2936 | "syn", 2937 | "wasm-bindgen-backend", 2938 | "wasm-bindgen-shared", 2939 | ] 2940 | 2941 | [[package]] 2942 | name = "wasm-bindgen-shared" 2943 | version = "0.2.83" 2944 | source = "registry+https://github.com/rust-lang/crates.io-index" 2945 | checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" 2946 | 2947 | [[package]] 2948 | name = "web-sys" 2949 | version = "0.3.60" 2950 | source = "registry+https://github.com/rust-lang/crates.io-index" 2951 | checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" 2952 | dependencies = [ 2953 | "js-sys", 2954 | "wasm-bindgen", 2955 | ] 2956 | 2957 | [[package]] 2958 | name = "webpki" 2959 | version = "0.22.0" 2960 | source = "registry+https://github.com/rust-lang/crates.io-index" 2961 | checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" 2962 | dependencies = [ 2963 | "ring", 2964 | "untrusted", 2965 | ] 2966 | 2967 | [[package]] 2968 | name = "wepoll-ffi" 2969 | version = "0.1.2" 2970 | source = "registry+https://github.com/rust-lang/crates.io-index" 2971 | checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" 2972 | dependencies = [ 2973 | "cc", 2974 | ] 2975 | 2976 | [[package]] 2977 | name = "which" 2978 | version = "4.3.0" 2979 | source = "registry+https://github.com/rust-lang/crates.io-index" 2980 | checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" 2981 | dependencies = [ 2982 | "either", 2983 | "libc", 2984 | "once_cell", 2985 | ] 2986 | 2987 | [[package]] 2988 | name = "widestring" 2989 | version = "0.5.1" 2990 | source = "registry+https://github.com/rust-lang/crates.io-index" 2991 | checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" 2992 | 2993 | [[package]] 2994 | name = "winapi" 2995 | version = "0.3.9" 2996 | source = "registry+https://github.com/rust-lang/crates.io-index" 2997 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2998 | dependencies = [ 2999 | "winapi-i686-pc-windows-gnu", 3000 | "winapi-x86_64-pc-windows-gnu", 3001 | ] 3002 | 3003 | [[package]] 3004 | name = "winapi-i686-pc-windows-gnu" 3005 | version = "0.4.0" 3006 | source = "registry+https://github.com/rust-lang/crates.io-index" 3007 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 3008 | 3009 | [[package]] 3010 | name = "winapi-util" 3011 | version = "0.1.5" 3012 | source = "registry+https://github.com/rust-lang/crates.io-index" 3013 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 3014 | dependencies = [ 3015 | "winapi", 3016 | ] 3017 | 3018 | [[package]] 3019 | name = "winapi-x86_64-pc-windows-gnu" 3020 | version = "0.4.0" 3021 | source = "registry+https://github.com/rust-lang/crates.io-index" 3022 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 3023 | 3024 | [[package]] 3025 | name = "windows" 3026 | version = "0.34.0" 3027 | source = "registry+https://github.com/rust-lang/crates.io-index" 3028 | checksum = "45296b64204227616fdbf2614cefa4c236b98ee64dfaaaa435207ed99fe7829f" 3029 | dependencies = [ 3030 | "windows_aarch64_msvc 0.34.0", 3031 | "windows_i686_gnu 0.34.0", 3032 | "windows_i686_msvc 0.34.0", 3033 | "windows_x86_64_gnu 0.34.0", 3034 | "windows_x86_64_msvc 0.34.0", 3035 | ] 3036 | 3037 | [[package]] 3038 | name = "windows-sys" 3039 | version = "0.42.0" 3040 | source = "registry+https://github.com/rust-lang/crates.io-index" 3041 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 3042 | dependencies = [ 3043 | "windows_aarch64_gnullvm", 3044 | "windows_aarch64_msvc 0.42.0", 3045 | "windows_i686_gnu 0.42.0", 3046 | "windows_i686_msvc 0.42.0", 3047 | "windows_x86_64_gnu 0.42.0", 3048 | "windows_x86_64_gnullvm", 3049 | "windows_x86_64_msvc 0.42.0", 3050 | ] 3051 | 3052 | [[package]] 3053 | name = "windows_aarch64_gnullvm" 3054 | version = "0.42.0" 3055 | source = "registry+https://github.com/rust-lang/crates.io-index" 3056 | checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" 3057 | 3058 | [[package]] 3059 | name = "windows_aarch64_msvc" 3060 | version = "0.34.0" 3061 | source = "registry+https://github.com/rust-lang/crates.io-index" 3062 | checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" 3063 | 3064 | [[package]] 3065 | name = "windows_aarch64_msvc" 3066 | version = "0.42.0" 3067 | source = "registry+https://github.com/rust-lang/crates.io-index" 3068 | checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" 3069 | 3070 | [[package]] 3071 | name = "windows_i686_gnu" 3072 | version = "0.34.0" 3073 | source = "registry+https://github.com/rust-lang/crates.io-index" 3074 | checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" 3075 | 3076 | [[package]] 3077 | name = "windows_i686_gnu" 3078 | version = "0.42.0" 3079 | source = "registry+https://github.com/rust-lang/crates.io-index" 3080 | checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" 3081 | 3082 | [[package]] 3083 | name = "windows_i686_msvc" 3084 | version = "0.34.0" 3085 | source = "registry+https://github.com/rust-lang/crates.io-index" 3086 | checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" 3087 | 3088 | [[package]] 3089 | name = "windows_i686_msvc" 3090 | version = "0.42.0" 3091 | source = "registry+https://github.com/rust-lang/crates.io-index" 3092 | checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" 3093 | 3094 | [[package]] 3095 | name = "windows_x86_64_gnu" 3096 | version = "0.34.0" 3097 | source = "registry+https://github.com/rust-lang/crates.io-index" 3098 | checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" 3099 | 3100 | [[package]] 3101 | name = "windows_x86_64_gnu" 3102 | version = "0.42.0" 3103 | source = "registry+https://github.com/rust-lang/crates.io-index" 3104 | checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" 3105 | 3106 | [[package]] 3107 | name = "windows_x86_64_gnullvm" 3108 | version = "0.42.0" 3109 | source = "registry+https://github.com/rust-lang/crates.io-index" 3110 | checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" 3111 | 3112 | [[package]] 3113 | name = "windows_x86_64_msvc" 3114 | version = "0.34.0" 3115 | source = "registry+https://github.com/rust-lang/crates.io-index" 3116 | checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" 3117 | 3118 | [[package]] 3119 | name = "windows_x86_64_msvc" 3120 | version = "0.42.0" 3121 | source = "registry+https://github.com/rust-lang/crates.io-index" 3122 | checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" 3123 | 3124 | [[package]] 3125 | name = "winreg" 3126 | version = "0.10.1" 3127 | source = "registry+https://github.com/rust-lang/crates.io-index" 3128 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" 3129 | dependencies = [ 3130 | "winapi", 3131 | ] 3132 | 3133 | [[package]] 3134 | name = "x25519-dalek" 3135 | version = "1.1.1" 3136 | source = "registry+https://github.com/rust-lang/crates.io-index" 3137 | checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" 3138 | dependencies = [ 3139 | "curve25519-dalek 3.2.0", 3140 | "rand_core 0.5.1", 3141 | "zeroize", 3142 | ] 3143 | 3144 | [[package]] 3145 | name = "x509-parser" 3146 | version = "0.14.0" 3147 | source = "registry+https://github.com/rust-lang/crates.io-index" 3148 | checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" 3149 | dependencies = [ 3150 | "asn1-rs", 3151 | "base64", 3152 | "data-encoding", 3153 | "der-parser", 3154 | "lazy_static", 3155 | "nom", 3156 | "oid-registry", 3157 | "rusticata-macros", 3158 | "thiserror", 3159 | "time", 3160 | ] 3161 | 3162 | [[package]] 3163 | name = "yamux" 3164 | version = "0.10.2" 3165 | source = "registry+https://github.com/rust-lang/crates.io-index" 3166 | checksum = "e5d9ba232399af1783a58d8eb26f6b5006fbefe2dc9ef36bd283324792d03ea5" 3167 | dependencies = [ 3168 | "futures", 3169 | "log", 3170 | "nohash-hasher", 3171 | "parking_lot", 3172 | "rand 0.8.5", 3173 | "static_assertions", 3174 | ] 3175 | 3176 | [[package]] 3177 | name = "yasna" 3178 | version = "0.5.0" 3179 | source = "registry+https://github.com/rust-lang/crates.io-index" 3180 | checksum = "346d34a236c9d3e5f3b9b74563f238f955bbd05fa0b8b4efa53c130c43982f4c" 3181 | dependencies = [ 3182 | "time", 3183 | ] 3184 | 3185 | [[package]] 3186 | name = "zeroize" 3187 | version = "1.5.7" 3188 | source = "registry+https://github.com/rust-lang/crates.io-index" 3189 | checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" 3190 | dependencies = [ 3191 | "zeroize_derive", 3192 | ] 3193 | 3194 | [[package]] 3195 | name = "zeroize_derive" 3196 | version = "1.3.3" 3197 | source = "registry+https://github.com/rust-lang/crates.io-index" 3198 | checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" 3199 | dependencies = [ 3200 | "proc-macro2", 3201 | "quote", 3202 | "syn", 3203 | "synstructure", 3204 | ] 3205 | --------------------------------------------------------------------------------