mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
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:
@@ -187,6 +187,14 @@ const MAX_BLS_TO_EXECUTION_CHANGE_QUEUE_LEN: usize = 16_384;
|
||||
/// will be stored before we start dropping them.
|
||||
const MAX_LIGHT_CLIENT_BOOTSTRAP_QUEUE_LEN: usize = 1_024;
|
||||
|
||||
/// The maximum number of queued `LightClientOptimisticUpdateRequest` objects received from the network RPC that
|
||||
/// will be stored before we start dropping them.
|
||||
const MAX_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUEUE_LEN: usize = 512;
|
||||
|
||||
/// The maximum number of queued `LightClientFinalityUpdateRequest` objects received from the network RPC that
|
||||
/// will be stored before we start dropping them.
|
||||
const MAX_LIGHT_CLIENT_FINALITY_UPDATE_QUEUE_LEN: usize = 512;
|
||||
|
||||
/// The maximum number of priority-0 (highest priority) messages that will be queued before
|
||||
/// they begin to be dropped.
|
||||
const MAX_API_REQUEST_P0_QUEUE_LEN: usize = 1_024;
|
||||
@@ -243,6 +251,8 @@ pub const BLOCKS_BY_ROOTS_REQUEST: &str = "blocks_by_roots_request";
|
||||
pub const BLOBS_BY_RANGE_REQUEST: &str = "blobs_by_range_request";
|
||||
pub const BLOBS_BY_ROOTS_REQUEST: &str = "blobs_by_roots_request";
|
||||
pub const LIGHT_CLIENT_BOOTSTRAP_REQUEST: &str = "light_client_bootstrap";
|
||||
pub const LIGHT_CLIENT_FINALITY_UPDATE_REQUEST: &str = "light_client_finality_update_request";
|
||||
pub const LIGHT_CLIENT_OPTIMISTIC_UPDATE_REQUEST: &str = "light_client_optimistic_update_request";
|
||||
pub const UNKNOWN_BLOCK_ATTESTATION: &str = "unknown_block_attestation";
|
||||
pub const UNKNOWN_BLOCK_AGGREGATE: &str = "unknown_block_aggregate";
|
||||
pub const UNKNOWN_LIGHT_CLIENT_UPDATE: &str = "unknown_light_client_update";
|
||||
@@ -620,6 +630,8 @@ pub enum Work<E: EthSpec> {
|
||||
BlobsByRootsRequest(BlockingFn),
|
||||
GossipBlsToExecutionChange(BlockingFn),
|
||||
LightClientBootstrapRequest(BlockingFn),
|
||||
LightClientOptimisticUpdateRequest(BlockingFn),
|
||||
LightClientFinalityUpdateRequest(BlockingFn),
|
||||
ApiRequestP0(BlockingOrAsync),
|
||||
ApiRequestP1(BlockingOrAsync),
|
||||
}
|
||||
@@ -659,6 +671,8 @@ impl<E: EthSpec> Work<E> {
|
||||
Work::BlobsByRangeRequest(_) => BLOBS_BY_RANGE_REQUEST,
|
||||
Work::BlobsByRootsRequest(_) => BLOBS_BY_ROOTS_REQUEST,
|
||||
Work::LightClientBootstrapRequest(_) => LIGHT_CLIENT_BOOTSTRAP_REQUEST,
|
||||
Work::LightClientOptimisticUpdateRequest(_) => LIGHT_CLIENT_OPTIMISTIC_UPDATE_REQUEST,
|
||||
Work::LightClientFinalityUpdateRequest(_) => LIGHT_CLIENT_FINALITY_UPDATE_REQUEST,
|
||||
Work::UnknownBlockAttestation { .. } => UNKNOWN_BLOCK_ATTESTATION,
|
||||
Work::UnknownBlockAggregate { .. } => UNKNOWN_BLOCK_AGGREGATE,
|
||||
Work::GossipBlsToExecutionChange(_) => GOSSIP_BLS_TO_EXECUTION_CHANGE,
|
||||
@@ -820,7 +834,11 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
let mut gossip_bls_to_execution_change_queue =
|
||||
FifoQueue::new(MAX_BLS_TO_EXECUTION_CHANGE_QUEUE_LEN);
|
||||
|
||||
let mut lcbootstrap_queue = FifoQueue::new(MAX_LIGHT_CLIENT_BOOTSTRAP_QUEUE_LEN);
|
||||
let mut lc_bootstrap_queue = FifoQueue::new(MAX_LIGHT_CLIENT_BOOTSTRAP_QUEUE_LEN);
|
||||
let mut lc_optimistic_update_queue =
|
||||
FifoQueue::new(MAX_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUEUE_LEN);
|
||||
let mut lc_finality_update_queue =
|
||||
FifoQueue::new(MAX_LIGHT_CLIENT_FINALITY_UPDATE_QUEUE_LEN);
|
||||
|
||||
let mut api_request_p0_queue = FifoQueue::new(MAX_API_REQUEST_P0_QUEUE_LEN);
|
||||
let mut api_request_p1_queue = FifoQueue::new(MAX_API_REQUEST_P1_QUEUE_LEN);
|
||||
@@ -1137,9 +1155,14 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
// Handle backfill sync chain segments.
|
||||
} else if let Some(item) = backfill_chain_segment.pop() {
|
||||
self.spawn_worker(item, idle_tx);
|
||||
// This statement should always be the final else statement.
|
||||
} else if let Some(item) = lcbootstrap_queue.pop() {
|
||||
// Handle light client requests.
|
||||
} else if let Some(item) = lc_bootstrap_queue.pop() {
|
||||
self.spawn_worker(item, idle_tx);
|
||||
} else if let Some(item) = lc_optimistic_update_queue.pop() {
|
||||
self.spawn_worker(item, idle_tx);
|
||||
} else if let Some(item) = lc_finality_update_queue.pop() {
|
||||
self.spawn_worker(item, idle_tx);
|
||||
// This statement should always be the final else statement.
|
||||
} else {
|
||||
// Let the journal know that a worker is freed and there's nothing else
|
||||
// for it to do.
|
||||
@@ -1249,7 +1272,13 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
blbrange_queue.push(work, work_id, &self.log)
|
||||
}
|
||||
Work::LightClientBootstrapRequest { .. } => {
|
||||
lcbootstrap_queue.push(work, work_id, &self.log)
|
||||
lc_bootstrap_queue.push(work, work_id, &self.log)
|
||||
}
|
||||
Work::LightClientOptimisticUpdateRequest { .. } => {
|
||||
lc_optimistic_update_queue.push(work, work_id, &self.log)
|
||||
}
|
||||
Work::LightClientFinalityUpdateRequest { .. } => {
|
||||
lc_finality_update_queue.push(work, work_id, &self.log)
|
||||
}
|
||||
Work::UnknownBlockAttestation { .. } => {
|
||||
unknown_block_attestation_queue.push(work)
|
||||
@@ -1480,7 +1509,9 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
| Work::GossipLightClientOptimisticUpdate(process_fn)
|
||||
| Work::Status(process_fn)
|
||||
| Work::GossipBlsToExecutionChange(process_fn)
|
||||
| Work::LightClientBootstrapRequest(process_fn) => {
|
||||
| Work::LightClientBootstrapRequest(process_fn)
|
||||
| Work::LightClientOptimisticUpdateRequest(process_fn)
|
||||
| Work::LightClientFinalityUpdateRequest(process_fn) => {
|
||||
task_spawner.spawn_blocking(process_fn)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -553,7 +553,11 @@ impl<E: EthSpec> PeerManager<E> {
|
||||
Protocol::BlocksByRange => PeerAction::MidToleranceError,
|
||||
Protocol::BlocksByRoot => PeerAction::MidToleranceError,
|
||||
Protocol::BlobsByRange => PeerAction::MidToleranceError,
|
||||
Protocol::LightClientBootstrap => PeerAction::LowToleranceError,
|
||||
// Lighthouse does not currently make light client requests; therefore, this
|
||||
// is an unexpected scenario. We do not ban the peer for rate limiting.
|
||||
Protocol::LightClientBootstrap => return,
|
||||
Protocol::LightClientOptimisticUpdate => return,
|
||||
Protocol::LightClientFinalityUpdate => return,
|
||||
Protocol::BlobsByRoot => PeerAction::MidToleranceError,
|
||||
Protocol::Goodbye => PeerAction::LowToleranceError,
|
||||
Protocol::MetaData => PeerAction::LowToleranceError,
|
||||
@@ -575,6 +579,8 @@ impl<E: EthSpec> PeerManager<E> {
|
||||
Protocol::BlobsByRoot => return,
|
||||
Protocol::Goodbye => return,
|
||||
Protocol::LightClientBootstrap => return,
|
||||
Protocol::LightClientOptimisticUpdate => return,
|
||||
Protocol::LightClientFinalityUpdate => return,
|
||||
Protocol::MetaData => PeerAction::Fatal,
|
||||
Protocol::Status => PeerAction::Fatal,
|
||||
}
|
||||
@@ -592,6 +598,8 @@ impl<E: EthSpec> PeerManager<E> {
|
||||
Protocol::BlobsByRange => PeerAction::MidToleranceError,
|
||||
Protocol::BlobsByRoot => PeerAction::MidToleranceError,
|
||||
Protocol::LightClientBootstrap => return,
|
||||
Protocol::LightClientOptimisticUpdate => return,
|
||||
Protocol::LightClientFinalityUpdate => return,
|
||||
Protocol::Goodbye => return,
|
||||
Protocol::MetaData => return,
|
||||
Protocol::Status => return,
|
||||
|
||||
@@ -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,9 +388,9 @@ 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
|
||||
{
|
||||
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!
|
||||
@@ -408,12 +409,31 @@ fn context_bytes<E: EthSpec>(
|
||||
SignedBeaconBlock::Altair { .. } => {
|
||||
fork_context.to_context_bytes(ForkName::Altair)
|
||||
}
|
||||
SignedBeaconBlock::Base { .. } => Some(fork_context.genesis_context_bytes()),
|
||||
SignedBeaconBlock::Base { .. } => {
|
||||
Some(fork_context.genesis_context_bytes())
|
||||
}
|
||||
};
|
||||
}
|
||||
if let RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) = rpc_variant {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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)?,
|
||||
|
||||
@@ -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),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ¤t_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 ¤t_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 ¤t_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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use libp2p::swarm::ConnectionId;
|
||||
use types::{BlobSidecar, EthSpec, LightClientBootstrap, SignedBeaconBlock};
|
||||
use types::{
|
||||
BlobSidecar, EthSpec, LightClientBootstrap, LightClientFinalityUpdate,
|
||||
LightClientOptimisticUpdate, SignedBeaconBlock,
|
||||
};
|
||||
|
||||
use crate::rpc::methods::{BlobsByRangeRequest, BlobsByRootRequest};
|
||||
use crate::rpc::{
|
||||
@@ -40,6 +43,10 @@ pub enum Request {
|
||||
BlocksByRoot(BlocksByRootRequest),
|
||||
// light client bootstrap request
|
||||
LightClientBootstrap(LightClientBootstrapRequest),
|
||||
// light client optimistic update request
|
||||
LightClientOptimisticUpdate,
|
||||
// light client finality update request
|
||||
LightClientFinalityUpdate,
|
||||
/// A request blobs root request.
|
||||
BlobsByRoot(BlobsByRootRequest),
|
||||
}
|
||||
@@ -64,7 +71,9 @@ impl<E: EthSpec> std::convert::From<Request> for OutboundRequest<E> {
|
||||
}),
|
||||
),
|
||||
},
|
||||
Request::LightClientBootstrap(_) => {
|
||||
Request::LightClientBootstrap(_)
|
||||
| Request::LightClientOptimisticUpdate
|
||||
| Request::LightClientFinalityUpdate => {
|
||||
unreachable!("Lighthouse never makes an outbound light client request")
|
||||
}
|
||||
Request::BlobsByRange(r) => OutboundRequest::BlobsByRange(r),
|
||||
@@ -94,6 +103,10 @@ pub enum Response<E: EthSpec> {
|
||||
BlobsByRoot(Option<Arc<BlobSidecar<E>>>),
|
||||
/// A response to a LightClientUpdate request.
|
||||
LightClientBootstrap(Arc<LightClientBootstrap<E>>),
|
||||
/// A response to a LightClientOptimisticUpdate request.
|
||||
LightClientOptimisticUpdate(Arc<LightClientOptimisticUpdate<E>>),
|
||||
/// A response to a LightClientFinalityUpdate request.
|
||||
LightClientFinalityUpdate(Arc<LightClientFinalityUpdate<E>>),
|
||||
}
|
||||
|
||||
impl<E: EthSpec> std::convert::From<Response<E>> for RPCCodedResponse<E> {
|
||||
@@ -119,6 +132,12 @@ impl<E: EthSpec> std::convert::From<Response<E>> for RPCCodedResponse<E> {
|
||||
Response::LightClientBootstrap(b) => {
|
||||
RPCCodedResponse::Success(RPCResponse::LightClientBootstrap(b))
|
||||
}
|
||||
Response::LightClientOptimisticUpdate(o) => {
|
||||
RPCCodedResponse::Success(RPCResponse::LightClientOptimisticUpdate(o))
|
||||
}
|
||||
Response::LightClientFinalityUpdate(f) => {
|
||||
RPCCodedResponse::Success(RPCResponse::LightClientFinalityUpdate(f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1170,6 +1170,14 @@ impl<AppReqId: ReqId, E: EthSpec> Network<AppReqId, E> {
|
||||
Request::LightClientBootstrap(_) => {
|
||||
metrics::inc_counter_vec(&metrics::TOTAL_RPC_REQUESTS, &["light_client_bootstrap"])
|
||||
}
|
||||
Request::LightClientOptimisticUpdate => metrics::inc_counter_vec(
|
||||
&metrics::TOTAL_RPC_REQUESTS,
|
||||
&["light_client_optimistic_update"],
|
||||
),
|
||||
Request::LightClientFinalityUpdate => metrics::inc_counter_vec(
|
||||
&metrics::TOTAL_RPC_REQUESTS,
|
||||
&["light_client_finality_update"],
|
||||
),
|
||||
Request::BlocksByRange { .. } => {
|
||||
metrics::inc_counter_vec(&metrics::TOTAL_RPC_REQUESTS, &["blocks_by_range"])
|
||||
}
|
||||
@@ -1508,6 +1516,22 @@ impl<AppReqId: ReqId, E: EthSpec> Network<AppReqId, E> {
|
||||
);
|
||||
Some(event)
|
||||
}
|
||||
InboundRequest::LightClientOptimisticUpdate => {
|
||||
let event = self.build_request(
|
||||
peer_request_id,
|
||||
peer_id,
|
||||
Request::LightClientOptimisticUpdate,
|
||||
);
|
||||
Some(event)
|
||||
}
|
||||
InboundRequest::LightClientFinalityUpdate => {
|
||||
let event = self.build_request(
|
||||
peer_request_id,
|
||||
peer_id,
|
||||
Request::LightClientFinalityUpdate,
|
||||
);
|
||||
Some(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
HandlerEvent::Ok(RPCReceived::Response(id, resp)) => {
|
||||
@@ -1545,6 +1569,16 @@ impl<AppReqId: ReqId, E: EthSpec> Network<AppReqId, E> {
|
||||
RPCResponse::LightClientBootstrap(bootstrap) => {
|
||||
self.build_response(id, peer_id, Response::LightClientBootstrap(bootstrap))
|
||||
}
|
||||
RPCResponse::LightClientOptimisticUpdate(update) => self.build_response(
|
||||
id,
|
||||
peer_id,
|
||||
Response::LightClientOptimisticUpdate(update),
|
||||
),
|
||||
RPCResponse::LightClientFinalityUpdate(update) => self.build_response(
|
||||
id,
|
||||
peer_id,
|
||||
Response::LightClientFinalityUpdate(update),
|
||||
),
|
||||
}
|
||||
}
|
||||
HandlerEvent::Ok(RPCReceived::EndOfStream(id, termination)) => {
|
||||
|
||||
@@ -605,6 +605,37 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Create a new work event to process a `LightClientOptimisticUpdate` request from the RPC network.
|
||||
pub fn send_light_client_optimistic_update_request(
|
||||
self: &Arc<Self>,
|
||||
peer_id: PeerId,
|
||||
request_id: PeerRequestId,
|
||||
) -> Result<(), Error<T::EthSpec>> {
|
||||
let processor = self.clone();
|
||||
let process_fn =
|
||||
move || processor.handle_light_client_optimistic_update(peer_id, request_id);
|
||||
|
||||
self.try_send(BeaconWorkEvent {
|
||||
drop_during_sync: true,
|
||||
work: Work::LightClientOptimisticUpdateRequest(Box::new(process_fn)),
|
||||
})
|
||||
}
|
||||
|
||||
/// Create a new work event to process a `LightClientFinalityUpdate` request from the RPC network.
|
||||
pub fn send_light_client_finality_update_request(
|
||||
self: &Arc<Self>,
|
||||
peer_id: PeerId,
|
||||
request_id: PeerRequestId,
|
||||
) -> Result<(), Error<T::EthSpec>> {
|
||||
let processor = self.clone();
|
||||
let process_fn = move || processor.handle_light_client_finality_update(peer_id, request_id);
|
||||
|
||||
self.try_send(BeaconWorkEvent {
|
||||
drop_during_sync: true,
|
||||
work: Work::LightClientFinalityUpdateRequest(Box::new(process_fn)),
|
||||
})
|
||||
}
|
||||
|
||||
/// Send a message to `sync_tx`.
|
||||
///
|
||||
/// Creates a log if there is an internal error.
|
||||
|
||||
@@ -293,7 +293,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle a `BlocksByRoot` request from the peer.
|
||||
/// Handle a `LightClientBootstrap` request from the peer.
|
||||
pub fn handle_light_client_bootstrap(
|
||||
self: &Arc<Self>,
|
||||
peer_id: PeerId,
|
||||
@@ -329,6 +329,60 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
};
|
||||
}
|
||||
|
||||
/// Handle a `LightClientOptimisticUpdate` request from the peer.
|
||||
pub fn handle_light_client_optimistic_update(
|
||||
self: &Arc<Self>,
|
||||
peer_id: PeerId,
|
||||
request_id: PeerRequestId,
|
||||
) {
|
||||
let Some(light_client_optimistic_update) = self
|
||||
.chain
|
||||
.light_client_server_cache
|
||||
.get_latest_optimistic_update()
|
||||
else {
|
||||
self.send_error_response(
|
||||
peer_id,
|
||||
RPCResponseErrorCode::ResourceUnavailable,
|
||||
"Latest optimistic update not available".into(),
|
||||
request_id,
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
self.send_response(
|
||||
peer_id,
|
||||
Response::LightClientOptimisticUpdate(Arc::new(light_client_optimistic_update)),
|
||||
request_id,
|
||||
)
|
||||
}
|
||||
|
||||
/// Handle a `LightClientFinalityUpdate` request from the peer.
|
||||
pub fn handle_light_client_finality_update(
|
||||
self: &Arc<Self>,
|
||||
peer_id: PeerId,
|
||||
request_id: PeerRequestId,
|
||||
) {
|
||||
let Some(light_client_finality_update) = self
|
||||
.chain
|
||||
.light_client_server_cache
|
||||
.get_latest_finality_update()
|
||||
else {
|
||||
self.send_error_response(
|
||||
peer_id,
|
||||
RPCResponseErrorCode::ResourceUnavailable,
|
||||
"Latest finality update not available".into(),
|
||||
request_id,
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
self.send_response(
|
||||
peer_id,
|
||||
Response::LightClientFinalityUpdate(Arc::new(light_client_finality_update)),
|
||||
request_id,
|
||||
)
|
||||
}
|
||||
|
||||
/// Handle a `BlocksByRange` request from the peer.
|
||||
pub fn handle_blocks_by_range_request(
|
||||
self: Arc<Self>,
|
||||
|
||||
@@ -220,6 +220,14 @@ impl<T: BeaconChainTypes> Router<T> {
|
||||
self.network_beacon_processor
|
||||
.send_light_client_bootstrap_request(peer_id, request_id, request),
|
||||
),
|
||||
Request::LightClientOptimisticUpdate => self.handle_beacon_processor_send_result(
|
||||
self.network_beacon_processor
|
||||
.send_light_client_optimistic_update_request(peer_id, request_id),
|
||||
),
|
||||
Request::LightClientFinalityUpdate => self.handle_beacon_processor_send_result(
|
||||
self.network_beacon_processor
|
||||
.send_light_client_finality_update_request(peer_id, request_id),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +258,10 @@ impl<T: BeaconChainTypes> Router<T> {
|
||||
Response::BlobsByRoot(blob) => {
|
||||
self.on_blobs_by_root_response(peer_id, request_id, blob);
|
||||
}
|
||||
Response::LightClientBootstrap(_) => unreachable!(),
|
||||
// Light client responses should not be received
|
||||
Response::LightClientBootstrap(_)
|
||||
| Response::LightClientOptimisticUpdate(_)
|
||||
| Response::LightClientFinalityUpdate(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ pub fn process_registry_updates<E: EthSpec>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn process_registry_updates_slow<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
pub fn process_registry_updates_slow<E: EthSpec>(
|
||||
state: &mut BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
process_epoch_single_pass(
|
||||
|
||||
@@ -47,8 +47,8 @@ pub fn process_slashings<E: EthSpec>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn process_slashings_slow<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
pub fn process_slashings_slow<E: EthSpec>(
|
||||
state: &mut BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
process_epoch_single_pass(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{test_utils::TestRandom, *};
|
||||
use derivative::Derivative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Decode;
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
@@ -109,6 +109,23 @@ impl<E: EthSpec> ExecutionPayloadHeader<E> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::arithmetic_side_effects)]
|
||||
pub fn ssz_max_var_len_for_fork(fork_name: ForkName) -> usize {
|
||||
// Matching here in case variable fields are added in future forks.
|
||||
// TODO(electra): review electra changes
|
||||
match fork_name {
|
||||
ForkName::Base
|
||||
| ForkName::Altair
|
||||
| ForkName::Merge
|
||||
| ForkName::Capella
|
||||
| ForkName::Deneb
|
||||
| ForkName::Electra => {
|
||||
// Max size of variable length `extra_data` field
|
||||
E::max_extra_data_bytes() * <u8 as Encode>::ssz_fixed_len()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec> ExecutionPayloadHeaderRef<'a, E> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{BeaconState, EthSpec, FixedVector, Hash256, SyncCommittee};
|
||||
use super::{BeaconState, EthSpec, FixedVector, Hash256, LightClientHeader, SyncCommittee};
|
||||
use crate::{
|
||||
light_client_update::*, test_utils::TestRandom, ChainSpec, ForkName, ForkVersionDeserialize,
|
||||
LightClientHeaderAltair, LightClientHeaderCapella, LightClientHeaderDeneb, SignedBeaconBlock,
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
use derivative::Derivative;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use ssz::Decode;
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::sync::Arc;
|
||||
use superstruct::superstruct;
|
||||
@@ -59,6 +59,17 @@ pub struct LightClientBootstrap<E: EthSpec> {
|
||||
}
|
||||
|
||||
impl<E: EthSpec> LightClientBootstrap<E> {
|
||||
pub fn map_with_fork_name<F, R>(&self, func: F) -> R
|
||||
where
|
||||
F: Fn(ForkName) -> R,
|
||||
{
|
||||
match self {
|
||||
Self::Altair(_) => func(ForkName::Altair),
|
||||
Self::Capella(_) => func(ForkName::Capella),
|
||||
Self::Deneb(_) => func(ForkName::Deneb),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_slot<'a>(&'a self) -> Slot {
|
||||
map_light_client_bootstrap_ref!(&'a _, self.to_ref(), |inner, cons| {
|
||||
cons(inner);
|
||||
@@ -85,6 +96,22 @@ impl<E: EthSpec> LightClientBootstrap<E> {
|
||||
Ok(bootstrap)
|
||||
}
|
||||
|
||||
#[allow(clippy::arithmetic_side_effects)]
|
||||
pub fn ssz_max_len_for_fork(fork_name: ForkName) -> usize {
|
||||
// TODO(electra): review electra changes
|
||||
match fork_name {
|
||||
ForkName::Base => 0,
|
||||
ForkName::Altair
|
||||
| ForkName::Merge
|
||||
| ForkName::Capella
|
||||
| ForkName::Deneb
|
||||
| ForkName::Electra => {
|
||||
<LightClientBootstrapAltair<E> as Encode>::ssz_fixed_len()
|
||||
+ LightClientHeader::<E>::ssz_max_var_len_for_fork(fork_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_beacon_state(
|
||||
beacon_state: &mut BeaconState<E>,
|
||||
block: &SignedBeaconBlock<E>,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{EthSpec, FixedVector, Hash256, Slot, SyncAggregate};
|
||||
use super::{EthSpec, FixedVector, Hash256, LightClientHeader, Slot, SyncAggregate};
|
||||
use crate::ChainSpec;
|
||||
use crate::{
|
||||
light_client_update::*, test_utils::TestRandom, ForkName, ForkVersionDeserialize,
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
use derivative::Derivative;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use ssz::Decode;
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::Decode;
|
||||
use ssz_derive::Encode;
|
||||
use superstruct::superstruct;
|
||||
@@ -59,9 +59,9 @@ pub struct LightClientFinalityUpdate<E: EthSpec> {
|
||||
pub finalized_header: LightClientHeaderDeneb<E>,
|
||||
/// Merkle proof attesting finalized header.
|
||||
pub finality_branch: FixedVector<Hash256, FinalizedRootProofLen>,
|
||||
/// current sync aggreggate
|
||||
/// current sync aggregate
|
||||
pub sync_aggregate: SyncAggregate<E>,
|
||||
/// Slot of the sync aggregated singature
|
||||
/// Slot of the sync aggregated signature
|
||||
pub signature_slot: Slot,
|
||||
}
|
||||
|
||||
@@ -126,6 +126,17 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
Ok(finality_update)
|
||||
}
|
||||
|
||||
pub fn map_with_fork_name<F, R>(&self, func: F) -> R
|
||||
where
|
||||
F: Fn(ForkName) -> R,
|
||||
{
|
||||
match self {
|
||||
Self::Altair(_) => func(ForkName::Altair),
|
||||
Self::Capella(_) => func(ForkName::Capella),
|
||||
Self::Deneb(_) => func(ForkName::Deneb),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_attested_header_slot<'a>(&'a self) -> Slot {
|
||||
map_light_client_finality_update_ref!(&'a _, self.to_ref(), |inner, cons| {
|
||||
cons(inner);
|
||||
@@ -153,6 +164,22 @@ impl<E: EthSpec> LightClientFinalityUpdate<E> {
|
||||
|
||||
Ok(finality_update)
|
||||
}
|
||||
|
||||
#[allow(clippy::arithmetic_side_effects)]
|
||||
pub fn ssz_max_len_for_fork(fork_name: ForkName) -> usize {
|
||||
// TODO(electra): review electra changes
|
||||
match fork_name {
|
||||
ForkName::Base => 0,
|
||||
ForkName::Altair
|
||||
| ForkName::Merge
|
||||
| ForkName::Capella
|
||||
| ForkName::Deneb
|
||||
| ForkName::Electra => {
|
||||
<LightClientFinalityUpdateAltair<E> as Encode>::ssz_fixed_len()
|
||||
+ 2 * LightClientHeader::<E>::ssz_max_var_len_for_fork(fork_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ForkVersionDeserialize for LightClientFinalityUpdate<E> {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::BeaconBlockHeader;
|
||||
use crate::ChainSpec;
|
||||
use crate::ForkName;
|
||||
use crate::ForkVersionDeserialize;
|
||||
@@ -7,6 +6,7 @@ use crate::{
|
||||
test_utils::TestRandom, EthSpec, ExecutionPayloadHeaderCapella, ExecutionPayloadHeaderDeneb,
|
||||
FixedVector, Hash256, SignedBeaconBlock,
|
||||
};
|
||||
use crate::{BeaconBlockHeader, ExecutionPayloadHeader};
|
||||
use derivative::Derivative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ssz::Decode;
|
||||
@@ -116,6 +116,15 @@ impl<E: EthSpec> LightClientHeader<E> {
|
||||
) -> Result<Self, ssz::DecodeError> {
|
||||
Self::from_ssz_bytes(bytes, fork_name)
|
||||
}
|
||||
|
||||
pub fn ssz_max_var_len_for_fork(fork_name: ForkName) -> usize {
|
||||
match fork_name {
|
||||
ForkName::Base | ForkName::Altair | ForkName::Merge => 0,
|
||||
ForkName::Capella | ForkName::Deneb | ForkName::Electra => {
|
||||
ExecutionPayloadHeader::<E>::ssz_max_var_len_for_fork(fork_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> LightClientHeaderAltair<E> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{EthSpec, ForkName, ForkVersionDeserialize, Slot, SyncAggregate};
|
||||
use super::{EthSpec, ForkName, ForkVersionDeserialize, LightClientHeader, Slot, SyncAggregate};
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{
|
||||
light_client_update::*, ChainSpec, LightClientHeaderAltair, LightClientHeaderCapella,
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
use derivative::Derivative;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde_json::Value;
|
||||
use ssz::Decode;
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::Decode;
|
||||
use ssz_derive::Encode;
|
||||
use superstruct::superstruct;
|
||||
@@ -53,9 +53,9 @@ pub struct LightClientOptimisticUpdate<E: EthSpec> {
|
||||
pub attested_header: LightClientHeaderCapella<E>,
|
||||
#[superstruct(only(Deneb), partial_getter(rename = "attested_header_deneb"))]
|
||||
pub attested_header: LightClientHeaderDeneb<E>,
|
||||
/// current sync aggreggate
|
||||
/// current sync aggregate
|
||||
pub sync_aggregate: SyncAggregate<E>,
|
||||
/// Slot of the sync aggregated singature
|
||||
/// Slot of the sync aggregated signature
|
||||
pub signature_slot: Slot,
|
||||
}
|
||||
|
||||
@@ -97,6 +97,17 @@ impl<E: EthSpec> LightClientOptimisticUpdate<E> {
|
||||
Ok(optimistic_update)
|
||||
}
|
||||
|
||||
pub fn map_with_fork_name<F, R>(&self, func: F) -> R
|
||||
where
|
||||
F: Fn(ForkName) -> R,
|
||||
{
|
||||
match self {
|
||||
Self::Altair(_) => func(ForkName::Altair),
|
||||
Self::Capella(_) => func(ForkName::Capella),
|
||||
Self::Deneb(_) => func(ForkName::Deneb),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_slot<'a>(&'a self) -> Slot {
|
||||
map_light_client_optimistic_update_ref!(&'a _, self.to_ref(), |inner, cons| {
|
||||
cons(inner);
|
||||
@@ -138,6 +149,22 @@ impl<E: EthSpec> LightClientOptimisticUpdate<E> {
|
||||
|
||||
Ok(optimistic_update)
|
||||
}
|
||||
|
||||
#[allow(clippy::arithmetic_side_effects)]
|
||||
pub fn ssz_max_len_for_fork(fork_name: ForkName) -> usize {
|
||||
// TODO(electra): review electra changes
|
||||
match fork_name {
|
||||
ForkName::Base => 0,
|
||||
ForkName::Altair
|
||||
| ForkName::Merge
|
||||
| ForkName::Capella
|
||||
| ForkName::Deneb
|
||||
| ForkName::Electra => {
|
||||
<LightClientOptimisticUpdateAltair<E> as Encode>::ssz_fixed_len()
|
||||
+ LightClientHeader::<E>::ssz_max_var_len_for_fork(fork_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ForkVersionDeserialize for LightClientOptimisticUpdate<E> {
|
||||
|
||||
Reference in New Issue
Block a user