-
Notifications
You must be signed in to change notification settings - Fork 996
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
misc/multistream-select: Differentiate interpretation of EOF #1823
Conversation
> When a listener rejects a protocol with [`Message::NotAvailable`] and the dialer does not have alternative protocols to propose then the dialer will stop the negotiation and drop the corresponding stream. As a listener interpret an EOF after sending a [`Message::NotAvailable`] as a failed negotiation. Interpret an EOF as an io error in all other cases.
Thanks to @tomaka who was a great help debugging this. |
// We don't explicitly check for `Failed` because the client might close the connection when it | ||
// realizes that we have no protocol in common. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code changes look good to me.
The logic of the change itself might be a bit more debatable, but I agree with this solution
How about always interpreting EOF during negotiation as a failed negotiation rather than only in this particular case? Essentially making explicit that dropping or closing an I/O stream is a permissible course of action to "gracefully" fail a negotiation. I'd prefer more uniform behavior over special cases. |
The argument is that the multiplexing layer has no choice but to report protocol errors in the form of an |
If I understand correctly, @romanb is suggesting to treat EOF errors as negotiation errors, not to treat all For the reference, the current implementation: rust-libp2p/misc/multistream-select/src/listener_select.rs Lines 152 to 164 in c812b8d
|
Right, I misread. |
Yes, I'm only referring to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, though I would have expected that the change is made for all cases of Poll::Ready(None)
during negotiation, i.e. for all occurrences in dialer_select.rs
and listener_select.rs
, instead of only at one place for the listener.
Agreed. adf31c8 makes it consistent across all cases of |
Summary / Commit Message
Context
The above surfaced in the following way:
With paritytech/substrate#7478 block-requests are send via
libp2p-request-response
. A full node supports both sending block requests and responding to block requests. A light client only supports sending block requests. When the full node asks the light client whether it supports the block request protocol, the light client replies withMessage::NotAvailable
. The full node thus drops the stream. Previously a dropped stream was interpreted as an io error on the light client side. Passed on tolibp2p-request-response
the connection is terminated (see here).There are two solutions to this:
Ignore io errors in
libp2p-request-responses
.Interpret an EOF after sending a
Message::NotAvailable
as a negotiation failure and not as an io failure.This pull request proposes the latter.