Support LightClientFinalityUpdate and LightClientOptimisticUpdate rpcs (#3849)

* add light client optimistic and finality update rpc

* Arc the updates in the response

* add conditional advertisement for both LightClientOptimisticUpdate and LightClientFinalityUpdate

* alter display for inboundrequest light client optimistic and finality updates

* remove LightClientOptimistic/FinalityReuest struct and some minor fixes

* rebase

* failing rpc_test for LightClientBootstrap and beginning of MockLib2pLightClient

* minor change

* added MockRPCHandler by importing everything except OutboundRequest. Need to implement the ConnectionHandler trait now should be copy pastable

* almost there but ran into issue where needed to implement BaseOutboundRequest.

* failing but running with a light client service of sorts

* small test change

* changed Protocol::LightClientBootstrap response limit

* deleted some stuff from ConnectionHandler Implementation for the mock light client if you need to make something with multiple requests work maybe check here

* deleted purging expired inbound/outbound streams code

* deleted drive inbound streams that need to be processed

* removed unused imports

* made things private again

* deleted inject_fully_negotiated_inbound

* made more things private again

* more

* turned the logger off in the test

* added failing test for new rpc

* add rate limit for new rpcs

* change InboundUpgrade function to use new rpcs. fmt. add test for LightClientFinalityUpdate

* rebasing fix

* add LightClientUpdate to handle_rpc functions

* added context bytes

* fmt

* use correct unsed_tcp4_port function

* fix for recent config changes and adding context_bytes for the light client protocols

* fix clippy complaint

* Merge branch 'unstable' into lc-reqresp

# Conflicts:
#	beacon_node/beacon_processor/src/lib.rs
#	beacon_node/lighthouse_network/src/peer_manager/mod.rs
#	beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs
#	beacon_node/lighthouse_network/src/rpc/config.rs
#	beacon_node/lighthouse_network/src/rpc/methods.rs
#	beacon_node/lighthouse_network/src/rpc/mod.rs
#	beacon_node/lighthouse_network/src/rpc/outbound.rs
#	beacon_node/lighthouse_network/src/rpc/protocol.rs
#	beacon_node/lighthouse_network/src/rpc/rate_limiter.rs
#	beacon_node/lighthouse_network/src/rpc/self_limiter.rs
#	beacon_node/lighthouse_network/src/service/api_types.rs
#	beacon_node/lighthouse_network/tests/common/mod.rs
#	beacon_node/lighthouse_network/tests/rpc_tests.rs
#	beacon_node/network/src/network_beacon_processor/rpc_methods.rs
#	beacon_node/network/src/router.rs

* Error handling updates and various cleanups.

* Moar minor clean ups.

* Do not ban peer for rate limiting light client requests

* Merge branch 'unstable' into lc-reqresp. Also removed the mock light client tests to make it compile (See #4940).

# Conflicts:
#	beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs
#	beacon_node/lighthouse_network/src/rpc/methods.rs
#	beacon_node/lighthouse_network/src/rpc/mod.rs
#	beacon_node/lighthouse_network/src/rpc/protocol.rs
#	beacon_node/lighthouse_network/src/service/api_types.rs
#	beacon_node/lighthouse_network/tests/common/mod.rs
#	beacon_node/network/src/network_beacon_processor/rpc_methods.rs
#	beacon_node/network/src/router.rs
#	consensus/types/src/light_client_bootstrap.rs
#	consensus/types/src/light_client_finality_update.rs
#	consensus/types/src/light_client_optimistic_update.rs

* Remove unnecessary changes

* Add missing light client queue handling.

* Merge branch 'unstable' into lc-reqresp

* Merge branch 'unstable' into lc-reqresp

# Conflicts:
#	beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs
#	beacon_node/lighthouse_network/src/service/api_types.rs
#	consensus/types/src/light_client_finality_update.rs
#	consensus/types/src/light_client_optimistic_update.rs

* Add context bytes for light client RPC responses.

* Add RPC limits for light client object.

* Fix lint

* Fix incorrect light client max size computation.

* Merge branch 'unstable' into lc-reqresp

# Conflicts:
#	beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs
#	beacon_node/lighthouse_network/src/rpc/protocol.rs
#	beacon_node/lighthouse_network/src/service/api_types.rs

* Remove unwanted local changes.

* Merge branch 'unstable' into lc-reqresp

* Replace `unimplemented` electra code path with deneb values.
This commit is contained in:
GeemoCandama
2024-04-09 16:23:39 +09:00
committed by GitHub
parent 1b88d29807
commit 32be063f0f
19 changed files with 612 additions and 70 deletions

View File

@@ -15,12 +15,11 @@ use std::io::{Read, Write};
use std::marker::PhantomData;
use std::sync::Arc;
use tokio_util::codec::{Decoder, Encoder};
use types::ChainSpec;
use types::{
BlobSidecar, EthSpec, ForkContext, ForkName, Hash256, LightClientBootstrap,
RuntimeVariableList, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase,
SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra,
SignedBeaconBlockMerge,
BlobSidecar, ChainSpec, EthSpec, ForkContext, ForkName, Hash256, LightClientBootstrap,
LightClientFinalityUpdate, LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock,
SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockCapella,
SignedBeaconBlockDeneb, SignedBeaconBlockElectra, SignedBeaconBlockMerge,
};
use unsigned_varint::codec::Uvi;
@@ -72,6 +71,8 @@ impl<E: EthSpec> Encoder<RPCCodedResponse<E>> for SSZSnappyInboundCodec<E> {
RPCResponse::BlobsByRange(res) => res.as_ssz_bytes(),
RPCResponse::BlobsByRoot(res) => res.as_ssz_bytes(),
RPCResponse::LightClientBootstrap(res) => res.as_ssz_bytes(),
RPCResponse::LightClientOptimisticUpdate(res) => res.as_ssz_bytes(),
RPCResponse::LightClientFinalityUpdate(res) => res.as_ssz_bytes(),
RPCResponse::Pong(res) => res.data.as_ssz_bytes(),
RPCResponse::MetaData(res) =>
// Encode the correct version of the MetaData response based on the negotiated version.
@@ -387,32 +388,51 @@ fn context_bytes<E: EthSpec>(
// Add the context bytes if required
if protocol.has_context_bytes() {
if let RPCCodedResponse::Success(rpc_variant) = resp {
if let RPCResponse::BlocksByRange(ref_box_block)
| RPCResponse::BlocksByRoot(ref_box_block) = rpc_variant
{
return match **ref_box_block {
// NOTE: If you are adding another fork type here, be sure to modify the
// `fork_context.to_context_bytes()` function to support it as well!
SignedBeaconBlock::Electra { .. } => {
fork_context.to_context_bytes(ForkName::Electra)
}
SignedBeaconBlock::Deneb { .. } => {
fork_context.to_context_bytes(ForkName::Deneb)
}
SignedBeaconBlock::Capella { .. } => {
fork_context.to_context_bytes(ForkName::Capella)
}
SignedBeaconBlock::Merge { .. } => {
fork_context.to_context_bytes(ForkName::Merge)
}
SignedBeaconBlock::Altair { .. } => {
fork_context.to_context_bytes(ForkName::Altair)
}
SignedBeaconBlock::Base { .. } => Some(fork_context.genesis_context_bytes()),
};
}
if let RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) = rpc_variant {
return fork_context.to_context_bytes(ForkName::Deneb);
match rpc_variant {
RPCResponse::BlocksByRange(ref_box_block)
| RPCResponse::BlocksByRoot(ref_box_block) => {
return match **ref_box_block {
// NOTE: If you are adding another fork type here, be sure to modify the
// `fork_context.to_context_bytes()` function to support it as well!
SignedBeaconBlock::Electra { .. } => {
fork_context.to_context_bytes(ForkName::Electra)
}
SignedBeaconBlock::Deneb { .. } => {
fork_context.to_context_bytes(ForkName::Deneb)
}
SignedBeaconBlock::Capella { .. } => {
fork_context.to_context_bytes(ForkName::Capella)
}
SignedBeaconBlock::Merge { .. } => {
fork_context.to_context_bytes(ForkName::Merge)
}
SignedBeaconBlock::Altair { .. } => {
fork_context.to_context_bytes(ForkName::Altair)
}
SignedBeaconBlock::Base { .. } => {
Some(fork_context.genesis_context_bytes())
}
};
}
RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) => {
return fork_context.to_context_bytes(ForkName::Deneb);
}
RPCResponse::LightClientBootstrap(lc_bootstrap) => {
return lc_bootstrap
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
}
RPCResponse::LightClientOptimisticUpdate(lc_optimistic_update) => {
return lc_optimistic_update
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
}
RPCResponse::LightClientFinalityUpdate(lc_finality_update) => {
return lc_finality_update
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
}
// These will not pass the has_context_bytes() check
RPCResponse::Status(_) | RPCResponse::Pong(_) | RPCResponse::MetaData(_) => {
return None;
}
}
}
}
@@ -500,6 +520,12 @@ fn handle_rpc_request<E: EthSpec>(
root: Hash256::from_ssz_bytes(decoded_buffer)?,
}),
)),
SupportedProtocol::LightClientOptimisticUpdateV1 => {
Ok(Some(InboundRequest::LightClientOptimisticUpdate))
}
SupportedProtocol::LightClientFinalityUpdateV1 => {
Ok(Some(InboundRequest::LightClientFinalityUpdate))
}
// MetaData requests return early from InboundUpgrade and do not reach the decoder.
// Handle this case just for completeness.
SupportedProtocol::MetaDataV2 => {
@@ -596,6 +622,30 @@ fn handle_rpc_response<E: EthSpec>(
),
)),
},
SupportedProtocol::LightClientOptimisticUpdateV1 => match fork_name {
Some(fork_name) => Ok(Some(RPCResponse::LightClientOptimisticUpdate(Arc::new(
LightClientOptimisticUpdate::from_ssz_bytes(decoded_buffer, fork_name)?,
)))),
None => Err(RPCError::ErrorResponse(
RPCResponseErrorCode::InvalidRequest,
format!(
"No context bytes provided for {:?} response",
versioned_protocol
),
)),
},
SupportedProtocol::LightClientFinalityUpdateV1 => match fork_name {
Some(fork_name) => Ok(Some(RPCResponse::LightClientFinalityUpdate(Arc::new(
LightClientFinalityUpdate::from_ssz_bytes(decoded_buffer, fork_name)?,
)))),
None => Err(RPCError::ErrorResponse(
RPCResponseErrorCode::InvalidRequest,
format!(
"No context bytes provided for {:?} response",
versioned_protocol
),
)),
},
// MetaData V2 responses have no context bytes, so behave similarly to V1 responses
SupportedProtocol::MetaDataV2 => Ok(Some(RPCResponse::MetaData(MetaData::V2(
MetaDataV2::from_ssz_bytes(decoded_buffer)?,

View File

@@ -92,6 +92,8 @@ pub struct RateLimiterConfig {
pub(super) blobs_by_range_quota: Quota,
pub(super) blobs_by_root_quota: Quota,
pub(super) light_client_bootstrap_quota: Quota,
pub(super) light_client_optimistic_update_quota: Quota,
pub(super) light_client_finality_update_quota: Quota,
}
impl RateLimiterConfig {
@@ -104,6 +106,8 @@ impl RateLimiterConfig {
pub const DEFAULT_BLOBS_BY_RANGE_QUOTA: Quota = Quota::n_every(768, 10);
pub const DEFAULT_BLOBS_BY_ROOT_QUOTA: Quota = Quota::n_every(128, 10);
pub const DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA: Quota = Quota::one_every(10);
pub const DEFAULT_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUOTA: Quota = Quota::one_every(10);
pub const DEFAULT_LIGHT_CLIENT_FINALITY_UPDATE_QUOTA: Quota = Quota::one_every(10);
}
impl Default for RateLimiterConfig {
@@ -118,6 +122,9 @@ impl Default for RateLimiterConfig {
blobs_by_range_quota: Self::DEFAULT_BLOBS_BY_RANGE_QUOTA,
blobs_by_root_quota: Self::DEFAULT_BLOBS_BY_ROOT_QUOTA,
light_client_bootstrap_quota: Self::DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA,
light_client_optimistic_update_quota:
Self::DEFAULT_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUOTA,
light_client_finality_update_quota: Self::DEFAULT_LIGHT_CLIENT_FINALITY_UPDATE_QUOTA,
}
}
}
@@ -164,6 +171,8 @@ impl FromStr for RateLimiterConfig {
let mut blobs_by_range_quota = None;
let mut blobs_by_root_quota = None;
let mut light_client_bootstrap_quota = None;
let mut light_client_optimistic_update_quota = None;
let mut light_client_finality_update_quota = None;
for proto_def in s.split(';') {
let ProtocolQuota { protocol, quota } = proto_def.parse()?;
@@ -180,6 +189,14 @@ impl FromStr for RateLimiterConfig {
Protocol::LightClientBootstrap => {
light_client_bootstrap_quota = light_client_bootstrap_quota.or(quota)
}
Protocol::LightClientOptimisticUpdate => {
light_client_optimistic_update_quota =
light_client_optimistic_update_quota.or(quota)
}
Protocol::LightClientFinalityUpdate => {
light_client_finality_update_quota =
light_client_finality_update_quota.or(quota)
}
}
}
Ok(RateLimiterConfig {
@@ -196,6 +213,10 @@ impl FromStr for RateLimiterConfig {
blobs_by_root_quota: blobs_by_root_quota.unwrap_or(Self::DEFAULT_BLOBS_BY_ROOT_QUOTA),
light_client_bootstrap_quota: light_client_bootstrap_quota
.unwrap_or(Self::DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA),
light_client_optimistic_update_quota: light_client_optimistic_update_quota
.unwrap_or(Self::DEFAULT_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUOTA),
light_client_finality_update_quota: light_client_finality_update_quota
.unwrap_or(Self::DEFAULT_LIGHT_CLIENT_FINALITY_UPDATE_QUOTA),
})
}
}

View File

@@ -15,7 +15,8 @@ use superstruct::superstruct;
use types::blob_sidecar::BlobIdentifier;
use types::{
blob_sidecar::BlobSidecar, ChainSpec, Epoch, EthSpec, Hash256, LightClientBootstrap,
RuntimeVariableList, SignedBeaconBlock, Slot,
LightClientFinalityUpdate, LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock,
Slot,
};
/// Maximum length of error message.
@@ -390,6 +391,12 @@ pub enum RPCResponse<E: EthSpec> {
/// A response to a get LIGHT_CLIENT_BOOTSTRAP request.
LightClientBootstrap(Arc<LightClientBootstrap<E>>),
/// A response to a get LIGHT_CLIENT_OPTIMISTIC_UPDATE request.
LightClientOptimisticUpdate(Arc<LightClientOptimisticUpdate<E>>),
/// A response to a get LIGHT_CLIENT_FINALITY_UPDATE request.
LightClientFinalityUpdate(Arc<LightClientFinalityUpdate<E>>),
/// A response to a get BLOBS_BY_ROOT request.
BlobsByRoot(Arc<BlobSidecar<E>>),
@@ -488,6 +495,8 @@ impl<E: EthSpec> RPCCodedResponse<E> {
RPCResponse::Pong(_) => false,
RPCResponse::MetaData(_) => false,
RPCResponse::LightClientBootstrap(_) => false,
RPCResponse::LightClientOptimisticUpdate(_) => false,
RPCResponse::LightClientFinalityUpdate(_) => false,
},
RPCCodedResponse::Error(_, _) => true,
// Stream terminations are part of responses that have chunks
@@ -526,6 +535,8 @@ impl<E: EthSpec> RPCResponse<E> {
RPCResponse::Pong(_) => Protocol::Ping,
RPCResponse::MetaData(_) => Protocol::MetaData,
RPCResponse::LightClientBootstrap(_) => Protocol::LightClientBootstrap,
RPCResponse::LightClientOptimisticUpdate(_) => Protocol::LightClientOptimisticUpdate,
RPCResponse::LightClientFinalityUpdate(_) => Protocol::LightClientFinalityUpdate,
}
}
}
@@ -571,6 +582,20 @@ impl<E: EthSpec> std::fmt::Display for RPCResponse<E> {
RPCResponse::LightClientBootstrap(bootstrap) => {
write!(f, "LightClientBootstrap Slot: {}", bootstrap.get_slot())
}
RPCResponse::LightClientOptimisticUpdate(update) => {
write!(
f,
"LightClientOptimisticUpdate Slot: {}",
update.signature_slot()
)
}
RPCResponse::LightClientFinalityUpdate(update) => {
write!(
f,
"LightClientFinalityUpdate Slot: {}",
update.signature_slot()
)
}
}
}
}

View File

@@ -19,7 +19,9 @@ use tokio_util::{
use types::{
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockCapella, BeaconBlockElectra,
BeaconBlockMerge, BlobSidecar, ChainSpec, EmptyBlock, EthSpec, ForkContext, ForkName,
MainnetEthSpec, Signature, SignedBeaconBlock,
LightClientBootstrap, LightClientBootstrapAltair, LightClientFinalityUpdate,
LightClientFinalityUpdateAltair, LightClientOptimisticUpdate,
LightClientOptimisticUpdateAltair, MainnetEthSpec, Signature, SignedBeaconBlock,
};
lazy_static! {
@@ -110,6 +112,16 @@ lazy_static! {
])
.as_ssz_bytes()
.len();
pub static ref LIGHT_CLIENT_FINALITY_UPDATE_CAPELLA_MAX: usize = LightClientFinalityUpdate::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Capella);
pub static ref LIGHT_CLIENT_FINALITY_UPDATE_DENEB_MAX: usize = LightClientFinalityUpdate::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Deneb);
pub static ref LIGHT_CLIENT_FINALITY_UPDATE_ELECTRA_MAX: usize = LightClientFinalityUpdate::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Electra);
pub static ref LIGHT_CLIENT_OPTIMISTIC_UPDATE_CAPELLA_MAX: usize = LightClientOptimisticUpdate::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Capella);
pub static ref LIGHT_CLIENT_OPTIMISTIC_UPDATE_DENEB_MAX: usize = LightClientOptimisticUpdate::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Deneb);
pub static ref LIGHT_CLIENT_OPTIMISTIC_UPDATE_ELECTRA_MAX: usize = LightClientOptimisticUpdate::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Electra);
pub static ref LIGHT_CLIENT_BOOTSTRAP_CAPELLA_MAX: usize = LightClientBootstrap::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Capella);
pub static ref LIGHT_CLIENT_BOOTSTRAP_DENEB_MAX: usize = LightClientBootstrap::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Deneb);
pub static ref LIGHT_CLIENT_BOOTSTRAP_ELECTRA_MAX: usize = LightClientBootstrap::<MainnetEthSpec>::ssz_max_len_for_fork(ForkName::Electra);
}
/// The protocol prefix the RPC protocol id.
@@ -161,6 +173,56 @@ pub fn rpc_block_limits_by_fork(current_fork: ForkName) -> RpcLimits {
}
}
fn rpc_light_client_finality_update_limits_by_fork(current_fork: ForkName) -> RpcLimits {
let altair_fixed_len = LightClientFinalityUpdateAltair::<MainnetEthSpec>::ssz_fixed_len();
match &current_fork {
ForkName::Base => RpcLimits::new(0, 0),
ForkName::Altair | ForkName::Merge => RpcLimits::new(altair_fixed_len, altair_fixed_len),
ForkName::Capella => {
RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_FINALITY_UPDATE_CAPELLA_MAX)
}
ForkName::Deneb => {
RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_FINALITY_UPDATE_DENEB_MAX)
}
ForkName::Electra => {
RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_FINALITY_UPDATE_ELECTRA_MAX)
}
}
}
fn rpc_light_client_optimistic_update_limits_by_fork(current_fork: ForkName) -> RpcLimits {
let altair_fixed_len = LightClientOptimisticUpdateAltair::<MainnetEthSpec>::ssz_fixed_len();
match &current_fork {
ForkName::Base => RpcLimits::new(0, 0),
ForkName::Altair | ForkName::Merge => RpcLimits::new(altair_fixed_len, altair_fixed_len),
ForkName::Capella => RpcLimits::new(
altair_fixed_len,
*LIGHT_CLIENT_OPTIMISTIC_UPDATE_CAPELLA_MAX,
),
ForkName::Deneb => {
RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_OPTIMISTIC_UPDATE_DENEB_MAX)
}
ForkName::Electra => RpcLimits::new(
altair_fixed_len,
*LIGHT_CLIENT_OPTIMISTIC_UPDATE_ELECTRA_MAX,
),
}
}
fn rpc_light_client_bootstrap_limits_by_fork(current_fork: ForkName) -> RpcLimits {
let altair_fixed_len = LightClientBootstrapAltair::<MainnetEthSpec>::ssz_fixed_len();
match &current_fork {
ForkName::Base => RpcLimits::new(0, 0),
ForkName::Altair | ForkName::Merge => RpcLimits::new(altair_fixed_len, altair_fixed_len),
ForkName::Capella => RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_BOOTSTRAP_CAPELLA_MAX),
ForkName::Deneb => RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_BOOTSTRAP_DENEB_MAX),
ForkName::Electra => RpcLimits::new(altair_fixed_len, *LIGHT_CLIENT_BOOTSTRAP_ELECTRA_MAX),
}
}
/// Protocol names to be used.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumString, AsRefStr, Display)]
#[strum(serialize_all = "snake_case")]
@@ -189,6 +251,12 @@ pub enum Protocol {
/// The `LightClientBootstrap` protocol name.
#[strum(serialize = "light_client_bootstrap")]
LightClientBootstrap,
/// The `LightClientOptimisticUpdate` protocol name.
#[strum(serialize = "light_client_optimistic_update")]
LightClientOptimisticUpdate,
/// The `LightClientFinalityUpdate` protocol name.
#[strum(serialize = "light_client_finality_update")]
LightClientFinalityUpdate,
}
impl Protocol {
@@ -203,6 +271,8 @@ impl Protocol {
Protocol::Ping => None,
Protocol::MetaData => None,
Protocol::LightClientBootstrap => None,
Protocol::LightClientOptimisticUpdate => None,
Protocol::LightClientFinalityUpdate => None,
}
}
}
@@ -228,6 +298,8 @@ pub enum SupportedProtocol {
MetaDataV1,
MetaDataV2,
LightClientBootstrapV1,
LightClientOptimisticUpdateV1,
LightClientFinalityUpdateV1,
}
impl SupportedProtocol {
@@ -245,6 +317,8 @@ impl SupportedProtocol {
SupportedProtocol::MetaDataV1 => "1",
SupportedProtocol::MetaDataV2 => "2",
SupportedProtocol::LightClientBootstrapV1 => "1",
SupportedProtocol::LightClientOptimisticUpdateV1 => "1",
SupportedProtocol::LightClientFinalityUpdateV1 => "1",
}
}
@@ -262,6 +336,10 @@ impl SupportedProtocol {
SupportedProtocol::MetaDataV1 => Protocol::MetaData,
SupportedProtocol::MetaDataV2 => Protocol::MetaData,
SupportedProtocol::LightClientBootstrapV1 => Protocol::LightClientBootstrap,
SupportedProtocol::LightClientOptimisticUpdateV1 => {
Protocol::LightClientOptimisticUpdate
}
SupportedProtocol::LightClientFinalityUpdateV1 => Protocol::LightClientFinalityUpdate,
}
}
@@ -318,6 +396,14 @@ impl<E: EthSpec> UpgradeInfo for RPCProtocol<E> {
SupportedProtocol::LightClientBootstrapV1,
Encoding::SSZSnappy,
));
supported_protocols.push(ProtocolId::new(
SupportedProtocol::LightClientOptimisticUpdateV1,
Encoding::SSZSnappy,
));
supported_protocols.push(ProtocolId::new(
SupportedProtocol::LightClientFinalityUpdateV1,
Encoding::SSZSnappy,
));
}
supported_protocols
}
@@ -392,6 +478,8 @@ impl ProtocolId {
<LightClientBootstrapRequest as Encode>::ssz_fixed_len(),
<LightClientBootstrapRequest as Encode>::ssz_fixed_len(),
),
Protocol::LightClientOptimisticUpdate => RpcLimits::new(0, 0),
Protocol::LightClientFinalityUpdate => RpcLimits::new(0, 0),
Protocol::MetaData => RpcLimits::new(0, 0), // Metadata requests are empty
}
}
@@ -416,10 +504,15 @@ impl ProtocolId {
<MetaDataV1<E> as Encode>::ssz_fixed_len(),
<MetaDataV2<E> as Encode>::ssz_fixed_len(),
),
Protocol::LightClientBootstrap => RpcLimits::new(
<LightClientBootstrapRequest as Encode>::ssz_fixed_len(),
<LightClientBootstrapRequest as Encode>::ssz_fixed_len(),
),
Protocol::LightClientBootstrap => {
rpc_light_client_bootstrap_limits_by_fork(fork_context.current_fork())
}
Protocol::LightClientOptimisticUpdate => {
rpc_light_client_optimistic_update_limits_by_fork(fork_context.current_fork())
}
Protocol::LightClientFinalityUpdate => {
rpc_light_client_finality_update_limits_by_fork(fork_context.current_fork())
}
}
}
@@ -431,7 +524,9 @@ impl ProtocolId {
| SupportedProtocol::BlocksByRootV2
| SupportedProtocol::BlobsByRangeV1
| SupportedProtocol::BlobsByRootV1
| SupportedProtocol::LightClientBootstrapV1 => true,
| SupportedProtocol::LightClientBootstrapV1
| SupportedProtocol::LightClientOptimisticUpdateV1
| SupportedProtocol::LightClientFinalityUpdateV1 => true,
SupportedProtocol::StatusV1
| SupportedProtocol::BlocksByRootV1
| SupportedProtocol::BlocksByRangeV1
@@ -515,6 +610,12 @@ where
SupportedProtocol::MetaDataV2 => {
Ok((InboundRequest::MetaData(MetadataRequest::new_v2()), socket))
}
SupportedProtocol::LightClientOptimisticUpdateV1 => {
Ok((InboundRequest::LightClientOptimisticUpdate, socket))
}
SupportedProtocol::LightClientFinalityUpdateV1 => {
Ok((InboundRequest::LightClientFinalityUpdate, socket))
}
_ => {
match tokio::time::timeout(
Duration::from_secs(REQUEST_TIMEOUT),
@@ -543,6 +644,8 @@ pub enum InboundRequest<E: EthSpec> {
BlobsByRange(BlobsByRangeRequest),
BlobsByRoot(BlobsByRootRequest),
LightClientBootstrap(LightClientBootstrapRequest),
LightClientOptimisticUpdate,
LightClientFinalityUpdate,
Ping(Ping),
MetaData(MetadataRequest<E>),
}
@@ -563,6 +666,8 @@ impl<E: EthSpec> InboundRequest<E> {
InboundRequest::Ping(_) => 1,
InboundRequest::MetaData(_) => 1,
InboundRequest::LightClientBootstrap(_) => 1,
InboundRequest::LightClientOptimisticUpdate => 1,
InboundRequest::LightClientFinalityUpdate => 1,
}
}
@@ -587,6 +692,12 @@ impl<E: EthSpec> InboundRequest<E> {
MetadataRequest::V2(_) => SupportedProtocol::MetaDataV2,
},
InboundRequest::LightClientBootstrap(_) => SupportedProtocol::LightClientBootstrapV1,
InboundRequest::LightClientOptimisticUpdate => {
SupportedProtocol::LightClientOptimisticUpdateV1
}
InboundRequest::LightClientFinalityUpdate => {
SupportedProtocol::LightClientFinalityUpdateV1
}
}
}
@@ -605,6 +716,8 @@ impl<E: EthSpec> InboundRequest<E> {
InboundRequest::Ping(_) => unreachable!(),
InboundRequest::MetaData(_) => unreachable!(),
InboundRequest::LightClientBootstrap(_) => unreachable!(),
InboundRequest::LightClientFinalityUpdate => unreachable!(),
InboundRequest::LightClientOptimisticUpdate => unreachable!(),
}
}
}
@@ -711,7 +824,13 @@ impl<E: EthSpec> std::fmt::Display for InboundRequest<E> {
InboundRequest::Ping(ping) => write!(f, "Ping: {}", ping.data),
InboundRequest::MetaData(_) => write!(f, "MetaData request"),
InboundRequest::LightClientBootstrap(bootstrap) => {
write!(f, "LightClientBootstrap: {}", bootstrap.root)
write!(f, "Light client boostrap: {}", bootstrap.root)
}
InboundRequest::LightClientOptimisticUpdate => {
write!(f, "Light client optimistic update request")
}
InboundRequest::LightClientFinalityUpdate => {
write!(f, "Light client finality update request")
}
}
}

