-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Open one substream for each notifications protocol #4909
Conversation
|
I just remembered that at the moment GRANDPA uses the legacy substream handshake to determine whether the remote is a full node or an authority. This "role" should instead be passed as part of the handshake. Before we merge, I will expose this handshake API and make it pass the role for GRANDPA. EDIT: actually no, we can't do that for backwards compatibility reasons |
twittner
left a comment
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.
I did not check every line but the overall structure looks good to me.
client/network/src/protocol/generic_proto/upgrade/notifications.rs
Outdated
Show resolved
Hide resolved
Co-Authored-By: Toralf Wittner <[email protected]>
mxinden
left a comment
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.
Took a first look. Thanks for putting so much effort into making this backward compatible!
Will take another (more in-depth) look. I am sorry for the delay.
|
|
||
| let validator = Arc::new(validator); | ||
| let gossip_engine = GossipEngine::new(service.clone(), GRANDPA_ENGINE_ID, validator.clone()); | ||
| let gossip_engine = GossipEngine::new(service.clone(), GRANDPA_ENGINE_ID, GRANDPA_PROTOCOL_NAME, validator.clone()); |
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.
| let gossip_engine = GossipEngine::new(service.clone(), GRANDPA_ENGINE_ID, GRANDPA_PROTOCOL_NAME, validator.clone()); | |
| let gossip_engine = GossipEngine::new( | |
| service.clone(), | |
| GRANDPA_ENGINE_ID, | |
| GRANDPA_PROTOCOL_NAME, | |
| validator.clone(), | |
| ); |
|
|
||
| let validator = Arc::new(validator); | ||
| let gossip_engine = GossipEngine::new(service.clone(), GRANDPA_ENGINE_ID, validator.clone()); | ||
| let gossip_engine = GossipEngine::new(service.clone(), GRANDPA_ENGINE_ID, GRANDPA_PROTOCOL_NAME, validator.clone()); |
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.
Do I understand correctly, that GRANDPA_ENGINE_ID is a legacy concept once this merges? If so, could we rename it to LEGACY_GRANDPA_ENGINE_ID or mention it in the doc comment of its definition?
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.
It is also used in non-networking parts of the code.
|
|
||
| /// Registers a new notifications protocol. | ||
| /// | ||
| /// You are very strongly encouraged to call this method very early on. Any connection open |
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.
| /// You are very strongly encouraged to call this method very early on. Any connection open | |
| /// You are very strongly encouraged to call this method very early on. Any open connection |
| /// will retain the protocols that were registered then, and not any new one. | ||
| pub fn register_notif_protocol( | ||
| &mut self, | ||
| proto_name: impl Into<Cow<'static, [u8]>>, |
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.
This patch uses both proto_name and protocol_name to refer to the same thing. Can we settle on one?
| /// - For each registered protocol, we also open an additional substream for this protocol. If the | ||
| /// remote refuses this substream, then it's fine. | ||
| /// | ||
| /// - Whenever we want to send a message, we pass either `None` to force the legacy substream, or |
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.
Does this refer to write_notification? As far as I can tell, none of its arguments take an Option.
| /// | ||
| /// See the documentation at the module level for more information. | ||
| pub struct NotifsHandlerProto { | ||
| /// Prototypes for handlers for ingoing substreams. |
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.
| /// Prototypes for handlers for ingoing substreams. | |
| /// Prototypes for handlers for incoming substreams. |
| /// | ||
| /// See the documentation at the module level for more information. | ||
| pub struct NotifsHandler { | ||
| /// Handlers for ingoing substreams. |
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.
| /// Handlers for ingoing substreams. | |
| /// Handlers for incoming substreams. |
* Open one substream for each notifications protocol * Fix WASM build * Apply suggestions from code review Co-Authored-By: Toralf Wittner <[email protected]> * Address concerns * Use unsigned-varint to read the varint * Use unsigned-varint * Forgot Cargo.lock Co-authored-by: Toralf Wittner <[email protected]>
In #4284 we introduced a new API for the networking crate, where one can register a "notifications protocol". The implementation, however, was simply translating notifications into old messages and sending them the same way as before.
This PR is the next step.
In addition to the current unique substream with the remote, we now also try to open a separate substream for each notifications protocol that has been registered.
If the remote doesn't support the new protocol, we don't care. If the remote does support the new protocol, then we use it to send our notifications.
(Note: connections that are already open when a new protocol is registered will not use the new protocol. This really should be fixed eventually by forbidding registering new protocols after the initialization process (cc #4587 ).)
Right now the only protocol concerned is GrandPa. I went with
/paritytech/grandpa/1for the protocol name.cc'ing @rphmeier @andresilva
New protocol description
The new substreams have the following properties:
Backwards compatibility
This PR is fully backwards compatible with the current network.
Also note that if we receive a notification the "old way", we still accept it even if the new protocol is in use.
Right now the legacy protocol is still the only way to perform syncing and light client requests, and therefore we make the presence of the legacy substream act as "the authority".
In other words, we are considered "connected" to a node if and only if we have a legacy substream open with that node. The new substreams exist in parallel but are optional. Also note that it is not possible to open a new substream without opening the legacy substream as well, but this will change in the future.
However nodes that have this PR will immediately talk to each other using the new protocol. It should therefore be strongly tested before it is deployed "for real" on Kusama.