> Futures managed by FuturesUnordered will only be polled when they
generate wake-up notifications. This reduces the required amount of work
needed to poll large numbers of futures.
https://docs.rs/futures/0.3.5/futures/stream/struct.FuturesUnordered.html
Instead of iterating each inbound and outbound upgrade looking for one
to make progress, use a `FuturesUnordered` for both pending inbound and
pending outbound upgrades. As a result only those upgrades are polled
that are ready to progress.
* add tokio floodsub chat example
* use swarmbuilder to specify tokio executor
* fix comments
* Tweak tokio chat example.
Co-authored-by: Roman S. Borschel <roman@parity.io>
* [multistream-select] Fix panic with V1Lazy and add integration tests.
Fixes a panic when using the `V1Lazy` negotiation protocol,
a regression introduced in https://github.com/libp2p/rust-libp2p/pull/1484.
Thereby adds integration tests for a transport upgrade with both
`V1` and `V1Lazy` to the `multistream-select` crate to prevent
future regressions.
* Cleanup.
* Update changelog.
Also add warn if parsing of a packet fails, so problems with for example packet
sizes can more easily be detected.
Reasoning:
The previous 2048 bytes is already larger than the recommend size by
[rfc6762](https://tools.ietf.org/html/rfc6762#page-46), which recommends
a packet size that fits within the interface MTU.
Nevertheless the rfc also states, that if more data needs to be
transmitted one should rely on IP fragments, which would only pose
problems when interfacing with devices not understanding IP fragments.
The standard also imposes a strict upper limit of 9000 bytes.
Therefore raising `recv_buffer` to 4096 seems sensible, given that we
already exceed the recommend size and given that we are not restricting
the size when sending in any way. Meaning the implementation already
sends packets larger than recommended, just can't handle them on
reception.
* Require remaining negotiation data to be flushed.
There appears to still be an edge-case whereby the
`remaining` data to send w.r.t. protocol negotiation to send
is successfully written before a `poll_read` on a `Negotiated` stream,
but where the subsequent `poll_flush()` is pending.
Now `remaining` is empty and the next `poll_read()`
will go straight to reading from the underlying
I/O stream, despite the flush not having happened
yet, which can lead to a form of deadlock during
protocol negotiation.
Rather than complicating the existing code further in
order to accommodate for this case, it seems preferable
to simplify the code by giving up on this optimisation
that only affects the last negotiation protocol message
sent by the "listener". So we give up on the ability
to combine data sent by the "listener" immediately
after protocol negotiation together with the final
negotiation frame in the same transport-level frame/packet.
* Update changelog.
* Add missing comma.
* Update cuckoofilter requirement from 0.3.2 to 0.5.0
Updates the requirements on [cuckoofilter](https://github.com/axiomhq/rust-cuckoofilter) to permit the latest version.
- [Release notes](https://github.com/axiomhq/rust-cuckoofilter/releases)
- [Changelog](https://github.com/axiomhq/rust-cuckoofilter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axiomhq/rust-cuckoofilter/commits)
Signed-off-by: dependabot[bot] <support@github.com>
* protocols/floodsub: Warn when Cuckoofilter has to evict item
With Cuckoofilter `v0.4.0` `add` and `test_and_add` return an error when
an old element has to be evicted in favor of a new one to take its
place. The previous behavior was panicing.
With this commit the error is logged on `warn` level.
* *: Update changelogs and cargo tomls
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Inden <mail@max-inden.de>
* Refactor Mplex.
Thereby addressing the following issues:
* Send a `Reset` frame when open substreams get dropped (313).
* Avoid stalls caused by a read operation on one substream
reading (and buffering) frames for another substream without
notifying the corresponding task. I.e. the tracked read-interest
must be scoped to a substream.
* Remove dropped substreams from the tracked set of open
substreams, to avoid artificially running into substream
limits.
* Update CHANGELOG.
* Refine behaviour of dropping substreams.
By taking the substream state into account. The refined
behaviour is modeled after the behaviour of Yamux.
* Tweak docs and recv buffer retention.
* Further small tweaks.
* Make the pending frames a FIFO queue.
* Take more care to avoid keeping read-wakers around
and to notify them when streams close.
* Prefer wake over unregister.
It is probably safer to always wake pending wakers.
* Update muxers/mplex/src/codec.rs
Co-authored-by: Max Inden <mail@max-inden.de>
* Update muxers/mplex/src/io.rs
Co-authored-by: Max Inden <mail@max-inden.de>
* Some review feedback and cosmetics.
* Update muxers/mplex/src/io.rs
Co-authored-by: Max Inden <mail@max-inden.de>
* Revise read control flow for clarity.
While seemingly duplicating some control flow between
`poll_next_strean` and `poll_read_stream`, the individual
control flow of each read operation is easier to follow.
* CI
* Rename Status::Ok to Status::Open.
* Rename pending_flush to pending_flush_open.
* Finishing touches.
* Tweak changelog.
Co-authored-by: Max Inden <mail@max-inden.de>
* protocols/plaintext: Do not UVI encode goodput
Only prefix handshake messages with the message length in bytes as an
unsigned varint. Return a plain socket once handshaking succeeded.
* *: Bump minor version in changelogs and cargo tomls
* Update atomic requirement from 0.4.6 to 0.5.0
Updates the requirements on [atomic](https://github.com/Amanieu/atomic-rs) to permit the latest version.
- [Release notes](https://github.com/Amanieu/atomic-rs/releases)
- [Commits](https://github.com/Amanieu/atomic-rs/compare/v0.4.6...v0.5.0)
Signed-off-by: dependabot[bot] <support@github.com>
* .github/workflows: Update Rust nightly
* misc/multistream-select: Don't mention private item in public doc
* .github/workflows: Update renamed doc flag
* core/src/connection/pool: Don't mention private item in public doc
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Inden <mail@max-inden.de>
With b601ed4 libp2p-core requires the `Ord` bound on `Multiaddr`. This
bound is only implemented with parity-multiaddr `0.9.2`. Make sure
libp2p-core requires at least parity-multiaddr `0.9.2`.
* *: Prepare libp2p 0.28.1 release
* Simplify incoming connection handling.
Instead of handing out a mutable borrow to the connection
pool in the `IncomingConnectionEvent`, so one can call
`IncomingConnectionEvent::accept()`, just provide
`Network::accept()`.
* Update docs.
* Update CHANGELOG.
* Restore `RequestResponse::throttled`.
In contrast to the existing "throttled" approach this PR adds back-
pressure to the protocol without requiring pre-existing knowledge
of all nodes about their limits. It adds small, CBOR-encoded headers
to the actual payload data. Extra credit messages communicate back
to the sender how many more requests it is allowed to send.
* Remove some noise.
* Resend credit grant after connection closed.
Should an error in some lower layer cause a connection to be closed,
our previously sent credit grant may not have reached the remote peer.
Therefore, pessimistically, a credit grant is resent whenever a
connection is closed. The remote ignores duplicate grants.
* Remove inbound/outbound tracking per peer.
* Send ACK as response to duplicate credit grants.
* Simplify.
* Fix grammar.
* Incorporate review feedback.
- Remove `ResponseSent` which was a leftover from previous attemps
and issue a credit grant immediately in `send_response`.
- Only resend credit grants after a connection is closed if we are
still connected to this peer.
* Move codec/header.rs to throttled/codec.rs.
* More review suggestions.
* Generalise `ProtocolWrapper` and use shorter prefix.
* Update protocols/request-response/src/lib.rs
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Update protocols/request-response/src/throttled.rs
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Update protocols/request-response/src/throttled.rs
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Minor comment changes.
* Limit max. header size to 8KiB
* Always construct initial limit with 1.
Since honest senders always assume a send budget of 1 and wait for
credit afterwards, setting the default limit to a higher value
can only become effective after informing the peer about it which
means leaving `max_recv` at 1 and setting `next_max` to the desired
value.
* Use LRU cache to keep previous peer infos.
Peers may send all their requests, reconnect and send again all their
requests, starting from a fresh budget. The LRU cache keeps the peer
information around and reuses it when the peer reconnects, continuing
with the previous remaining limit.
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
Previously a `Listener` would return its own address as the
`remote_addr` in the `ListenerEvent::Upgrade` event.
With this commit a `Listener` returns the dialer address as the
`remote_addr` in the `ListenerEvent::Upgrade` event. To do so a
`DialFuture` registers a port with the global `HUB` at construction
which is later on unregistered in the `Drop` implementation of the
dialer's `Chan`. The sending side of the `mpsc::channel` registered in
the `HUB` is dropped at `DialFuture` construction, thus one can not dial
the dialer port. This mimics the TCP transport behaviour preventing both
dialing and listening on the same TCP port.
* Restore `RequestResponse::throttled`.
In contrast to the existing "throttled" approach this PR adds back-
pressure to the protocol without requiring pre-existing knowledge
of all nodes about their limits. It adds small, CBOR-encoded headers
to the actual payload data. Extra credit messages communicate back
to the sender how many more requests it is allowed to send.
* Remove some noise.
* Resend credit grant after connection closed.
Should an error in some lower layer cause a connection to be closed,
our previously sent credit grant may not have reached the remote peer.
Therefore, pessimistically, a credit grant is resent whenever a
connection is closed. The remote ignores duplicate grants.
* Remove inbound/outbound tracking per peer.
* Send ACK as response to duplicate credit grants.
* Simplify.
* Fix grammar.
* Incorporate review feedback.
- Remove `ResponseSent` which was a leftover from previous attemps
and issue a credit grant immediately in `send_response`.
- Only resend credit grants after a connection is closed if we are
still connected to this peer.
* Move codec/header.rs to throttled/codec.rs.
* More review suggestions.
* Generalise `ProtocolWrapper` and use shorter prefix.
* Update protocols/request-response/src/lib.rs
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Update protocols/request-response/src/throttled.rs
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Update protocols/request-response/src/throttled.rs
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Minor comment changes.
* Limit max. header size to 8KiB
* Always construct initial limit with 1.
Since honest senders always assume a send budget of 1 and wait for
credit afterwards, setting the default limit to a higher value
can only become effective after informing the peer about it which
means leaving `max_recv` at 1 and setting `next_max` to the desired
value.
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>