View File

@@ -98,7 +98,11 @@ pub struct RPCRateLimiter {
/// BlobsByRoot rate limiter.
blbroot_rl: Limiter<PeerId>,
/// LightClientBootstrap rate limiter.
lcbootstrap_rl: Limiter<PeerId>,
lc_bootstrap_rl: Limiter<PeerId>,
/// LightClientOptimisticUpdate rate limiter.
lc_optimistic_update_rl: Limiter<PeerId>,
/// LightClientFinalityUpdate rate limiter.
lc_finality_update_rl: Limiter<PeerId>,
}
/// Error type for non conformant requests
@@ -131,6 +135,10 @@ pub struct RPCRateLimiterBuilder {
blbroot_quota: Option<Quota>,
/// Quota for the LightClientBootstrap protocol.
lcbootstrap_quota: Option<Quota>,
/// Quota for the LightClientOptimisticUpdate protocol.
lc_optimistic_update_quota: Option<Quota>,
/// Quota for the LightClientOptimisticUpdate protocol.
lc_finality_update_quota: Option<Quota>,
}
impl RPCRateLimiterBuilder {
@@ -147,6 +155,8 @@ impl RPCRateLimiterBuilder {
Protocol::BlobsByRange => self.blbrange_quota = q,
Protocol::BlobsByRoot => self.blbroot_quota = q,
Protocol::LightClientBootstrap => self.lcbootstrap_quota = q,
Protocol::LightClientOptimisticUpdate => self.lc_optimistic_update_quota = q,
Protocol::LightClientFinalityUpdate => self.lc_finality_update_quota = q,
}
self
}
@@ -163,9 +173,15 @@ impl RPCRateLimiterBuilder {
let bbrange_quota = self
.bbrange_quota
.ok_or("BlocksByRange quota not specified")?;
let lcbootstrap_quote = self
let lc_bootstrap_quota = self
.lcbootstrap_quota
.ok_or("LightClientBootstrap quota not specified")?;
let lc_optimistic_update_quota = self
.lc_optimistic_update_quota
.ok_or("LightClientOptimisticUpdate quota not specified")?;
let lc_finality_update_quota = self
.lc_finality_update_quota
.ok_or("LightClientFinalityUpdate quota not specified")?;
let blbrange_quota = self
.blbrange_quota
@@ -184,7 +200,9 @@ impl RPCRateLimiterBuilder {
let bbrange_rl = Limiter::from_quota(bbrange_quota)?;
let blbrange_rl = Limiter::from_quota(blbrange_quota)?;
let blbroot_rl = Limiter::from_quota(blbroots_quota)?;
let lcbootstrap_rl = Limiter::from_quota(lcbootstrap_quote)?;
let lc_bootstrap_rl = Limiter::from_quota(lc_bootstrap_quota)?;
let lc_optimistic_update_rl = Limiter::from_quota(lc_optimistic_update_quota)?;
let lc_finality_update_rl = Limiter::from_quota(lc_finality_update_quota)?;
// check for peers to prune every 30 seconds, starting in 30 seconds
let prune_every = tokio::time::Duration::from_secs(30);
@@ -200,7 +218,9 @@ impl RPCRateLimiterBuilder {
bbrange_rl,
blbrange_rl,
blbroot_rl,
lcbootstrap_rl,
lc_bootstrap_rl,
lc_optimistic_update_rl,
lc_finality_update_rl,
init_time: Instant::now(),
})
}
@@ -243,6 +263,8 @@ impl RPCRateLimiter {
blobs_by_range_quota,
blobs_by_root_quota,
light_client_bootstrap_quota,
light_client_optimistic_update_quota,
light_client_finality_update_quota,
} = config;
Self::builder()
@@ -255,6 +277,14 @@ impl RPCRateLimiter {
.set_quota(Protocol::BlobsByRange, blobs_by_range_quota)
.set_quota(Protocol::BlobsByRoot, blobs_by_root_quota)
.set_quota(Protocol::LightClientBootstrap, light_client_bootstrap_quota)
.set_quota(
Protocol::LightClientOptimisticUpdate,
light_client_optimistic_update_quota,
)
.set_quota(
Protocol::LightClientFinalityUpdate,
light_client_finality_update_quota,
)
.build()
}
@@ -282,7 +312,9 @@ impl RPCRateLimiter {
Protocol::BlocksByRoot => &mut self.bbroots_rl,
Protocol::BlobsByRange => &mut self.blbrange_rl,
Protocol::BlobsByRoot => &mut self.blbroot_rl,
Protocol::LightClientBootstrap => &mut self.lcbootstrap_rl,
Protocol::LightClientBootstrap => &mut self.lc_bootstrap_rl,
Protocol::LightClientOptimisticUpdate => &mut self.lc_optimistic_update_rl,
Protocol::LightClientFinalityUpdate => &mut self.lc_finality_update_rl,
};
check(limiter)
}