324 Commits

Author SHA1 Message Date
Darius Clark
c2230f9948
feat(swarm): allow NetworkBehaviours to create and remove listeners
This extends `ToSwarm` to add `ToSwarm::ListenOn` and `ToSwarm::RemoveListener`, which allows creating and removing listeners from a `NetworkBehaviour`.

Resolves https://github.com/libp2p/rust-libp2p/issues/3291.

Pull-Request: #3292.
2023-06-09 01:34:33 +00:00
Thomas Eizinger
ed14630672
feat: leverage type-safe /p2p in multiaddr
This updates `multiaddr` to version `0.19`.

Depends-On: #3656.
Depends-On: https://github.com/multiformats/rust-multiaddr/pull/83.
Resolves: #4039.

Pull-Request: #4037.
2023-06-08 01:38:18 +00:00
Thomas Eizinger
61128713eb
feat(core): remove deprecated identity module
Related: #3647.

Pull-Request: #4040.
2023-06-06 19:22:50 +00:00
Thomas Eizinger
2f8e1489c9
fix(swarm): make test not flaky
In the unlikely event that we generated a random number twice, the 2nd address would not get added. Ensure we loop until we have 20 addresses.

Pull-Request: #4030.
2023-06-05 20:37:06 +00:00
Thomas Eizinger
1d3db7d9a8
fix(core): remove UpgradeError from public API
Not making this private was an oversight from an earlier refactoring.

Related: #3915.

Pull-Request: #4012.
2023-06-05 15:16:04 +00:00
dependabot[bot]
49eed8c4fd
deps: bump once_cell from 1.17.1 to 1.18.0
Pull-Request: #4026.
2023-06-05 10:41:11 +00:00
Thomas Eizinger
92c8cc451f
feat(kad): implement automatic client mode
Currently, the kademlia behaviour can only learn that the remote node supports kademlia on a particular connection if we successfully negotiate a stream to them.

Using the newly introduced abstractions from #3651, we don't have to attempt to establish a stream to the remote to learn whether they support kademlia on a connection but we can directly learn it from the `ConnectionEvent::RemoteProtocolsChange` event. This happens directly once a connection is established which should overall benefit the DHT.

Clients do not advertise the kademlia protocol and thus we will immediately learn that a given connection is not suitable for kadmelia requests. We may receive inbound messages from it but this does not affect the routing table.

Resolves: #2032.

Pull-Request: #3877.
2023-05-31 09:02:19 +00:00
Onur
801023f468
feat(gossipsub): allow compiling for WASM
This modification removes deprecated dependency `wasm_timer` and enables wasm compatibility on the gossibsup protocol by simply substituting the `wasm_timer::Instant` with `instant::Instant`(which supports `fn checked_add`) and `wasm_timer::Interval` with `futures_ticker::Ticker`.

Pull-Request: #3973.
2023-05-25 06:19:47 +00:00
Thomas Coratger
6329d74334
feat(swarm): remove deprecated items
Related: https://github.com/libp2p/rust-libp2p/issues/3647.

Pull-Request: #3956.
2023-05-24 14:32:59 +00:00
Thomas Eizinger
25bc30f07e
feat(ping): don't close connections upon failures
Previously, the `libp2p-ping` module came with a policy to close a connection after X failed pings. This is only one of many possible policies on how users would want to do connection management.

We remove this policy without a replacement. If users wish to restore this functionality, they can easily implement such policy themselves: The default value of `max_failures` was 1. To restore the previous functionality users can simply close the connection upon the first received ping error.

In this same patch, we also simplify the API of `ping::Event` by removing the layer of `ping::Success` and instead reporting the RTT to the peer directly.

Related: #3591.

Pull-Request: #3947.
2023-05-24 12:33:18 +00:00
Thomas Eizinger
5e8f2e82e4
feat(swarm): replace address scoring with explicit candidates
Previously, a `NetworkBehaviour` could report an `AddressScore` for an external address. This score was a `u32` and addresses would be ranked amongst those.

In reality, an address is either confirmed to be publicly reachable (via a protocol such as AutoNAT) or merely represents a candidate that might be an external address. In a way, addresses are guilty (private) until proven innocent (publicly reachable).

When a `NetworkBehaviour` reports an address candidate, we perform address translation on it to potentially correct for ephemeral ports of TCP. These candidates are then injected back into the `NetworkBehaviour`. Protocols such as AutoNAT can use these addresses as a source for probing their NAT status. Once confirmed, they can emit a `ToSwarm::ExternalAddrConfirmed` event which again will be passed to all `NetworkBehaviour`s.

