Skip to content

Commit

Permalink
Light client updates by range RPC (#6383)
Browse files Browse the repository at this point in the history
* enable lc update over rpc

* resolve TODOs

* resolve merge conflicts

* move max light client updates to eth spec

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into light-client-updates-by-range-rpc

* remove ethspec dependency

* Update beacon_node/network/src/network_beacon_processor/rpc_methods.rs

Co-authored-by: Michael Sproul <micsproul@gmail.com>

* Update beacon_node/lighthouse_network/src/rpc/methods.rs

Co-authored-by: Michael Sproul <micsproul@gmail.com>
  • Loading branch information
eserilev and michaelsproul authored Oct 18, 2024
1 parent 9f1bec6 commit d1fda93
Show file tree
Hide file tree
Showing 15 changed files with 383 additions and 11 deletions.
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 @@ -135,6 +135,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 @@ -202,6 +203,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 @@ -622,6 +624,7 @@ pub enum Work<E: EthSpec> {
LightClientBootstrapRequest(BlockingFn),
LightClientOptimisticUpdateRequest(BlockingFn),
LightClientFinalityUpdateRequest(BlockingFn),
LightClientUpdatesByRangeRequest(BlockingFn),
ApiRequestP0(BlockingOrAsync),
ApiRequestP1(BlockingOrAsync),
}
Expand Down Expand Up @@ -673,6 +676,7 @@ pub enum WorkType {
LightClientBootstrapRequest,
LightClientOptimisticUpdateRequest,
LightClientFinalityUpdateRequest,
LightClientUpdatesByRangeRequest,
ApiRequestP0,
ApiRequestP1,
}
Expand Down Expand Up @@ -723,6 +727,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 @@ -902,6 +907,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 @@ -1379,6 +1385,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 @@ -1470,6 +1479,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 @@ -1622,7 +1632,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 @@ -558,6 +558,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 @@ -585,6 +586,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 @@ -606,6 +608,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
38 changes: 35 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> {
RpcSuccessResponse::LightClientBootstrap(res) => res.as_ssz_bytes(),
RpcSuccessResponse::LightClientOptimisticUpdate(res) => res.as_ssz_bytes(),
RpcSuccessResponse::LightClientFinalityUpdate(res) => res.as_ssz_bytes(),
RpcSuccessResponse::LightClientUpdatesByRange(res) => res.as_ssz_bytes(),
RpcSuccessResponse::Pong(res) => res.data.as_ssz_bytes(),
RpcSuccessResponse::MetaData(res) =>
// Encode the correct version of the MetaData response based on the negotiated version.
Expand Down Expand Up @@ -342,6 +343,7 @@ impl<E: EthSpec> Encoder<RequestType> for SSZSnappyOutboundCodec<E> {
RequestType::DataColumnsByRoot(req) => req.data_column_ids.as_ssz_bytes(),
RequestType::Ping(req) => req.as_ssz_bytes(),
RequestType::LightClientBootstrap(req) => req.as_ssz_bytes(),
RequestType::LightClientUpdatesByRange(req) => req.as_ssz_bytes(),
// no metadata to encode
RequestType::MetaData(_)
| RequestType::LightClientOptimisticUpdate
Expand Down Expand Up @@ -503,6 +505,10 @@ fn context_bytes<E: EthSpec>(
return lc_finality_update
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
}
RpcSuccessResponse::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
RpcSuccessResponse::Status(_)
| RpcSuccessResponse::Pong(_)
Expand Down Expand Up @@ -613,6 +619,11 @@ fn handle_rpc_request(
SupportedProtocol::LightClientFinalityUpdateV1 => {
Ok(Some(RequestType::LightClientFinalityUpdate))
}
SupportedProtocol::LightClientUpdatesByRangeV1 => {
Ok(Some(RequestType::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 @@ -795,6 +806,21 @@ fn handle_rpc_response<E: EthSpec>(
),
)),
},
SupportedProtocol::LightClientUpdatesByRangeV1 => match fork_name {
Some(fork_name) => Ok(Some(RpcSuccessResponse::LightClientUpdatesByRange(
Arc::new(LightClientUpdate::from_ssz_bytes(
decoded_buffer,
&fork_name,
)?),
))),
None => Err(RPCError::ErrorResponse(
RpcErrorResponse::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(RpcSuccessResponse::MetaData(MetaData::V3(
MetaDataV3::from_ssz_bytes(decoded_buffer)?,
Expand Down Expand Up @@ -1215,6 +1241,12 @@ mod tests {
)
}
RequestType::LightClientOptimisticUpdate | RequestType::LightClientFinalityUpdate => {}
RequestType::LightClientUpdatesByRange(light_client_updates_by_range) => {
assert_eq!(
decoded,
RequestType::LightClientUpdatesByRange(light_client_updates_by_range)
)
}
}
}

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
45 changes: 44 additions & 1 deletion beacon_node/lighthouse_network/src/rpc/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ use std::sync::Arc;
use strum::IntoStaticStr;
use superstruct::superstruct;
use types::blob_sidecar::BlobIdentifier;
use types::light_client_update::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
use types::{
blob_sidecar::BlobSidecar, ChainSpec, ColumnIndex, DataColumnIdentifier, DataColumnSidecar,
Epoch, EthSpec, Hash256, LightClientBootstrap, LightClientFinalityUpdate,
LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock, Slot,
LightClientOptimisticUpdate, LightClientUpdate, RuntimeVariableList, SignedBeaconBlock, Slot,
};

/// Maximum length of error message.
Expand Down Expand Up @@ -471,6 +472,34 @@ 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(&self) -> u64 {
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 {
Self::ssz_min_len()
}
}

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

Expand Down Expand Up @@ -498,6 +527,9 @@ pub enum RpcSuccessResponse<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 @@ -534,6 +566,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 @@ -633,6 +668,7 @@ impl<E: EthSpec> RpcSuccessResponse<E> {
Protocol::LightClientOptimisticUpdate
}
RpcSuccessResponse::LightClientFinalityUpdate(_) => Protocol::LightClientFinalityUpdate,
RpcSuccessResponse::LightClientUpdatesByRange(_) => Protocol::LightClientUpdatesByRange,
}
}
}
Expand Down Expand Up @@ -704,6 +740,13 @@ impl<E: EthSpec> std::fmt::Display for RpcSuccessResponse<E> {
update.signature_slot()
)
}
RpcSuccessResponse::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 @@ -553,6 +553,9 @@ where
ResponseTermination::BlobsByRoot => Protocol::BlobsByRoot,
ResponseTermination::DataColumnsByRoot => Protocol::DataColumnsByRoot,
ResponseTermination::DataColumnsByRange => Protocol::DataColumnsByRange,
ResponseTermination::LightClientUpdatesByRange => {
Protocol::LightClientUpdatesByRange
}
},
),
};
Expand Down
Loading

0 comments on commit d1fda93

Please sign in to comment.