Commit Graph

85 Commits

Author SHA1 Message Date
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
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
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
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
25d14349cc chore(gossipsub): remove deprecated items
Removes deprecated items from gossipsub and make certain modules crate-private.

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

Pull-Request: #3862.
2023-05-02 16:02:21 +00:00
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
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
270d204db2 feat(gossipsub): make gossipsub modules private
Resolves #3494.

Pull-Request: #3777.
2023-04-23 21:00:23 +00:00
058c2d85ec refactor(identity): follow naming conventions for conversion methods
This PR renames some method names that don't follow Rust naming conventions or behave differently from what the name suggests:
- Enforce "try" prefix on all methods that return `Result`.
- Enforce "encode" method name for methods that return encoded bytes.
- Enforce "to_bytes" method name for methods that return raw bytes.
- Enforce "decode" method name for methods that convert encoded key.
- Enforce "from_bytes" method name for methods that convert raw bytes.

Pull-Request: #3775.
2023-04-14 08:55:13 +00:00
f2a7457fde fix(gossipsub): prevent erroneously duplicate message IDs
Previously, we only mutably borrowed the `last_seq_no` in the current scope but did not modify the underlying number. This is because `u64` is copy and calling `wrapping_add` consumes `self` so the compiler just copied it. We introduce a new-type instead that is not `Copy`.

Additionally, `wrapping_add` and initializing with a random u64 might actually warp the number and thus not give us sequential numbers as intended in #3551. To solve this, we initialize with the current unix timestamp in nanoseconds. This allows a node to publish 1000000 messages a second and still not reuse sequence numbers even after a restart / re-initialization of the configuration. This is also what the go implementation does.

Resolves #3714.

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>

Pull-Request: #3716.
2023-04-04 10:52:16 +00:00
dcbc04e89e feat(swarm): rename NetworkBehaviourAction to ToSwarm
Resolves #3123.

Pull-Request: #3658.
2023-03-24 13:43:49 +00:00
eb5e269165 fix(gossipsub): signed messages use monotonically increasing seq numbers
This modifies the gossipsub implementation to use monotonically increasing sequence numbers for signed messages (as dictated by the specification). There is a discussion about this in #3453. This change will make rust-libp2p gossipsub align with the go-implementation when messages are signed.

Messages will however still use randomized sequence numbers when messages are unsigned for security reasons (as discussed in the issue linked).

This shouldn't change any user-level API, only the seqno behavior. It is fully backwards compatible.

Resolves #3453.

Pull-Request: #3551.
2023-03-14 00:06:01 +00:00
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
7069d78ee3 test: introduce libp2p-swarm-test
This patch-set introduces `libp2p-swarm-test`. It provides utilities for quick and safe bootstrapping of tests for `NetworkBehaviour`s. The main design features are:

- Everything has timeouts
- APIs don't get in your way
- Minimal boilerplate

Closes #2884.

Pull-Request: #2888.
2023-03-08 09:36:35 +00:00
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
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
58af2e0887 refactor(gossipsub): make error module private
Resolves https://github.com/libp2p/rust-libp2p/issues/3392.

