mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-31 13:17:09 +00:00
Use E for EthSpec globally (#5264)
* Use `E` for `EthSpec` globally * Fix tests * Merge branch 'unstable' into e-ethspec * Merge branch 'unstable' into e-ethspec # Conflicts: # beacon_node/execution_layer/src/engine_api.rs # beacon_node/execution_layer/src/engine_api/http.rs # beacon_node/execution_layer/src/engine_api/json_structures.rs # beacon_node/execution_layer/src/test_utils/handle_rpc.rs # beacon_node/store/src/partial_beacon_state.rs # consensus/types/src/beacon_block.rs # consensus/types/src/beacon_block_body.rs # consensus/types/src/beacon_state.rs # consensus/types/src/config_and_preset.rs # consensus/types/src/execution_payload.rs # consensus/types/src/execution_payload_header.rs # consensus/types/src/light_client_optimistic_update.rs # consensus/types/src/payload.rs # lcli/src/parse_ssz.rs
This commit is contained in:
@@ -20,20 +20,20 @@ pub trait OutboundCodec<TItem>: Encoder<TItem> + Decoder {
|
||||
/* Global Inbound Codec */
|
||||
// This deals with Decoding RPC Requests from other peers and encoding our responses
|
||||
|
||||
pub struct BaseInboundCodec<TCodec, TSpec>
|
||||
pub struct BaseInboundCodec<TCodec, E>
|
||||
where
|
||||
TCodec: Encoder<RPCCodedResponse<TSpec>> + Decoder,
|
||||
TSpec: EthSpec,
|
||||
TCodec: Encoder<RPCCodedResponse<E>> + Decoder,
|
||||
E: EthSpec,
|
||||
{
|
||||
/// Inner codec for handling various encodings
|
||||
inner: TCodec,
|
||||
phantom: PhantomData<TSpec>,
|
||||
phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<TCodec, TSpec> BaseInboundCodec<TCodec, TSpec>
|
||||
impl<TCodec, E> BaseInboundCodec<TCodec, E>
|
||||
where
|
||||
TCodec: Encoder<RPCCodedResponse<TSpec>> + Decoder,
|
||||
TSpec: EthSpec,
|
||||
TCodec: Encoder<RPCCodedResponse<E>> + Decoder,
|
||||
E: EthSpec,
|
||||
{
|
||||
pub fn new(codec: TCodec) -> Self {
|
||||
BaseInboundCodec {
|
||||
@@ -45,22 +45,22 @@ where
|
||||
|
||||
/* Global Outbound Codec */
|
||||
// This deals with Decoding RPC Responses from other peers and encoding our requests
|
||||
pub struct BaseOutboundCodec<TOutboundCodec, TSpec>
|
||||
pub struct BaseOutboundCodec<TOutboundCodec, E>
|
||||
where
|
||||
TOutboundCodec: OutboundCodec<OutboundRequest<TSpec>>,
|
||||
TSpec: EthSpec,
|
||||
TOutboundCodec: OutboundCodec<OutboundRequest<E>>,
|
||||
E: EthSpec,
|
||||
{
|
||||
/// Inner codec for handling various encodings.
|
||||
inner: TOutboundCodec,
|
||||
/// Keeps track of the current response code for a chunk.
|
||||
current_response_code: Option<u8>,
|
||||
phantom: PhantomData<TSpec>,
|
||||
phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<TOutboundCodec, TSpec> BaseOutboundCodec<TOutboundCodec, TSpec>
|
||||
impl<TOutboundCodec, E> BaseOutboundCodec<TOutboundCodec, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
TOutboundCodec: OutboundCodec<OutboundRequest<TSpec>>,
|
||||
E: EthSpec,
|
||||
TOutboundCodec: OutboundCodec<OutboundRequest<E>>,
|
||||
{
|
||||
pub fn new(codec: TOutboundCodec) -> Self {
|
||||
BaseOutboundCodec {
|
||||
@@ -76,18 +76,14 @@ where
|
||||
/* Base Inbound Codec */
|
||||
|
||||
// This Encodes RPC Responses sent to external peers
|
||||
impl<TCodec, TSpec> Encoder<RPCCodedResponse<TSpec>> for BaseInboundCodec<TCodec, TSpec>
|
||||
impl<TCodec, E> Encoder<RPCCodedResponse<E>> for BaseInboundCodec<TCodec, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
TCodec: Decoder + Encoder<RPCCodedResponse<TSpec>>,
|
||||
E: EthSpec,
|
||||
TCodec: Decoder + Encoder<RPCCodedResponse<E>>,
|
||||
{
|
||||
type Error = <TCodec as Encoder<RPCCodedResponse<TSpec>>>::Error;
|
||||
type Error = <TCodec as Encoder<RPCCodedResponse<E>>>::Error;
|
||||
|
||||
fn encode(
|
||||
&mut self,
|
||||
item: RPCCodedResponse<TSpec>,
|
||||
dst: &mut BytesMut,
|
||||
) -> Result<(), Self::Error> {
|
||||
fn encode(&mut self, item: RPCCodedResponse<E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
dst.clear();
|
||||
dst.reserve(1);
|
||||
dst.put_u8(
|
||||
@@ -99,12 +95,12 @@ where
|
||||
}
|
||||
|
||||
// This Decodes RPC Requests from external peers
|
||||
impl<TCodec, TSpec> Decoder for BaseInboundCodec<TCodec, TSpec>
|
||||
impl<TCodec, E> Decoder for BaseInboundCodec<TCodec, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
TCodec: Encoder<RPCCodedResponse<TSpec>> + Decoder<Item = InboundRequest<TSpec>>,
|
||||
E: EthSpec,
|
||||
TCodec: Encoder<RPCCodedResponse<E>> + Decoder<Item = InboundRequest<E>>,
|
||||
{
|
||||
type Item = InboundRequest<TSpec>;
|
||||
type Item = InboundRequest<E>;
|
||||
type Error = <TCodec as Decoder>::Error;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
@@ -115,30 +111,26 @@ where
|
||||
/* Base Outbound Codec */
|
||||
|
||||
// This Encodes RPC Requests sent to external peers
|
||||
impl<TCodec, TSpec> Encoder<OutboundRequest<TSpec>> for BaseOutboundCodec<TCodec, TSpec>
|
||||
impl<TCodec, E> Encoder<OutboundRequest<E>> for BaseOutboundCodec<TCodec, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
TCodec: OutboundCodec<OutboundRequest<TSpec>> + Encoder<OutboundRequest<TSpec>>,
|
||||
E: EthSpec,
|
||||
TCodec: OutboundCodec<OutboundRequest<E>> + Encoder<OutboundRequest<E>>,
|
||||
{
|
||||
type Error = <TCodec as Encoder<OutboundRequest<TSpec>>>::Error;
|
||||
type Error = <TCodec as Encoder<OutboundRequest<E>>>::Error;
|
||||
|
||||
fn encode(
|
||||
&mut self,
|
||||
item: OutboundRequest<TSpec>,
|
||||
dst: &mut BytesMut,
|
||||
) -> Result<(), Self::Error> {
|
||||
fn encode(&mut self, item: OutboundRequest<E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
self.inner.encode(item, dst)
|
||||
}
|
||||
}
|
||||
|
||||
// This decodes RPC Responses received from external peers
|
||||
impl<TCodec, TSpec> Decoder for BaseOutboundCodec<TCodec, TSpec>
|
||||
impl<TCodec, E> Decoder for BaseOutboundCodec<TCodec, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
TCodec: OutboundCodec<OutboundRequest<TSpec>, CodecErrorType = ErrorType>
|
||||
+ Decoder<Item = RPCResponse<TSpec>>,
|
||||
E: EthSpec,
|
||||
TCodec: OutboundCodec<OutboundRequest<E>, CodecErrorType = ErrorType>
|
||||
+ Decoder<Item = RPCResponse<E>>,
|
||||
{
|
||||
type Item = RPCCodedResponse<TSpec>;
|
||||
type Item = RPCCodedResponse<E>;
|
||||
type Error = <TCodec as Decoder>::Error;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
@@ -154,7 +146,7 @@ where
|
||||
});
|
||||
|
||||
let inner_result = {
|
||||
if RPCCodedResponse::<TSpec>::is_response(response_code) {
|
||||
if RPCCodedResponse::<E>::is_response(response_code) {
|
||||
// decode an actual response and mutates the buffer if enough bytes have been read
|
||||
// returning the result.
|
||||
self.inner
|
||||
|
||||
@@ -10,26 +10,26 @@ use tokio_util::codec::{Decoder, Encoder};
|
||||
use types::EthSpec;
|
||||
|
||||
// Known types of codecs
|
||||
pub enum InboundCodec<TSpec: EthSpec> {
|
||||
SSZSnappy(BaseInboundCodec<SSZSnappyInboundCodec<TSpec>, TSpec>),
|
||||
pub enum InboundCodec<E: EthSpec> {
|
||||
SSZSnappy(BaseInboundCodec<SSZSnappyInboundCodec<E>, E>),
|
||||
}
|
||||
|
||||
pub enum OutboundCodec<TSpec: EthSpec> {
|
||||
SSZSnappy(BaseOutboundCodec<SSZSnappyOutboundCodec<TSpec>, TSpec>),
|
||||
pub enum OutboundCodec<E: EthSpec> {
|
||||
SSZSnappy(BaseOutboundCodec<SSZSnappyOutboundCodec<E>, E>),
|
||||
}
|
||||
|
||||
impl<T: EthSpec> Encoder<RPCCodedResponse<T>> for InboundCodec<T> {
|
||||
impl<E: EthSpec> Encoder<RPCCodedResponse<E>> for InboundCodec<E> {
|
||||
type Error = RPCError;
|
||||
|
||||
fn encode(&mut self, item: RPCCodedResponse<T>, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
fn encode(&mut self, item: RPCCodedResponse<E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
match self {
|
||||
InboundCodec::SSZSnappy(codec) => codec.encode(item, dst),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> Decoder for InboundCodec<TSpec> {
|
||||
type Item = InboundRequest<TSpec>;
|
||||
impl<E: EthSpec> Decoder for InboundCodec<E> {
|
||||
type Item = InboundRequest<E>;
|
||||
type Error = RPCError;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
@@ -39,22 +39,18 @@ impl<TSpec: EthSpec> Decoder for InboundCodec<TSpec> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> Encoder<OutboundRequest<TSpec>> for OutboundCodec<TSpec> {
|
||||
impl<E: EthSpec> Encoder<OutboundRequest<E>> for OutboundCodec<E> {
|
||||
type Error = RPCError;
|
||||
|
||||
fn encode(
|
||||
&mut self,
|
||||
item: OutboundRequest<TSpec>,
|
||||
dst: &mut BytesMut,
|
||||
) -> Result<(), Self::Error> {
|
||||
fn encode(&mut self, item: OutboundRequest<E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
match self {
|
||||
OutboundCodec::SSZSnappy(codec) => codec.encode(item, dst),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> Decoder for OutboundCodec<T> {
|
||||
type Item = RPCCodedResponse<T>;
|
||||
impl<E: EthSpec> Decoder for OutboundCodec<E> {
|
||||
type Item = RPCCodedResponse<E>;
|
||||
type Error = RPCError;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
|
||||
@@ -28,17 +28,17 @@ const CONTEXT_BYTES_LEN: usize = 4;
|
||||
|
||||
/* Inbound Codec */
|
||||
|
||||
pub struct SSZSnappyInboundCodec<TSpec: EthSpec> {
|
||||
pub struct SSZSnappyInboundCodec<E: EthSpec> {
|
||||
protocol: ProtocolId,
|
||||
inner: Uvi<usize>,
|
||||
len: Option<usize>,
|
||||
/// Maximum bytes that can be sent in one req/resp chunked responses.
|
||||
max_packet_size: usize,
|
||||
fork_context: Arc<ForkContext>,
|
||||
phantom: PhantomData<TSpec>,
|
||||
phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> SSZSnappyInboundCodec<T> {
|
||||
impl<E: EthSpec> SSZSnappyInboundCodec<E> {
|
||||
pub fn new(
|
||||
protocol: ProtocolId,
|
||||
max_packet_size: usize,
|
||||
@@ -60,14 +60,10 @@ impl<T: EthSpec> SSZSnappyInboundCodec<T> {
|
||||
}
|
||||
|
||||
// Encoder for inbound streams: Encodes RPC Responses sent to peers.
|
||||
impl<TSpec: EthSpec> Encoder<RPCCodedResponse<TSpec>> for SSZSnappyInboundCodec<TSpec> {
|
||||
impl<E: EthSpec> Encoder<RPCCodedResponse<E>> for SSZSnappyInboundCodec<E> {
|
||||
type Error = RPCError;
|
||||
|
||||
fn encode(
|
||||
&mut self,
|
||||
item: RPCCodedResponse<TSpec>,
|
||||
dst: &mut BytesMut,
|
||||
) -> Result<(), Self::Error> {
|
||||
fn encode(&mut self, item: RPCCodedResponse<E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
let bytes = match &item {
|
||||
RPCCodedResponse::Success(resp) => match &resp {
|
||||
RPCResponse::Status(res) => res.as_ssz_bytes(),
|
||||
@@ -125,8 +121,8 @@ impl<TSpec: EthSpec> Encoder<RPCCodedResponse<TSpec>> for SSZSnappyInboundCodec<
|
||||
}
|
||||
|
||||
// Decoder for inbound streams: Decodes RPC requests from peers
|
||||
impl<TSpec: EthSpec> Decoder for SSZSnappyInboundCodec<TSpec> {
|
||||
type Item = InboundRequest<TSpec>;
|
||||
impl<E: EthSpec> Decoder for SSZSnappyInboundCodec<E> {
|
||||
type Item = InboundRequest<E>;
|
||||
type Error = RPCError;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
@@ -175,7 +171,7 @@ impl<TSpec: EthSpec> Decoder for SSZSnappyInboundCodec<TSpec> {
|
||||
}
|
||||
|
||||
/* Outbound Codec: Codec for initiating RPC requests */
|
||||
pub struct SSZSnappyOutboundCodec<TSpec: EthSpec> {
|
||||
pub struct SSZSnappyOutboundCodec<E: EthSpec> {
|
||||
inner: Uvi<usize>,
|
||||
len: Option<usize>,
|
||||
protocol: ProtocolId,
|
||||
@@ -184,10 +180,10 @@ pub struct SSZSnappyOutboundCodec<TSpec: EthSpec> {
|
||||
/// The fork name corresponding to the received context bytes.
|
||||
fork_name: Option<ForkName>,
|
||||
fork_context: Arc<ForkContext>,
|
||||
phantom: PhantomData<TSpec>,
|
||||
phantom: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> SSZSnappyOutboundCodec<TSpec> {
|
||||
impl<E: EthSpec> SSZSnappyOutboundCodec<E> {
|
||||
pub fn new(
|
||||
protocol: ProtocolId,
|
||||
max_packet_size: usize,
|
||||
@@ -210,14 +206,10 @@ impl<TSpec: EthSpec> SSZSnappyOutboundCodec<TSpec> {
|
||||
}
|
||||
|
||||
// Encoder for outbound streams: Encodes RPC Requests to peers
|
||||
impl<TSpec: EthSpec> Encoder<OutboundRequest<TSpec>> for SSZSnappyOutboundCodec<TSpec> {
|
||||
impl<E: EthSpec> Encoder<OutboundRequest<E>> for SSZSnappyOutboundCodec<E> {
|
||||
type Error = RPCError;
|
||||
|
||||
fn encode(
|
||||
&mut self,
|
||||
item: OutboundRequest<TSpec>,
|
||||
dst: &mut BytesMut,
|
||||
) -> Result<(), Self::Error> {
|
||||
fn encode(&mut self, item: OutboundRequest<E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
let bytes = match item {
|
||||
OutboundRequest::Status(req) => req.as_ssz_bytes(),
|
||||
OutboundRequest::Goodbye(req) => req.as_ssz_bytes(),
|
||||
@@ -262,8 +254,8 @@ impl<TSpec: EthSpec> Encoder<OutboundRequest<TSpec>> for SSZSnappyOutboundCodec<
|
||||
// The majority of the decoding has now been pushed upstream due to the changing specification.
|
||||
// We prefer to decode blocks and attestations with extra knowledge about the chain to perform
|
||||
// faster verification checks before decoding entire blocks/attestations.
|
||||
impl<TSpec: EthSpec> Decoder for SSZSnappyOutboundCodec<TSpec> {
|
||||
type Item = RPCResponse<TSpec>;
|
||||
impl<E: EthSpec> Decoder for SSZSnappyOutboundCodec<E> {
|
||||
type Item = RPCResponse<E>;
|
||||
type Error = RPCError;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
@@ -287,9 +279,7 @@ impl<TSpec: EthSpec> Decoder for SSZSnappyOutboundCodec<TSpec> {
|
||||
|
||||
// Should not attempt to decode rpc chunks with `length > max_packet_size` or not within bounds of
|
||||
// packet size for ssz container corresponding to `self.protocol`.
|
||||
let ssz_limits = self
|
||||
.protocol
|
||||
.rpc_response_limits::<TSpec>(&self.fork_context);
|
||||
let ssz_limits = self.protocol.rpc_response_limits::<E>(&self.fork_context);
|
||||
if ssz_limits.is_out_of_bounds(length, self.max_packet_size) {
|
||||
return Err(RPCError::InvalidData(format!(
|
||||
"RPC response length is out of bounds, length {}, max {}, min {}",
|
||||
@@ -320,7 +310,7 @@ impl<TSpec: EthSpec> Decoder for SSZSnappyOutboundCodec<TSpec> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> OutboundCodec<OutboundRequest<TSpec>> for SSZSnappyOutboundCodec<TSpec> {
|
||||
impl<E: EthSpec> OutboundCodec<OutboundRequest<E>> for SSZSnappyOutboundCodec<E> {
|
||||
type CodecErrorType = ErrorType;
|
||||
|
||||
fn decode_error(
|
||||
@@ -389,10 +379,10 @@ fn handle_error<T>(
|
||||
|
||||
/// Returns `Some(context_bytes)` for encoding RPC responses that require context bytes.
|
||||
/// Returns `None` when context bytes are not required.
|
||||
fn context_bytes<T: EthSpec>(
|
||||
fn context_bytes<E: EthSpec>(
|
||||
protocol: &ProtocolId,
|
||||
fork_context: &ForkContext,
|
||||
resp: &RPCCodedResponse<T>,
|
||||
resp: &RPCCodedResponse<E>,
|
||||
) -> Option<[u8; CONTEXT_BYTES_LEN]> {
|
||||
// Add the context bytes if required
|
||||
if protocol.has_context_bytes() {
|
||||
@@ -457,11 +447,11 @@ fn handle_length(
|
||||
/// Decodes an `InboundRequest` from the byte stream.
|
||||
/// `decoded_buffer` should be an ssz-encoded bytestream with
|
||||
// length = length-prefix received in the beginning of the stream.
|
||||
fn handle_rpc_request<T: EthSpec>(
|
||||
fn handle_rpc_request<E: EthSpec>(
|
||||
versioned_protocol: SupportedProtocol,
|
||||
decoded_buffer: &[u8],
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Option<InboundRequest<T>>, RPCError> {
|
||||
) -> Result<Option<InboundRequest<E>>, RPCError> {
|
||||
match versioned_protocol {
|
||||
SupportedProtocol::StatusV1 => Ok(Some(InboundRequest::Status(
|
||||
StatusMessage::from_ssz_bytes(decoded_buffer)?,
|
||||
@@ -537,11 +527,11 @@ fn handle_rpc_request<T: EthSpec>(
|
||||
///
|
||||
/// For BlocksByRange/BlocksByRoot reponses, decodes the appropriate response
|
||||
/// according to the received `ForkName`.
|
||||
fn handle_rpc_response<T: EthSpec>(
|
||||
fn handle_rpc_response<E: EthSpec>(
|
||||
versioned_protocol: SupportedProtocol,
|
||||
decoded_buffer: &[u8],
|
||||
fork_name: Option<ForkName>,
|
||||
) -> Result<Option<RPCResponse<T>>, RPCError> {
|
||||
) -> Result<Option<RPCResponse<E>>, RPCError> {
|
||||
match versioned_protocol {
|
||||
SupportedProtocol::StatusV1 => Ok(Some(RPCResponse::Status(
|
||||
StatusMessage::from_ssz_bytes(decoded_buffer)?,
|
||||
|
||||
@@ -47,12 +47,12 @@ impl SubstreamId {
|
||||
}
|
||||
}
|
||||
|
||||
type InboundSubstream<TSpec> = InboundFramed<Stream, TSpec>;
|
||||
type InboundSubstream<E> = InboundFramed<Stream, E>;
|
||||
|
||||
/// Events the handler emits to the behaviour.
|
||||
#[derive(Debug)]
|
||||
pub enum HandlerEvent<Id, T: EthSpec> {
|
||||
Ok(RPCReceived<Id, T>),
|
||||
pub enum HandlerEvent<Id, E: EthSpec> {
|
||||
Ok(RPCReceived<Id, E>),
|
||||
Err(HandlerErr<Id>),
|
||||
Close(RPCError),
|
||||
}
|
||||
@@ -84,30 +84,30 @@ pub enum HandlerErr<Id> {
|
||||
}
|
||||
|
||||
/// Implementation of `ConnectionHandler` for the RPC protocol.
|
||||
pub struct RPCHandler<Id, TSpec>
|
||||
pub struct RPCHandler<Id, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
E: EthSpec,
|
||||
{
|
||||
/// The upgrade for inbound substreams.
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol<TSpec>, ()>,
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol<E>, ()>,
|
||||
|
||||
/// Queue of events to produce in `poll()`.
|
||||
events_out: SmallVec<[HandlerEvent<Id, TSpec>; 4]>,
|
||||
events_out: SmallVec<[HandlerEvent<Id, E>; 4]>,
|
||||
|
||||
/// Queue of outbound substreams to open.
|
||||
dial_queue: SmallVec<[(Id, OutboundRequest<TSpec>); 4]>,
|
||||
dial_queue: SmallVec<[(Id, OutboundRequest<E>); 4]>,
|
||||
|
||||
/// Current number of concurrent outbound substreams being opened.
|
||||
dial_negotiated: u32,
|
||||
|
||||
/// Current inbound substreams awaiting processing.
|
||||
inbound_substreams: FnvHashMap<SubstreamId, InboundInfo<TSpec>>,
|
||||
inbound_substreams: FnvHashMap<SubstreamId, InboundInfo<E>>,
|
||||
|
||||
/// Inbound substream `DelayQueue` which keeps track of when an inbound substream will timeout.
|
||||
inbound_substreams_delay: DelayQueue<SubstreamId>,
|
||||
|
||||
/// Map of outbound substreams that need to be driven to completion.
|
||||
outbound_substreams: FnvHashMap<SubstreamId, OutboundInfo<Id, TSpec>>,
|
||||
outbound_substreams: FnvHashMap<SubstreamId, OutboundInfo<Id, E>>,
|
||||
|
||||
/// Inbound substream `DelayQueue` which keeps track of when an inbound substream will timeout.
|
||||
outbound_substreams_delay: DelayQueue<SubstreamId>,
|
||||
@@ -155,11 +155,11 @@ enum HandlerState {
|
||||
}
|
||||
|
||||
/// Contains the information the handler keeps on established inbound substreams.
|
||||
struct InboundInfo<TSpec: EthSpec> {
|
||||
struct InboundInfo<E: EthSpec> {
|
||||
/// State of the substream.
|
||||
state: InboundState<TSpec>,
|
||||
state: InboundState<E>,
|
||||
/// Responses queued for sending.
|
||||
pending_items: VecDeque<RPCCodedResponse<TSpec>>,
|
||||
pending_items: VecDeque<RPCCodedResponse<E>>,
|
||||
/// Protocol of the original request we received from the peer.
|
||||
protocol: Protocol,
|
||||
/// Responses that the peer is still expecting from us.
|
||||
@@ -172,9 +172,9 @@ struct InboundInfo<TSpec: EthSpec> {
|
||||
}
|
||||
|
||||
/// Contains the information the handler keeps on established outbound substreams.
|
||||
struct OutboundInfo<Id, TSpec: EthSpec> {
|
||||
struct OutboundInfo<Id, E: EthSpec> {
|
||||
/// State of the substream.
|
||||
state: OutboundSubstreamState<TSpec>,
|
||||
state: OutboundSubstreamState<E>,
|
||||
/// Key to keep track of the substream's timeout via `self.outbound_substreams_delay`.
|
||||
delay_key: delay_queue::Key,
|
||||
/// Info over the protocol this substream is handling.
|
||||
@@ -186,39 +186,39 @@ struct OutboundInfo<Id, TSpec: EthSpec> {
|
||||
}
|
||||
|
||||
/// State of an inbound substream connection.
|
||||
enum InboundState<TSpec: EthSpec> {
|
||||
enum InboundState<E: EthSpec> {
|
||||
/// The underlying substream is not being used.
|
||||
Idle(InboundSubstream<TSpec>),
|
||||
Idle(InboundSubstream<E>),
|
||||
/// The underlying substream is processing responses.
|
||||
/// The return value of the future is (substream, stream_was_closed). The stream_was_closed boolean
|
||||
/// indicates if the stream was closed due to an error or successfully completing a response.
|
||||
Busy(Pin<Box<dyn Future<Output = Result<(InboundSubstream<TSpec>, bool), RPCError>> + Send>>),
|
||||
Busy(Pin<Box<dyn Future<Output = Result<(InboundSubstream<E>, bool), RPCError>> + Send>>),
|
||||
/// Temporary state during processing
|
||||
Poisoned,
|
||||
}
|
||||
|
||||
/// State of an outbound substream. Either waiting for a response, or in the process of sending.
|
||||
pub enum OutboundSubstreamState<TSpec: EthSpec> {
|
||||
pub enum OutboundSubstreamState<E: EthSpec> {
|
||||
/// A request has been sent, and we are awaiting a response. This future is driven in the
|
||||
/// handler because GOODBYE requests can be handled and responses dropped instantly.
|
||||
RequestPendingResponse {
|
||||
/// The framed negotiated substream.
|
||||
substream: Box<OutboundFramed<Stream, TSpec>>,
|
||||
substream: Box<OutboundFramed<Stream, E>>,
|
||||
/// Keeps track of the actual request sent.
|
||||
request: OutboundRequest<TSpec>,
|
||||
request: OutboundRequest<E>,
|
||||
},
|
||||
/// Closing an outbound substream>
|
||||
Closing(Box<OutboundFramed<Stream, TSpec>>),
|
||||
Closing(Box<OutboundFramed<Stream, E>>),
|
||||
/// Temporary state during processing
|
||||
Poisoned,
|
||||
}
|
||||
|
||||
impl<Id, TSpec> RPCHandler<Id, TSpec>
|
||||
impl<Id, E> RPCHandler<Id, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
E: EthSpec,
|
||||
{
|
||||
pub fn new(
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol<TSpec>, ()>,
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol<E>, ()>,
|
||||
fork_context: Arc<ForkContext>,
|
||||
log: &slog::Logger,
|
||||
resp_timeout: Duration,
|
||||
@@ -273,7 +273,7 @@ where
|
||||
}
|
||||
|
||||
/// Opens an outbound substream with a request.
|
||||
fn send_request(&mut self, id: Id, req: OutboundRequest<TSpec>) {
|
||||
fn send_request(&mut self, id: Id, req: OutboundRequest<E>) {
|
||||
match self.state {
|
||||
HandlerState::Active => {
|
||||
self.dial_queue.push((id, req));
|
||||
@@ -291,7 +291,7 @@ where
|
||||
/// Sends a response to a peer's request.
|
||||
// NOTE: If the substream has closed due to inactivity, or the substream is in the
|
||||
// wrong state a response will fail silently.
|
||||
fn send_response(&mut self, inbound_id: SubstreamId, response: RPCCodedResponse<TSpec>) {
|
||||
fn send_response(&mut self, inbound_id: SubstreamId, response: RPCCodedResponse<E>) {
|
||||
// check if the stream matching the response still exists
|
||||
let Some(inbound_info) = self.inbound_substreams.get_mut(&inbound_id) else {
|
||||
if !matches!(response, RPCCodedResponse::StreamTermination(..)) {
|
||||
@@ -320,16 +320,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id, TSpec> ConnectionHandler for RPCHandler<Id, TSpec>
|
||||
impl<Id, E> ConnectionHandler for RPCHandler<Id, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
E: EthSpec,
|
||||
Id: ReqId,
|
||||
{
|
||||
type FromBehaviour = RPCSend<Id, TSpec>;
|
||||
type ToBehaviour = HandlerEvent<Id, TSpec>;
|
||||
type InboundProtocol = RPCProtocol<TSpec>;
|
||||
type OutboundProtocol = OutboundRequestContainer<TSpec>;
|
||||
type OutboundOpenInfo = (Id, OutboundRequest<TSpec>); // Keep track of the id and the request
|
||||
type FromBehaviour = RPCSend<Id, E>;
|
||||
type ToBehaviour = HandlerEvent<Id, E>;
|
||||
type InboundProtocol = RPCProtocol<E>;
|
||||
type OutboundProtocol = OutboundRequestContainer<E>;
|
||||
type OutboundOpenInfo = (Id, OutboundRequest<E>); // Keep track of the id and the request
|
||||
type InboundOpenInfo = ();
|
||||
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, ()> {
|
||||
@@ -868,12 +868,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id, TSpec: EthSpec> RPCHandler<Id, TSpec>
|
||||
impl<Id, E: EthSpec> RPCHandler<Id, E>
|
||||
where
|
||||
Id: ReqId,
|
||||
TSpec: EthSpec,
|
||||
E: EthSpec,
|
||||
{
|
||||
fn on_fully_negotiated_inbound(&mut self, substream: InboundOutput<Stream, TSpec>) {
|
||||
fn on_fully_negotiated_inbound(&mut self, substream: InboundOutput<Stream, E>) {
|
||||
// only accept new peer requests when active
|
||||
if !matches!(self.state, HandlerState::Active) {
|
||||
return;
|
||||
@@ -928,8 +928,8 @@ where
|
||||
|
||||
fn on_fully_negotiated_outbound(
|
||||
&mut self,
|
||||
substream: OutboundFramed<Stream, TSpec>,
|
||||
(id, request): (Id, OutboundRequest<TSpec>),
|
||||
substream: OutboundFramed<Stream, E>,
|
||||
(id, request): (Id, OutboundRequest<E>),
|
||||
) {
|
||||
self.dial_negotiated -= 1;
|
||||
// Reset any io-retries counter.
|
||||
@@ -985,7 +985,7 @@ where
|
||||
}
|
||||
fn on_dial_upgrade_error(
|
||||
&mut self,
|
||||
request_info: (Id, OutboundRequest<TSpec>),
|
||||
request_info: (Id, OutboundRequest<E>),
|
||||
error: StreamUpgradeError<RPCError>,
|
||||
) {
|
||||
let (id, req) = request_info;
|
||||
@@ -1041,11 +1041,11 @@ impl slog::Value for SubstreamId {
|
||||
///
|
||||
/// This function returns the given substream, along with whether it has been closed or not. Any
|
||||
/// error that occurred with sending a message is reported also.
|
||||
async fn send_message_to_inbound_substream<TSpec: EthSpec>(
|
||||
mut substream: InboundSubstream<TSpec>,
|
||||
message: RPCCodedResponse<TSpec>,
|
||||
async fn send_message_to_inbound_substream<E: EthSpec>(
|
||||
mut substream: InboundSubstream<E>,
|
||||
message: RPCCodedResponse<E>,
|
||||
last_chunk: bool,
|
||||
) -> Result<(InboundSubstream<TSpec>, bool), RPCError> {
|
||||
) -> Result<(InboundSubstream<E>, bool), RPCError> {
|
||||
if matches!(message, RPCCodedResponse::StreamTermination(_)) {
|
||||
substream.close().await.map(|_| (substream, true))
|
||||
} else {
|
||||
|
||||
@@ -91,11 +91,11 @@ pub struct Ping {
|
||||
variant_attributes(derive(Clone, Debug, PartialEq, Serialize),)
|
||||
)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct MetadataRequest<T: EthSpec> {
|
||||
_phantom_data: PhantomData<T>,
|
||||
pub struct MetadataRequest<E: EthSpec> {
|
||||
_phantom_data: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> MetadataRequest<T> {
|
||||
impl<E: EthSpec> MetadataRequest<E> {
|
||||
pub fn new_v1() -> Self {
|
||||
Self::V1(MetadataRequestV1 {
|
||||
_phantom_data: PhantomData,
|
||||
@@ -114,22 +114,22 @@ impl<T: EthSpec> MetadataRequest<T> {
|
||||
variants(V1, V2),
|
||||
variant_attributes(
|
||||
derive(Encode, Decode, Clone, Debug, PartialEq, Serialize),
|
||||
serde(bound = "T: EthSpec", deny_unknown_fields),
|
||||
serde(bound = "E: EthSpec", deny_unknown_fields),
|
||||
)
|
||||
)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct MetaData<T: EthSpec> {
|
||||
#[serde(bound = "E: EthSpec")]
|
||||
pub struct MetaData<E: EthSpec> {
|
||||
/// A sequential counter indicating when data gets modified.
|
||||
pub seq_number: u64,
|
||||
/// The persistent attestation subnet bitfield.
|
||||
pub attnets: EnrAttestationBitfield<T>,
|
||||
pub attnets: EnrAttestationBitfield<E>,
|
||||
/// The persistent sync committee bitfield.
|
||||
#[superstruct(only(V2))]
|
||||
pub syncnets: EnrSyncCommitteeBitfield<T>,
|
||||
pub syncnets: EnrSyncCommitteeBitfield<E>,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> MetaData<T> {
|
||||
impl<E: EthSpec> MetaData<E> {
|
||||
/// Returns a V1 MetaData response from self.
|
||||
pub fn metadata_v1(&self) -> Self {
|
||||
match self {
|
||||
@@ -373,31 +373,31 @@ impl BlobsByRootRequest {
|
||||
// Collection of enums and structs used by the Codecs to encode/decode RPC messages
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum RPCResponse<T: EthSpec> {
|
||||
pub enum RPCResponse<E: EthSpec> {
|
||||
/// A HELLO message.
|
||||
Status(StatusMessage),
|
||||
|
||||
/// A response to a get BLOCKS_BY_RANGE request. A None response signifies the end of the
|
||||
/// batch.
|
||||
BlocksByRange(Arc<SignedBeaconBlock<T>>),
|
||||
BlocksByRange(Arc<SignedBeaconBlock<E>>),
|
||||
|
||||
/// A response to a get BLOCKS_BY_ROOT request.
|
||||
BlocksByRoot(Arc<SignedBeaconBlock<T>>),
|
||||
BlocksByRoot(Arc<SignedBeaconBlock<E>>),
|
||||
|
||||
/// A response to a get BLOBS_BY_RANGE request
|
||||
BlobsByRange(Arc<BlobSidecar<T>>),
|
||||
BlobsByRange(Arc<BlobSidecar<E>>),
|
||||
|
||||
/// A response to a get LIGHT_CLIENT_BOOTSTRAP request.
|
||||
LightClientBootstrap(Arc<LightClientBootstrap<T>>),
|
||||
LightClientBootstrap(Arc<LightClientBootstrap<E>>),
|
||||
|
||||
/// A response to a get BLOBS_BY_ROOT request.
|
||||
BlobsByRoot(Arc<BlobSidecar<T>>),
|
||||
BlobsByRoot(Arc<BlobSidecar<E>>),
|
||||
|
||||
/// A PONG response to a PING request.
|
||||
Pong(Ping),
|
||||
|
||||
/// A response to a META_DATA request.
|
||||
MetaData(MetaData<T>),
|
||||
MetaData(MetaData<E>),
|
||||
}
|
||||
|
||||
/// Indicates which response is being terminated by a stream termination response.
|
||||
@@ -419,9 +419,9 @@ pub enum ResponseTermination {
|
||||
/// The structured response containing a result/code indicating success or failure
|
||||
/// and the contents of the response
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RPCCodedResponse<T: EthSpec> {
|
||||
pub enum RPCCodedResponse<E: EthSpec> {
|
||||
/// The response is a successful.
|
||||
Success(RPCResponse<T>),
|
||||
Success(RPCResponse<E>),
|
||||
|
||||
Error(RPCResponseErrorCode, ErrorType),
|
||||
|
||||
@@ -448,7 +448,7 @@ pub enum RPCResponseErrorCode {
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> RPCCodedResponse<T> {
|
||||
impl<E: EthSpec> RPCCodedResponse<E> {
|
||||
/// Used to encode the response in the codec.
|
||||
pub fn as_u8(&self) -> Option<u8> {
|
||||
match self {
|
||||
@@ -515,7 +515,7 @@ impl RPCResponseErrorCode {
|
||||
}
|
||||
|
||||
use super::Protocol;
|
||||
impl<T: EthSpec> RPCResponse<T> {
|
||||
impl<E: EthSpec> RPCResponse<E> {
|
||||
pub fn protocol(&self) -> Protocol {
|
||||
match self {
|
||||
RPCResponse::Status(_) => Protocol::Status,
|
||||
@@ -550,7 +550,7 @@ impl std::fmt::Display for StatusMessage {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> std::fmt::Display for RPCResponse<T> {
|
||||
impl<E: EthSpec> std::fmt::Display for RPCResponse<E> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
RPCResponse::Status(status) => write!(f, "{}", status),
|
||||
@@ -575,7 +575,7 @@ impl<T: EthSpec> std::fmt::Display for RPCResponse<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> std::fmt::Display for RPCCodedResponse<T> {
|
||||
impl<E: EthSpec> std::fmt::Display for RPCCodedResponse<E> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
RPCCodedResponse::Success(res) => write!(f, "{}", res),
|
||||
|
||||
@@ -51,41 +51,41 @@ impl<T> ReqId for T where T: Send + 'static + std::fmt::Debug + Copy + Clone {}
|
||||
|
||||
/// RPC events sent from Lighthouse.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RPCSend<Id, TSpec: EthSpec> {
|
||||
pub enum RPCSend<Id, E: EthSpec> {
|
||||
/// A request sent from Lighthouse.
|
||||
///
|
||||
/// The `Id` is given by the application making the request. These
|
||||
/// go over *outbound* connections.
|
||||
Request(Id, OutboundRequest<TSpec>),
|
||||
Request(Id, OutboundRequest<E>),
|
||||
/// A response sent from Lighthouse.
|
||||
///
|
||||
/// The `SubstreamId` must correspond to the RPC-given ID of the original request received from the
|
||||
/// peer. The second parameter is a single chunk of a response. These go over *inbound*
|
||||
/// connections.
|
||||
Response(SubstreamId, RPCCodedResponse<TSpec>),
|
||||
Response(SubstreamId, RPCCodedResponse<E>),
|
||||
/// Lighthouse has requested to terminate the connection with a goodbye message.
|
||||
Shutdown(Id, GoodbyeReason),
|
||||
}
|
||||
|
||||
/// RPC events received from outside Lighthouse.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RPCReceived<Id, T: EthSpec> {
|
||||
pub enum RPCReceived<Id, E: EthSpec> {
|
||||
/// A request received from the outside.
|
||||
///
|
||||
/// The `SubstreamId` is given by the `RPCHandler` as it identifies this request with the
|
||||
/// *inbound* substream over which it is managed.
|
||||
Request(SubstreamId, InboundRequest<T>),
|
||||
Request(SubstreamId, InboundRequest<E>),
|
||||
/// A response received from the outside.
|
||||
///
|
||||
/// The `Id` corresponds to the application given ID of the original request sent to the
|
||||
/// peer. The second parameter is a single chunk of a response. These go over *outbound*
|
||||
/// connections.
|
||||
Response(Id, RPCResponse<T>),
|
||||
Response(Id, RPCResponse<E>),
|
||||
/// Marks a request as completed
|
||||
EndOfStream(Id, ResponseTermination),
|
||||
}
|
||||
|
||||
impl<T: EthSpec, Id: std::fmt::Debug> std::fmt::Display for RPCSend<Id, T> {
|
||||
impl<E: EthSpec, Id: std::fmt::Debug> std::fmt::Display for RPCSend<Id, E> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
RPCSend::Request(id, req) => write!(f, "RPC Request(id: {:?}, {})", id, req),
|
||||
@@ -97,16 +97,16 @@ impl<T: EthSpec, Id: std::fmt::Debug> std::fmt::Display for RPCSend<Id, T> {
|
||||
|
||||
/// Messages sent to the user from the RPC protocol.
|
||||
#[derive(Debug)]
|
||||
pub struct RPCMessage<Id, TSpec: EthSpec> {
|
||||
pub struct RPCMessage<Id, E: EthSpec> {
|
||||
/// The peer that sent the message.
|
||||
pub peer_id: PeerId,
|
||||
/// Handler managing this message.
|
||||
pub conn_id: ConnectionId,
|
||||
/// The message that was sent.
|
||||
pub event: HandlerEvent<Id, TSpec>,
|
||||
pub event: HandlerEvent<Id, E>,
|
||||
}
|
||||
|
||||
type BehaviourAction<Id, TSpec> = ToSwarm<RPCMessage<Id, TSpec>, RPCSend<Id, TSpec>>;
|
||||
type BehaviourAction<Id, E> = ToSwarm<RPCMessage<Id, E>, RPCSend<Id, E>>;
|
||||
|
||||
pub struct NetworkParams {
|
||||
pub max_chunk_size: usize,
|
||||
@@ -116,13 +116,13 @@ pub struct NetworkParams {
|
||||
|
||||
/// Implements the libp2p `NetworkBehaviour` trait and therefore manages network-level
|
||||
/// logic.
|
||||
pub struct RPC<Id: ReqId, TSpec: EthSpec> {
|
||||
pub struct RPC<Id: ReqId, E: EthSpec> {
|
||||
/// Rate limiter
|
||||
limiter: Option<RateLimiter>,
|
||||
/// Rate limiter for our own requests.
|
||||
self_limiter: Option<SelfRateLimiter<Id, TSpec>>,
|
||||
self_limiter: Option<SelfRateLimiter<Id, E>>,
|
||||
/// Queue of events to be processed.
|
||||
events: Vec<BehaviourAction<Id, TSpec>>,
|
||||
events: Vec<BehaviourAction<Id, E>>,
|
||||
fork_context: Arc<ForkContext>,
|
||||
enable_light_client_server: bool,
|
||||
/// Slog logger for RPC behaviour.
|
||||
@@ -131,7 +131,7 @@ pub struct RPC<Id: ReqId, TSpec: EthSpec> {
|
||||
network_params: NetworkParams,
|
||||
}
|
||||
|
||||
impl<Id: ReqId, TSpec: EthSpec> RPC<Id, TSpec> {
|
||||
impl<Id: ReqId, E: EthSpec> RPC<Id, E> {
|
||||
pub fn new(
|
||||
fork_context: Arc<ForkContext>,
|
||||
enable_light_client_server: bool,
|
||||
@@ -170,7 +170,7 @@ impl<Id: ReqId, TSpec: EthSpec> RPC<Id, TSpec> {
|
||||
&mut self,
|
||||
peer_id: PeerId,
|
||||
id: (ConnectionId, SubstreamId),
|
||||
event: RPCCodedResponse<TSpec>,
|
||||
event: RPCCodedResponse<E>,
|
||||
) {
|
||||
self.events.push(ToSwarm::NotifyHandler {
|
||||
peer_id,
|
||||
@@ -182,7 +182,7 @@ impl<Id: ReqId, TSpec: EthSpec> RPC<Id, TSpec> {
|
||||
/// Submits an RPC request.
|
||||
///
|
||||
/// The peer must be connected for this to succeed.
|
||||
pub fn send_request(&mut self, peer_id: PeerId, request_id: Id, req: OutboundRequest<TSpec>) {
|
||||
pub fn send_request(&mut self, peer_id: PeerId, request_id: Id, req: OutboundRequest<E>) {
|
||||
let event = if let Some(self_limiter) = self.self_limiter.as_mut() {
|
||||
match self_limiter.allows(peer_id, request_id, req) {
|
||||
Ok(event) => event,
|
||||
@@ -213,13 +213,13 @@ impl<Id: ReqId, TSpec: EthSpec> RPC<Id, TSpec> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id, TSpec> NetworkBehaviour for RPC<Id, TSpec>
|
||||
impl<Id, E> NetworkBehaviour for RPC<Id, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
E: EthSpec,
|
||||
Id: ReqId,
|
||||
{
|
||||
type ConnectionHandler = RPCHandler<Id, TSpec>;
|
||||
type ToSwarm = RPCMessage<Id, TSpec>;
|
||||
type ConnectionHandler = RPCHandler<Id, E>;
|
||||
type ToSwarm = RPCMessage<Id, E>;
|
||||
|
||||
fn handle_established_inbound_connection(
|
||||
&mut self,
|
||||
@@ -394,9 +394,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id, TSpec> slog::KV for RPCMessage<Id, TSpec>
|
||||
impl<Id, E> slog::KV for RPCMessage<Id, E>
|
||||
where
|
||||
TSpec: EthSpec,
|
||||
E: EthSpec,
|
||||
Id: ReqId,
|
||||
{
|
||||
fn serialize(
|
||||
|
||||
@@ -22,14 +22,14 @@ use types::{EthSpec, ForkContext};
|
||||
// `OutboundUpgrade`
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OutboundRequestContainer<TSpec: EthSpec> {
|
||||
pub req: OutboundRequest<TSpec>,
|
||||
pub struct OutboundRequestContainer<E: EthSpec> {
|
||||
pub req: OutboundRequest<E>,
|
||||
pub fork_context: Arc<ForkContext>,
|
||||
pub max_rpc_size: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum OutboundRequest<TSpec: EthSpec> {
|
||||
pub enum OutboundRequest<E: EthSpec> {
|
||||
Status(StatusMessage),
|
||||
Goodbye(GoodbyeReason),
|
||||
BlocksByRange(OldBlocksByRangeRequest),
|
||||
@@ -37,10 +37,10 @@ pub enum OutboundRequest<TSpec: EthSpec> {
|
||||
BlobsByRange(BlobsByRangeRequest),
|
||||
BlobsByRoot(BlobsByRootRequest),
|
||||
Ping(Ping),
|
||||
MetaData(MetadataRequest<TSpec>),
|
||||
MetaData(MetadataRequest<E>),
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> UpgradeInfo for OutboundRequestContainer<TSpec> {
|
||||
impl<E: EthSpec> UpgradeInfo for OutboundRequestContainer<E> {
|
||||
type Info = ProtocolId;
|
||||
type InfoIter = Vec<Self::Info>;
|
||||
|
||||
@@ -51,7 +51,7 @@ impl<TSpec: EthSpec> UpgradeInfo for OutboundRequestContainer<TSpec> {
|
||||
}
|
||||
|
||||
/// Implements the encoding per supported protocol for `RPCRequest`.
|
||||
impl<TSpec: EthSpec> OutboundRequest<TSpec> {
|
||||
impl<E: EthSpec> OutboundRequest<E> {
|
||||
pub fn supported_protocols(&self) -> Vec<ProtocolId> {
|
||||
match self {
|
||||
// add more protocols when versions/encodings are supported
|
||||
@@ -98,7 +98,7 @@ impl<TSpec: EthSpec> OutboundRequest<TSpec> {
|
||||
OutboundRequest::Goodbye(_) => 0,
|
||||
OutboundRequest::BlocksByRange(req) => *req.count(),
|
||||
OutboundRequest::BlocksByRoot(req) => req.block_roots().len() as u64,
|
||||
OutboundRequest::BlobsByRange(req) => req.max_blobs_requested::<TSpec>(),
|
||||
OutboundRequest::BlobsByRange(req) => req.max_blobs_requested::<E>(),
|
||||
OutboundRequest::BlobsByRoot(req) => req.blob_ids.len() as u64,
|
||||
OutboundRequest::Ping(_) => 1,
|
||||
OutboundRequest::MetaData(_) => 1,
|
||||
@@ -150,14 +150,14 @@ impl<TSpec: EthSpec> OutboundRequest<TSpec> {
|
||||
|
||||
/* Outbound upgrades */
|
||||
|
||||
pub type OutboundFramed<TSocket, TSpec> = Framed<Compat<TSocket>, OutboundCodec<TSpec>>;
|
||||
pub type OutboundFramed<TSocket, E> = Framed<Compat<TSocket>, OutboundCodec<E>>;
|
||||
|
||||
impl<TSocket, TSpec> OutboundUpgrade<TSocket> for OutboundRequestContainer<TSpec>
|
||||
impl<TSocket, E> OutboundUpgrade<TSocket> for OutboundRequestContainer<E>
|
||||
where
|
||||
TSpec: EthSpec + Send + 'static,
|
||||
E: EthSpec + Send + 'static,
|
||||
TSocket: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||
{
|
||||
type Output = OutboundFramed<TSocket, TSpec>;
|
||||
type Output = OutboundFramed<TSocket, E>;
|
||||
type Error = RPCError;
|
||||
type Future = BoxFuture<'static, Result<Self::Output, Self::Error>>;
|
||||
|
||||
@@ -186,7 +186,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> std::fmt::Display for OutboundRequest<TSpec> {
|
||||
impl<E: EthSpec> std::fmt::Display for OutboundRequest<E> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
OutboundRequest::Status(status) => write!(f, "Status Message: {}", status),
|
||||
|
||||
@@ -298,15 +298,15 @@ impl std::fmt::Display for Encoding {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RPCProtocol<TSpec: EthSpec> {
|
||||
pub struct RPCProtocol<E: EthSpec> {
|
||||
pub fork_context: Arc<ForkContext>,
|
||||
pub max_rpc_size: usize,
|
||||
pub enable_light_client_server: bool,
|
||||
pub phantom: PhantomData<TSpec>,
|
||||
pub phantom: PhantomData<E>,
|
||||
pub ttfb_timeout: Duration,
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> UpgradeInfo for RPCProtocol<TSpec> {
|
||||
impl<E: EthSpec> UpgradeInfo for RPCProtocol<E> {
|
||||
type Info = ProtocolId;
|
||||
type InfoIter = Vec<Self::Info>;
|
||||
|
||||
@@ -397,7 +397,7 @@ impl ProtocolId {
|
||||
}
|
||||
|
||||
/// Returns min and max size for messages of given protocol id responses.
|
||||
pub fn rpc_response_limits<T: EthSpec>(&self, fork_context: &ForkContext) -> RpcLimits {
|
||||
pub fn rpc_response_limits<E: EthSpec>(&self, fork_context: &ForkContext) -> RpcLimits {
|
||||
match self.versioned_protocol.protocol() {
|
||||
Protocol::Status => RpcLimits::new(
|
||||
<StatusMessage as Encode>::ssz_fixed_len(),
|
||||
@@ -406,15 +406,15 @@ impl ProtocolId {
|
||||
Protocol::Goodbye => RpcLimits::new(0, 0), // Goodbye request has no response
|
||||
Protocol::BlocksByRange => rpc_block_limits_by_fork(fork_context.current_fork()),
|
||||
Protocol::BlocksByRoot => rpc_block_limits_by_fork(fork_context.current_fork()),
|
||||
Protocol::BlobsByRange => rpc_blob_limits::<T>(),
|
||||
Protocol::BlobsByRoot => rpc_blob_limits::<T>(),
|
||||
Protocol::BlobsByRange => rpc_blob_limits::<E>(),
|
||||
Protocol::BlobsByRoot => rpc_blob_limits::<E>(),
|
||||
Protocol::Ping => RpcLimits::new(
|
||||
<Ping as Encode>::ssz_fixed_len(),
|
||||
<Ping as Encode>::ssz_fixed_len(),
|
||||
),
|
||||
Protocol::MetaData => RpcLimits::new(
|
||||
<MetaDataV1<T> as Encode>::ssz_fixed_len(),
|
||||
<MetaDataV2<T> as Encode>::ssz_fixed_len(),
|
||||
<MetaDataV1<E> as Encode>::ssz_fixed_len(),
|
||||
<MetaDataV2<E> as Encode>::ssz_fixed_len(),
|
||||
),
|
||||
Protocol::LightClientBootstrap => RpcLimits::new(
|
||||
<LightClientBootstrapRequest as Encode>::ssz_fixed_len(),
|
||||
@@ -462,10 +462,10 @@ impl ProtocolId {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rpc_blob_limits<T: EthSpec>() -> RpcLimits {
|
||||
pub fn rpc_blob_limits<E: EthSpec>() -> RpcLimits {
|
||||
RpcLimits::new(
|
||||
BlobSidecar::<T>::empty().as_ssz_bytes().len(),
|
||||
BlobSidecar::<T>::max_size(),
|
||||
BlobSidecar::<E>::empty().as_ssz_bytes().len(),
|
||||
BlobSidecar::<E>::max_size(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -474,16 +474,16 @@ pub fn rpc_blob_limits<T: EthSpec>() -> RpcLimits {
|
||||
// The inbound protocol reads the request, decodes it and returns the stream to the protocol
|
||||
// handler to respond to once ready.
|
||||
|
||||
pub type InboundOutput<TSocket, TSpec> = (InboundRequest<TSpec>, InboundFramed<TSocket, TSpec>);
|
||||
pub type InboundFramed<TSocket, TSpec> =
|
||||
Framed<std::pin::Pin<Box<TimeoutStream<Compat<TSocket>>>>, InboundCodec<TSpec>>;
|
||||
pub type InboundOutput<TSocket, E> = (InboundRequest<E>, InboundFramed<TSocket, E>);
|
||||
pub type InboundFramed<TSocket, E> =
|
||||
Framed<std::pin::Pin<Box<TimeoutStream<Compat<TSocket>>>>, InboundCodec<E>>;
|
||||
|
||||
impl<TSocket, TSpec> InboundUpgrade<TSocket> for RPCProtocol<TSpec>
|
||||
impl<TSocket, E> InboundUpgrade<TSocket> for RPCProtocol<E>
|
||||
where
|
||||
TSocket: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||
TSpec: EthSpec,
|
||||
E: EthSpec,
|
||||
{
|
||||
type Output = InboundOutput<TSocket, TSpec>;
|
||||
type Output = InboundOutput<TSocket, E>;
|
||||
type Error = RPCError;
|
||||
type Future = BoxFuture<'static, Result<Self::Output, Self::Error>>;
|
||||
|
||||
@@ -535,7 +535,7 @@ where
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum InboundRequest<TSpec: EthSpec> {
|
||||
pub enum InboundRequest<E: EthSpec> {
|
||||
Status(StatusMessage),
|
||||
Goodbye(GoodbyeReason),
|
||||
BlocksByRange(OldBlocksByRangeRequest),
|
||||
@@ -544,11 +544,11 @@ pub enum InboundRequest<TSpec: EthSpec> {
|
||||
BlobsByRoot(BlobsByRootRequest),
|
||||
LightClientBootstrap(LightClientBootstrapRequest),
|
||||
Ping(Ping),
|
||||
MetaData(MetadataRequest<TSpec>),
|
||||
MetaData(MetadataRequest<E>),
|
||||
}
|
||||
|
||||
/// Implements the encoding per supported protocol for `RPCRequest`.
|
||||
impl<TSpec: EthSpec> InboundRequest<TSpec> {
|
||||
impl<E: EthSpec> InboundRequest<E> {
|
||||
/* These functions are used in the handler for stream management */
|
||||
|
||||
/// Number of responses expected for this request.
|
||||
@@ -558,7 +558,7 @@ impl<TSpec: EthSpec> InboundRequest<TSpec> {
|
||||
InboundRequest::Goodbye(_) => 0,
|
||||
InboundRequest::BlocksByRange(req) => *req.count(),
|
||||
InboundRequest::BlocksByRoot(req) => req.block_roots().len() as u64,
|
||||
InboundRequest::BlobsByRange(req) => req.max_blobs_requested::<TSpec>(),
|
||||
InboundRequest::BlobsByRange(req) => req.max_blobs_requested::<E>(),
|
||||
InboundRequest::BlobsByRoot(req) => req.blob_ids.len() as u64,
|
||||
InboundRequest::Ping(_) => 1,
|
||||
InboundRequest::MetaData(_) => 1,
|
||||
@@ -699,7 +699,7 @@ impl std::error::Error for RPCError {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSpec: EthSpec> std::fmt::Display for InboundRequest<TSpec> {
|
||||
impl<E: EthSpec> std::fmt::Display for InboundRequest<E> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
InboundRequest::Status(status) => write!(f, "Status Message: {}", status),
|
||||
|
||||
@@ -211,7 +211,7 @@ pub trait RateLimiterItem {
|
||||
fn expected_responses(&self) -> u64;
|
||||
}
|
||||
|
||||
impl<T: EthSpec> RateLimiterItem for super::InboundRequest<T> {
|
||||
impl<E: EthSpec> RateLimiterItem for super::InboundRequest<E> {
|
||||
fn protocol(&self) -> Protocol {
|
||||
self.versioned_protocol().protocol()
|
||||
}
|
||||
@@ -221,7 +221,7 @@ impl<T: EthSpec> RateLimiterItem for super::InboundRequest<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> RateLimiterItem for super::OutboundRequest<T> {
|
||||
impl<E: EthSpec> RateLimiterItem for super::OutboundRequest<E> {
|
||||
fn protocol(&self) -> Protocol {
|
||||
self.versioned_protocol().protocol()
|
||||
}
|
||||
|
||||
@@ -19,22 +19,22 @@ use super::{
|
||||
|
||||
/// A request that was rate limited or waiting on rate limited requests for the same peer and
|
||||
/// protocol.
|
||||
struct QueuedRequest<Id: ReqId, TSpec: EthSpec> {
|
||||
req: OutboundRequest<TSpec>,
|
||||
struct QueuedRequest<Id: ReqId, E: EthSpec> {
|
||||
req: OutboundRequest<E>,
|
||||
request_id: Id,
|
||||
}
|
||||
|
||||
pub(crate) struct SelfRateLimiter<Id: ReqId, TSpec: EthSpec> {
|
||||
pub(crate) struct SelfRateLimiter<Id: ReqId, E: EthSpec> {
|
||||
/// Requests queued for sending per peer. This requests are stored when the self rate
|
||||
/// limiter rejects them. Rate limiting is based on a Peer and Protocol basis, therefore
|
||||
/// are stored in the same way.
|
||||
delayed_requests: HashMap<(PeerId, Protocol), VecDeque<QueuedRequest<Id, TSpec>>>,
|
||||
delayed_requests: HashMap<(PeerId, Protocol), VecDeque<QueuedRequest<Id, E>>>,
|
||||
/// The delay required to allow a peer's outbound request per protocol.
|
||||
next_peer_request: DelayQueue<(PeerId, Protocol)>,
|
||||
/// Rate limiter for our own requests.
|
||||
limiter: RateLimiter,
|
||||
/// Requests that are ready to be sent.
|
||||
ready_requests: SmallVec<[BehaviourAction<Id, TSpec>; 3]>,
|
||||
ready_requests: SmallVec<[BehaviourAction<Id, E>; 3]>,
|
||||
/// Slog logger.
|
||||
log: Logger,
|
||||
}
|
||||
@@ -48,7 +48,7 @@ pub enum Error {
|
||||
RateLimited,
|
||||
}
|
||||
|
||||
impl<Id: ReqId, TSpec: EthSpec> SelfRateLimiter<Id, TSpec> {
|
||||
impl<Id: ReqId, E: EthSpec> SelfRateLimiter<Id, E> {
|
||||
/// Creates a new [`SelfRateLimiter`] based on configration values.
|
||||
pub fn new(config: OutboundRateLimiterConfig, log: Logger) -> Result<Self, &'static str> {
|
||||
debug!(log, "Using self rate limiting params"; "config" => ?config);
|
||||
@@ -70,8 +70,8 @@ impl<Id: ReqId, TSpec: EthSpec> SelfRateLimiter<Id, TSpec> {
|
||||
&mut self,
|
||||
peer_id: PeerId,
|
||||
request_id: Id,
|
||||
req: OutboundRequest<TSpec>,
|
||||
) -> Result<BehaviourAction<Id, TSpec>, Error> {
|
||||
req: OutboundRequest<E>,
|
||||
) -> Result<BehaviourAction<Id, E>, Error> {
|
||||
let protocol = req.versioned_protocol().protocol();
|
||||
// First check that there are not already other requests waiting to be sent.
|
||||
if let Some(queued_requests) = self.delayed_requests.get_mut(&(peer_id, protocol)) {
|
||||
@@ -101,9 +101,9 @@ impl<Id: ReqId, TSpec: EthSpec> SelfRateLimiter<Id, TSpec> {
|
||||
limiter: &mut RateLimiter,
|
||||
peer_id: PeerId,
|
||||
request_id: Id,
|
||||
req: OutboundRequest<TSpec>,
|
||||
req: OutboundRequest<E>,
|
||||
log: &Logger,
|
||||
) -> Result<BehaviourAction<Id, TSpec>, (QueuedRequest<Id, TSpec>, Duration)> {
|
||||
) -> Result<BehaviourAction<Id, E>, (QueuedRequest<Id, E>, Duration)> {
|
||||
match limiter.allows(&peer_id, &req) {
|
||||
Ok(()) => Ok(BehaviourAction::NotifyHandler {
|
||||
peer_id,
|
||||
@@ -160,7 +160,7 @@ impl<Id: ReqId, TSpec: EthSpec> SelfRateLimiter<Id, TSpec> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<BehaviourAction<Id, TSpec>> {
|
||||
pub fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<BehaviourAction<Id, E>> {
|
||||
// First check the requests that were self rate limited, since those might add events to
|
||||
// the queue. Also do this this before rate limiter prunning to avoid removing and
|
||||
// immediately adding rate limiting keys.
|
||||
|
||||
Reference in New Issue
Block a user