* Allow multiple connections per peer in libp2p-core.
Instead of trying to enforce a single connection per peer,
which involves quite a bit of additional complexity e.g.
to prioritise simultaneously opened connections and can
have other undesirable consequences [1], we now
make multiple connections per peer a feature.
The gist of these changes is as follows:
The concept of a "node" with an implicit 1-1 correspondence
to a connection has been replaced with the "first-class"
concept of a "connection". The code from `src/nodes` has moved
(with varying degrees of modification) to `src/connection`.
A `HandledNode` has become a `Connection`, a `NodeHandler` a
`ConnectionHandler`, the `CollectionStream` was the basis for
the new `connection::Pool`, and so forth.
Conceptually, a `Network` contains a `connection::Pool` which
in turn internally employs the `connection::Manager` for
handling the background `connection::manager::Task`s, one
per connection, as before. These are all considered implementation
details. On the public API, `Peer`s are managed as before through
the `Network`, except now the API has changed with the shift of focus
to (potentially multiple) connections per peer. The `NetworkEvent`s have
accordingly also undergone changes.
The Swarm APIs remain largely unchanged, except for the fact that
`inject_replaced` is no longer called. It may now practically happen
that multiple `ProtocolsHandler`s are associated with a single
`NetworkBehaviour`, one per connection. If implementations of
`NetworkBehaviour` rely somehow on communicating with exactly
one `ProtocolsHandler`, this may cause issues, but it is unlikely.
[1]: https://github.com/paritytech/substrate/issues/4272
* Fix intra-rustdoc links.
* Update core/src/connection/pool.rs
Co-Authored-By: Max Inden <mail@max-inden.de>
* Address some review feedback and fix doc links.
* Allow responses to be sent on the same connection.
* Remove unnecessary remainders of inject_replaced.
* Update swarm/src/behaviour.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update swarm/src/lib.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update core/src/connection/manager.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update core/src/connection/manager.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update core/src/connection/pool.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Incorporate more review feedback.
* Move module declaration below imports.
* Update core/src/connection/manager.rs
Co-Authored-By: Toralf Wittner <tw@dtex.org>
* Update core/src/connection/manager.rs
Co-Authored-By: Toralf Wittner <tw@dtex.org>
* Simplify as per review.
* Fix rustoc link.
* Add try_notify_handler and simplify.
* Relocate DialingConnection and DialingAttempt.
For better visibility constraints.
* Small cleanup.
* Small cleanup. More robust EstablishedConnectionIter.
* Clarify semantics of `DialingPeer::connect`.
* Don't call inject_disconnected on InvalidPeerId.
To preserve the previous behavior and ensure calls to
`inject_disconnected` are always paired with calls to
`inject_connected`.
* Provide public ConnectionId constructor.
Mainly needed for testing purposes, e.g. in substrate.
* Move the established connection limit check to the right place.
* Clean up connection error handling.
Separate connection errors into those occuring during
connection setup or upon rejecting a newly established
connection (the `PendingConnectionError`) and those
errors occurring on previously established connections,
i.e. for which a `ConnectionEstablished` event has
been emitted by the connection pool earlier.
* Revert change in log level and clarify an invariant.
* Remove inject_replaced entirely.
* Allow notifying all connection handlers.
Thereby simplify by introducing a new enum `NotifyHandler`,
used with a single constructor `NetworkBehaviourAction::NotifyHandler`.
* Finishing touches.
Small API simplifications and code deduplication.
Some more useful debug logging.
Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Fix broken links in rustdoc
This fixes all of the rustdoc warnings on nightly.
* Check documentation intra-link
* Fix config
* Fix bad indent
* Make nightly explicit
* More links fixes
* Fix link broken after master merge
Co-authored-by: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com>
The current implementation defines the InboundUpgrade only for `R = ()`
so notably a `NoiseConfig` created by `NoiseConfig::ik_dialer` can not
be an `InboundUpgrade`.
Fixes#1378.
* Configurable multistream-select protocol. Add V1Lazy variant. (#1245)
Make the multistream-select protocol (version) configurable
on transport upgrades as well as for individual substreams.
Add a "lazy" variant of multistream-select 1.0 that delays
sending of negotiation protocol frames as much as possible
but is only safe to use under additional assumptions that
go beyond what is required by the multistream-select v1
specification.
* Improve the code readability of the chat example (#1253)
* Add bridged chats (#1252)
* Try fix CI (#1261)
* Print Rust version on CI
* Don't print where not appropriate
* Change caching strategy
* Remove win32 build
* Remove win32 from list
* Update libsecp256k1 dep to 0.3.0 (#1258)
* Update libsecp256k1 dep to 0.3.0
* Sign now cannot fail
* Upgrade url and percent-encoding deps to 2.1.0 (#1267)
* Upgrade percent-encoding dep to 2.1.0
* Upgrade url dep to 2.1.0
* Fix more conflicts
* Revert CIPHERS set to null (#1273)
* protocols/noise: Fix obvious future errors
* protocol/noise: Make Handshake methods independent functions
* protocols/noise: Abstract T and C for handshake
* protocols/noise: Replace FutureResult with Result
* protocols/noise: Introduce recv_identity stub
* protocols/noise: Implement recv_identity stub
* protocols/noise: Change NoiseConfig::Future from Handshake to Result
* protocols/noise: Adjust to new Poll syntax
* protocols/noise: Return early on state creation failure
* protocols/noise: Add bounds Async{Write,Read} to initiator / respoder
* protocols/noise: Add Protocol trait bound for C in rt functions
* protocols/noise: Do io operations on state.io instead of state
* protocols/noise: Have upgrade_xxx return a pinned future
* protocols/noise: Have NoiseOutput::poll_read self be mutable
* protocols/noise: Make recv_identity buffers mutable
* protocols/noise: Fix warnings
* protocols/noise: Replace NoiseOutput io::Read impl with AsyncRead
* protocols/noise: Replace NoiseOutput io::Write impl with AsyncWrite
* protocols/noise: Adjust tests to new futures
* protocols/noise: Don't use {AsyncRead,AsyncWrite,TryStream}*Ext* bound
* protocols/noise: Don't use async_closure feature
* protocols/noise: use futures::ready! macro
* protocols/noise: Make NoiseOutput AsyncRead return unsafe NopInitializer
The previous implementation of AsyncRead for NoiseOutput would operate
on uninitialized buffers, given that it properly returned the number of
bytest that were written to the buffer. With this patch the current
implementation operates on uninitialized buffers as well by returning an
Initializer::nop() in AsyncRead::initializer.
* protocols/noise: Remove resolved TODO questions
* protocols/noise: Remove 'this = self' comment
Given that `let mut this = &mut *self` is not specific to a pinned self,
but follows the dereference coercion [1] happening at compile time when
trying to mutably borrow two distinct struct fields, this patch removes
the code comment.
[1]
```rust
let x = &mut self.deref_mut().x;
let y = &mut self.deref_mut().y; // error
// ---
let mut this = self.deref_mut();
let x = &mut this.x;
let y = &mut this.y; // ok
```
* Remove redundant nested futures.
* protocols/noise/Cargo: Update to futures preview 0.3.0-alpha.18
* protocols/noise: Improve formatting
* protocols/noise: Return pinned future on authenticated noise upgrade
* protocols/noise: Specify Output of Future embedded in Handshake directly
* *: Ensure Noise handshake futures are Send
* Revert "*: Ensure Noise handshake futures are Send"
This reverts commit 555c2df315e44f21ad39d4408445ce2cb84dd1a4.
* protocols/noise: Ensure NoiseConfig Future is Send
* protocols/noise: Use relative import path for {In,Out}boundUpgrade
* Rework the transport upgrade API.
ALthough transport upgrades must follow a specific pattern
in order fot the resulting transport to be usable with a
`Network` or `Swarm`, that pattern is currently not well
reflected in the transport upgrade API. Rather, transport
upgrades are rather laborious and involve non-trivial code
duplication.
This commit introduces a `transport::upgrade::Builder` that is
obtained from `Transport::upgrade`. The `Builder` encodes the
previously implicit rules for transport upgrades:
1. Authentication upgrades must happen first.
2. Any number of upgrades may follow.
3. A multiplexer upgrade must happen last.
Since multiplexing is the last (regular) transport upgrade (because
that upgrade yields a `StreamMuxer` which is no longer a `AsyncRead`
/ `AsyncWrite` resource, which the upgrade process is based on),
the upgrade starts with `Transport::upgrade` and ends with
`Builder::multiplex`, which drops back down to the `Transport`,
providing a fluent API.
Authentication and multiplexer upgrades must furthermore adhere
to a minimal contract w.r.t their outputs:
1. An authentication upgrade is given an (async) I/O resource `C`
and must produce a pair `(I, D)` where `I: ConnectionInfo` and
`D` is a new (async) I/O resource `D`.
2. A multiplexer upgrade is given an (async) I/O resource `C`
and must produce a `M: StreamMuxer`.
To that end, two changes to the `secio` and `noise` protocols have been
made:
1. The `secio` upgrade now outputs a pair of `(PeerId, SecioOutput)`.
The former implements `ConnectionInfo` and the latter `AsyncRead` /
`AsyncWrite`, fulfilling the `Builder` contract.
2. A new `NoiseAuthenticated` upgrade has been added that wraps around
any noise upgrade (i.e. `NoiseConfig`) and has an output of
`(PeerId, NoiseOutput)`, i.e. it checks if the `RemoteIdentity` from
the handshake output is an `IdentityKey`, failing if that is not the
case. This is the standard upgrade procedure one wants for integrating
noise with libp2p-core/swarm.
* Cleanup
* Add a new integration test.
* Add missing license.
* Integrate use of identity keys into libp2p-noise.
In order to make libp2p-noise usable with a `Swarm`, which requires a
`Transport::Output` that is a pair of a peer ID and an implementation
of `StreamMuxer`, it is necessary to bridge the gap between static
DH public keys and public identity keys from which peer IDs are derived.
Because the DH static keys and the identity keys need not be
related, it is thus generally necessary that the public identity keys are
exchanged as part of the Noise handshake, which the Noise protocol
accomodates for through the use of handshake message payloads.
The implementation of the existing (IK, IX, XX) handshake patterns is thus
changed to send the public identity keys in the handshake payloads.
Additionally, to facilitate the use of any identity keypair with Noise
handshakes, the static DH public keys are signed using the identity
keypairs and the signatures sent alongside the public identity key
in handshake payloads, unless the static DH public key is "linked"
to the public identity key by other means, e.g. when an Ed25519 identity
keypair is (re)used as an X25519 keypair.
* libp2p-noise doesn't build for wasm.
Thus the development transport needs to be still constructed with secio
for transport security when building for wasm.
* Documentation tweaks.
* For consistency, avoid wildcard enum imports.
* For consistency, avoid wildcard enum imports.
* Slightly simplify io:🤝:State::finish.
* Simplify creation of 2-byte arrays.
* Remove unnecessary cast and obey 100 char line limit.
* Update protocols/noise/src/protocol.rs
Co-Authored-By: romanb <romanb@users.noreply.github.com>
* Address more review comments.
* Cosmetics
* Cosmetics
* Give authentic DH keypairs a distinct type.
This has a couple of advantages:
* Signing the DH public key only needs to happen once, before
creating a `NoiseConfig` for an authenticated handshake.
* The identity keypair only needs to be borrowed and can be
dropped if it is not used further outside of the Noise
protocol, since it is no longer needed during Noise handshakes.
* It is explicit in the construction of a `NoiseConfig` for
a handshake pattern, whether it operates with a plain `Keypair`
or a keypair that is authentic w.r.t. a public identity key
and future handshake patterns may be built with either.
* The function signatures for constructing `NoiseConfig`s for
handshake patterns are simplified and a few unnecessary trait
bounds removed.
* Post-merge corrections.
* Add note on experimental status of libp2p-noise.
* Consolidate keypairs in core.
Introduce the concept of a node's identity keypair in libp2p-core,
instead of only the public key:
* New module: libp2p_core::identity with submodules for the currently
supported key types. An identity::Keypair and identity::PublicKey
support the creation and verification of signatures. The public key
supports encoding/decoding according to the libp2p specs.
* The secio protocol is simplified as a result of moving code to libp2p-core.
* The noise protocol is slightly simplified by consolidating ed25519
keypairs in libp2p-core and using x25519-dalek for DH. Furthermore,
Ed25519 to X25519 keypair conversion is now complete and tested.
Generalise over the DH keys in the noise protocol.
Generalise over the DH keys and thus DH parameter in handshake patterns
of the Noise protocol, such that it is easy to support other DH schemes
in the future, e.g. X448.
* Address new review comments.