Commit Graph

131 Commits

Author SHA1 Message Date
76abab9e20 feat: log bandwidth on substream instead of socket level (#3180)
Previously, the `with_bandwidth_logging` extension to `Transport` would track the bytes sent and received on a socket level. This however only works in conjunction with `Transport` upgrades where a separate multiplexer is negotiated on top of a regular stream.

With QUIC and WebRTC landing, this no longer works as those `Transport`s bring their own multiplexing stack. To still allow for tracking of bandwidth, we refactor the `with_bandwidth_logging` extension to count the bytes send on all substreams opened through a `StreamMuxer`. This works, regardless of the underlying transport technology. It does omit certain layers. However, there isn't necessarily a "correct" layer to count bandwidth on because you can always go down another layer (IP, Ethernet, etc).

Closes #3157.
2022-12-19 07:26:19 +00:00
d7363a53d3 fix: Remove circular dependencies across workspace (#3023)
Circular dependencies are problematic in several ways:

- They result in cognitive overhead for developers, in trying to figure out what depends on what.
- They present `cargo` with limits in what order the crates can be compiled in.
- They invalidate build caches unnecessarily thus forcing `cargo` to rebuild certain crates.
- They cause problems with tooling such as `release-please`.

To actually break the circular dependencies, this patch inlines the uses of `development_transport` in the examples and tests for all sub-crates. This is only meant to be a short-term fix until https://github.com/libp2p/rust-libp2p/issues/3111 and https://github.com/libp2p/rust-libp2p/pull/2888 are fixed.

To ensure we don't accidentally reintroduce this dependency, we add a basic CI that queries `cargo metadata` using `jq`.

Resolves https://github.com/libp2p/rust-libp2p/issues/3053.
Fixes https://github.com/libp2p/rust-libp2p/issues/3223.
Related: https://github.com/libp2p/rust-libp2p/pull/2918#discussion_r976514245
Related: https://github.com/googleapis/release-please/issues/1662
2022-12-12 20:58:01 +00:00
4fe518de86 feat!: Remove simple::SimpleProtocol (#3191)
Due to lack of usage, remove the `simple::SimpleProtocol`. Users may look at `libp2p::core::upgrade`
for alternatives.
2022-12-09 18:56:30 +01:00
8cb79f4c79 chore(swarm): Remove deprecated functions (#3170)
Remove functions deprecated in 0.41.0.
2022-12-09 15:44:08 +01:00
8678dc7569 chore(meta): Remove unnecessary quic module (#3139) 2022-11-18 19:40:10 +00:00
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
a714864885 feat: Add WebRTC transport (#2622)
Hey 👋 This is a WebRTC transport implemented in accordance w/ the [spec](https://github.com/libp2p/specs/pull/412). It's based on the [webrtc-rs](https://github.com/webrtc-rs/webrtc) library.

Resolves: #1066.
2022-11-17 05:17:31 +00:00
0f5c491d91 feat(transports/quic): Add implementation based on quinn-proto (#2289)
Co-authored-by: Demi Marie Obenour <demiobenour@gmail.com>
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: David Craven <david@craven.ch>
Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: elenaf9 <elena.frank@protonmail.com>
Co-authored-by: Marco Munizaga <marco@marcopolo.io>
2022-11-14 13:12:16 +01:00
afb777e937 swarm-derive: Add prelude configuration option to NetworkBehaviour macro (#3055)
Currently, our `NetworkBehaviour` derive macro depends on the `libp2p` crate to be in scope. This prevents standalone usage which forces us to depend on `libp2p` in all our tests where we want to derive a `NetworkBehaviour`.

This PR introduces a `prelude` option that - by default - points to `libp2p::swarm::derive_prelude`, a new module added to `libp2p_swarm`. With this config option, users of `libp2p_swarm` can now refer to the macro without depending on `libp2p`, breaking the circular dependency in our workspace. For consistency with the ecosystem, the macro is now also re-exported by `libp2p_swarm` instead of `libp2p` at the same position as the trait that it implements.

Lastly, we introduce an off-by-default `macros` feature flag that shrinks the dependency tree for users that don't need the derive macro.
2022-11-12 23:59:14 +00:00
280c51ef83 *: Link to libp2p/specs in doc comments (#3077) 2022-11-04 10:32:41 +00:00
4d1b165982 transports/tcp: Unify symbol naming (#2961)
Co-authored-by: Elena Frank <elena.frank@protonmail.com>
2022-10-24 15:41:08 +11:00
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
159a10b812 transports/tls: Add libp2p-tls as per spec (#2945)
Co-authored-by: David Craven <david@craven.ch>
Co-authored-by: Demi Marie Obenour <demiobenour@gmail.com>
Co-authored-by: Elena Frank <elena.frank@protonmail.com>
Co-authored-by: Max Inden <mail@max-inden.de
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Roman Proskuryakov <r.proskuryakoff@gmail.com>
2022-10-24 11:54:44 +11:00
3e4a0640fd Cargo.toml: Remove deprecated executor-specific features (#3001)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-10-20 14:17:20 +11:00
31a45f2d76 Cargo.toml: Deprecate executor specific features for sub-crates (#2962) 2022-10-11 23:10:10 +11:00
1da75b2b25 protocols/ping: Properly deprecate types with Ping prefix (#2937)
Co-authored-by: Elena Frank <elena.frank@protonmail.com>
Co-authored-by:  João Oliveira <hello@jxs.pt>
2022-10-01 00:19:34 +10:00
2c739e9bdb protocols/noise: Introduce NoiseAuthenticated::xx constructor with X25519 DH key exchange (#2887)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-09-16 11:41:35 +10:00
89f898c69f protocols/mdns: Allow users to choose between async-io and tokio runtime (#2748)
Allow users to choose between async-io and tokio runtime
in the mdns protocol implementation. `async-io` is a default
feature, with an additional `tokio` feature.

Fix high CPU usage with Tokio library.
2022-09-02 05:53:38 +02:00
62622a1bad core/src/transport: Poll Transport directly, remove Transport::Listener (#2652)
Remove the concept of individual `Transport::Listener` streams from `Transport`.
Instead the `Transport` is polled directly via `Transport::poll`. The
`Transport` is now responsible for driving its listeners.
2022-07-04 04:16:57 +02:00
6078fc619f transports/{tcp,dns,websocket}: Remove Clone imp for *Config (#2682)
This commit removes the `Clone` implementation on `GenTcpConfig` and consequently the `Clone`
implementations on `GenDnsConfig` and `WsConfig`.

When port-reuse is enabled, `GenTcpConfig` tracks the addresses it is listening in a `HashSet`. This
`HashSet` is shared with the `TcpListenStream`s via an `Arc<Mutex<_>>`. Given that `Clone` is
`derive`d on `GenTcpConfig`, cloning a `GenTcpConfig`, results in both instances sharing the same
set of listen addresses. This is not intuitive.

This behavior is for example error prone in the scenario where one wants to speak both plain DNS/TCP and
Websockets. Say a user creates the transport in the following way:

``` Rust
let transport = {
    let tcp = tcp::TcpConfig::new().nodelay(true).port_reuse(true);
    let dns_tcp = dns::DnsConfig::system(tcp).await?;
    let ws_dns_tcp = websocket::WsConfig::new(dns_tcp.clone());
    dns_tcp.or_transport(ws_dns_tcp)
};
```

Both `dns_tcp` and `ws_dns_tcp` share the set of listen addresses, given the `dns_tcp.clone()` to
create the `ws_dns_tcp`. Thus, with port-reuse, a Websocket dial might reuse a DNS/TCP listening
port instead of a Websocket listening port.

With this commit a user is forced to do the below, preventing the above error:

``` Rust
let transport = {
    let dns_tcp = dns::DnsConfig::system(tcp::TcpConfig::new().nodelay(true).port_reuse(true)).await?;
    let ws_dns_tcp = websocket::WsConfig::new(
        dns::DnsConfig::system(tcp::TcpConfig::new().nodelay(true).port_reuse(true)).await?,
    );
    dns_tcp.or_transport(ws_dns_tcp)
};
```

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2022-05-31 12:29:43 +02:00
1d6b08b0b6 protocols/dcutr/examples: Wait to tell relay its public addr (#2659)
As a listening client, when requesting a reservation with a relay, the relay
responds with its public addresses. The listening client can then use the public
addresses of the relay to advertise itself as reachable under a relayed
address (`/<public-relay-addr>/p2p-circuit/p2p/<listening-client-peer-id>`).

The above operates under the assumption that the relay knows its public address.
A relay learns its public address from remote peers, via the identify protocol.
In the case where the relay just started up, the listening client might be the
very first node to connect to it.

Such scenario allows for a race condition. The listening client requests a
reservation from the relay, while the relay requests its public address from the
listening client. The former needs to contain the response from the latter.

This commit serializes the two requests, making sure, in the case of a freshly
started relay, that the listening client tells the relay its public address
before requesting a reservation from the relay.

Co-authored-by: Elena Frank <elena.frank@protonmail.com>
2022-05-20 21:59:32 +02:00
0e9ab1c960 protocols/dcutr/example: Wait for relay to accept reservation request (#2642)
When in listening mode, wait for the relay to accept our reservation
request. Only then can a client in dialing mode establish a relayed
connection to us via the relay.

See also
https://github.com/libp2p/rust-libp2p/issues/2621#issuecomment-1123549348
2022-05-19 20:08:32 +02:00
d69681b27c Drop atomic dependency (#2643)
Replace `atomic::Atomic<u64>` by `std::sync::atomic:AtomicU64`.

The original motivation of using `atomic::Atomic<u64>` instead of
`std`'s version in #1670 was the following:

> I used the atomic crate and an Atomic<u64> because the AtomicU64 type
> isn't available on all architectures. The atomic crate automatically
> falls back to using a Mutex on platforms that don't support AtomicU64.

This argumentation is moot because the crate directly depends on
`libp2p-core` which also uses `AtomicU64`.
2022-05-12 14:05:33 +10:00
f46fecd4d7 src/tutorials/ping: Fix typo in multiaddress (#2623) 2022-04-27 08:48:22 +02:00
0c1ac781a2 src/tutorials/hole-punching: Clarify use of libp2p-lookup & server IP (#2616) 2022-04-18 14:41:25 +02:00
2ad905f35a {core,swarm}/: Don't require Transport: Clone and take &mut (#2529)
Previously `libp2p-swarm` required a `Transport` to be `Clone`. Methods
on `Transport`, e.g. `Transport::dial` would take ownership, requiring
e.g. a `Clone::clone` before calling `Transport::dial`.

The requirement of `Transport` to be `Clone` is no longer needed in
`libp2p-swarm`. E.g.  concurrent dialing can be done without a clone per
dial.

This commit removes the requirement of `Clone` for `Transport` in
`libp2p-swarm`. As a follow-up methods on `Transport` no longer take
ownership, but instead a mutable reference (`&mut self`).

On the one hand this simplifies `libp2p-swarm`, on the other it
simplifies implementations of `Transport`.
2022-04-06 20:23:16 +02:00
a30d93e34b src/tutorials/hole-punching: Correct commands to use ip4 instead of dns4 (#2563) 2022-03-17 17:09:19 +01:00
a168410dbe src/tutorials/hole-punching: Update to published blog post (#2550) 2022-03-06 18:06:35 +01:00
7dfc15fa3d src/tutorials: Do minor text improvements (#2547) 2022-03-06 17:43:09 +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
861e15dabb src/tutorials: Add hole punching tutorial (#2460) 2022-02-10 16:36:20 +01:00
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
96dbfcd1ad core/src/transport: Add Transport::dial_as_listener (#2363)
Allows `NetworkBehaviour` implementations to dial a peer, but instruct
the dialed connection to be upgraded as if it were the listening
endpoint.

This is needed when establishing direct connections through NATs and/or
Firewalls (hole punching). When hole punching via TCP (QUIC is different
but similar) both ends dial the other at the same time resulting in a
simultaneously opened TCP connection. To disambiguate who is the dialer
and who the listener there are two options:

1. Use the Simultaneous Open Extension of Multistream Select. See
   [sim-open] specification and [sim-open-rust] Rust implementation.

2. Disambiguate the role (dialer or listener) based on the role within
   the DCUtR [dcutr] protocol. More specifically the node initiating the
   DCUtR process will act as a listener and the other as a dialer.

This commit enables (2), i.e. enables the DCUtR protocol to specify the
role used once the connection is established.

While on the positive side (2) requires one round trip less than (1), on
the negative side (2) only works for coordinated simultaneous dials.
I.e. when a simultaneous dial happens by chance, and not coordinated via
DCUtR, the connection attempt fails when only (2) is in place.

[sim-open]: https://github.com/libp2p/specs/blob/master/connections/simopen.md
[sim-open-rust]: https://github.com/libp2p/rust-libp2p/pull/2066
[dcutr]: https://github.com/libp2p/specs/blob/master/relay/DCUtR.md
2022-01-17 16:35:14 +01:00
c61ea6ad29 protocols/: Add basic AutoNAT implementation (#2262)
This commit adds a behaviour protocol that implements the AutoNAT specification.
It enables users to detect whether they are behind a NAT. The Autonat Protocol
implements a Codec for the Request-Response protocol, and wraps it in a new
Network Behaviour with some additional functionality.

Co-authored-by: David Craven <david@craven.ch>
Co-authored-by: Max Inden <mail@max-inden.de>
2022-01-14 10:27:28 +01:00
2c75fbe812 examples/*: Migrate to async await (#2356)
* Adapt examples to async style loop
* Adapt async style loop for chat.rs
* Adapt async style loop for distributed-key-value-store.rs
* Adapt async style loop for gossibsub-chat.rs
* Adapt async style loop for ipfs-private.rs
* Adapt ping to use async
* Update tutorial crate to reflect new changes

Co-authored-by: Max Inden <mail@max-inden.de>
2021-12-06 17:32:58 +01:00
a7ed1d6b6e *: Migrate to Rust 2021 edition (#2339)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-11-26 17:34:58 +01:00
220f84a97f swarm/: Enable advanced dialing requests (#2317)
Enable advanced dialing requests both on `Swarm` and via
`NetworkBehaviourAction`. Users can now trigger a dial with a specific
set of addresses, optionally extended via
`NetworkBehaviour::addresses_of_peer`. In addition the whole process is
now modelled in a type safe way via the builder pattern.

Example of a `NetworkBehaviour` requesting a dial to a specific peer
with a set of addresses additionally extended through
`NetworkBehaviour::addresses_of_peer`:

```rust
NetworkBehaviourAction::Dial {
    opts: DialOpts::peer_id(peer_id)
              .condition(PeerCondition::Always)
              .addresses(addresses)
              .extend_addresses_through_behaviour()
              .build(),
    handler,
}
```

Example of a user requesting a dial to an unknown peer with a single
address via `Swarm`:

```rust
swarm1.dial(
    DialOpts::unknown_peer_id()
        .address(addr2.clone())
        .build()
)
```
2021-11-15 14:17:23 +01:00
3c0f5c7848 src/tutorial.rs: Display ping events (#2234)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-09-25 15:58:04 +02:00
adcfdc0750 protocols/rendezvous: Implement protocol (#2107)
Implement the libp2p rendezvous protocol.

> A lightweight mechanism for generalized peer discovery. It can be used for
bootstrap purposes, real time peer discovery, application specific routing, and
so on.

Co-authored-by: rishflab <rishflab@hotmail.com>
Co-authored-by: Daniel Karzel <daniel@comit.network>
2021-09-07 16:36:52 +02:00
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
f701b24ec0 *: Format with rustfmt (#2188)
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2021-08-11 13:12:12 +02:00
68b5f743ad src/tutorial,examples/: Enhance docs on multiaddrs (#2187)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-08-09 15:07:14 +02:00
a414afd83c swarm/: include ListenerId in SwarmEvents (#2123)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-07-08 11:41:33 +02:00
e8fed53598 swarm/: Drive ExpandedSwarm via Stream trait only (#2100)
Change `Stream` implementation of `ExpandedSwarm` to return all
`SwarmEvents` instead of only the `NetworkBehaviour`'s events.

Remove `ExpandedSwarm::next_event`. Users can use `<ExpandedSwarm as
StreamExt>::next` instead.

Remove `ExpandedSwarm::next`. Users can use `<ExpandedSwarm as
StreamExt>::filter_map` instead.
2021-06-14 20:41:44 +02:00
a2e774992d src: Move introduction to new tutorial.rs (#2018)
This commit extends the ping example in `src/tutorial.rs, by walking a
newcomer through the implementation of a simple ping node step-by-step,
introducing all the core libp2p concepts along the way.

With the ping tutorial in place, there is no need for the lengthy libp2p
crate level introduction, which is thus removed with this commit.

Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
2021-04-01 15:46:41 +02:00
45f07bf863 [libp2p-dns] Implement /dnsaddr resolution. (#1931)
* Implement `/dnsaddr` support on `libp2p-dns`.

To that end, since resolving `/dnsaddr` addresses needs
"fully qualified" multiaddresses when dialing, i.e. those
that end with the `/p2p/...` protocol, we make sure that
dialing always uses such fully qualified addresses by
appending the `/p2p` protocol as necessary. As a side-effect,
this adds support for dialing peers via "fully qualified"
addresses, as an alternative to using a `PeerId` together
with a `Multiaddr` with or without the `/p2p` protocol.

* Adapt libp2p-relay.

* Update versions, changelogs and small cleanups.
2021-03-17 10:53:19 +01:00
cd15bc9c62 [libp2p-dns] Use trust-dns-resolver (with either async-std or tokio). Remove thread pool. (#1927)
* [libp2p-dns] Use trust-dns-resolver.

Use the `trust-dns-resolver` library for DNS resolution,
thereby removing current use of the thread pool.

Since `trust-dns-resolver` and related crates already
provide support for both `async-std` and `tokio`, we
make use of that here in our own feature flags.

Since `trust-dns-resolver` provides many useful
configuration options and error detail, central
types of `trust-dns-resolver` like `ResolverConfig`,
`ResolverOpts` and `ResolveError` are re-exposed
in the API of `libp2p-dns`. Full encapsulation
does not seem preferable in this case.

* Cleanup

* Fix two intra-doc links.

* Simplify slightly.

* Incorporate review feedback.

* Remove git dependency and fix example.

* Update version and changelogs.
2021-03-16 11:48:48 +01:00
2f9c1759e6 protocols/relay: Implement circuit relay specification (#1838)
This commit implements the [libp2p circuit
relay](https://github.com/libp2p/specs/tree/master/relay) specification. It is
based on previous work from https://github.com/libp2p/rust-libp2p/pull/1134.

Instead of altering the `Transport` trait, the approach taken in this commit
is to wrap an existing implementation of `Transport` allowing one to:

- Intercept `dial` requests with a relayed address.

- Inject incoming relayed connections with the local node being the destination.

- Intercept `listen_on` requests pointing to a relay, ensuring to keep a
  constant connection to the relay, waiting for incoming requests with the local
  node being the destination.

More concretely one would wrap an existing `Transport` implementation as seen
below, allowing the `Relay` behaviour and the `RelayTransport` to communicate
via channels.

### Example

```rust
let (relay_transport, relay_behaviour) = new_transport_and_behaviour(
    RelayConfig::default(),
    MemoryTransport::default(),
);

let transport = relay_transport
    .upgrade(upgrade::Version::V1)
    .authenticate(plaintext)
    .multiplex(YamuxConfig::default())
    .boxed();

let mut swarm = Swarm::new(transport, relay_behaviour, local_peer_id);

let relay_addr = Multiaddr::from_str("/memory/1234").unwrap()
    .with(Protocol::P2p(PeerId::random().into()))
    .with(Protocol::P2pCircuit);
let dst_addr = relay_addr.clone().with(Protocol::Memory(5678));

// Listen for incoming connections via relay node (1234).
Swarm::listen_on(&mut swarm, relay_addr).unwrap();

// Dial node (5678) via relay node (1234).
Swarm::dial_addr(&mut swarm, dst_addr).unwrap();
```

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
Co-authored-by: David Craven <david@craven.ch>
2021-03-11 16:07:59 +01:00
2ecf42a2bf [libp2p-secio] Remove crate. (#1940)
* Remove the SECIO transport protocol.

* Remove stray mentions of secio.
2021-02-01 14:39:44 +01:00
ac9798297b Rename and move libp2p-core-derive as libp2p-swarm-derive. (#1935) 2021-01-26 22:49:08 +01:00