Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Light client updates by range RPC #6383

Merged
merged 8 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion beacon_node/beacon_processor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub struct BeaconProcessorQueueLengths {
lc_bootstrap_queue: usize,
lc_optimistic_update_queue: usize,
lc_finality_update_queue: usize,
lc_update_range_queue: usize,
api_request_p0_queue: usize,
api_request_p1_queue: usize,
}
Expand Down Expand Up @@ -191,6 +192,7 @@ impl BeaconProcessorQueueLengths {
lc_bootstrap_queue: 1024,
lc_optimistic_update_queue: 512,
lc_finality_update_queue: 512,
lc_update_range_queue: 512,
api_request_p0_queue: 1024,
api_request_p1_queue: 1024,
})
Expand Down Expand Up @@ -611,6 +613,7 @@ pub enum Work<E: EthSpec> {
LightClientBootstrapRequest(BlockingFn),
LightClientOptimisticUpdateRequest(BlockingFn),
LightClientFinalityUpdateRequest(BlockingFn),
LightClientUpdatesByRangeRequest(BlockingFn),
ApiRequestP0(BlockingOrAsync),
ApiRequestP1(BlockingOrAsync),
}
Expand Down Expand Up @@ -662,6 +665,7 @@ pub enum WorkType {
LightClientBootstrapRequest,
LightClientOptimisticUpdateRequest,
LightClientFinalityUpdateRequest,
LightClientUpdatesByRangeRequest,
ApiRequestP0,
ApiRequestP1,
}
Expand Down Expand Up @@ -712,6 +716,7 @@ impl<E: EthSpec> Work<E> {
WorkType::LightClientOptimisticUpdateRequest
}
Work::LightClientFinalityUpdateRequest(_) => WorkType::LightClientFinalityUpdateRequest,
Work::LightClientUpdatesByRangeRequest(_) => WorkType::LightClientUpdatesByRangeRequest,
Work::UnknownBlockAttestation { .. } => WorkType::UnknownBlockAttestation,
Work::UnknownBlockAggregate { .. } => WorkType::UnknownBlockAggregate,
Work::UnknownBlockSamplingRequest { .. } => WorkType::UnknownBlockSamplingRequest,
Expand Down Expand Up @@ -891,6 +896,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
let mut lc_optimistic_update_queue =
FifoQueue::new(queue_lengths.lc_optimistic_update_queue);
let mut lc_finality_update_queue = FifoQueue::new(queue_lengths.lc_finality_update_queue);
let mut lc_update_range_queue = FifoQueue::new(queue_lengths.lc_update_range_queue);

let mut api_request_p0_queue = FifoQueue::new(queue_lengths.api_request_p0_queue);
let mut api_request_p1_queue = FifoQueue::new(queue_lengths.api_request_p1_queue);
Expand Down Expand Up @@ -1368,6 +1374,9 @@ impl<E: EthSpec> BeaconProcessor<E> {
Work::LightClientFinalityUpdateRequest { .. } => {
lc_finality_update_queue.push(work, work_id, &self.log)
}
Work::LightClientUpdatesByRangeRequest { .. } => {
lc_update_range_queue.push(work, work_id, &self.log)
}
Work::UnknownBlockAttestation { .. } => {
unknown_block_attestation_queue.push(work)
}
Expand Down Expand Up @@ -1459,6 +1468,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
WorkType::LightClientFinalityUpdateRequest => {
lc_finality_update_queue.len()
}
WorkType::LightClientUpdatesByRangeRequest => lc_update_range_queue.len(),
WorkType::ApiRequestP0 => api_request_p0_queue.len(),
WorkType::ApiRequestP1 => api_request_p1_queue.len(),
};
Expand Down Expand Up @@ -1611,7 +1621,8 @@ impl<E: EthSpec> BeaconProcessor<E> {
| Work::GossipBlsToExecutionChange(process_fn)
| Work::LightClientBootstrapRequest(process_fn)
| Work::LightClientOptimisticUpdateRequest(process_fn)
| Work::LightClientFinalityUpdateRequest(process_fn) => {
| Work::LightClientFinalityUpdateRequest(process_fn)
| Work::LightClientUpdatesByRangeRequest(process_fn) => {
task_spawner.spawn_blocking(process_fn)
}
};
Expand Down
3 changes: 3 additions & 0 deletions beacon_node/lighthouse_network/src/peer_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::LightClientBootstrap => return,
Protocol::LightClientOptimisticUpdate => return,
Protocol::LightClientFinalityUpdate => return,
Protocol::LightClientUpdatesByRange => return,
Protocol::BlobsByRoot => PeerAction::MidToleranceError,
Protocol::DataColumnsByRoot => PeerAction::MidToleranceError,
Protocol::DataColumnsByRange => PeerAction::MidToleranceError,
Expand Down Expand Up @@ -599,6 +600,7 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::LightClientBootstrap => return,
Protocol::LightClientOptimisticUpdate => return,
Protocol::LightClientFinalityUpdate => return,
Protocol::LightClientUpdatesByRange => return,
Protocol::MetaData => PeerAction::Fatal,
Protocol::Status => PeerAction::Fatal,
}
Expand All @@ -620,6 +622,7 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::LightClientBootstrap => return,
Protocol::LightClientOptimisticUpdate => return,
Protocol::LightClientFinalityUpdate => return,
Protocol::LightClientUpdatesByRange => return,
Protocol::Goodbye => return,
Protocol::MetaData => return,
Protocol::Status => return,
Expand Down
28 changes: 25 additions & 3 deletions beacon_node/lighthouse_network/src/rpc/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use tokio_util::codec::{Decoder, Encoder};
use types::{
BlobSidecar, ChainSpec, DataColumnSidecar, EthSpec, ForkContext, ForkName, Hash256,
LightClientBootstrap, LightClientFinalityUpdate, LightClientOptimisticUpdate,
RuntimeVariableList, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase,
SignedBeaconBlockBellatrix, SignedBeaconBlockCapella, SignedBeaconBlockDeneb,
SignedBeaconBlockElectra,
LightClientUpdate, RuntimeVariableList, SignedBeaconBlock, SignedBeaconBlockAltair,
SignedBeaconBlockBase, SignedBeaconBlockBellatrix, SignedBeaconBlockCapella,
SignedBeaconBlockDeneb, SignedBeaconBlockElectra,
};
use unsigned_varint::codec::Uvi;

