26 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
Max Inden
7f865448c0
fix(metrics/swarm): correct metric, name and help
Pull-Request: #4014.
2023-05-31 02:10:41 +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 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
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
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
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
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
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
d1336a7d81
feat(swarm)!: introduce ListenError (#3375)
In case an error happens for an outgoing connection, `Pool` reports an `OutgoingConnectionError`. This one is mapped to a `DialError` and reported via `SwarmEvent::OutgoingConnectionError` and `FromSwarm::DialFailure`.

For incoming connections, we didn't quite do the same thing. For one, `SwarmEvent::IncomingConnectionError` directly contained a `PendingInboundConnectionError`. Two, `FromSwarm::ListenFailure` did not include an error at all.

With this patch, we now introduce a `ListenError` enum which we use in `SwarmEvent::IncomingConnectionError` and we pass a reference to it along in `FromSwarm::ListenFailure`.
2023-01-26 23:23:55 +00:00
Thomas Eizinger
14825c7ecb
feat(swarm): remove unused DialError::ConnectionIo variant (#3374)
This variant is never constructed.
2023-01-26 08:10:08 +00:00
Anton
9f7145912a
feat(swarm)!: report connections to our own PeerId in separate error (#3377)
Previously, inbound connections that happened to resolve to our own `PeerId` were reported as `WrongPeerId`. With this patch, we now report those in a dedicated `LocalPeerId` error.

Related: #3205.
2023-01-26 07:20:23 +00:00
Thomas Eizinger
90af08cb59
feat(swarm)!: remove unused PendingConnectionError::Io variant (#3373)
This variant is never constructed.
2023-01-26 05:26:54 +00:00
Max Inden
2621528639
chore(metrics): Upgrade to prometheus-client v0.19.0 (#3207) 2023-01-03 19:42:32 +00:00
Thomas Eizinger
5782a96af2
refactor(swarm)!: don't be generic over Transport (#3272)
Ever since we moved `Pool` into `libp2p-swarm`, we always use it with the same `Transport`: `Boxed`. It is thus unnecessary for us to be overly generic over what kind of `Transport` we are using. This allows us to remove a few type parameters from the implementation which overall simplifies things.

This is technically a breaking change because I am removing a type parameter from two exported type aliases:

- `PendingInboundConnectionError`
- `PendingOutboundConnectionError`

Those have always only be used with `std::io::Error` in our API but it is still a breaking change.
2022-12-23 00:13:34 +00:00
Max Inden
fb45ce3773
fix(metrics): Update connections_establishment_duration buckets (#3256)
Currently the `libp2p_swarm_connections_establishment_duration` metric has the following buckets:

```
// exponential_buckets(1e-3, 2., 10)

[0.001, 0.002, 0.004, 0.008, 0.016, 0.032, 0.064, 0.128, 0.256, 0.512]
```

It is unlikely that a connection is established in 1ms, even within a datacenter. It is very likely that libp2p connection establishment takes longer than 512ms over the internet.

This commit proposes the following buckets:

```
// exponential_buckets(0.01, 1.5, 20)

[0.01, 0.015, 0.0225, 0.03375, 0.050625, 0.0759375, 0.11390625, 0.170859375, 0.2562890625,
0.38443359375, 0.576650390625, 0.8649755859375, 1.29746337890625, 1.946195068359375,
2.9192926025390626, 4.378938903808594, 6.568408355712891, 9.852612533569337, 14.778918800354004,
22.168378200531006]
```

- Buckets start at 10ms.
- Reasonably high resolution in the sub-second area.
- Largest bucket at 22s, e.g. for a relayed connection.
- Unfortunately rather obscure numbers.
2022-12-17 20:49:09 +00:00
John Turpish
f8f19baad0
time to establish connection (#3134)
Implementing #2745 , adding  a metric to break down time from connection pending to connection established, per protocol stack.

````
$curl -s http://127.0.0.1:42183/metrics | grep nt_duration
# HELP libp2p_swarm_connection_establishment_duration Time it took (locally) to finish establishing connections.
# TYPE libp2p_swarm_connection_establishment_duration histogram
libp2p_swarm_connection_establishment_duration_sum{role="Listener",protocols="/ip4/tcp"} 0.007
libp2p_swarm_connection_establishment_duration_count{role="Listener",protocols="/ip4/tcp"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.001"} 0
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.002"} 0
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.004"} 0
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.008"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.016"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.032"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.064"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.128"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.256"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="0.512"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Listener",protocols="/ip4/tcp",le="+Inf"} 1

lbl@chomp:~lbl
$curl -s http://127.0.0.1:34283/metrics | grep nt_duration
# HELP libp2p_swarm_connection_establishment_duration Time it took (locally) to finish establishing connections.
# TYPE libp2p_swarm_connection_establishment_duration histogram
libp2p_swarm_connection_establishment_duration_sum{role="Dialer",protocols="/ip4/tcp"} 0.009
libp2p_swarm_connection_establishment_duration_count{role="Dialer",protocols="/ip4/tcp"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.001"} 0
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.002"} 0
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.004"} 0
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.008"} 0
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.016"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.032"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.064"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.128"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.256"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="0.512"} 1
libp2p_swarm_connection_establishment_duration_bucket{role="Dialer",protocols="/ip4/tcp",le="+Inf"} 1
````
2022-12-12 14:40:36 +00:00
John Turpish
69efe63229
misc/metrics: Add protocols label to address-specific metrics (#2982)
Previously, we would only track the metrics like the number of open connections. With this patch, we extend these metrics with a `protocols` label that contains a "protocol stack". A protocol stack is a multi-address with all variable parts removed. For example, `/ip4/127.0.0.1/tcp/1234` turns into `/ip4/tcp`.

Resolves https://github.com/libp2p/rust-libp2p/issues/2758.
2022-11-15 20:45:14 +00: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
7fc342e6c0
{core,swarm}: Remove Network abstraction (#2492)
This commit removes the `Network` abstraction, thus managing `Listeners`
and the connection `Pool` in `Swarm` directly. This is done under the
assumption that noone uses the `Network` abstraction directly, but
instead everyone always uses it through `Swarm`. Both `Listeners` and
`Pool` are moved from `libp2p-core` into `libp2p-swarm`. Given that they
are no longer exposed via `Network`, they can be treated as an
implementation detail of `libp2p-swarm` and `Swarm`.

This change does not include any behavioural changes.

This change has the followin benefits:

- Removal of `NetworkEvent`, which was mostly an isomorphism of
  `SwarmEvent`.
- Removal of the never-directly-used `Network` abstraction.
- Removal of now obsolete verbose `Peer` (`core/src/network/peer.rs`)
  construct.
- Removal of `libp2p-core` `DialOpts`, which is a direct mapping of
  `libp2p-swarm` `DialOpts`.
- Allowing breaking changes to the connection handling and `Swarm` API
  interface without a breaking change in `libp2p-core` and thus a
  without a breaking change in `/transport` protocols.

This change enables the following potential future changes:

- Removal of `NodeHandler` and `ConnectionHandler`. Thus allowing to
  rename `ProtocolsHandler` into `ConnectionHandler`.
- Moving `NetworkBehaviour` and `ProtocolsHandler` into `libp2p-core`,
  having `libp2p-xxx` protocol crates only depend on `libp2p-core` and
  thus allowing general breaking changes to `Swarm` without breaking all
  `libp2p-xxx` crates.
2022-02-13 21:57:38 +01:00
Max Inden
3f4dbb1717
{misc,protocols/gossipsub}: Move to prometheus-client (#2442)
`open-metrics-client` has been accepted as the official Prometheus Rust
client and thus renamed to `prometheus-client`.

See https://groups.google.com/g/prometheus-developers/c/E67ByGmVQKM
2022-02-03 11:31:41 +01:00
Max Inden
4001b565b6
*: Rework reporting of invalid and wrong PeerIds (#2441)
Previously, the negotiated PeerId was included in the swarm event and
inject_dial_failure’s arguments while the expected one was absent. This
patch adds the negotiated PeerId to the DialError and includes the expected
one in the notifications.

Co-authored-by: Roland Kuhn <rk@rkuhn.info>
2022-01-18 21:21:11 +01:00
Max Inden
40c5335e3b
core/: Concurrent dial attempts (#2248)
Concurrently dial address candidates within a single dial attempt.

Main motivation for this feature is to increase success rate on hole punching
(see https://github.com/libp2p/rust-libp2p/issues/1896#issuecomment-885894496
for details). Though, as a nice side effect, as one would expect, it does
improve connection establishment time.

Cleanups and fixes done along the way:

- Merge `pool.rs` and `manager.rs`.

- Instead of manually implementing state machines in `task.rs` use
  `async/await`.

- Fix bug where `NetworkBehaviour::inject_connection_closed` is called without a
  previous `NetworkBehaviour::inject_connection_established` (see
  https://github.com/libp2p/rust-libp2p/issues/2242).

- Return handler to behaviour on incoming connection limit error. Missed in
  https://github.com/libp2p/rust-libp2p/issues/2242.
2021-10-14 18:05:07 +02:00
Max Inden
fcb2f62752
misc/metrics/src/swarm: Expose role on connections_closed (#2220)
Expose whether closed connection was a Dialer or Listener.
2021-09-09 15:35:45 +02:00
Max Inden
c161acfb50
*: Dial with handler and return handler on error and closed (#2191)
Require `NetworkBehaviourAction::{DialPeer,DialAddress}` to contain a
`ProtocolsHandler`. This allows a behaviour to attach custom state to its
handler. The behaviour would no longer need to track this state separately
during connection establishment, thus reducing state required in a behaviour.
E.g. in the case of `libp2p-kad` the behaviour can include a `GetRecord` request
in its handler, or e.g. in the case of `libp2p-request-response` the behaviour
can include the first request in the handler.

Return `ProtocolsHandler` on connection error and close. This allows a behaviour
to extract its custom state previously included in the handler on connection
failure and connection closing. E.g. in the case of `libp2p-kad` the behaviour
could extract the attached `GetRecord` from the handler of the failed connection
and then start another connection attempt with a new handler with the same
`GetRecord` or bubble up an error to the user.

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2021-08-31 17:00:51 +02:00
Max Inden
98bc5e6486
misc/metrics: Add auxiliary crate to record events as OpenMetrics (#2063)
This commit adds an auxiliary crate recording protocol and Swarm events
and exposing them as metrics in the OpenMetrics format.
2021-08-13 22:51:54 +02:00