mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-16 03:12:41 +00:00
Custom RPC request management for sync (#3029)
## Proposed Changes Make `lighthouse_network` generic over request ids, now usable by sync
This commit is contained in:
@@ -70,9 +70,16 @@ pub type PeerRequestId = (ConnectionId, SubstreamId);
|
||||
pub type SubscriptionFilter = MaxCountSubscriptionFilter<WhitelistSubscriptionFilter>;
|
||||
pub type Gossipsub = BaseGossipsub<SnappyTransform, SubscriptionFilter>;
|
||||
|
||||
/// Identifier of a request.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum RequestId<AppReqId> {
|
||||
Application(AppReqId),
|
||||
Behaviour,
|
||||
}
|
||||
|
||||
/// The types of events than can be obtained from polling the behaviour.
|
||||
#[derive(Debug)]
|
||||
pub enum BehaviourEvent<TSpec: EthSpec> {
|
||||
pub enum BehaviourEvent<AppReqId: ReqId, TSpec: EthSpec> {
|
||||
/// We have successfully dialed and connected to a peer.
|
||||
PeerConnectedOutgoing(PeerId),
|
||||
/// A peer has successfully dialed and connected to us.
|
||||
@@ -86,7 +93,7 @@ pub enum BehaviourEvent<TSpec: EthSpec> {
|
||||
/// An RPC Request that was sent failed.
|
||||
RPCFailed {
|
||||
/// The id of the failed request.
|
||||
id: RequestId,
|
||||
id: AppReqId,
|
||||
/// The peer to which this request was sent.
|
||||
peer_id: PeerId,
|
||||
},
|
||||
@@ -102,7 +109,7 @@ pub enum BehaviourEvent<TSpec: EthSpec> {
|
||||
/// Peer that sent the response.
|
||||
peer_id: PeerId,
|
||||
/// Id of the request to which the peer is responding.
|
||||
id: RequestId,
|
||||
id: AppReqId,
|
||||
/// Response the peer sent.
|
||||
response: Response<TSpec>,
|
||||
},
|
||||
@@ -134,16 +141,16 @@ enum InternalBehaviourMessage {
|
||||
/// behaviours.
|
||||
#[derive(NetworkBehaviour)]
|
||||
#[behaviour(
|
||||
out_event = "BehaviourEvent<TSpec>",
|
||||
out_event = "BehaviourEvent<AppReqId, TSpec>",
|
||||
poll_method = "poll",
|
||||
event_process = true
|
||||
)]
|
||||
pub struct Behaviour<TSpec: EthSpec> {
|
||||
pub struct Behaviour<AppReqId: ReqId, TSpec: EthSpec> {
|
||||
/* Sub-Behaviours */
|
||||
/// The routing pub-sub mechanism for eth2.
|
||||
gossipsub: Gossipsub,
|
||||
/// The Eth2 RPC specified in the wire-0 protocol.
|
||||
eth2_rpc: RPC<TSpec>,
|
||||
eth2_rpc: RPC<RequestId<AppReqId>, TSpec>,
|
||||
/// Discv5 Discovery protocol.
|
||||
discovery: Discovery<TSpec>,
|
||||
/// Keep regular connection to peers and disconnect if absent.
|
||||
@@ -156,7 +163,7 @@ pub struct Behaviour<TSpec: EthSpec> {
|
||||
/* Auxiliary Fields */
|
||||
/// The output events generated by this behaviour to be consumed in the swarm poll.
|
||||
#[behaviour(ignore)]
|
||||
events: VecDeque<BehaviourEvent<TSpec>>,
|
||||
events: VecDeque<BehaviourEvent<AppReqId, TSpec>>,
|
||||
/// Internal behaviour events, the NBAction type is composed of sub-behaviours, so we use a
|
||||
/// custom type here to avoid having to specify the concrete type.
|
||||
#[behaviour(ignore)]
|
||||
@@ -192,7 +199,7 @@ pub struct Behaviour<TSpec: EthSpec> {
|
||||
}
|
||||
|
||||
/// Implements the combined behaviour for the libp2p service.
|
||||
impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
impl<AppReqId: ReqId, TSpec: EthSpec> Behaviour<AppReqId, TSpec> {
|
||||
pub async fn new(
|
||||
local_key: &Keypair,
|
||||
ctx: ServiceContext<'_>,
|
||||
@@ -562,9 +569,9 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
/* Eth2 RPC behaviour functions */
|
||||
|
||||
/// Send a request to a peer over RPC.
|
||||
pub fn send_request(&mut self, peer_id: PeerId, request_id: RequestId, request: Request) {
|
||||
pub fn send_request(&mut self, peer_id: PeerId, request_id: AppReqId, request: Request) {
|
||||
self.eth2_rpc
|
||||
.send_request(peer_id, request_id, request.into())
|
||||
.send_request(peer_id, RequestId::Application(request_id), request.into())
|
||||
}
|
||||
|
||||
/// Send a successful response to a peer over RPC.
|
||||
@@ -718,12 +725,12 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
}
|
||||
|
||||
/// Sends a Ping request to the peer.
|
||||
fn ping(&mut self, id: RequestId, peer_id: PeerId) {
|
||||
fn ping(&mut self, peer_id: PeerId) {
|
||||
let ping = crate::rpc::Ping {
|
||||
data: *self.network_globals.local_metadata.read().seq_number(),
|
||||
};
|
||||
trace!(self.log, "Sending Ping"; "request_id" => id, "peer_id" => %peer_id);
|
||||
|
||||
trace!(self.log, "Sending Ping"; "peer_id" => %peer_id);
|
||||
let id = RequestId::Behaviour;
|
||||
self.eth2_rpc
|
||||
.send_request(peer_id, id, OutboundRequest::Ping(ping));
|
||||
}
|
||||
@@ -761,13 +768,19 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
|
||||
// RPC Propagation methods
|
||||
/// Queues the response to be sent upwards as long at it was requested outside the Behaviour.
|
||||
fn propagate_response(&mut self, id: RequestId, peer_id: PeerId, response: Response<TSpec>) {
|
||||
if !matches!(id, RequestId::Behaviour) {
|
||||
self.add_event(BehaviourEvent::ResponseReceived {
|
||||
fn propagate_response(
|
||||
&mut self,
|
||||
id: RequestId<AppReqId>,
|
||||
peer_id: PeerId,
|
||||
response: Response<TSpec>,
|
||||
) {
|
||||
match id {
|
||||
RequestId::Application(id) => self.add_event(BehaviourEvent::ResponseReceived {
|
||||
peer_id,
|
||||
id,
|
||||
response,
|
||||
});
|
||||
}),
|
||||
RequestId::Behaviour => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -793,7 +806,7 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
}
|
||||
|
||||
/// Adds an event to the queue waking the current task to process it.
|
||||
fn add_event(&mut self, event: BehaviourEvent<TSpec>) {
|
||||
fn add_event(&mut self, event: BehaviourEvent<AppReqId, TSpec>) {
|
||||
self.events.push_back(event);
|
||||
if let Some(waker) = &self.waker {
|
||||
waker.wake_by_ref();
|
||||
@@ -869,7 +882,11 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
*/
|
||||
|
||||
// Gossipsub
|
||||
impl<TSpec: EthSpec> NetworkBehaviourEventProcess<GossipsubEvent> for Behaviour<TSpec> {
|
||||
impl<AppReqId, TSpec> NetworkBehaviourEventProcess<GossipsubEvent> for Behaviour<AppReqId, TSpec>
|
||||
where
|
||||
AppReqId: ReqId,
|
||||
TSpec: EthSpec,
|
||||
{
|
||||
fn inject_event(&mut self, event: GossipsubEvent) {
|
||||
match event {
|
||||
GossipsubEvent::Message {
|
||||
@@ -961,8 +978,13 @@ impl<TSpec: EthSpec> NetworkBehaviourEventProcess<GossipsubEvent> for Behaviour<
|
||||
}
|
||||
|
||||
// RPC
|
||||
impl<TSpec: EthSpec> NetworkBehaviourEventProcess<RPCMessage<TSpec>> for Behaviour<TSpec> {
|
||||
fn inject_event(&mut self, event: RPCMessage<TSpec>) {
|
||||
impl<AppReqId, TSpec> NetworkBehaviourEventProcess<RPCMessage<RequestId<AppReqId>, TSpec>>
|
||||
for Behaviour<AppReqId, TSpec>
|
||||
where
|
||||
AppReqId: ReqId,
|
||||
TSpec: EthSpec,
|
||||
{
|
||||
fn inject_event(&mut self, event: RPCMessage<RequestId<AppReqId>, TSpec>) {
|
||||
let peer_id = event.peer_id;
|
||||
|
||||
if !self.peer_manager.is_connected(&peer_id) {
|
||||
@@ -1006,7 +1028,7 @@ impl<TSpec: EthSpec> NetworkBehaviourEventProcess<RPCMessage<TSpec>> for Behavio
|
||||
ConnectionDirection::Outgoing,
|
||||
);
|
||||
// inform failures of requests comming outside the behaviour
|
||||
if !matches!(id, RequestId::Behaviour) {
|
||||
if let RequestId::Application(id) = id {
|
||||
self.add_event(BehaviourEvent::RPCFailed { peer_id, id });
|
||||
}
|
||||
}
|
||||
@@ -1090,7 +1112,11 @@ impl<TSpec: EthSpec> NetworkBehaviourEventProcess<RPCMessage<TSpec>> for Behavio
|
||||
}
|
||||
|
||||
// Discovery
|
||||
impl<TSpec: EthSpec> NetworkBehaviourEventProcess<DiscoveryEvent> for Behaviour<TSpec> {
|
||||
impl<AppReqId, TSpec> NetworkBehaviourEventProcess<DiscoveryEvent> for Behaviour<AppReqId, TSpec>
|
||||
where
|
||||
AppReqId: ReqId,
|
||||
TSpec: EthSpec,
|
||||
{
|
||||
fn inject_event(&mut self, event: DiscoveryEvent) {
|
||||
match event {
|
||||
DiscoveryEvent::SocketUpdated(socket_addr) => {
|
||||
@@ -1119,7 +1145,11 @@ impl<TSpec: EthSpec> NetworkBehaviourEventProcess<DiscoveryEvent> for Behaviour<
|
||||
}
|
||||
|
||||
// Identify
|
||||
impl<TSpec: EthSpec> NetworkBehaviourEventProcess<IdentifyEvent> for Behaviour<TSpec> {
|
||||
impl<AppReqId, TSpec> NetworkBehaviourEventProcess<IdentifyEvent> for Behaviour<AppReqId, TSpec>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
AppReqId: ReqId,
|
||||
{
|
||||
fn inject_event(&mut self, event: IdentifyEvent) {
|
||||
match event {
|
||||
IdentifyEvent::Received { peer_id, mut info } => {
|
||||
@@ -1140,15 +1170,20 @@ impl<TSpec: EthSpec> NetworkBehaviourEventProcess<IdentifyEvent> for Behaviour<T
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
type BehaviourHandler<AppReqId, TSpec> =
|
||||
<Behaviour<AppReqId, TSpec> as NetworkBehaviour>::ConnectionHandler;
|
||||
|
||||
impl<AppReqId, TSpec> Behaviour<AppReqId, TSpec>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
AppReqId: ReqId,
|
||||
{
|
||||
/// Consumes the events list and drives the Lighthouse global NetworkBehaviour.
|
||||
fn poll(
|
||||
&mut self,
|
||||
cx: &mut Context,
|
||||
_: &mut impl PollParameters,
|
||||
) -> Poll<
|
||||
NBAction<BehaviourEvent<TSpec>, <Behaviour<TSpec> as NetworkBehaviour>::ConnectionHandler>,
|
||||
> {
|
||||
) -> Poll<NBAction<BehaviourEvent<AppReqId, TSpec>, BehaviourHandler<AppReqId, TSpec>>> {
|
||||
if let Some(waker) = &self.waker {
|
||||
if waker.will_wake(cx.waker()) {
|
||||
self.waker = Some(cx.waker().clone());
|
||||
@@ -1207,7 +1242,9 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> NetworkBehaviourEventProcess<PeerManagerEvent> for Behaviour<TSpec> {
|
||||
impl<AppReqId: ReqId, TSpec: EthSpec> NetworkBehaviourEventProcess<PeerManagerEvent>
|
||||
for Behaviour<AppReqId, TSpec>
|
||||
{
|
||||
fn inject_event(&mut self, event: PeerManagerEvent) {
|
||||
match event {
|
||||
PeerManagerEvent::PeerConnectedIncoming(peer_id) => {
|
||||
@@ -1242,7 +1279,7 @@ impl<TSpec: EthSpec> NetworkBehaviourEventProcess<PeerManagerEvent> for Behaviou
|
||||
}
|
||||
PeerManagerEvent::Ping(peer_id) => {
|
||||
// send a ping request to this peer
|
||||
self.ping(RequestId::Behaviour, peer_id);
|
||||
self.ping(peer_id);
|
||||
}
|
||||
PeerManagerEvent::MetaData(peer_id) => {
|
||||
self.send_meta_data_request(peer_id);
|
||||
@@ -1251,7 +1288,8 @@ impl<TSpec: EthSpec> NetworkBehaviourEventProcess<PeerManagerEvent> for Behaviou
|
||||
debug!(self.log, "Peer Manager disconnecting peer";
|
||||
"peer_id" => %peer_id, "reason" => %reason);
|
||||
// send one goodbye
|
||||
self.eth2_rpc.shutdown(peer_id, reason);
|
||||
self.eth2_rpc
|
||||
.shutdown(peer_id, RequestId::Behaviour, reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1335,3 +1373,19 @@ pub fn save_metadata_to_disk<E: EthSpec>(dir: &Path, metadata: MetaData<E>, log:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<AppReqId: std::fmt::Debug> slog::Value for RequestId<AppReqId> {
|
||||
fn serialize(
|
||||
&self,
|
||||
record: &slog::Record,
|
||||
key: slog::Key,
|
||||
serializer: &mut dyn slog::Serializer,
|
||||
) -> slog::Result {
|
||||
match self {
|
||||
RequestId::Behaviour => slog::Value::serialize("Behaviour", record, key, serializer),
|
||||
RequestId::Application(ref id) => {
|
||||
slog::Value::serialize(&format_args!("{:?}", id), record, key, serializer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user