Remove `NotifyHandler::All` thus removing the requirement for events
send from a `NetworkBehaviour` to a `ProtocolsHandler` to be `Clone`. An
implementor of `NetworkBehaviour` can still notify all
`ProtocolHandler`s for a given peer by emitting one `NotifyHandler`
event per connection to that peer.
Commit 335e55e6 removed the `ConnectionInfo` trait in favor of
`PeerId`s. Commit 1bd013c8 removed `ExpandedSwarm::connection_info` as
it would only return the `PeerId` that the caller is already aware of.
One could use `ExpandedSwarm::connection_info` not only to retrieve the
`ConnectionInfo` for a given peer, but also to check whether the
underlying `Network` has a connection to the peer.
This commit exposes the `is_connected` method on `Network` via
`ExpandedSwarm` to check whether the `Network` has an established
connection to a given peer.
* Refactor and extend configurable connection limits.
To better track different connection counts, permit configurable
limits for these counts and make these available for
inspection efficiently, introduce dedicated connection counters
via a `ConnectionCounters` structure that is exposed on the
API via the `NetworkInfo`. All connection or connection
states that are counted in this way can also have effective
configurable limits.
* Cleanup
* Add missing file.
* Refine naming and config API.
* Update core/CHANGELOG.md
Co-authored-by: Max Inden <mail@max-inden.de>
* Update core/CHANGELOG.md
Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Max Inden <mail@max-inden.de>
* Add "infinite" scores for external addresses.
Extend address scores with an infinite cardinal, permitting
addresses to be retained "forever" or until explicitly removed.
Expose (external) address scores on the API.
* Update swarm/src/registry.rs
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
* Fix compilation.
* Update CHANGELOG
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
* feat: upgrade to multihash 0.13
`multihash` changes a lot internally, it is using stack allocation instead
of heap allocation. This leads to a few limitations in regards on how
`Multihash` can be used.
Therefore `PeerId` is now using a `Bytes` internally so that only minimal
changes are needed.
* Update versions and changelogs.
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
Co-authored-by: Roman S. Borschel <roman@parity.io>
In all cases, we pass the PeerId directly as the connection info.
The flexbility of doing something different here was originally
envisioned but turned out to be never needed.
For reference see: https://github.com/libp2p/rust-libp2p/issues/1798#issuecomment-714526056
Co-authored-by: Max Inden <mail@max-inden.de>
> Futures managed by FuturesUnordered will only be polled when they
generate wake-up notifications. This reduces the required amount of work
needed to poll large numbers of futures.
https://docs.rs/futures/0.3.5/futures/stream/struct.FuturesUnordered.html
Instead of iterating each inbound and outbound upgrade looking for one
to make progress, use a `FuturesUnordered` for both pending inbound and
pending outbound upgrades. As a result only those upgrades are polled
that are ready to progress.
* [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.
* Implement ProtocolsHandler methods in wrappers.
This PR forwards calls to some ProtocolsHandler methods that were
previously not implemented in wrappers such as `MapInEvent`.
It is unclear though how this can be implemented in some handlers
such as `MultiHandler` as the information at hand does not enable
it to decide which handler to forward the call to.
* Add `MultiHandler::inject_listen_ugrade_error`.
* swarm/one_shot: Add test for not keeping alive idle connection
A `OneShotHandler` without any ongoing requests should not keep the
underlying connection alive indefinitely.
* swarm/one_shot: Initialize handler with KeepAlive::Until
The `OneShotHandler` `keep_alive` property is altered on incoming and
outgoing reqeusts. By default it is initialized in `KeepAlive::Yes`. In
case there are no incoming or outgoing requests happening, this state is
never changed and thus the handler keeps the underlying connection alive
indefinitely.
With this commit the handler is initialized with `KeepAlive::Until`. As
before the `keep_alive` timer is updated on incoming requests and set to
`KeepAlive::Yes` on outgoing requests.
* swarm/one_shot: Move KeepAlive logic to poll
A `ProtocolsHandler` can be created before the underlying connection is
established. Thus setting a keep alive timeout might be problematic.
Instead set `keep_alive` to `Yes` at construction and alter it within
`ProtocolsHandler::poll`.
* swarm/CHANGELOG: Add entry for OneShotHandler keep-alive
* Use a single exchange instead of two one_shots.
* Add `Throttled` to libp2p-request-response.
Wraps the existing `RequestResponse` behaviour and applies strict limits
to the number of inbound and outbound requests per peer.
The wrapper is opt-in and if not used, the protocol behaviour of
`RequestResponse` does not change. This PR also does not introduce
an extra protocol, hence the limits applied need to be known a priori
for all nodes which is not always possible or desirable. As mentioned
in #1687 I think that we should eventually augment the protocol with
metadata which allows a more dynamic exchange of requests and responses.
This PR also replaces the two oneshot channels with a single one from the
scambio crate which saves one allocation per request/response. If not
desirable because the crate has seen less testing the first commit could
be reverted.
* Fix rustdoc error.
* Remove some leftovers from development.
* Add docs to `NetworBehaviourAction::{map_in,map_out}`.
* Apply suggestions from code review
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Add `ping_protocol_throttled` test.
* Add another test.
* Revert "Use a single exchange instead of two one_shots."
This reverts commit e34e1297d411298f6c69e238aa6c96e0b795d989.
# Conflicts:
# protocols/request-response/Cargo.toml
# protocols/request-response/src/handler/protocol.rs
* Update CHANGELOG.
* Update CHANGELOG.
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Emit events for active connection close and fix `disconnect()`.
The `Network` does currently not emit events for actively
closed connections, e.g. via `EstablishedConnection::close`
or `ConnectedPeer::disconnect()`. As a result, when actively
closing connections, there will be `ConnectionEstablished`
events emitted without eventually a matching `ConnectionClosed`
event. This seems undesirable and has the consequence that
the `Swarm::ban_peer_id` feature in `libp2p-swarm` does not
result in appropriate calls to `NetworkBehaviour::inject_connection_closed`
and `NetworkBehaviour::inject_disconnected`. Furthermore,
the `disconnect()` functionality in `libp2p-core` is currently
broken as it leaves the `Pool` in an inconsistent state.
This commit does the following:
1. When connection background tasks are dropped
(i.e. removed from the `Manager`), they
always terminate immediately, without attempting
an orderly close of the connection.
2. An orderly close is sent to the background task
of a connection as a regular command. The
background task emits a `Closed` event
before terminating.
3. `Pool::disconnect()` removes all connection
tasks for the affected peer from the `Manager`,
i.e. without an orderly close, thereby also
fixing the discovered state inconsistency
due to not removing the corresponding entries
in the `Pool` itself after removing them from
the `Manager`.
4. A new test is added to `libp2p-swarm` that
exercises the ban/unban functionality and
places assertions on the number and order
of calls to the `NetworkBehaviour`. In that
context some new testing utilities have
been added to `libp2p-swarm`.
This addresses https://github.com/libp2p/rust-libp2p/issues/1584.
* Update swarm/src/lib.rs
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Incorporate some review feedback.
* Adapt to changes in master.
* More verbose panic messages.
* Simplify
There is no need for a `StartClose` future.
* Fix doc links.
* Further small cleanup.
* Update CHANGELOGs and versions.
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Ignore a node's own addresses on dialing.
Dialing attempts of a local node to one of its own
addresses for what appears to be a different peer
ID are futile and bound to fail with an `InvalidPeerId`
error. To avoid such futile dialing attempts, filter
out the node's own addresses from the addresses
reported by the `NetworkBehaviour` for any peer.
There can be a few reasons why a `NetworkBehaviour` may
think an address belongs to a different peer, e.g.:
1. In the context of e.g. `libp2p-kad`, the local node
may have changed its network identity (e.g. key rotation)
and "discovers" its former identity in the DHT, with the same
address(es).
2. Another peer may erroneously or intentionally, possibly even maliciously,
report one of the local node's addresses as its own, making the node
try to connect to itself.
Relates to https://github.com/paritytech/stakingops-issues/issues/18.
* Remove filtering of external addresses.
Since these are obtained from other peers, it would constitute
an attack vector. It is furthermore usually not possible for
a peer behind a NAT to dial its own external address so these
are unlikely to cause `InvalidPeerId` errors as a result of a
peer dialing itself under the expectation of one of its
former peer IDs.
* Allow users to opt-out of the NetworkBehaviourEventProcess mechanism
* Add CHANGELOG entry
* Prepare release.
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
Co-authored-by: Roman S. Borschel <roman@parity.io>
* 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>
* Add the libp2p-request-response protocol.
This crate provides a generic implementation for request/response
protocols, whereby each request is sent on a new substream.
* Fix OneShotHandler usage in floodsub.
* Custom ProtocolsHandler and multiple protocols.
1. Implement a custom ProtocolsHandler instead of using
the OneShotHandler for better control and error handling.
In particular, all request/response sending/receiving is
kept in the substreams upgrades and thus the background
task of a connection.
2. Support multiple protocols (usually protocol versions)
with a single `RequestResponse` instance, with
configurable inbound/outbound support.
* Small doc clarification.
* Remove unnecessary Sync bounds.
* Remove redundant Clone constraint.
* Update protocols/request-response/Cargo.toml
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Update dev-dependencies.
* Update Cargo.tomls.
* Add changelog.
* Remove Sync bound from RequestResponseCodec::Protocol.
Apparently the compiler just needs some help with the scope
of borrows, which is unfortunate.
* Try async-trait.
* Allow checking whether a ResponseChannel is still open.
Also expand the commentary on `send_response` to indicate that
responses may be discard if they come in too late.
* Add `RequestResponse::is_pending`.
As an analogue of `ResponseChannel::is_open` for outbound requests.
* Revert now unnecessary changes to the OneShotHandler.
Since `libp2p-request-response` is no longer using it.
* Update CHANGELOG for libp2p-swarm.
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Make the number of events buffered to/from tasks configurable
* Assign a PR number
* Fix comment
* Apply suggestions from code review
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Rename variables
* Apply suggestions from code review
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
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.
* Pass the error to inject_listener_closed method
If there is an error when the listener closes, found in the
`NetworkEvent::ListenerClosed` `reason` field, we would like to pass it
on to the `inject_listener_closed()` method so that implementors of this
method have access to it.
Add an error parameter to `inject_listener_closed`. Convert the
`reason` field from a `Result` to an `Option` and if there is an error
pass `Some(error)` at the method call site.
* Pass 'reason' as a Result
* Finish change
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
* [libp2p-swarm] Make the multiple connections per peer first-class.
This commit makes the notion of multiple connections per peer
first-class in the API of libp2p-swarm, introducing the new
callbacks `inject_connection_established` and
`inject_connection_closed`. The `endpoint` parameter from
`inject_connected` and `inject_disconnected` is removed,
since the first connection to open may not be the last
connection to close, i.e. it cannot be guaranteed,
as was previously the case, that the endpoints passed
to these callbacks match up.
* Have identify track all addresses.
So that identify requests can be answered with the correct
observed address of the connection on which the request
arrives.
* Cleanup
* Cleanup
* Improve the `Peer` state API.
* Remove connection ID from `SwarmEvent::Dialing`.
* Mark `DialPeerCondition` non-exhaustive.
* Re-encapsulate `NetworkConfig`.
To retain the possibility of not re-exposing all
network configuration choices, thereby providing
a more convenient API on the \`SwarmBuilder\`.
* Rework Swarm::dial API.
* Update CHANGELOG.
* Doc formatting tweaks.