Pull-Request: #3457.
2023-02-20 19:35:21 +00:00
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
ab59af4d46 refactor(gossipsub): revise symbol naming to follow conventions (#3303)
Changes regarding the  #2217
2023-01-27 04:44:04 +00:00
e55202200c refactor(gossipsub)!: initialize ProtocolConfig from GossipsubConfig (#3381)
This simplifies the tests as we don't have to go through the `new_handler` abstraction.
2023-01-26 14:39:48 +00:00
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
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
e3c7023350 fix(gossipsub): allow clippy beta lint (#3321)
It doesn't appear that https://github.com/rust-lang/rust-clippy/issues/10061 is going to be fixed any time soon. In the meantime, our CI is "red" which is misleading because we purposely don't require this CI check. It will however hit stable in ~ 2 weeks at which point our required clippy CI check will fail.

Suppress clippy lint with an `allow` to make it pass.
2023-01-13 12:28:04 +00:00
1b6c915813 refactor(gossipsub): remove unnecessary trait bounds (#3317)
Trait bounds on struct declarations should be avoided as much as possible because they creep into every reference of the type. To supply default type parameters, we don't need the trait bounds.
2023-01-11 09:53:20 +00:00
88fa8e66b8 refactor(gossipsub): don't store messages within Arc (#3243)
Currently, we store messages to be sent to the `ConnectionHandler` in an `Arc`. However, we never actually clone these messages as we can see with this patch, hence we remove this wrapping.

Related: https://github.com/libp2p/rust-libp2p/pull/3242
2022-12-20 00:59:25 +00:00
8c139f2d3b chore: apply suggestions from beta clippy (#3251) 2022-12-17 02:01:45 +00:00
3df3c88f3d swarm/behaviour: Replace inject_* with on_event (#3011) 2022-11-17 09:28:40 +00:00
c32f03c317 *: Fix newly raised clippy warnings (#3106)
Fixed minor issues raised by clippy to improve correctness and readablitity.
2022-11-11 20:30:58 +00:00
e530118fb0 build(deps): Bump rand to 0.8 and quickcheck to 1 (#2857)
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Max Inden <mail@max-inden.de>
2022-09-22 18:48:32 +10:00
c81b06a9b2 *: Fix various clippy warnings (#2900) 2022-09-16 16:30:11 +02:00
b8c3b282ee protocols/gossipsub: Allow publishing to anything that implements Into<TopicHash> (#2862) 2022-09-05 06:31:13 +02:00
a4110a2b69 *: Remove inject_connected / inject_disconnected from docs (#2805) 2022-08-10 10:20:31 +02:00
1012579d77 protocols/: Remove passing default variant to WithPeerId::condition (#2802) 2022-08-10 09:50:24 +02:00
6db57121e9 protocols/gossipsub/: Allow custom protocol id (#2718)
Allow for custom protocol ID via `GossipsubConfigBuilder::protocol_id()`.
2022-07-02 10:30:02 +02:00
748588e3f0 protocols/gossipsub: Fix a typo in error message (#2739)
* protocols/gossipsub: Fix a typo in error message

* protocols/gossipsub: Make the error message accurately
2022-06-30 10:20:26 +02:00
c7c21b1023 protocols/gossipsub: Fix duplicate connection id (#2702) 2022-06-14 16:31:27 +02:00
70d38520fd *: Activate clippy::style lint group (#2620) 2022-05-03 13:11:48 +02:00
99855b1d10 *: Apply clippy suggestions (#2540) 2022-02-28 10:05:17 +01:00
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
65cc8994a6 *: Derive Debug and Clone(#2495)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-02-16 16:16:54 +01:00
9f1114d8b9 protocols/gossipsub: Add IWANT and memcache misses metrics (#2518)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-02-16 15:54:24 +01:00
60666f5455 protocols/gossipsub: Revert back to wasm_timer for interval (#2506)
Removed the custom interval implementation and removes support for
wasm32-unknown-unknown. See https://github.com/libp2p/rust-libp2p/issues/2497
for details.

Co-authored-by: Diva M <divma@protonmail.com>
Co-authored-by: Max Inden <mail@max-inden.de>
2022-02-14 11:24:58 +01:00
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
78f5981856 protocols/gossipsub: Emit gossip of all non empty topics (#2481)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-02-07 20:00:46 +01:00
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
30fc882037 protocols/gossipsub: Implement unsub backoff spec changes (#2403)
Implements the changes specified by
https://github.com/libp2p/specs/pull/383.

Co-authored-by: Max Inden <mail@max-inden.de>
2022-01-17 18:08:34 +01:00
17861d9cac add performance metrics to gossipsub (#2346)
* add performance metrics to gossipsub

* add changelog entry

* Re-export open-client-metrics crate

* Added some extra metrics

* More metrics

* Additional metrics

* Correct topic encoding

* More manual encoding of metric labels

* Clean up metric labelling

* Improve heartbeat duration buckets

* Remove re-export

Co-authored-by: Age Manning <Age@AgeManning.com>
2021-12-22 09:31:19 +11:00
379001a1d0 protocols/gossipsub: Improve bandwidth (#2327)
This PR adds some bandwidth improvements to gossipsub.

After a bit of inspection on live networks a number of improvements have been
made that can help reduce unnecessary bandwidth on gossipsub networks. This PR
introduces the following:

- A 1:1 tracking of all in-flight IWANT requests. This not only ensures that all
  IWANT requests are answered and peers penalized accordingly, but gossipsub
  will no no longer create multiple IWANT requests for multiple peers.
  Previously, gossipsub sampled the in-flight IWANT requests in order to
  penalize peers for not responding with a high probability that we would detect
  non-responsive nodes. Futher, it was possible to re-request IWANT messages
  that are already being requested causing added duplication in messages and
  wasted unnecessary IWANT control messages. This PR shifts this logic to only
  request message ids that we are not currently requesting from peers.

- Triangle routing naturally gives rise to unnecessary duplicates. Consider a
  mesh of 4 peers that are interconnected. Peer 1 sends a new message to 2,3,4.
  2 propagates to 3,4 and 3 propagates to 2,4 and 4 propagates to 2,3. In this
  case 3 has received the message 3 times. If we keep track of peers that send
  us messages, when publishing or forwarding we no longer send to peers that
  have sent us a duplicate, we can eliminate one of the sends in the scenario
  above. This only occurs when message validation is async however. This PR adds
  this logic to remove some elements of triangle-routing duplicates.

Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com>
Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Diva M <divma@protonmail.com>
2021-12-21 12:09:15 +01:00
2d61fe296f *: Fix clippy errors from upgrade to Rust 1.57 (#2365)
* core: Mark "unused" field with "_"

We need to keep this marker type to ensure that the type continues
to be required to be pinned.

* tranports/noise: Derive `Default` for `Config`

`false` is the default for `bool`, we can derive this.

* protocols/request-response: Remove unused fields

These are already included the `RequestResponseMessage::Request`
variant.

* *: Allow clippy's large-enum-variant lint

Tackling these suggestions would require performance measurement
which we don't want to do at this stage.

Co-authored-by: Max Inden <mail@max-inden.de>
2021-12-06 16:13:42 +01:00
2066a192ad protocols/gossipsub: Add mesh metrics (#2316)
Enable instrumenting mesh through metrics and add gossipsub to
misc/metrics.

Co-authored-by: Max Inden <mail@max-inden.de>
2021-11-16 14:59:39 +01:00