This simplified approach will allow us implement Kademlia's client-mode (https://github.com/libp2p/rust-libp2p/issues/2032) without additional configuration options: As soon as an address is reported as publicly reachable, we can activate server-mode for that connection.

Related: https://github.com/libp2p/rust-libp2p/pull/3877.
Related: https://github.com/libp2p/rust-libp2p/issues/3953.
Related: https://github.com/libp2p/rust-libp2p/issues/2032.
Related: https://github.com/libp2p/go-libp2p/issues/2229.

Co-authored-by: Max Inden <mail@max-inden.de>

Pull-Request: #3954.
2023-05-24 07:52:16 +00:00
Thomas Eizinger
a424310d60
fix(swarm): poll handler after injecting LocalProtocolsChange event
Previously, we would not call the handler upon injecting `ConnectionEvent::LocalProtocolsChange`. This would prevent protocols from being able to react to this change and e.g. issue events or open streams.

Pull-Request: #3979.
2023-05-24 06:25:05 +00:00
dependabot[bot]
61725ca772
deps: bump wasm-bindgen-futures from 0.4.35 to 0.4.36
Pull-Request: #3968.
2023-05-22 19:28:36 +00:00
Max Inden
cc5b346a7c
feat(swarm): expose ConnectionId and add conn duration metric
- Exposes the `ConnectionId` in the various `SwarmEvent` variants.
- Tracks connection duration in `libp2p-metrics::swarm`.

Pull-Request: #3927.
2023-05-17 05:19:53 +00:00
Thomas Coratger
9f3c85164c
feat(swarm): rename Custom variant to NotifyBehaviour
Rename `ConnectionHandlerEvent::Custom` to `ConnectionHandlerEvent::NotifyBehaviour`.

Related #3848.

Pull-Request: #3955.
2023-05-16 19:20:00 +00:00
dependabot[bot]
86ea8fe4aa
deps: bump wasm-bindgen-futures from 0.4.34 to 0.4.35
Pull-Request: #3935.
2023-05-15 17:08:16 +00:00
Thomas Eizinger
adcc10b841
refactor(swarm-derive): better error reporting for invalid attributes
This PR refactors the error reporting away from panicking to returning `syn::Result` and adds two unit tests for the parsing of attributes that users interact with.

Pull-Request: #3922.
2023-05-15 12:15:14 +00:00
Thomas Eizinger
a00daca5fa
refactor(swarm-derive): improve warning message
Pull-Request: #3921.
2023-05-14 13:12:06 +00:00
Thomas Eizinger
38c08049e2
feat(swarm): remove deprecated NetworkBehaviourAction type
Pull-Request: #3919.
2023-05-14 11:23:49 +00:00
Thomas Coratger
6e36e8aa35
feat(swarm): rename associated types for message passing
Previously, the associated types on `NetworkBehaviour` and `ConnectionHandler` carried generic names like `InEvent` and `OutEvent`. These names are _correct_ in that `OutEvent`s are passed out and `InEvent`s are passed in but they don't help users understand how these types are used.

In theory, a `ConnectionHandler` could be used separately from `NetworkBehaviour`s but that is highly unlikely. Thus, we rename these associated types to indicate, where the message is going to be sent to:

- `NetworkBehaviour::OutEvent` is renamed to `ToSwarm`: It describes the message(s) a `NetworkBehaviour` can emit to the `Swarm`. The user is going to receive those in `SwarmEvent::Behaviour`.
- `ConnectionHandler::InEvent` is renamed to `FromBehaviour`: It describes the message(s) a `ConnectionHandler` can receive from its behaviour via `ConnectionHandler::on_swarm_event`. The `NetworkBehaviour` can send it via the `ToSwarm::NotifyHandler` command.
- `ConnectionHandler::OutEvent` is renamed to `ToBehaviour`: It describes the message(s) a `ConnectionHandler` can send back to the behaviour via the now also renamed `ConnectionHandlerEvent::NotifyBehaviour` (previously `ConnectionHandlerEvent::Custom`)

Resolves: #2854.

