Rework internal rpc protocol handling (#4290)

## Issue Addressed

Resolves #3980. Builds on work by @GeemoCandama in #4084 

## Proposed Changes

Extends the `SupportedProtocol` abstraction added in Geemo's PR and attempts to fix internal versioning of requests that are mentioned in this comment https://github.com/sigp/lighthouse/pull/4084#issuecomment-1496380033 

Co-authored-by: geemo <geemo@tutanota.com>
This commit is contained in:
Pawan Dhananjay
2023-06-14 05:08:50 +00:00
parent 0caaad4c03
commit 0ecca1dcb0
17 changed files with 619 additions and 584 deletions

View File

@@ -7,7 +7,8 @@ use types::{EthSpec, SignedBeaconBlock};
use crate::rpc::{
methods::{
BlocksByRangeRequest, BlocksByRootRequest, LightClientBootstrapRequest,
OldBlocksByRangeRequest, RPCCodedResponse, RPCResponse, ResponseTermination, StatusMessage,
OldBlocksByRangeRequest, OldBlocksByRangeRequestV1, OldBlocksByRangeRequestV2,
RPCCodedResponse, RPCResponse, ResponseTermination, StatusMessage,
},
OutboundRequest, SubstreamId,
};
@@ -43,14 +44,25 @@ impl<TSpec: EthSpec> std::convert::From<Request> for OutboundRequest<TSpec> {
fn from(req: Request) -> OutboundRequest<TSpec> {
match req {
Request::BlocksByRoot(r) => OutboundRequest::BlocksByRoot(r),
Request::BlocksByRange(BlocksByRangeRequest { start_slot, count }) => {
OutboundRequest::BlocksByRange(OldBlocksByRangeRequest {
start_slot,
count,
step: 1,
})
Request::BlocksByRange(r) => match r {
BlocksByRangeRequest::V1(req) => OutboundRequest::BlocksByRange(
OldBlocksByRangeRequest::V1(OldBlocksByRangeRequestV1 {
start_slot: req.start_slot,
count: req.count,
step: 1,
}),
),
BlocksByRangeRequest::V2(req) => OutboundRequest::BlocksByRange(
OldBlocksByRangeRequest::V2(OldBlocksByRangeRequestV2 {
start_slot: req.start_slot,
count: req.count,
step: 1,
}),
),
},
Request::LightClientBootstrap(_) => {
unreachable!("Lighthouse never makes an outbound light client request")
}
Request::LightClientBootstrap(b) => OutboundRequest::LightClientBootstrap(b),
Request::Status(s) => OutboundRequest::Status(s),
}
}

View File

@@ -9,6 +9,7 @@ use crate::peer_manager::{
ConnectionDirection, PeerManager, PeerManagerEvent,
};
use crate::peer_manager::{MIN_OUTBOUND_ONLY_FACTOR, PEER_EXCESS_FACTOR, PRIORITY_PEER_EXCESS};
use crate::rpc::methods::MetadataRequest;
use crate::rpc::*;
use crate::service::behaviour::BehaviourEvent;
pub use crate::service::behaviour::Gossipsub;
@@ -37,7 +38,6 @@ use slog::{crit, debug, info, o, trace, warn};
use std::path::PathBuf;
use std::pin::Pin;
use std::{
marker::PhantomData,
sync::Arc,
task::{Context, Poll},
};
@@ -944,16 +944,25 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
/// Sends a METADATA request to a peer.
fn send_meta_data_request(&mut self, peer_id: PeerId) {
let event = OutboundRequest::MetaData(PhantomData);
// We always prefer sending V2 requests
let event = OutboundRequest::MetaData(MetadataRequest::new_v2());
self.eth2_rpc_mut()
.send_request(peer_id, RequestId::Internal, event);
}
/// Sends a METADATA response to a peer.
fn send_meta_data_response(&mut self, id: PeerRequestId, peer_id: PeerId) {
let event = RPCCodedResponse::Success(RPCResponse::MetaData(
self.network_globals.local_metadata.read().clone(),
));
fn send_meta_data_response(
&mut self,
req: MetadataRequest<TSpec>,
id: PeerRequestId,
peer_id: PeerId,
) {
let metadata = self.network_globals.local_metadata.read().clone();
let metadata = match req {
MetadataRequest::V1(_) => metadata.metadata_v1(),
MetadataRequest::V2(_) => metadata,
};
let event = RPCCodedResponse::Success(RPCResponse::MetaData(metadata));
self.eth2_rpc_mut().send_response(peer_id, id, event);
}
@@ -1196,9 +1205,9 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
self.pong(peer_request_id, peer_id);
None
}
InboundRequest::MetaData(_) => {
InboundRequest::MetaData(req) => {
// send the requested meta-data
self.send_meta_data_response((handler_id, id), peer_id);
self.send_meta_data_response(req, (handler_id, id), peer_id);
None
}
InboundRequest::Goodbye(reason) => {
@@ -1225,13 +1234,9 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
Some(event)
}
InboundRequest::BlocksByRange(req) => {
let methods::OldBlocksByRangeRequest {
start_slot,
mut count,
step,
} = req;
// Still disconnect the peer if the request is naughty.
if step == 0 {
let mut count = *req.count();
if *req.step() == 0 {
self.peer_manager_mut().handle_rpc_error(
&peer_id,
Protocol::BlocksByRange,
@@ -1243,14 +1248,18 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
return None;
}
// return just one block in case the step parameter is used. https://github.com/ethereum/consensus-specs/pull/2856
if step > 1 {
if *req.step() > 1 {
count = 1;
}
let event = self.build_request(
peer_request_id,
peer_id,
Request::BlocksByRange(BlocksByRangeRequest { start_slot, count }),
);
let request = match req {
methods::OldBlocksByRangeRequest::V1(req) => Request::BlocksByRange(
BlocksByRangeRequest::new_v1(req.start_slot, count),
),
methods::OldBlocksByRangeRequest::V2(req) => Request::BlocksByRange(
BlocksByRangeRequest::new(req.start_slot, count),
),
};
let event = self.build_request(peer_request_id, peer_id, request);
Some(event)
}
InboundRequest::BlocksByRoot(req) => {

View File

@@ -272,9 +272,11 @@ pub(crate) fn save_metadata_to_disk<E: EthSpec>(
log: &slog::Logger,
) {
let _ = std::fs::create_dir_all(dir);
match File::create(dir.join(METADATA_FILENAME))
.and_then(|mut f| f.write_all(&metadata.as_ssz_bytes()))
{
let metadata_bytes = match metadata {
MetaData::V1(md) => md.as_ssz_bytes(),
MetaData::V2(md) => md.as_ssz_bytes(),
};
match File::create(dir.join(METADATA_FILENAME)).and_then(|mut f| f.write_all(&metadata_bytes)) {
Ok(_) => {
debug!(log, "Metadata written to disk");
}