49 Commits

Author SHA1 Message Date
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 Coratger
a4450d41c0
feat(dcutr): keep connection alive while we are using it
Similar to #3876, we now compute `connection_keep_alive` based on whether we are still using the connection, applied to the `dcutr` protocol.

Related: https://github.com/libp2p/rust-libp2p/issues/3844.

Pull-Request: #3960.
2023-06-04 07:43:01 +00:00
Thomas Coratger
87e863e8c9
refactor(dcutr): remove direct::Handler
With recent refactorings in `libp2p-swarm`, there is no more need for `handler::direct` at all.

Resolves #4013.

Pull-Request: #4016.
2023-06-01 04:34:28 +00:00
Arpan Kapoor
5321a4479b
fix(dcutr): always check for relayed connection first
For a non-relay connection, check if it corresponds to a direct connection upgrade.

As discussed in #3964.

Pull-Request: #3982.
2023-05-31 01:14:10 +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 Coratger
b655e84d06
refactor(dcutr): fix typo in observed_addreses
Pull-Request: #3962.
2023-05-18 18:44:25 +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
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
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
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
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
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
Hannes
cacfb59781
chore(dcutr): remove deprecated items
Removes deprecated items from `libp2p-dcutr`.

Related https://github.com/libp2p/rust-libp2p/issues/3647

Pull-Request: #3700.
2023-05-02 13:30:04 +00:00
Thomas Eizinger
66466c43af
refactor(dcutr): don't use OutboundOpenInfo
In a previous refactoring, we actually removed the usage of this openinfo so this is just removing dead code.

Related: #3268.

Pull-Request: #3762.
2023-04-28 11:33:31 +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
Thomas Eizinger
dcbc04e89e
feat(swarm): rename NetworkBehaviourAction to ToSwarm
Resolves #3123.

Pull-Request: #3658.
2023-03-24 13:43:49 +00:00
Thomas Eizinger
2a14df25eb
feat: introduce libp2p-identity crate
This patch combines the `libp2p_core::identity` and `libp2p_core::peer_id` modules into a new crate: `libp2p-identity`.

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

Pull-Request: #3350.
2023-03-12 15:46:58 +01:00
Miguel Guarniz
db82e0210e
feat: migrate to quick-protobuf
Instead of relying on `protoc` and buildscripts, we generate the bindings using `pb-rs` and version them within our codebase. This makes for a better IDE integration, a faster build and an easier use of `rust-libp2p` because we don't force the `protoc` dependency onto them.

Resolves #3024.

Pull-Request: #3312.
2023-03-02 10:45:07 +00:00
Thomas Eizinger
19a554965f
feat(swarm)!: allow NetworkBehaviours to manage connections
Previously, a `ConnectionHandler` was immediately requested from the `NetworkBehaviour` as soon as a new dial was initiated or a new incoming connection accepted.

With this patch, we delay the creation of the handler until the connection is actually established and fully upgraded, i.e authenticated and multiplexed.

As a consequence, `NetworkBehaviour::new_handler` is now deprecated in favor of a new set of callbacks:

- `NetworkBehaviour::handle_pending_inbound_connection`
- `NetworkBehaviour::handle_pending_outbound_connection`
- `NetworkBehaviour::handle_established_inbound_connection`
- `NetworkBehaviour::handle_established_outbound_connection`

All callbacks are fallible, allowing the `NetworkBehaviour` to abort the connection either immediately or after it is fully established. All callbacks also receive a `ConnectionId` parameter which uniquely identifies the connection. For example, in case a `NetworkBehaviour` issues a dial via `NetworkBehaviourAction::Dial`, it can unambiguously detect this dial in these lifecycle callbacks via the `ConnectionId`.

Finally, `NetworkBehaviour::handle_pending_outbound_connection` also replaces `NetworkBehaviour::addresses_of_peer` by allowing the behaviour to return more addresses to be used for the dial.

Resolves #2824.

