Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GossipSub: cancel inflight msgs when receiving duplicate #851

Closed
wants to merge 1 commit into from

Conversation

Menduist
Copy link
Contributor

@Menduist Menduist commented Jan 24, 2023

ref #850

@codecov
Copy link

codecov bot commented Jan 24, 2023

Codecov Report

Merging #851 (d306c44) into unstable (351bda2) will increase coverage by 0.02%.
The diff coverage is 91.17%.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##           unstable     #851      +/-   ##
============================================
+ Coverage     83.73%   83.75%   +0.02%     
============================================
  Files            85       85              
  Lines         15047    15073      +26     
============================================
+ Hits          12599    12625      +26     
  Misses         2448     2448              
Impacted Files Coverage Δ
libp2p/protocols/pubsub/pubsubpeer.nim 85.49% <66.66%> (-0.77%) ⬇️
libp2p/protocols/pubsub/pubsub.nim 82.82% <90.90%> (+0.01%) ⬆️
libp2p/protocols/pubsub/gossipsub.nim 85.14% <94.73%> (+0.63%) ⬆️
libp2p/protocols/pubsub/gossipsub/behavior.nim 87.75% <100.00%> (-0.10%) ⬇️
libp2p/multicodec.nim 91.30% <0.00%> (-8.70%) ⬇️
libp2p/transports/wstransport.nim 85.26% <0.00%> (ø)
... and 2 more

@arnetheduck
Copy link
Contributor

this carries the risk that the other end disconnects / descores due to the stream being reset mid-sending - I'm not sure it's a good idea in general - ie once the channel is open and streaming, interrupting the send looks like we're just trying to waste bandwidth

@Menduist
Copy link
Contributor Author

Menduist commented Jan 24, 2023

Cancelling a write will not reset a stream, it will just "unqueue" the message if that is still possible

However, for very big messages, it might make sense to a open a new stream just for it (when we'll have 0rtt negotiation), and being able to reset it mid-air.

EDIT: issue for 0 rtt negotiation is here: #746

@arnetheduck
Copy link
Contributor

However, for very big messages,

right, right now, I'm in the middle of discussions of features like this for 1mb-sized messages - partial streaming is highly likely - a similar feature is to not send messages to peers that have an in-progress send of potentially the same message via some kind of prefix comparison (or maybe by including the computed message id in the "header" of the stream.

# Fast path that only encodes message once
let encoded = encodeRpcMsg(msg, p.anonymize)
for peer in sendPeers:
result[peer.peerId] = peer.sendEncoded(encoded)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't this already synchronously put bytes in the send buffer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With mplex, that will indeed go synchronously through every layer, down to chronos
I thought that chronos supported write cancellation, apparently not, quoting cheatfate:

There is a big problem with write and i wish not to solve it today or tomorrow, because write is made using queue, so cancelling write in the middle should remove this write call from the queue, but it will break cross-platform compatibility, because on Windows this queue is in system, so i can't freely remove write call from the middle of the queue...

So we could add cancellation support to linux at least

With yamux, there is an intermediary queue before chronos (since there is per-stream backpressure), that does support cancellation:
https://github.com/status-im/nim-libp2p/blob/351bda2b56e4389a91fb42199621b3617bdbbdd3/libp2p/muxers/yamux/yamux.nim#L285

So this PR only makes sense if we get chronos support for write cancellation on linux, or enable yamux in nimbus :/

Copy link
Contributor Author

@Menduist Menduist Jan 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting TCP cancellation support in chronos seems less complex than expected (even on windows): status-im/nim-chronos#353
I'll wait for reviews to be sure

let
futsTable = g.cancellableBroadcast(peers, msg)
futs = toSeq(futsTable.values)
g.sendingFutures[msgIdSalted] = futsTable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't there be two inflight lazy broadcasts of the same message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That shouldn't happen, I may add an assert to be sure

@Menduist
Copy link
Contributor Author

a similar feature is to not send messages to peers that have an in-progress send of potentially the same message via some kind of prefix comparison

Yeah, seems like the ideal solution would be a new protocol that opens a stream eagerly, sends the message id & the message

The receiving end can reset the stream at any point if he gets the message first somewhere else (or if many peers are currently sending him the same message)

@arnetheduck
Copy link
Contributor

Yeah, seems like the ideal solution would be a new protocol that opens a stream eagerly, sends the message id & the message

actually, if we start receiving a message from someone we could actually look at the first few bytes and delay send iff they match whatever is being sent - basically, when we perform the send, we'd compare the message being sent against whatever partial bytes that have been received - a bit tricky perhaps because of protobuf and its unordered fields, but perhaps doable. easier to do with explicit support perhaps.

@Menduist
Copy link
Contributor Author

This is not actually doable, since cancelling an outbound message is unpractical

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants