feat: report changes in supported protocols to ConnectionHandler

With this patch, implementations of `ConnectionHandler` (which are typically composed in a tree) can exchange information about the supported protocols of a remote with each other via `ConnectionHandlerEvent::ReportRemoteProtocols`. The provided `ProtocolSupport` enum can describe either additions or removals of the remote peer's protocols.

This information is aggregated in the connection and passed down to the `ConnectionHandler` via `ConnectionEvent::RemoteProtocolsChange`.

Similarly, if the listen protocols of a connection change, all `ConnectionHandler`s on the connection will be notified via `ConnectionEvent::LocalProtocolsChange`. This will allow us to eventually remove `PollParameters` from `NetworkBehaviour`.

This pattern allows protocols on a connection to communicate with each other. For example, protocols like identify can share the list of (supposedly) supported protocols by the remote with all other handlers. A protocol like kademlia can accurately add and remove a remote from its routing table as a result.

Resolves: #2680.
Related: #3124.

Pull-Request: #3651.
This commit is contained in:
Thomas Eizinger
2023-05-08 16:36:30 +02:00
committed by GitHub
parent b8a7684153
commit b035fc80a0
30 changed files with 844 additions and 243 deletions

View File

@ -240,6 +240,9 @@ where
.map_info(Either::Left),
});
}
Poll::Ready(ConnectionHandlerEvent::ReportRemoteProtocols(support)) => {
return Poll::Ready(ConnectionHandlerEvent::ReportRemoteProtocols(support));
}
Poll::Pending => (),
};
@ -257,6 +260,9 @@ where
.map_info(Either::Right),
});
}
Poll::Ready(ConnectionHandlerEvent::ReportRemoteProtocols(support)) => {
return Poll::Ready(ConnectionHandlerEvent::ReportRemoteProtocols(support));
}
Poll::Pending => (),
};
@ -317,6 +323,26 @@ where
ConnectionEvent::ListenUpgradeError(listen_upgrade_error) => {
self.on_listen_upgrade_error(listen_upgrade_error)
}
ConnectionEvent::LocalProtocolsChange(supported_protocols) => {
self.proto1
.on_connection_event(ConnectionEvent::LocalProtocolsChange(
supported_protocols.clone(),
));
self.proto2
.on_connection_event(ConnectionEvent::LocalProtocolsChange(
supported_protocols,
));
}
ConnectionEvent::RemoteProtocolsChange(supported_protocols) => {
self.proto1
.on_connection_event(ConnectionEvent::RemoteProtocolsChange(
supported_protocols.clone(),
));
self.proto2
.on_connection_event(ConnectionEvent::RemoteProtocolsChange(
supported_protocols,
));
}
}
}
}