Expand Down Expand Up @@ -76,6 +76,7 @@ impl<E: EthSpec> SSZSnappyInboundCodec<E> {
RPCResponse::LightClientBootstrap(res) => res.as_ssz_bytes(),
RPCResponse::LightClientOptimisticUpdate(res) => res.as_ssz_bytes(),
RPCResponse::LightClientFinalityUpdate(res) => res.as_ssz_bytes(),
RPCResponse::LightClientUpdatesByRange(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.
Expand Down Expand Up @@ -494,6 +495,10 @@ fn context_bytes<E: EthSpec>(
return lc_finality_update
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
}
RPCResponse::LightClientUpdatesByRange(lc_update) => {
return lc_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;
Expand Down Expand Up @@ -602,6 +607,11 @@ fn handle_rpc_request<E: EthSpec>(
SupportedProtocol::LightClientFinalityUpdateV1 => {
Ok(Some(InboundRequest::LightClientFinalityUpdate))
}
SupportedProtocol::LightClientUpdatesByRangeV1 => {
Ok(Some(InboundRequest::LightClientUpdatesByRange(
LightClientUpdatesByRangeRequest::from_ssz_bytes(decoded_buffer)?,
)))
}
// MetaData requests return early from InboundUpgrade and do not reach the decoder.
// Handle this case just for completeness.
SupportedProtocol::MetaDataV3 => {
Expand Down Expand Up @@ -776,6 +786,18 @@ fn handle_rpc_response<E: EthSpec>(
),
)),
},
SupportedProtocol::LightClientUpdatesByRangeV1 => match fork_name {
Some(fork_name) => Ok(Some(RPCResponse::LightClientUpdatesByRange(Arc::new(
LightClientUpdate::from_ssz_bytes(decoded_buffer, &fork_name)?,
)))),
None => Err(RPCError::ErrorResponse(
RPCResponseErrorCode::InvalidRequest,
format!(
"No context bytes provided for {:?} response",
versioned_protocol
),
)),
},
// MetaData V2/V3 responses have no context bytes, so behave similarly to V1 responses
SupportedProtocol::MetaDataV3 => Ok(Some(RPCResponse::MetaData(MetaData::V3(
MetaDataV3::from_ssz_bytes(decoded_buffer)?,
Expand Down
10 changes: 10 additions & 0 deletions beacon_node/lighthouse_network/src/rpc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub struct RateLimiterConfig {
pub(super) light_client_bootstrap_quota: Quota,
pub(super) light_client_optimistic_update_quota: Quota,
pub(super) light_client_finality_update_quota: Quota,
pub(super) light_client_updates_by_range_quota: Quota,
}

impl RateLimiterConfig {
Expand All @@ -121,6 +122,7 @@ impl RateLimiterConfig {
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);
pub const DEFAULT_LIGHT_CLIENT_UPDATES_BY_RANGE_QUOTA: Quota = Quota::one_every(10);
}

impl Default for RateLimiterConfig {
Expand All @@ -140,6 +142,7 @@ impl Default for RateLimiterConfig {
light_client_optimistic_update_quota:
Self::DEFAULT_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUOTA,
light_client_finality_update_quota: Self::DEFAULT_LIGHT_CLIENT_FINALITY_UPDATE_QUOTA,
light_client_updates_by_range_quota: Self::DEFAULT_LIGHT_CLIENT_UPDATES_BY_RANGE_QUOTA,
}
}
}
Expand Down Expand Up @@ -198,6 +201,7 @@ impl FromStr for RateLimiterConfig {
let mut light_client_bootstrap_quota = None;
let mut light_client_optimistic_update_quota = None;
let mut light_client_finality_update_quota = None;
let mut light_client_updates_by_range_quota = None;

for proto_def in s.split(';') {
let ProtocolQuota { protocol, quota } = proto_def.parse()?;
Expand Down Expand Up @@ -228,6 +232,10 @@ impl FromStr for RateLimiterConfig {
light_client_finality_update_quota =
light_client_finality_update_quota.or(quota)
}
Protocol::LightClientUpdatesByRange => {
light_client_updates_by_range_quota =
light_client_updates_by_range_quota.or(quota)
}
}
}
Ok(RateLimiterConfig {
Expand All @@ -252,6 +260,8 @@ impl FromStr for RateLimiterConfig {
.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),
light_client_updates_by_range_quota: light_client_updates_by_range_quota
.unwrap_or(Self::DEFAULT_LIGHT_CLIENT_UPDATES_BY_RANGE_QUOTA),
})
}
}
Expand Down
52 changes: 52 additions & 0 deletions beacon_node/lighthouse_network/src/rpc/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::sync::Arc;
use strum::IntoStaticStr;
use superstruct::superstruct;
use types::blob_sidecar::BlobIdentifier;
use types::LightClientUpdate;
use types::{
blob_sidecar::BlobSidecar, ChainSpec, ColumnIndex, DataColumnIdentifier, DataColumnSidecar,
Epoch, EthSpec, Hash256, LightClientBootstrap, LightClientFinalityUpdate,
Expand All @@ -24,6 +25,10 @@ use types::{
pub type MaxErrorLen = U256;
pub const MAX_ERROR_LEN: u64 = 256;

// Max light client updates by range request limits
// spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/p2p-interface.md#configuration
pub const MAX_REQUEST_LIGHT_CLIENT_UPDATES: u64 = 128;

/// Wrapper over SSZ List to represent error message in rpc responses.
#[derive(Debug, Clone)]
pub struct ErrorType(pub VariableList<u8, MaxErrorLen>);
Expand Down Expand Up @@ -477,6 +482,39 @@ impl DataColumnsByRootRequest {
}
}

/// Request a number of beacon data columns from a peer.
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
pub struct LightClientUpdatesByRangeRequest {
/// The starting period to request light client updates.
pub start_period: u64,
/// The number of periods from `start_period`.
pub count: u64,
}

impl LightClientUpdatesByRangeRequest {
pub fn max_requested<E: EthSpec>(&self) -> u64 {
michaelsproul marked this conversation as resolved.
Show resolved Hide resolved
MAX_REQUEST_LIGHT_CLIENT_UPDATES
}

pub fn ssz_min_len() -> usize {
LightClientUpdatesByRangeRequest {
start_period: 0,
count: 0,
}
.as_ssz_bytes()
.len()
}

pub fn ssz_max_len() -> usize {
LightClientUpdatesByRangeRequest {
start_period: 0,
count: 0,
}
.as_ssz_bytes()
.len()
dapplion marked this conversation as resolved.
Show resolved Hide resolved
}
}

/* RPC Handling and Grouping */
// Collection of enums and structs used by the Codecs to encode/decode RPC messages

Expand Down Expand Up @@ -504,6 +542,9 @@ pub enum RPCResponse<E: EthSpec> {
/// A response to a get LIGHT_CLIENT_FINALITY_UPDATE request.
LightClientFinalityUpdate(Arc<LightClientFinalityUpdate<E>>),

/// A response to a get LIGHT_CLIENT_UPDATES_BY_RANGE request.
LightClientUpdatesByRange(Arc<LightClientUpdate<E>>),

/// A response to a get BLOBS_BY_ROOT request.
BlobsByRoot(Arc<BlobSidecar<E>>),

Expand Down Expand Up @@ -540,6 +581,9 @@ pub enum ResponseTermination {

/// Data column sidecars by range stream termination.
DataColumnsByRange,

/// Light client updates by range stream termination.
LightClientUpdatesByRange,
}

/// The structured response containing a result/code indicating success or failure
Expand Down Expand Up @@ -637,6 +681,7 @@ impl<E: EthSpec> RPCResponse<E> {
RPCResponse::LightClientBootstrap(_) => Protocol::LightClientBootstrap,
RPCResponse::LightClientOptimisticUpdate(_) => Protocol::LightClientOptimisticUpdate,
RPCResponse::LightClientFinalityUpdate(_) => Protocol::LightClientFinalityUpdate,
RPCResponse::LightClientUpdatesByRange(_) => Protocol::LightClientUpdatesByRange,
}
}
}
Expand Down Expand Up @@ -706,6 +751,13 @@ impl<E: EthSpec> std::fmt::Display for RPCResponse<E> {
update.signature_slot()
)
}
RPCResponse::LightClientUpdatesByRange(update) => {
write!(
f,
"LightClientUpdatesByRange Slot: {}",
update.signature_slot(),
)
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions beacon_node/lighthouse_network/src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,9 @@ where
ResponseTermination::BlobsByRoot => Protocol::BlobsByRoot,
ResponseTermination::DataColumnsByRoot => Protocol::DataColumnsByRoot,
ResponseTermination::DataColumnsByRange => Protocol::DataColumnsByRange,
ResponseTermination::LightClientUpdatesByRange => {
Protocol::LightClientUpdatesByRange
}
},
),
};
Expand Down
Loading
Loading