* [multistream-select] Fix panic with V1Lazy and add integration tests.
Fixes a panic when using the `V1Lazy` negotiation protocol,
a regression introduced in https://github.com/libp2p/rust-libp2p/pull/1484.
Thereby adds integration tests for a transport upgrade with both
`V1` and `V1Lazy` to the `multistream-select` crate to prevent
future regressions.
* Cleanup.
* Update changelog.
* Simplify incoming connection handling.
Instead of handing out a mutable borrow to the connection
pool in the `IncomingConnectionEvent`, so one can call
`IncomingConnectionEvent::accept()`, just provide
`Network::accept()`.
* Update docs.
* Update CHANGELOG.
* Allow StreamMuxer to notify changes in the address
* Fix doc link
* Revert accidental rename
* Other accidental rename
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Permit concurrent dialing attempts per peer.
This is a follow-up to https://github.com/libp2p/rust-libp2p/pull/1440
and relates to https://github.com/libp2p/rust-libp2p/issues/925.
This change permits multiple dialing attempts per peer.
Note though that `libp2p-swarm` does not yet make use of this ability,
retaining the current behaviour. The essence of the changes are that the
`Peer` API now provides `Peer::dial()`, i.e. regardless of the state in
which the peer is. A dialing attempt is always made up of one or more
addresses tried sequentially, as before, but now there can be multiple
dialing attempts per peer. A configurable per-peer limit for outgoing
connections and thus concurrent dialing attempts is also included.
* Introduce `DialError` in `libp2p-swarm`.
For a cleaner API and to treat the case of no addresses
for a peer as an error, such that a `NetworkBehaviourAction::DialPeer`
request is always matched up with either `inject_connection_established`
or `inject_dial_error`.
* Fix rustdoc link.
* Add `DialPeerCondition::Always`.
* Adapt to master.
* Update changelog.
* Fix regression w.r.t. reporting of dial errors.
PR [1440] introduced a regression w.r.t. the reporting of
dial errors. In particular, if a connection attempt fails
due to an invalid remote peer ID, any remaining addresses
for the same peer would not be tried (intentional) but
the dial failure would not be reported to the behaviour,
causing e.g. libp2p-kad queries to potentially stall.
In hindsight, I figured it is better to preserve the
previous behaviour to still try alternative addresses
of the peer even on invalid peer ID errors on an earlier
address. In particular because in the context of libp2p-kad
it is not uncommon for peers to report localhost addresses
while the local node actually has e.g. an ipfs node running
on that address, obviously with a different peer ID, which
is the scenario causing frequent invalid peer ID (mismatch)
errors when running the ipfs-kad example.
This commit thus restores the previous behaviour w.r.t.
trying all remaining addresses on invalid peer ID errors
as well as making sure `inject_dial_error` is always
called when the last attempt failed.
[1440]: https://github.com/libp2p/rust-libp2p/pull/1440.
* Remove an fmt::Debug requirement.
* 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>
* Simplify trait bounds requirements
* More work
* Moar
* Finish
* Fix final tests
* More simplification
* Use separate traits for Inbound/Outbound
* Update gossipsub and remove warnings
* Add documentation to swarm
* Remove BoxSubstream
* Fix tests not compiling
* Fix stack overflow
* Address concerns
* For some reason my IDE ignored libp2p-kad
* Allow configuring the tasks executor
* Minor tweaks
* Add executor_fn
* Create ThreadsPool at the end if necessary
* Allow configuring the tasks executor
* Minor tweaks
* Add executor_fn
* Create ThreadsPool at the end if necessary
* WIP
* Don't depend on async-std and tokio in core
* Replace FutureObj with PinBoxFuture
* Some docs on Executor
* Fix tests
Co-authored-by: Toralf Wittner <tw@dtex.org>
- Pin `futures_codec` to version 0.3.3 as later versions require
at least bytes-0.5 which he have not upgraded to yet.
- Replace `futures::executor::block_on` with `async_std::task::block_on`
where `async-std` is already a dependency to work around an issue with
`park`/`unpark` behaviour.
- Use the published version of `quicksink`.
* 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
* Revert CIPHERS set to null (#1273)
* Update dependency versions (#1265)
* Update versions of many dependencies
* Bump version of rand
* Updates for changed APIs in rand, ring, and webpki
* Replace references to `snow::Session`
`Session` no longer exists in `snow` but the replacement is two structs `HandshakeState` and `TransportState`
Something will have to be done to harmonize `NoiseOutput.session`
* Add precise type for UnparsedPublicKey
* Update data structures/functions to match new snow's API
* Delete diff.diff
Remove accidentally committed diff file
* Remove commented lines in identity/rsa.rs
* Bump libsecp256k1 to 0.3.1
* Implement /plaintext/2.0.0 (#1236)
* WIP
* plaintext/2.0.0
* Refactor protobuf related issues to compatible with the spec
* Rename: new PlainTextConfig -> PlainText2Config
* Keep plaintext/1.0.0 as PlainText1Config
* Config contains pubkey
* Rename: proposition -> exchange
* Add PeerId to Exchange
* Check the validity of the remote's `Exchange`
* Tweak
* Delete unused import
* Add debug log
* Delete unused field: public_key_encoded
* Delete unused field: local
* Delete unused field: exchange_bytes
* The inner instance should not be public
* identity::Publickey::Rsa is not available on wasm
* Delete PeerId from Config as it should be generated from the pubkey
* Catch up for #1240
* Tweak
* Update protocols/plaintext/src/error.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update protocols/plaintext/src/handshake.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update protocols/plaintext/src/error.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update protocols/plaintext/src/error.rs
Co-Authored-By: Roman Borschel <romanb@users.noreply.github.com>
* Update protocols/plaintext/src/error.rs
Co-Authored-By: Roman Borschel <romanb@users.noreply.github.com>
* Rename: pubkey -> local_public_key
* Delete unused error
* Rename: PeerIdValidationFailed -> InvalidPeerId
* Fix: HandShake -> Handshake
* Use bytes insteadof Publickey to avoid code duplication
* Replace with ProtobufError
* Merge HandshakeContext<()> into HandshakeContext<Local>
* Improve the peer ID validation to simplify the handshake
* Propagate Remote to allow extracting the PeerId from the Remote
* Collapse the same kind of errors into the variant
* [noise]: `sodiumoxide 0.2.5` (#1276)
Fixes https://github.com/RustSec/advisory-db/pull/192
* examples/ipfs-kad.rs: Remove outdated reference to `without_init` (#1280)
* CircleCI Test Fix (#1282)
* Disabling "Docker Layer Caching" because it breaks one of the circleci checks
* Bump to trigger CircleCI build
* unbump
* zeroize: Upgrade to v1.0 (#1284)
v1.0 final release is out. Release notes:
https://github.com/iqlusioninc/crates/pull/279
* *: Consolidate protobuf scripts and update to rust-protobuf 2.8.1 (#1275)
* *: Consolidate protobuf generation scripts
* *: Update to rust-protobuf 2.8.1
* *: Mark protobuf generated modules with '_proto'
* examples: Add distributed key value store (#1281)
* examples: Add distributed key value store
This commit adds a basic distributed key value store supporting GET and
PUT commands using Kademlia and mDNS.
* examples/distributed-key-value-store: Fix typo
* Simple Warning Cleanup (#1278)
* Cleaning up warnings - removing unused `use`
* Cleaning up warnings - unused tuple value
* Cleaning up warnings - removing dead code
* Cleaning up warnings - fixing deprecated name
* Cleaning up warnings - removing dead code
* Revert "Cleaning up warnings - removing dead code"
This reverts commit f18a765e4bf240b0ed9294ec3ae5dab5c186b801.
* Enable the std feature of ring (#1289)
* 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)
* 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.
* Replace `listen_addr` with `local_addr`.
In `ListenerUpgrade`, `ConnectedPoint` and other event types where we
were previously using the listen address we now report the local address
of an incoming connection. The reason being that it is difficult to get
the listen address right. In case clients want to know, which listener
produced an incoming connection upgrade they are advised to use the
`ListenerId` for such purposes.
* Update transports/tcp/src/lib.rs
Co-Authored-By: Max Inden <mail@max-inden.de>
* Remove tokio-codec dependency from multistream-select.
In preparation for the eventual switch from tokio to std futures.
Includes some initial refactoring in preparation for further work
in the context of https://github.com/libp2p/rust-libp2p/issues/659.
* Reduce default buffer sizes.
* Allow more than one frame to be buffered for sending.
* Doc tweaks.
* Remove superfluous (duplicated) Message types.
* Reduce roundtrips in multistream-select negotiation.
1. Enable 0-RTT: If the dialer only supports a single protocol, it can send
protocol data (e.g. the actual application request) together with
the multistream-select header and protocol proposal. Similarly,
if the listener supports a proposed protocol, it can send protocol
data (e.g. the actual application response) together with the
multistream-select header and protocol confirmation.
2. In general, the dialer "settles on" an expected protocol as soon
as it runs out of alternatives. Furthermore, both dialer and listener
do not immediately flush the final protocol confirmation, allowing it
to be sent together with application protocol data. Attempts to read
from the negotiated I/O stream implicitly flushes any pending data.
3. A clean / graceful shutdown of an I/O stream always completes protocol
negotiation.
The publich API of multistream-select changed slightly, requiring both
AsyncRead and AsyncWrite bounds for async reading and writing due to
the implicit buffering and "lazy" negotiation. The error types have
also been changed, but they were not previously fully exported.
Includes some general refactoring with simplifications and some more tests,
e.g. there was an edge case relating to a possible ambiguity when parsing
multistream-select protocol messages.
* Further missing commentary.
* Remove unused test dependency.
* Adjust commentary.
* Cleanup NegotiatedComplete::poll()
* Fix deflate protocol tests.
* Stabilise network_simult test.
The test implicitly relied on "slow" connection establishment
in order to have a sufficient probability of passing.
With the removal of roundtrips in multistream-select, it is now
more likely that within the up to 50ms duration between swarm1
and swarm2 dialing, the connection is already established, causing
the expectation of step == 1 to fail when receiving a Connected event,
since the step may then still be 0.
This commit aims to avoid these spurious errors by detecting runs
during which a connection is established "too quickly", repeating
the test run.
It still seems theoretically possible that, if connections are always
established "too quickly", the test runs forever. However, given that
the delta between swarm1 and swarm2 dialing is 0-50ms and that the
TCP transport is used, that seems probabilistically unlikely.
Nevertheless, the purpose of the artificial dialing delay between
swarm1 and swarm2 should be re-evaluated and possibly at least
the maximum delay further reduced.
* Complete negotiation between upgrades in libp2p-core.
While multistream-select, as a standalone library and providing
an API at the granularity of a single negotiation, supports
lazy negotiation (and in particular 0-RTT negotiation), in the
context of libp2p-core where any number of negotiations are
composed generically within the concept of composable "upgrades",
it is necessary to wait for protocol negotiation between upgrades
to complete.
* Clarify docs. Simplify listener upgrades.
Since reading from a Negotiated I/O stream implicitly flushes any pending
negotiation data, there is no pitfall involved in not waiting for completion.
* Rename RawSwarm* to Network*.
To complete the cut performed in [1].
The only remaining mention of a "swarm" in libp2p-core is in some tests
which actually depend on libp2p-swarm.
[1]: https://github.com/libp2p/rust-libp2p/pull/1188
* Post-merge corrections.
* Fix connection & handler shutdown when using `KeepAlive::Now`.
Delay::new(Instant::now()) is never immediately ready, resulting in
`KeepAlive::Now` to have no effect, since the delay is re-created on
every execution of `poll()` in the `NodeHandlerWrapper`. It can also
send the node handler into a busy-loop, since every newly
created Delay will trigger a task wakeup, which creates a new Delay
with Instant::now(), and so forth.
The use of `Delay::new(Instant::now())` for "immediate" connection shutdown
is therefore removed here entirely. An important assumption is thereby
that as long as the node handler non-empty `negotiating_in` and `negotiating_out`,
the handler is not dependent on such a Delay for task wakeup.
* Trigger CI.
* libp2p-ping improvements.
* re #950: Removes use of the `OneShotHandler`, but still sending each
ping over a new substream, as seems to be intentional since #828.
* re #842: Adds an integration test that exercises the ping behaviour through
a Swarm, requiring the RTT to be below a threshold. This requires disabling
Nagle's algorithm as it can interact badly with delayed ACKs (and has been
observed to do so in the context of the new ping example and integration test).
* re #864: Control of the inbound and outbound (sub)stream protocol upgrade
timeouts has been moved from the `NodeHandlerWrapperBuilder` to the
`ProtocolsHandler`. That may also alleviate the need for a custom timeout
on an `OutboundSubstreamRequest` as a `ProtocolsHandler` is now free to
adjust these timeouts over time.
Other changes:
* A new ping example.
* Documentation improvements.
* More documentation improvements.
* Add PingPolicy and ensure no event is dropped.
* Remove inbound_timeout/outbound_timeout.
As per review comment, the inbound timeout is now configured
as part of the `listen_protocol` and the outbound timeout as
part of the `OutboundSubstreamRequest`.
* Simplify and generalise.
Generalise `ListenProtocol` to `SubstreamProtocol`, reusing it in
the context of `ProtocolsHandlerEvent::OutboundSubstreamRequest`.
* Doc comments for SubstreamProtocol.
* Adapt to changes in master.
* Relax upper bound for ping integration test rtt.
For "slow" CI build machines?
Replace the listener and address pair returned from `Transport::listen_on` with just a listener that produces `ListenerEvent` values which include upgrades as well as address changes.
* 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.
* Fix the dialing priority system
* Bump libp2p-core to 0.3.1
* Cancel dialing attempt if we don't have priority
* Add test for simultaneous dialing
* Improve test
* Fix test stuck forever
* The SwarmFuture is now a Stream
* Return the produced future in the message
* Remove IncomingConnection event
* Pass error when failing to dial
* Fix loop break mistake
* Fix concern
* Rename SwarmFuture to SwarmEvents
* Increase type length limit
* Remove todo
* Stronger typing for the swarm handler future
* The swarm future is now a swarm stream of events
* Rewrite StreamMuxer in core
* Update libp2p_mplex for the new stream muxer
* Update yamux for new stream muxer
* Rewrite multiplex
* Increase the packet size limit to 32 MB
* Fix waiting for poll_complete to finish
* Typo
* Properly close substreams
* Add a limit to the number of substreams
* Add a limit to the length of the internal buffer
* Fix concerns