Pull-Request: #3254.
2023-02-23 23:43:33 +00:00
Thomas Eizinger
caed1fe2c7
refactor(swarm)!: remove handler from NetworkBehaviourAction::Dial (#3328)
We create the `ConnectionId` for the new connection as part of `DialOpts`. This allows `NetworkBehaviour`s to accurately track state regarding their own dial attempts.

This patch is the main enabler of https://github.com/libp2p/rust-libp2p/pull/3254. Removing the `handler` field will allow us to deprecate the `NetworkBehaviour::new_handler` function in favor of four new ones that give more control over the connection lifecycle.
2023-02-14 01:09:29 +00:00
Thomas Eizinger
4de54f00f9
refactor: expose and use THandlerOutEvent type alias (#3368)
Previously, we used the full reference to the `OutEvent` of the `ConnectionHandler` in all implementations of `NetworkBehaviour`. Not only is this very verbose, it is also more brittle to changes. With the current implementation plan for #2824, we will be removing the `IntoConnectionHandler` abstraction. Using a type-alias to refer to the `OutEvent` makes the migration much easier.
2023-01-26 11:55:02 +00:00
Thomas Eizinger
4b41f5a994
refactor(core)!: remove EitherOutput (#3341)
The trick with this one is to use `futures::Either` everywhere where we may wrap something that implements any of the `futures` traits. This includes the output of `EitherFuture` itself. We also need to implement `StreamMuxer` on `future::Either` because `StreamMuxer`s may be the the `Output` of `InboundUpgrade`.
2023-01-23 12:31:30 +00:00
Thomas Eizinger
475dc80a07
refactor!: Move ConnectionId and PendingPoint to libp2p-swarm (#3346)
Both of these are only needed as part of `libp2p-swarm`. Them residing in `libp2p-core` is a left-over from when `libp2p-core` still contained `Pool`.
2023-01-18 08:56:32 +00:00
Thomas Eizinger
db2cd43826
refactor(core)!: remove EitherUpgrade (#3339)
We don't need to define our own type here, we can simply implement `UpgradeInfo`, `InboundUpgrade` and `OutboundUpgrade` on `either::Either`.
2023-01-18 02:35:07 +00:00
Thomas Eizinger
f4fed3880b
refactor(core)!: remove EitherError in favor of either::Either (#3337)
Defining our own `EitherError` type has no value now that `Either` provides the same implementation.

Related: https://github.com/libp2p/rust-libp2p/issues/3271
2023-01-17 23:05:59 +00:00
João Oliveira
4c65c7d7c7
refactor(swarm): remove deprecated inject calls (#3264)
Finishes work first started with https://github.com/libp2p/rust-libp2p/issues/2832
2023-01-12 11:21:02 +00:00
Max Inden
3cc824796d
fix(dcutr): Skip unparsable multiaddr (#3320)
With this commit `libp2p-dcutr` no longer discards the whole remote payload in case an addr is unparsable, but instead logs the failure and skips the unparsable multiaddr.

See https://github.com/libp2p/rust-libp2p/issues/3244 for details.
2023-01-12 08:46:31 +00:00
João Oliveira
20ce07c7d3
refactor(dcutr): remove ActionBuilder. (#3304)
addresses #3299
2023-01-10 03:43:59 +00:00
Elena Frank
30640968ac
fix: typo in ExternalAddresses::on_swarm_event (#3297)
Fix typo `swarn` -> `swarm`.
2023-01-04 16:41:34 +00:00
Thomas Eizinger
93335b8818
refactor(dcutr): reshape public API to follow naming guidelines (#3214)
With this patch, the naming of types follows the guidelines discussed in #2217.
2022-12-20 05:03:40 +00:00
Thomas Eizinger
be3ec6c62b
refactor(swarm)!: deprecate PollParameters where possible (#3153)
This patch deprecates 3 out of 4 functions on `PollParameters`:

- `local_peer_id`
- `listened_addresses`
- `external_addresses`

The addresses can be obtained by inspecting the `FromSwarm` event. To make this easier, we introduce two utility structs in `libp2p-swarm`:

- `ExternalAddresses`
- `ListenAddresses`

A node's `PeerId` is always known to the caller, thus we can require them to pass it in.

Related: #3124.
2022-12-14 00:50:08 +00:00
Thomas Eizinger
bffe4153bc
fix(dcutr): rename error types to bypass cargo-semver-checks hickup (#3213)
`cargo semver-checks` is still missing features in regards to properly detecting renamed exports. To make our CI pass again, we remove the renamed export, replace it with type-aliases and deprecate them to point users types exported under a module which now follows the conventions set in #2217.
2022-12-13 04:14:57 +00:00
Thomas Eizinger
0c85839dab
.github/workflows: Refactor CI jobs (#3090)
We refactor our continuous integration workflow with the following goals in mind:

- Run as few jobs as possible
- Have the jobs finish as fast as possible
- Have the jobs redo as little work as possible

There are only so many jobs that GitHub Actions will run in parallel.
Thus, it makes sense to not create massive matrices but instead group
things together meaningfully.

The new `test` job will:

- Run once for each crate
- Ensure that the crate compiles on its specified MSRV
- Ensure that the tests pass
- Ensure that there are no semver violations

This is an improvement to before because we are running all of these
in parallel which speeds up execution and highlights more errors at
once. Previously, tests run later in the pipeline would not get run
at all until you make sure the "first" one passes.

We also previously did not verify the MSRV of each crate, making the
setting in the `Cargo.toml` rather pointless.

The new `cross` job supersedes the existing `wasm` job.

This is an improvement because we now also compile the crate for
windows and MacOS. Something that wasn't checked before.
We assume that checking MSRV and the tests under Linux is good enough.
Hence, this job only checks for compile-errors.

The new `feature_matrix` ensures we compile correctly with certain feature combinations.

`libp2p` exposes a fair few feature-flags. Some of the combinations
are worth checking independently. For the moment, this concerns only
the executor related transports together with the executor flags but
this list can easily be extended.

The new `clippy` job runs for `stable` and `beta` rust.

Clippy gets continuously extended with new lints. Up until now, we would only
learn about those as soon as a new version of Rust is released and CI would
run the new lints. This leads to unrelated failures in CI. Running clippy on with `beta`
Rust gives us a heads-up of 6 weeks before these lints land on stable.

Fixes #2951.
2022-11-18 11:04:16 +00:00
João Oliveira
7803524a76
swarm/handler: replace inject_* methods (#3085)
Previously, we had one callback for each kind of message that a `ConnectionHandler` would receive from either its `NetworkBehaviour` or the connection itself.

With this patch, we combine these functions, resulting in two callbacks:

- `on_behaviour_event`
- `on_connection_event`

Resolves #3080.
2022-11-17 17:19:36 +00:00
João Oliveira
3df3c88f3d
swarm/behaviour: Replace inject_* with on_event (#3011) 2022-11-17 09:28:40 +00:00
Thomas Eizinger
71131e0622
*: Don't leak prost dependency in error types (#3058)
With the current design, a major version bump of `prost` leaks into
all consumers of `prost-codec`.
2022-11-02 12:02:21 +00:00
Hannes
fcadc83aca
*: Use auto_doc_cfg instead of doc(cfg) attributes (#2983)
Co-authored-by: João Oliveira <hello@jxs.pt>
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2022-10-24 13:00:20 +11:00
Thomas Eizinger
eb10af7a4b
protocols/{relay,dcutr}: Replace std::time::SystemTime with instant::SystemTime (#2991) 2022-10-12 14:09:47 +01:00
Thomas Eizinger
bdf9209824
swarm: Split off "keep alive" functionality from DummyConnectionHandler (#2859)
Previously, the `DummyConnectionHandler` offered a "keep alive" functionality,
i.e. it allowed users to set the value of what is returned from
`ConnectionHandler::keep_alive`. This handler is primarily used in tests or
`NetworkBehaviour`s that don't open any connections (like mDNS). In all of these
cases, it is statically known whether we want to keep connections alive. As
such, this functionality is better represented by a static
`KeepAliveConnectionHandler` that always returns `KeepAlive::Yes` and a
`DummyConnectionHandler` that always returns `KeepAlive::No`.

To follow the naming conventions described in
https://github.com/libp2p/rust-libp2p/issues/2217, we introduce a top-level
`keep_alive` and `dummy` behaviour in `libp2p-swarm` that contains both the
`NetworkBehaviour` and `ConnectionHandler` implementation for either case.
2022-10-05 17:50:11 +01:00
Elena Frank
06aaea67f3
*: Fix clippy::derive-partial-eq-without-eq (#2818) 2022-08-14 04:03:04 +02:00
Elena Frank
09c690862e
protocols/dcutr: Fix clippy lints (#2772) 2022-07-28 03:04:36 +02:00
Max Inden
d4f8ec2d48
misc/metrics: Track # connected nodes supporting specific protocol (#2734)
* misc/metrics: Explicitly delegate event recording to each recorder

This allows delegating a single event to multiple `Recorder`s. That enables e.g. the
`identify::Metrics` `Recorder` to act both on `IdentifyEvent` and `SwarmEvent`. The latter enables
it to garbage collect per peer data on disconnects.

* protocols/dcutr: Expose PROTOCOL_NAME

* protocols/identify: Expose PROTOCOL_NAME and PUSH_PROTOCOL_NAME

* protocols/ping: Expose PROTOCOL_NAME

* protocols/relay: Expose HOP_PROTOCOL_NAME and STOP_PROTOCOL_NAME

* misc/metrics: Track # connected nodes supporting specific protocol

An example metric exposed with this patch:

```
libp2p_identify_protocols{protocol="/ipfs/ping/1.0.0"} 10
```

This implies that 10 of the currently connected nodes support the ping protocol.
2022-07-15 09:16:03 +02:00
Max Inden
59a74b4083
protocols/dcutr: Upgrade at most one inbound connect request (#2695)
Sending two concurrent connect requests is nonsensical. In the case where a
remote sends two, the earlier is dropped in favor of the latter.
2022-06-07 14:52:35 +02:00
Max Inden
bbd2f8f009
misc/prost-codec: Introduce codec for varint prefixed Protobuf messages (#2630)
Extracts the Protobuf en-/decoding pattern into its separate crate
and applies it to `libp2p-identify`.
2022-05-05 18:28:47 +02:00
Max Inden
4d796fdca1
protocols/{dcutr,relay}: Expose error types (#2605)
Co-authored-by: canewsin <canews.in@gmail.com>
2022-04-04 11:32:54 +02:00
Max Inden
fd2be38faf
swarm/: Rename ProtocolsHandler to ConnectionHandler (#2527)
A `ProtocolsHandler`, now `ConnectionHandler`, handels a connection, not
a protocol. Thus the name `CONNECTIONHandler` is more appropriate.

Next to the rename of `ProtocolsHandler` this commit renames the `mod
protocols_handler` to `mod handler`. Finally all combinators (e.g.
`ProtocolsHandlerSelect`) are renamed appropriately.
2022-02-21 13:32:24 +01:00
Divma
dc8433e3fc
swarm/src/behaviour: Merge inject_* paired methods (#2445)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-02-09 16:08:28 +01:00
Max Inden
0bb8ee98d5
protocols/: Implement Direct Connection Upgrade through Relay (DCUtR) (#2438)
Enables two peers to coordinate a hole punch (direct connection upgrade)
via a relayed connection.

See https://github.com/libp2p/specs/blob/master/relay/DCUtR.md for
specification.
2022-02-08 15:56:35 +01:00