Pull-Request: #3848.
2023-05-14 10:58:08 +00:00
Darius Clark
5b32c8a0d2
feat(transport): allow ListenerId to be user-controlled
`Transport::listen_on` is an asynchronous operation. It returns immediately but the actual process of establishing a listening socket happens as part of `Transport::poll` which will return one or more `TransportEvent`s related to a particular `listen_on` call.

Currently, `listen_on` returns a `ListenerId` which allows the user of the `Transport` interface to correlate the events with a particular `listen_on` call. This "user" is the `Swarm` runtime. Currently, a user of libp2p establishes a new listening socket by talking to the `Swarm::listen_on` interface and it is not possible to do the same thing via the `NetworkBehaviour` trait.

Within the `NetworkBehaviour` trait, we emit _commands_ to the `Swarm` like `ToSwarm::Dial`. These commands don't have a "return value" like a synchronous function does and thus, if we were to add a `ToSwarm::ListenOn` command, it could not receive the `ListenerId` from the `Transport`.

To fix this and to be consistent with our [coding guidelines](https://github.com/libp2p/rust-libp2p/blob/master/docs/coding-guidelines.md#allow-correlating-asynchronous-responses-to-their-requests) we change the interface of `Transport::listen_on` to require the user to pass in a `ListenerId`. This will allow us to construct a command in a `NetworkBehaviour` that remembers this ID which enables precise tracking of which events containing a `ListenerId` correlate which a particular `listen_on` command.

This is especially important in the context of listening on wildcard addresses like `0.0.0.0` because we end up binding to multiple network interfaces and thus emit multiple events for a single `listen_on` call.

Pull-Request: #3567.
2023-05-14 09:42:51 +00:00
Thomas Eizinger
9e625881d5
feat(swarm): deprecate NegotiatedSubstream in favor of Stream
This patch tackles two things at once that are fairly intertwined:

1. There is no such thing as a "substream" in libp2p, the spec and other implementations only talk about "streams". We fix this by deprecating `NegotiatedSubstream`.
2. Previously, `NegotiatedSubstream` was a type alias that pointed to a type from `multistream-select`, effectively leaking the version of `multistream-select` to all dependencies of `libp2p-swarm`. We fix this by introducing a `Stream` newtype.

Resolves: #3759.
Related: #3748.

Pull-Request: #3912.
2023-05-12 06:19:23 +00:00
Thomas Eizinger
b035fc80a0
feat: report changes in supported protocols to ConnectionHandler
With this patch, implementations of `ConnectionHandler` (which are typically composed in a tree) can exchange information about the supported protocols of a remote with each other via `ConnectionHandlerEvent::ReportRemoteProtocols`. The provided `ProtocolSupport` enum can describe either additions or removals of the remote peer's protocols.

This information is aggregated in the connection and passed down to the `ConnectionHandler` via `ConnectionEvent::RemoteProtocolsChange`.

Similarly, if the listen protocols of a connection change, all `ConnectionHandler`s on the connection will be notified via `ConnectionEvent::LocalProtocolsChange`. This will allow us to eventually remove `PollParameters` from `NetworkBehaviour`.

This pattern allows protocols on a connection to communicate with each other. For example, protocols like identify can share the list of (supposedly) supported protocols by the remote with all other handlers. A protocol like kademlia can accurately add and remove a remote from its routing table as a result.

Resolves: #2680.
Related: #3124.

Pull-Request: #3651.
2023-05-08 14:36:30 +00:00
Thomas Eizinger
b8a7684153
feat(swarm): remove deprecated connection limits
Users are encouraged to use `libp2p::connection_limit::Behaviour` which is a one-to-one replacement for this functionality but built as a `NetworkBehaviour`.

Related: #3647.

Pull-Request: #3885.
2023-05-08 10:54:53 +00:00
Thomas Eizinger
81c424ea9e
feat(swarm): make stream uprade errors more ergonomic
The currently provided `ConnectionHandlerUpgrErr` is very hard to use. Not only does it have a long name, it also features 3 levels of nesting which results in a lot of boilerplate. Last but not least, it exposes `multistream-select` as a dependency to all protocols.

We fix all of the above by renaming the type to `StreamUpgradeError` and flattening out its interface. Unrecoverable errors during protocol selection are hidden within the `Io` variant.

Related: #3759.

Pull-Request: #3882.
2023-05-08 08:55:17 +00:00
Thomas Eizinger
0e36c7c072
feat(swarm): remove deprecated IntoConnectionHandler
This removes the deprecated `IntoConnectionHandler` trait and all its implementations. Consequently, `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` are now gone and the two `handle_` functions are now required to implement.

Related: #3647.

Pull-Request: #3884.
2023-05-08 08:30:29 +00:00
Thomas Eizinger
b4e724dd72
feat(swarm): remove deprecated banning API
This is replaced by the `libp2p::allow_block_list` module.

Related: #3647.

Pull-Request: #3886.
2023-05-08 05:50:27 +00:00
Thomas Eizinger
53e5370919
feat: don't report inbound stream upgrade errors to handler
When an inbound stream upgrade fails, there isn't a whole lot we can do about that in the handler. In fact, for several errors, we wouldn't even know which specific handler to target, for example, `NegotiationFailed`. Similiarly, in case of an IO error during the upgrade, we don't know which handler the stream was eventually meant to be for.

Pull-Request: #3605.
2023-05-08 04:54:50 +00:00
Thomas Eizinger
eecfe2f094
feat(swarm): report outcome of handling SwarmEvent
Previously, a user wouldn't know whether passing a `SwarmEvent` to `ListenAddresses` or `ExternalAddresses` changed the state. We now return a boolean where `true` indicates that we handled the event **and** changed state as a result.

The API is inspired by `HashSet::insert` and the like.

Pull-Request: #3865.
2023-05-05 07:46:31 +00:00
Thomas Eizinger
c93f753018
feat: replace ProtocolName with AsRef<str>
Previously, a protocol could be any sequence of bytes as long as it started with `/`. Now, we directly parse a protocol as `String` which enforces it to be valid UTF8.

To notify users of this change, we delete the `ProtocolName` trait. The new requirement is that users need to provide a type that implements `AsRef<str>`.

We also add a `StreamProtocol` newtype in `libp2p-swarm` which provides an easy way for users to ensure their protocol strings are compliant. The newtype enforces that protocol strings start with `/`. `StreamProtocol` also implements `AsRef<str>`, meaning users can directly use it in their upgrades.

`multistream-select` by itself only changes marginally with this patch. The only thing we enforce in the type-system is that protocols must implement `AsRef<str>`.

Resolves: #2831.

Pull-Request: #3746.
2023-05-04 04:47:11 +00:00
Thomas Eizinger
996b5c8bd0
chore: leverage cargo's workspace inheritance
Previously, we would specify the version and path of our workspace dependencies in each of our crates. This is error prone as https://github.com/libp2p/rust-libp2p/pull/3658#discussion_r1153278072 for example shows. Problems like these happened in the past too.

There is no need for us to ever depend on a earlier version than the most current one in our crates. It thus makes sense that we manage this version in a single place.

Cargo supports a feature called "workspace inheritance" which allows us to share a dependency declaration across a workspace and inherit it with `{ workspace = true }`.

We do this for all our workspace dependencies and for the MSRV.

Resolves #3787.

Pull-Request: #3715.
2023-05-02 09:14:14 +00:00
Max Inden
2d9ae3800f
chore: prepare patch releases on top of v0.51.3
Note that this does not release v0.51.4, i.e. there is no patch release of the meta crate `libp2p`.

Pull-Request: #3854.
2023-05-01 02:56:32 +00:00
Thomas Eizinger
b1cdf8d4bb
feat(yamux): rename symbols to follow module-based naming convention
Implements our naming convention for the `libp2p-yamux` crate.

Related: #2217.

Pull-Request: #3852.
2023-05-01 02:25:52 +00:00
dependabot[bot]
8a0e61e3ac
deps: bump tokio from 1.27.0 to 1.28.0
Pull-Request: #3834.
2023-04-28 10:49:08 +00:00
Thomas Eizinger
135942d319
chore: enforce unreachable_pub lint
The `unreachable_pub` lint makes us aware of uses of `pub` that are not actually reachable from the crate root. This is considered good because it means reading a `pub` somewhere means it is actually public API. Some of our crates are quite large and keeping their entire API surface in your head is difficult.

We should strive for most items being `pub(crate)`. This lint helps us enforce that.

Pull-Request: #3735.
2023-04-26 07:31:56 +00:00
Victor Ermolaev
96288b8984
fix(gossipsub): gracefully disable handler on stream errors
Previously, we closed the entire connection upon receiving too many upgrade errors. This is unnecessarily aggressive. For example, an upgrade error may be caused by the remote dropping a stream during the initial handshake which is completely isolated from other protocols running on the same connection.

Instead of closing the connection, set `KeepAlive::No`.

Related: #3591.
Resolves: #3690.

Pull-Request: #3625.
2023-04-14 15:19:47 +00:00
dependabot[bot]
7fe2f1cd6d
deps: bump getrandom from 0.2.8 to 0.2.9
Pull-Request: #3751.
2023-04-10 12:54:34 +00:00
dependabot[bot]
17dd72755d
deps: bump tokio from 1.26.0 to 1.27.0
Pull-Request: #3729.
2023-04-05 14:37:42 +00:00
dependabot[bot]
0ff0ef7a35
deps: bump futures from 0.3.27 to 0.3.28
Pull-Request: #3725.
2023-04-03 14:43:42 +00:00
shamil-gadelshin
85bde7eed8
feat(swarm): downgrade connection limits warning from warn to debug
This tiny PR contains a proposed change for the warning related to the exceeded pending incoming connections limit. This warning can't be controlled and causes user confusion. It contains useful technical info but IMHO should be downgraded from `warn` to `debug`.

Pull-Request: #3671.
2023-03-31 10:30:53 +00:00
Max Inden
d7396706d0
fix(changelog): Make release heading levels consistent
See `##` for release headings everywhere. This is consistent with markdown conventions of one `#` per document and in line with https://keepachangelog.com/.

See report in https://github.com/libp2p/rust-libp2p/issues/3531.

Pull-Request: #3561.
2023-03-30 21:04:01 +00:00
Max Inden
486ac8baf2
chore: prepare libp2p v0.51.2
Depends-On: #3693.

Pull-Request: #3694.
2023-03-29 13:04:18 +00:00
Thomas Eizinger
dcbc04e89e
feat(swarm): rename NetworkBehaviourAction to ToSwarm
Resolves #3123.

Pull-Request: #3658.
2023-03-24 13:43:49 +00:00
Thomas Eizinger
f64187049d
feat: introduce libp2p-allow-block-list connection management module
Currently, banning peers is a first-class feature of `Swarm`. With the new connection management capabilities of `NetworkBehaviour`, we can now implement allow and block lists as a separate module.

We introduce a new crate `libp2p-allow-block-list` and deprecate `Swarm::ban_peer_id` in favor of that.

Related #2824.

Pull-Request: #3590.
2023-03-21 20:58:09 +00:00
Thomas Eizinger
3fa10be0d5
feat(swarm): introduce ConnectionId::new_unchecked constructor
In earlier iterations of the design for generic connection management, we removed the `ConnectionId::new` constructor because it would have allowed users to create `ConnectionId`s that are already taken, thus breaking invariants that `NetworkBehaviour`s rely on. Later, we incorporated the creation of `ConnectionId` in `DialOpts` which mitigates this risk altogether.

Thus, it is reasonably safe to introduce a public, non-deprecated constructor for `ConnectionId` that can be used for tests.

Related https://github.com/libp2p/rust-libp2p/pull/3327#issuecomment-1469870307.

Pull-Request: #3652.
2023-03-21 19:28:46 +00:00
Thomas Eizinger
48a70e5102
feat: introduce libp2p-connection-limits connection management module
This patch deprecates the existing connection limits within `Swarm` and uses the new `NetworkBehaviour` APIs to implement it as a plugin instead.

Related #2824.

Pull-Request: #3386.
2023-03-21 15:04:53 +00:00
dependabot[bot]
4f18d0413c
deps: bump syn from 1.0.109 to 2.0.2
Pull-Request: #3645.
2023-03-20 18:22:58 +00:00
Victor Ermolaev
2a18f7a5f0
fix(swarm): gracefully disable oneshot handler on dial upgrade errors
Resolves https://github.com/libp2p/rust-libp2p/issues/3269.

Pull-Request: #3577.
2023-03-13 20:37:59 +00:00
Victor Ermolaev
2ec5402474
feat(swarm): enforce creation of Swarm via SwarmBuilder
Mark constructors `Swarm::with_X_executor` as deprecated.
Move the deprecated functionality to `SwarmBuilder::with_X_executor`
Use `SwarmBuilder` throughout.

Resolves #3186.
Resolves #3107.

Pull-Request: #3588.
2023-03-13 19:53:14 +00:00
dependabot[bot]
9d0ec7e074
deps: bump futures from 0.3.26 to 0.3.27
Pull-Request: #3597.
2023-03-13 11:35:04 +00:00