diff --git a/Cargo.lock b/Cargo.lock index f4613da..f59603e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,9 +48,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "arrayref" @@ -282,9 +282,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3" dependencies = [ "proc-macro2", "quote", @@ -303,7 +303,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -346,9 +346,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "blake2" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b12e5fd123190ce1c2e559308a94c9bacad77907d4c6005d9e58fe1a0689e55e" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ "digest 0.10.6", ] @@ -975,6 +975,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hostname" version = "0.3.1" @@ -1090,9 +1099,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" @@ -1120,9 +1129,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libipld" @@ -1683,9 +1692,9 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nom" -version = "7.1.1" +version = "7.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c" dependencies = [ "memchr", "minimal-lexical", @@ -1733,11 +1742,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -1752,9 +1761,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "opaque-debug" @@ -1809,9 +1818,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b" +checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" [[package]] name = "pem" @@ -1931,9 +1940,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c142c0e46b57171fe0c528bee8c5b7569e80f0c17e377cd0e30ea57dbc11bb51" +checksum = "2c8992a85d8e93a28bdf76137db888d3874e3b230dee5ed8bebac4c9f7617773" dependencies = [ "proc-macro2", "syn", @@ -1975,9 +1984,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] @@ -1999,9 +2008,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b18e655c21ff5ac2084a5ad0611e827b3f92badf79f4910b5a5c58f4d87ff0" +checksum = "c01db6702aa05baa3f57dec92b8eeeeb4cb19e894e73996b32a4093289e54592" dependencies = [ "bytes", "prost-derive", @@ -2009,9 +2018,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276470f7f281b0ed53d2ae42dd52b4a8d08853a3c70e7fe95882acbb98a6ae94" +checksum = "cb5320c680de74ba083512704acb90fe00f28f79207286a848e730c45dd73ed6" dependencies = [ "bytes", "heck", @@ -2031,9 +2040,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164ae68b6587001ca506d3bf7f1000bfa248d0e1217b618108fba4ec1d0cc306" +checksum = "c8842bad1a5419bca14eac663ba798f6bc19c413c2fdceb5f3ba3b0932d96720" dependencies = [ "anyhow", "itertools", @@ -2044,9 +2053,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.11.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747761bc3dc48f9a34553bf65605cf6cb6288ba219f3450b4275dbd81539551a" +checksum = "017f79637768cde62820bc2d4fe0e45daaa027755c323ad077767c6c5f173091" dependencies = [ "bytes", "prost", @@ -2084,9 +2093,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -2336,15 +2345,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" [[package]] name = "serde" -version = "1.0.150" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" [[package]] name = "sha2" @@ -2493,9 +2502,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -2560,18 +2569,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -2776,9 +2785,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" @@ -3175,9 +3184,9 @@ dependencies = [ [[package]] name = "yasna" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346d34a236c9d3e5f3b9b74563f238f955bbd05fa0b8b4efa53c130c43982f4c" +checksum = "aed2e7a52e3744ab4d0c05c20aa065258e84c49fd4226f5191b2ed29712710b4" dependencies = [ "time", ] diff --git a/src/behaviour.rs b/src/behaviour.rs index b025b94..88b580e 100644 --- a/src/behaviour.rs +++ b/src/behaviour.rs @@ -6,7 +6,7 @@ //! The `Bitswap` struct implements the `NetworkBehaviour` trait. When used, it //! will allow providing and reciving IPFS blocks. #[cfg(feature = "compat")] -use crate::compat::{CompatMessage, CompatProtocol, InboundMessage}; +use crate::compat::{CompatMessage, CompatProtocolInbound, CompatProtocolOutbound, InboundMessage}; use crate::protocol::{ BitswapCodec, BitswapProtocol, BitswapRequest, BitswapResponse, RequestType, }; @@ -26,7 +26,7 @@ use libp2p::core::either::EitherOutput; use libp2p::core::{connection::ConnectionId, Multiaddr, PeerId}; use libp2p::swarm::derive_prelude::{ConnectionClosed, DialFailure, FromSwarm, ListenFailure}; #[cfg(feature = "compat")] -use libp2p::swarm::{ConnectionHandlerSelect, NotifyHandler, OneShotHandler}; +use libp2p::swarm::{ConnectionHandlerSelect, NotifyHandler, OneShotHandler, SubstreamProtocol}; use libp2p::{ request_response::{ InboundFailure, OutboundFailure, ProtocolSupport, RequestId, RequestResponse, @@ -72,6 +72,9 @@ pub struct BitswapConfig { pub request_timeout: Duration, /// Time a connection is kept alive. pub connection_keep_alive: Duration, + /// Custom protocol name for go-bitswap compatible mode, default is [crate::compat::DEFAULT_COMPAT_PROTOCOL_NAME] + #[cfg(feature = "compat")] + pub compat_protocol_name: &'static [u8], } impl BitswapConfig { @@ -80,6 +83,8 @@ impl BitswapConfig { Self { request_timeout: Duration::from_secs(10), connection_keep_alive: Duration::from_secs(10), + #[cfg(feature = "compat")] + compat_protocol_name: crate::compat::DEFAULT_COMPAT_PROTOCOL_NAME, } } } @@ -115,6 +120,9 @@ pub struct Bitswap { db_tx: mpsc::UnboundedSender>, /// Db response channel. db_rx: mpsc::UnboundedReceiver, + /// Custom protocol name for go-bitswap compatible mode, default is [DEFAULT_COMPAT_PROTOCOL_NAME] + #[cfg(feature = "compat")] + pub compat_protocol_name: &'static [u8], /// Compat peers. #[cfg(feature = "compat")] compat: FnvHashSet, @@ -136,6 +144,8 @@ impl Bitswap

{ db_tx, db_rx, #[cfg(feature = "compat")] + compat_protocol_name: config.compat_protocol_name, + #[cfg(feature = "compat")] compat: Default::default(), } } @@ -365,6 +375,21 @@ impl Bitswap

{ } } } + + #[cfg(feature = "compat")] + fn new_compat_handler( + &self, + ) -> OneShotHandler { + OneShotHandler::new( + SubstreamProtocol::new( + CompatProtocolInbound { + protocol_name: self.compat_protocol_name, + }, + (), + ), + Default::default(), + ) + } } impl NetworkBehaviour for Bitswap

{ @@ -376,7 +401,7 @@ impl NetworkBehaviour for Bitswap

{ #[allow(clippy::type_complexity)] type ConnectionHandler = ConnectionHandlerSelect< > as NetworkBehaviour>::ConnectionHandler, - OneShotHandler, + OneShotHandler, >; type OutEvent = BitswapEvent; @@ -384,7 +409,7 @@ impl NetworkBehaviour for Bitswap

{ #[cfg(not(feature = "compat"))] return self.inner.new_handler(); #[cfg(feature = "compat")] - ConnectionHandler::select(self.inner.new_handler(), OneShotHandler::default()) + ConnectionHandler::select(self.inner.new_handler(), self.new_compat_handler()) } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { @@ -517,7 +542,10 @@ impl NetworkBehaviour for Bitswap

{ return Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::Any, - event: EitherOutput::Second(compat), + event: EitherOutput::Second(CompatProtocolOutbound { + protocol_name: self.compat_protocol_name, + message: compat, + }), }); } }, @@ -583,7 +611,7 @@ impl NetworkBehaviour for Bitswap

{ NetworkBehaviourAction::GenerateEvent(event) => event, NetworkBehaviourAction::Dial { opts, handler } => { #[cfg(feature = "compat")] - let handler = ConnectionHandler::select(handler, Default::default()); + let handler = ConnectionHandler::select(handler, self.new_compat_handler()); return Poll::Ready(NetworkBehaviourAction::Dial { opts, handler }); } NetworkBehaviourAction::NotifyHandler { @@ -652,9 +680,10 @@ impl NetworkBehaviour for Bitswap

{ return Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id: peer, handler: NotifyHandler::Any, - event: EitherOutput::Second(CompatMessage::Request( - request, - )), + event: EitherOutput::Second(CompatProtocolOutbound { + protocol_name: self.compat_protocol_name, + message: CompatMessage::Request(request), + }), }); } } diff --git a/src/compat/mod.rs b/src/compat/mod.rs index b3400c2..c868a67 100644 --- a/src/compat/mod.rs +++ b/src/compat/mod.rs @@ -3,7 +3,9 @@ mod prefix; mod protocol; pub use message::CompatMessage; -pub use protocol::{CompatProtocol, InboundMessage}; +pub use protocol::{ + CompatProtocolInbound, CompatProtocolOutbound, InboundMessage, DEFAULT_COMPAT_PROTOCOL_NAME, +}; fn other(e: E) -> std::io::Error { std::io::Error::new(std::io::ErrorKind::Other, e) diff --git a/src/compat/protocol.rs b/src/compat/protocol.rs index d05a597..5c64b47 100644 --- a/src/compat/protocol.rs +++ b/src/compat/protocol.rs @@ -6,20 +6,23 @@ use std::{io, iter}; // 2MB Block Size according to the specs at https://github.com/ipfs/specs/blob/main/BITSWAP.md const MAX_BUF_SIZE: usize = 2_097_152; +pub const DEFAULT_COMPAT_PROTOCOL_NAME: &[u8] = b"/ipfs/bitswap/1.2.0"; -#[derive(Clone, Debug, Default)] -pub struct CompatProtocol; +#[derive(Clone, Debug)] +pub struct CompatProtocolInbound { + pub(crate) protocol_name: &'static [u8], +} -impl UpgradeInfo for CompatProtocol { +impl UpgradeInfo for CompatProtocolInbound { type Info = &'static [u8]; type InfoIter = iter::Once; fn protocol_info(&self) -> Self::InfoIter { - iter::once(b"/ipfs/bitswap/1.2.0") + iter::once(self.protocol_name) } } -impl InboundUpgrade for CompatProtocol +impl InboundUpgrade for CompatProtocolInbound where TSocket: AsyncRead + AsyncWrite + Send + Unpin + 'static, { @@ -48,12 +51,40 @@ where } } +#[derive(Clone, Debug)] +pub struct CompatProtocolOutbound { + pub(crate) protocol_name: &'static [u8], + pub(crate) message: CompatMessage, +} + +impl OutboundUpgrade for CompatProtocolOutbound +where + TSocket: AsyncRead + AsyncWrite + Send + Unpin + 'static, +{ + type Output = >::Output; + type Error = >::Error; + type Future = >::Future; + + fn upgrade_outbound(self, socket: TSocket, info: Self::Info) -> Self::Future { + CompatMessage::upgrade_outbound(self.message, socket, info) + } +} + +impl UpgradeInfo for CompatProtocolOutbound { + type Info = &'static [u8]; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(self.protocol_name) + } +} + impl UpgradeInfo for CompatMessage { type Info = &'static [u8]; type InfoIter = iter::Once; fn protocol_info(&self) -> Self::InfoIter { - iter::once(b"/ipfs/bitswap/1.2.0") + unimplemented!() } } @@ -100,19 +131,27 @@ mod tests { let server = async move { let incoming = listener.incoming().into_future().await.0.unwrap().unwrap(); - upgrade::apply_inbound(incoming, CompatProtocol) - .await - .unwrap(); + upgrade::apply_inbound( + incoming, + CompatProtocolInbound { + protocol_name: DEFAULT_COMPAT_PROTOCOL_NAME, + }, + ) + .await + .unwrap(); }; let client = async move { let stream = TcpStream::connect(&listener_addr).await.unwrap(); upgrade::apply_outbound( stream, - CompatMessage::Request(BitswapRequest { - ty: RequestType::Have, - cid: Cid::default(), - }), + CompatProtocolOutbound { + protocol_name: DEFAULT_COMPAT_PROTOCOL_NAME, + message: CompatMessage::Request(BitswapRequest { + ty: RequestType::Have, + cid: Cid::default(), + }), + }, upgrade::Version::V1, ) .await diff --git a/src/lib.rs b/src/lib.rs index 5087f68..4be3b10 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,3 +12,6 @@ mod stats; pub use crate::behaviour::{Bitswap, BitswapConfig, BitswapEvent, BitswapStore, Channel}; pub use crate::query::QueryId; + +/// Re-exports +pub use libipld;