mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-30 19:23:50 +00:00
Implement data columns by network boilerplate (#6224)
* Implement data columns by network boilerplate * Use correct quota values * Address PR review * Update currently_supported * Merge remote-tracking branch 'sigp/unstable' into peerdas-network-boilerplate * PR reviews * Fix data column rpc request not being sent due to incorrect limits set. (#6000)
This commit is contained in:
@@ -16,10 +16,11 @@ use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
use tokio_util::codec::{Decoder, Encoder};
|
||||
use types::{
|
||||
BlobSidecar, ChainSpec, EthSpec, ForkContext, ForkName, Hash256, LightClientBootstrap,
|
||||
LightClientFinalityUpdate, LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock,
|
||||
SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix,
|
||||
SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra,
|
||||
BlobSidecar, ChainSpec, DataColumnSidecar, EthSpec, ForkContext, ForkName, Hash256,
|
||||
LightClientBootstrap, LightClientFinalityUpdate, LightClientOptimisticUpdate,
|
||||
RuntimeVariableList, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase,
|
||||
SignedBeaconBlockBellatrix, SignedBeaconBlockCapella, SignedBeaconBlockDeneb,
|
||||
SignedBeaconBlockElectra,
|
||||
};
|
||||
use unsigned_varint::codec::Uvi;
|
||||
|
||||
@@ -70,6 +71,8 @@ impl<E: EthSpec> Encoder<RPCCodedResponse<E>> for SSZSnappyInboundCodec<E> {
|
||||
RPCResponse::BlocksByRoot(res) => res.as_ssz_bytes(),
|
||||
RPCResponse::BlobsByRange(res) => res.as_ssz_bytes(),
|
||||
RPCResponse::BlobsByRoot(res) => res.as_ssz_bytes(),
|
||||
RPCResponse::DataColumnsByRoot(res) => res.as_ssz_bytes(),
|
||||
RPCResponse::DataColumnsByRange(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(),
|
||||
@@ -224,6 +227,8 @@ impl<E: EthSpec> Encoder<OutboundRequest<E>> for SSZSnappyOutboundCodec<E> {
|
||||
},
|
||||
OutboundRequest::BlobsByRange(req) => req.as_ssz_bytes(),
|
||||
OutboundRequest::BlobsByRoot(req) => req.blob_ids.as_ssz_bytes(),
|
||||
OutboundRequest::DataColumnsByRange(req) => req.as_ssz_bytes(),
|
||||
OutboundRequest::DataColumnsByRoot(req) => req.data_column_ids.as_ssz_bytes(),
|
||||
OutboundRequest::Ping(req) => req.as_ssz_bytes(),
|
||||
OutboundRequest::MetaData(_) => return Ok(()), // no metadata to encode
|
||||
};
|
||||
@@ -414,7 +419,12 @@ fn context_bytes<E: EthSpec>(
|
||||
}
|
||||
};
|
||||
}
|
||||
RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) => {
|
||||
RPCResponse::BlobsByRange(_)
|
||||
| RPCResponse::BlobsByRoot(_)
|
||||
| RPCResponse::DataColumnsByRoot(_)
|
||||
| RPCResponse::DataColumnsByRange(_) => {
|
||||
// TODO(das): If DataColumnSidecar is defined as an Electra type, update the
|
||||
// context bytes to point to ForkName::Electra
|
||||
return fork_context.to_context_bytes(ForkName::Deneb);
|
||||
}
|
||||
RPCResponse::LightClientBootstrap(lc_bootstrap) => {
|
||||
@@ -512,6 +522,17 @@ fn handle_rpc_request<E: EthSpec>(
|
||||
)?,
|
||||
})))
|
||||
}
|
||||
SupportedProtocol::DataColumnsByRootV1 => Ok(Some(InboundRequest::DataColumnsByRoot(
|
||||
DataColumnsByRootRequest {
|
||||
data_column_ids: RuntimeVariableList::from_ssz_bytes(
|
||||
decoded_buffer,
|
||||
spec.max_request_data_column_sidecars as usize,
|
||||
)?,
|
||||
},
|
||||
))),
|
||||
SupportedProtocol::DataColumnsByRangeV1 => Ok(Some(InboundRequest::DataColumnsByRange(
|
||||
DataColumnsByRangeRequest::from_ssz_bytes(decoded_buffer)?,
|
||||
))),
|
||||
SupportedProtocol::PingV1 => Ok(Some(InboundRequest::Ping(Ping {
|
||||
data: u64::from_ssz_bytes(decoded_buffer)?,
|
||||
}))),
|
||||
@@ -604,6 +625,51 @@ fn handle_rpc_response<E: EthSpec>(
|
||||
),
|
||||
)),
|
||||
},
|
||||
SupportedProtocol::DataColumnsByRootV1 => match fork_name {
|
||||
Some(fork_name) => {
|
||||
// TODO(das): PeerDAS is currently supported for both deneb and electra. This check
|
||||
// does not advertise the topic on deneb, simply allows it to decode it. Advertise
|
||||
// logic is in `SupportedTopic::currently_supported`.
|
||||
if fork_name.deneb_enabled() {
|
||||
Ok(Some(RPCResponse::DataColumnsByRoot(Arc::new(
|
||||
DataColumnSidecar::from_ssz_bytes(decoded_buffer)?,
|
||||
))))
|
||||
} else {
|
||||
Err(RPCError::ErrorResponse(
|
||||
RPCResponseErrorCode::InvalidRequest,
|
||||
"Invalid fork name for data columns by root".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
None => Err(RPCError::ErrorResponse(
|
||||
RPCResponseErrorCode::InvalidRequest,
|
||||
format!(
|
||||
"No context bytes provided for {:?} response",
|
||||
versioned_protocol
|
||||
),
|
||||
)),
|
||||
},
|
||||
SupportedProtocol::DataColumnsByRangeV1 => match fork_name {
|
||||
Some(fork_name) => {
|
||||
if fork_name.deneb_enabled() {
|
||||
Ok(Some(RPCResponse::DataColumnsByRange(Arc::new(
|
||||
DataColumnSidecar::from_ssz_bytes(decoded_buffer)?,
|
||||
))))
|
||||
} else {
|
||||
Err(RPCError::ErrorResponse(
|
||||
RPCResponseErrorCode::InvalidRequest,
|
||||
"Invalid fork name for data columns by range".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
None => Err(RPCError::ErrorResponse(
|
||||
RPCResponseErrorCode::InvalidRequest,
|
||||
format!(
|
||||
"No context bytes provided for {:?} response",
|
||||
versioned_protocol
|
||||
),
|
||||
)),
|
||||
},
|
||||
SupportedProtocol::PingV1 => Ok(Some(RPCResponse::Pong(Ping {
|
||||
data: u64::from_ssz_bytes(decoded_buffer)?,
|
||||
}))),
|
||||
@@ -747,7 +813,8 @@ mod tests {
|
||||
use crate::types::{EnrAttestationBitfield, EnrSyncCommitteeBitfield};
|
||||
use types::{
|
||||
blob_sidecar::BlobIdentifier, BeaconBlock, BeaconBlockAltair, BeaconBlockBase,
|
||||
BeaconBlockBellatrix, EmptyBlock, Epoch, FullPayload, Signature, Slot,
|
||||
BeaconBlockBellatrix, DataColumnIdentifier, EmptyBlock, Epoch, FullPayload, Signature,
|
||||
Slot,
|
||||
};
|
||||
|
||||
type Spec = types::MainnetEthSpec;
|
||||
@@ -794,6 +861,10 @@ mod tests {
|
||||
Arc::new(BlobSidecar::empty())
|
||||
}
|
||||
|
||||
fn empty_data_column_sidecar() -> Arc<DataColumnSidecar<Spec>> {
|
||||
Arc::new(DataColumnSidecar::empty())
|
||||
}
|
||||
|
||||
/// Bellatrix block with length < max_rpc_size.
|
||||
fn bellatrix_block_small(
|
||||
fork_context: &ForkContext,
|
||||
@@ -855,6 +926,27 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn dcbrange_request() -> DataColumnsByRangeRequest {
|
||||
DataColumnsByRangeRequest {
|
||||
start_slot: 0,
|
||||
count: 10,
|
||||
columns: vec![1, 2, 3],
|
||||
}
|
||||
}
|
||||
|
||||
fn dcbroot_request(spec: &ChainSpec) -> DataColumnsByRootRequest {
|
||||
DataColumnsByRootRequest {
|
||||
data_column_ids: RuntimeVariableList::new(
|
||||
vec![DataColumnIdentifier {
|
||||
block_root: Hash256::zero(),
|
||||
index: 0,
|
||||
}],
|
||||
spec.max_request_data_column_sidecars as usize,
|
||||
)
|
||||
.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn bbroot_request_v1(spec: &ChainSpec) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new_v1(vec![Hash256::zero()], spec)
|
||||
}
|
||||
@@ -1012,6 +1104,12 @@ mod tests {
|
||||
OutboundRequest::BlobsByRoot(bbroot) => {
|
||||
assert_eq!(decoded, InboundRequest::BlobsByRoot(bbroot))
|
||||
}
|
||||
OutboundRequest::DataColumnsByRoot(dcbroot) => {
|
||||
assert_eq!(decoded, InboundRequest::DataColumnsByRoot(dcbroot))
|
||||
}
|
||||
OutboundRequest::DataColumnsByRange(dcbrange) => {
|
||||
assert_eq!(decoded, InboundRequest::DataColumnsByRange(dcbrange))
|
||||
}
|
||||
OutboundRequest::Ping(ping) => {
|
||||
assert_eq!(decoded, InboundRequest::Ping(ping))
|
||||
}
|
||||
@@ -1138,6 +1236,34 @@ mod tests {
|
||||
),
|
||||
Ok(Some(RPCResponse::BlobsByRoot(empty_blob_sidecar()))),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::DataColumnsByRangeV1,
|
||||
RPCCodedResponse::Success(RPCResponse::DataColumnsByRange(
|
||||
empty_data_column_sidecar()
|
||||
)),
|
||||
ForkName::Deneb,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RPCResponse::DataColumnsByRange(
|
||||
empty_data_column_sidecar()
|
||||
))),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::DataColumnsByRootV1,
|
||||
RPCCodedResponse::Success(RPCResponse::DataColumnsByRoot(
|
||||
empty_data_column_sidecar()
|
||||
)),
|
||||
ForkName::Deneb,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RPCResponse::DataColumnsByRoot(
|
||||
empty_data_column_sidecar()
|
||||
))),
|
||||
);
|
||||
}
|
||||
|
||||
// Test RPCResponse encoding/decoding for V1 messages
|
||||
@@ -1491,6 +1617,8 @@ mod tests {
|
||||
OutboundRequest::MetaData(MetadataRequest::new_v1()),
|
||||
OutboundRequest::BlobsByRange(blbrange_request()),
|
||||
OutboundRequest::BlobsByRoot(blbroot_request(&chain_spec)),
|
||||
OutboundRequest::DataColumnsByRange(dcbrange_request()),
|
||||
OutboundRequest::DataColumnsByRoot(dcbroot_request(&chain_spec)),
|
||||
OutboundRequest::MetaData(MetadataRequest::new_v2()),
|
||||
];
|
||||
|
||||
|
||||
@@ -91,6 +91,8 @@ pub struct RateLimiterConfig {
|
||||
pub(super) blocks_by_root_quota: Quota,
|
||||
pub(super) blobs_by_range_quota: Quota,
|
||||
pub(super) blobs_by_root_quota: Quota,
|
||||
pub(super) data_columns_by_root_quota: Quota,
|
||||
pub(super) data_columns_by_range_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,
|
||||
@@ -110,6 +112,12 @@ impl RateLimiterConfig {
|
||||
// measured against the maximum request size.
|
||||
pub const DEFAULT_BLOBS_BY_RANGE_QUOTA: Quota = Quota::n_every(6144, 10);
|
||||
pub const DEFAULT_BLOBS_BY_ROOT_QUOTA: Quota = Quota::n_every(768, 10);
|
||||
// 320 blocks worth of columns for regular node, or 40 blocks for supernode.
|
||||
// Range sync load balances when requesting blocks, and each batch is 32 blocks.
|
||||
pub const DEFAULT_DATA_COLUMNS_BY_RANGE_QUOTA: Quota = Quota::n_every(5120, 10);
|
||||
// 512 columns per request from spec. This should be plenty as peers are unlikely to send all
|
||||
// sampling requests to a single peer.
|
||||
pub const DEFAULT_DATA_COLUMNS_BY_ROOT_QUOTA: Quota = Quota::n_every(512, 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);
|
||||
@@ -126,6 +134,8 @@ impl Default for RateLimiterConfig {
|
||||
blocks_by_root_quota: Self::DEFAULT_BLOCKS_BY_ROOT_QUOTA,
|
||||
blobs_by_range_quota: Self::DEFAULT_BLOBS_BY_RANGE_QUOTA,
|
||||
blobs_by_root_quota: Self::DEFAULT_BLOBS_BY_ROOT_QUOTA,
|
||||
data_columns_by_root_quota: Self::DEFAULT_DATA_COLUMNS_BY_ROOT_QUOTA,
|
||||
data_columns_by_range_quota: Self::DEFAULT_DATA_COLUMNS_BY_RANGE_QUOTA,
|
||||
light_client_bootstrap_quota: Self::DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA,
|
||||
light_client_optimistic_update_quota:
|
||||
Self::DEFAULT_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUOTA,
|
||||
@@ -175,6 +185,8 @@ impl FromStr for RateLimiterConfig {
|
||||
let mut blocks_by_root_quota = None;
|
||||
let mut blobs_by_range_quota = None;
|
||||
let mut blobs_by_root_quota = None;
|
||||
let mut data_columns_by_root_quota = None;
|
||||
let mut data_columns_by_range_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;
|
||||
@@ -189,6 +201,12 @@ impl FromStr for RateLimiterConfig {
|
||||
Protocol::BlocksByRoot => blocks_by_root_quota = blocks_by_root_quota.or(quota),
|
||||
Protocol::BlobsByRange => blobs_by_range_quota = blobs_by_range_quota.or(quota),
|
||||
Protocol::BlobsByRoot => blobs_by_root_quota = blobs_by_root_quota.or(quota),
|
||||
Protocol::DataColumnsByRoot => {
|
||||
data_columns_by_root_quota = data_columns_by_root_quota.or(quota)
|
||||
}
|
||||
Protocol::DataColumnsByRange => {
|
||||
data_columns_by_range_quota = data_columns_by_range_quota.or(quota)
|
||||
}
|
||||
Protocol::Ping => ping_quota = ping_quota.or(quota),
|
||||
Protocol::MetaData => meta_data_quota = meta_data_quota.or(quota),
|
||||
Protocol::LightClientBootstrap => {
|
||||
@@ -216,6 +234,10 @@ impl FromStr for RateLimiterConfig {
|
||||
blobs_by_range_quota: blobs_by_range_quota
|
||||
.unwrap_or(Self::DEFAULT_BLOBS_BY_RANGE_QUOTA),
|
||||
blobs_by_root_quota: blobs_by_root_quota.unwrap_or(Self::DEFAULT_BLOBS_BY_ROOT_QUOTA),
|
||||
data_columns_by_root_quota: data_columns_by_root_quota
|
||||
.unwrap_or(Self::DEFAULT_DATA_COLUMNS_BY_ROOT_QUOTA),
|
||||
data_columns_by_range_quota: data_columns_by_range_quota
|
||||
.unwrap_or(Self::DEFAULT_DATA_COLUMNS_BY_RANGE_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
|
||||
|
||||
@@ -14,9 +14,9 @@ use strum::IntoStaticStr;
|
||||
use superstruct::superstruct;
|
||||
use types::blob_sidecar::BlobIdentifier;
|
||||
use types::{
|
||||
blob_sidecar::BlobSidecar, ChainSpec, Epoch, EthSpec, Hash256, LightClientBootstrap,
|
||||
LightClientFinalityUpdate, LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock,
|
||||
Slot,
|
||||
blob_sidecar::BlobSidecar, ChainSpec, ColumnIndex, DataColumnIdentifier, DataColumnSidecar,
|
||||
Epoch, EthSpec, Hash256, LightClientBootstrap, LightClientFinalityUpdate,
|
||||
LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock, Slot,
|
||||
};
|
||||
|
||||
/// Maximum length of error message.
|
||||
@@ -293,6 +293,43 @@ impl BlobsByRangeRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/// Request a number of beacon data columns from a peer.
|
||||
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
|
||||
pub struct DataColumnsByRangeRequest {
|
||||
/// The starting slot to request data columns.
|
||||
pub start_slot: u64,
|
||||
/// The number of slots from the start slot.
|
||||
pub count: u64,
|
||||
/// The list column indices being requested.
|
||||
pub columns: Vec<ColumnIndex>,
|
||||
}
|
||||
|
||||
impl DataColumnsByRangeRequest {
|
||||
pub fn max_requested<E: EthSpec>(&self) -> u64 {
|
||||
self.count.saturating_mul(self.columns.len() as u64)
|
||||
}
|
||||
|
||||
pub fn ssz_min_len() -> usize {
|
||||
DataColumnsByRangeRequest {
|
||||
start_slot: 0,
|
||||
count: 0,
|
||||
columns: vec![0],
|
||||
}
|
||||
.as_ssz_bytes()
|
||||
.len()
|
||||
}
|
||||
|
||||
pub fn ssz_max_len(spec: &ChainSpec) -> usize {
|
||||
DataColumnsByRangeRequest {
|
||||
start_slot: 0,
|
||||
count: 0,
|
||||
columns: vec![0; spec.number_of_columns],
|
||||
}
|
||||
.as_ssz_bytes()
|
||||
.len()
|
||||
}
|
||||
}
|
||||
|
||||
/// Request a number of beacon block roots from a peer.
|
||||
#[superstruct(
|
||||
variants(V1, V2),
|
||||
@@ -370,6 +407,27 @@ impl BlobsByRootRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/// Request a number of data columns from a peer.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct DataColumnsByRootRequest {
|
||||
/// The list of beacon block roots and column indices being requested.
|
||||
pub data_column_ids: RuntimeVariableList<DataColumnIdentifier>,
|
||||
}
|
||||
|
||||
impl DataColumnsByRootRequest {
|
||||
pub fn new(data_column_ids: Vec<DataColumnIdentifier>, spec: &ChainSpec) -> Self {
|
||||
let data_column_ids = RuntimeVariableList::from_vec(
|
||||
data_column_ids,
|
||||
spec.max_request_data_column_sidecars as usize,
|
||||
);
|
||||
Self { data_column_ids }
|
||||
}
|
||||
|
||||
pub fn new_single(block_root: Hash256, index: ColumnIndex, spec: &ChainSpec) -> Self {
|
||||
Self::new(vec![DataColumnIdentifier { block_root, index }], spec)
|
||||
}
|
||||
}
|
||||
|
||||
/* RPC Handling and Grouping */
|
||||
// Collection of enums and structs used by the Codecs to encode/decode RPC messages
|
||||
|
||||
@@ -400,6 +458,12 @@ pub enum RPCResponse<E: EthSpec> {
|
||||
/// A response to a get BLOBS_BY_ROOT request.
|
||||
BlobsByRoot(Arc<BlobSidecar<E>>),
|
||||
|
||||
/// A response to a get DATA_COLUMN_SIDECARS_BY_ROOT request.
|
||||
DataColumnsByRoot(Arc<DataColumnSidecar<E>>),
|
||||
|
||||
/// A response to a get DATA_COLUMN_SIDECARS_BY_RANGE request.
|
||||
DataColumnsByRange(Arc<DataColumnSidecar<E>>),
|
||||
|
||||
/// A PONG response to a PING request.
|
||||
Pong(Ping),
|
||||
|
||||
@@ -421,6 +485,12 @@ pub enum ResponseTermination {
|
||||
|
||||
/// Blobs by root stream termination.
|
||||
BlobsByRoot,
|
||||
|
||||
/// Data column sidecars by root stream termination.
|
||||
DataColumnsByRoot,
|
||||
|
||||
/// Data column sidecars by range stream termination.
|
||||
DataColumnsByRange,
|
||||
}
|
||||
|
||||
/// The structured response containing a result/code indicating success or failure
|
||||
@@ -511,6 +581,8 @@ impl<E: EthSpec> RPCResponse<E> {
|
||||
RPCResponse::BlocksByRoot(_) => Protocol::BlocksByRoot,
|
||||
RPCResponse::BlobsByRange(_) => Protocol::BlobsByRange,
|
||||
RPCResponse::BlobsByRoot(_) => Protocol::BlobsByRoot,
|
||||
RPCResponse::DataColumnsByRoot(_) => Protocol::DataColumnsByRoot,
|
||||
RPCResponse::DataColumnsByRange(_) => Protocol::DataColumnsByRange,
|
||||
RPCResponse::Pong(_) => Protocol::Ping,
|
||||
RPCResponse::MetaData(_) => Protocol::MetaData,
|
||||
RPCResponse::LightClientBootstrap(_) => Protocol::LightClientBootstrap,
|
||||
@@ -556,6 +628,16 @@ impl<E: EthSpec> std::fmt::Display for RPCResponse<E> {
|
||||
RPCResponse::BlobsByRoot(sidecar) => {
|
||||
write!(f, "BlobsByRoot: Blob slot: {}", sidecar.slot())
|
||||
}
|
||||
RPCResponse::DataColumnsByRoot(sidecar) => {
|
||||
write!(f, "DataColumnsByRoot: Data column slot: {}", sidecar.slot())
|
||||
}
|
||||
RPCResponse::DataColumnsByRange(sidecar) => {
|
||||
write!(
|
||||
f,
|
||||
"DataColumnsByRange: Data column slot: {}",
|
||||
sidecar.slot()
|
||||
)
|
||||
}
|
||||
RPCResponse::Pong(ping) => write!(f, "Pong: {}", ping.data),
|
||||
RPCResponse::MetaData(metadata) => write!(f, "Metadata: {}", metadata.seq_number()),
|
||||
RPCResponse::LightClientBootstrap(bootstrap) => {
|
||||
|
||||
@@ -471,6 +471,8 @@ where
|
||||
ResponseTermination::BlocksByRoot => Protocol::BlocksByRoot,
|
||||
ResponseTermination::BlobsByRange => Protocol::BlobsByRange,
|
||||
ResponseTermination::BlobsByRoot => Protocol::BlobsByRoot,
|
||||
ResponseTermination::DataColumnsByRoot => Protocol::DataColumnsByRoot,
|
||||
ResponseTermination::DataColumnsByRange => Protocol::DataColumnsByRange,
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
@@ -36,6 +36,8 @@ pub enum OutboundRequest<E: EthSpec> {
|
||||
BlocksByRoot(BlocksByRootRequest),
|
||||
BlobsByRange(BlobsByRangeRequest),
|
||||
BlobsByRoot(BlobsByRootRequest),
|
||||
DataColumnsByRoot(DataColumnsByRootRequest),
|
||||
DataColumnsByRange(DataColumnsByRangeRequest),
|
||||
Ping(Ping),
|
||||
MetaData(MetadataRequest<E>),
|
||||
}
|
||||
@@ -79,6 +81,14 @@ impl<E: EthSpec> OutboundRequest<E> {
|
||||
SupportedProtocol::BlobsByRootV1,
|
||||
Encoding::SSZSnappy,
|
||||
)],
|
||||
OutboundRequest::DataColumnsByRoot(_) => vec![ProtocolId::new(
|
||||
SupportedProtocol::DataColumnsByRootV1,
|
||||
Encoding::SSZSnappy,
|
||||
)],
|
||||
OutboundRequest::DataColumnsByRange(_) => vec![ProtocolId::new(
|
||||
SupportedProtocol::DataColumnsByRangeV1,
|
||||
Encoding::SSZSnappy,
|
||||
)],
|
||||
OutboundRequest::Ping(_) => vec![ProtocolId::new(
|
||||
SupportedProtocol::PingV1,
|
||||
Encoding::SSZSnappy,
|
||||
@@ -100,6 +110,8 @@ impl<E: EthSpec> OutboundRequest<E> {
|
||||
OutboundRequest::BlocksByRoot(req) => req.block_roots().len() as u64,
|
||||
OutboundRequest::BlobsByRange(req) => req.max_blobs_requested::<E>(),
|
||||
OutboundRequest::BlobsByRoot(req) => req.blob_ids.len() as u64,
|
||||
OutboundRequest::DataColumnsByRoot(req) => req.data_column_ids.len() as u64,
|
||||
OutboundRequest::DataColumnsByRange(req) => req.max_requested::<E>(),
|
||||
OutboundRequest::Ping(_) => 1,
|
||||
OutboundRequest::MetaData(_) => 1,
|
||||
}
|
||||
@@ -113,6 +125,8 @@ impl<E: EthSpec> OutboundRequest<E> {
|
||||
OutboundRequest::BlocksByRoot(_) => false,
|
||||
OutboundRequest::BlobsByRange(_) => false,
|
||||
OutboundRequest::BlobsByRoot(_) => false,
|
||||
OutboundRequest::DataColumnsByRoot(_) => false,
|
||||
OutboundRequest::DataColumnsByRange(_) => false,
|
||||
OutboundRequest::Ping(_) => true,
|
||||
OutboundRequest::MetaData(_) => true,
|
||||
}
|
||||
@@ -133,6 +147,8 @@ impl<E: EthSpec> OutboundRequest<E> {
|
||||
},
|
||||
OutboundRequest::BlobsByRange(_) => SupportedProtocol::BlobsByRangeV1,
|
||||
OutboundRequest::BlobsByRoot(_) => SupportedProtocol::BlobsByRootV1,
|
||||
OutboundRequest::DataColumnsByRoot(_) => SupportedProtocol::DataColumnsByRootV1,
|
||||
OutboundRequest::DataColumnsByRange(_) => SupportedProtocol::DataColumnsByRangeV1,
|
||||
OutboundRequest::Ping(_) => SupportedProtocol::PingV1,
|
||||
OutboundRequest::MetaData(req) => match req {
|
||||
MetadataRequest::V1(_) => SupportedProtocol::MetaDataV1,
|
||||
@@ -151,6 +167,8 @@ impl<E: EthSpec> OutboundRequest<E> {
|
||||
OutboundRequest::BlocksByRoot(_) => ResponseTermination::BlocksByRoot,
|
||||
OutboundRequest::BlobsByRange(_) => ResponseTermination::BlobsByRange,
|
||||
OutboundRequest::BlobsByRoot(_) => ResponseTermination::BlobsByRoot,
|
||||
OutboundRequest::DataColumnsByRoot(_) => ResponseTermination::DataColumnsByRoot,
|
||||
OutboundRequest::DataColumnsByRange(_) => ResponseTermination::DataColumnsByRange,
|
||||
OutboundRequest::Status(_) => unreachable!(),
|
||||
OutboundRequest::Goodbye(_) => unreachable!(),
|
||||
OutboundRequest::Ping(_) => unreachable!(),
|
||||
@@ -208,6 +226,10 @@ impl<E: EthSpec> std::fmt::Display for OutboundRequest<E> {
|
||||
OutboundRequest::BlocksByRoot(req) => write!(f, "Blocks by root: {:?}", req),
|
||||
OutboundRequest::BlobsByRange(req) => write!(f, "Blobs by range: {:?}", req),
|
||||
OutboundRequest::BlobsByRoot(req) => write!(f, "Blobs by root: {:?}", req),
|
||||
OutboundRequest::DataColumnsByRoot(req) => write!(f, "Data columns by root: {:?}", req),
|
||||
OutboundRequest::DataColumnsByRange(req) => {
|
||||
write!(f, "Data columns by range: {:?}", req)
|
||||
}
|
||||
OutboundRequest::Ping(ping) => write!(f, "Ping: {}", ping.data),
|
||||
OutboundRequest::MetaData(_) => write!(f, "MetaData request"),
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ use tokio_util::{
|
||||
};
|
||||
use types::{
|
||||
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockCapella, BeaconBlockElectra,
|
||||
BlobSidecar, ChainSpec, EmptyBlock, EthSpec, ForkContext, ForkName, LightClientBootstrap,
|
||||
LightClientBootstrapAltair, LightClientFinalityUpdate, LightClientFinalityUpdateAltair,
|
||||
LightClientOptimisticUpdate, LightClientOptimisticUpdateAltair, MainnetEthSpec, Signature,
|
||||
SignedBeaconBlock,
|
||||
BlobSidecar, ChainSpec, DataColumnSidecar, EmptyBlock, EthSpec, ForkContext, ForkName,
|
||||
LightClientBootstrap, LightClientBootstrapAltair, LightClientFinalityUpdate,
|
||||
LightClientFinalityUpdateAltair, LightClientOptimisticUpdate,
|
||||
LightClientOptimisticUpdateAltair, MainnetEthSpec, Signature, SignedBeaconBlock,
|
||||
};
|
||||
|
||||
// Note: Hardcoding the `EthSpec` type for `SignedBeaconBlock` as min/max values is
|
||||
@@ -268,6 +268,12 @@ pub enum Protocol {
|
||||
/// The `BlobsByRoot` protocol name.
|
||||
#[strum(serialize = "blob_sidecars_by_root")]
|
||||
BlobsByRoot,
|
||||
/// The `DataColumnSidecarsByRoot` protocol name.
|
||||
#[strum(serialize = "data_column_sidecars_by_root")]
|
||||
DataColumnsByRoot,
|
||||
/// The `DataColumnSidecarsByRange` protocol name.
|
||||
#[strum(serialize = "data_column_sidecars_by_range")]
|
||||
DataColumnsByRange,
|
||||
/// The `Ping` protocol name.
|
||||
Ping,
|
||||
/// The `MetaData` protocol name.
|
||||
@@ -293,6 +299,8 @@ impl Protocol {
|
||||
Protocol::BlocksByRoot => Some(ResponseTermination::BlocksByRoot),
|
||||
Protocol::BlobsByRange => Some(ResponseTermination::BlobsByRange),
|
||||
Protocol::BlobsByRoot => Some(ResponseTermination::BlobsByRoot),
|
||||
Protocol::DataColumnsByRoot => Some(ResponseTermination::DataColumnsByRoot),
|
||||
Protocol::DataColumnsByRange => Some(ResponseTermination::DataColumnsByRange),
|
||||
Protocol::Ping => None,
|
||||
Protocol::MetaData => None,
|
||||
Protocol::LightClientBootstrap => None,
|
||||
@@ -319,6 +327,8 @@ pub enum SupportedProtocol {
|
||||
BlocksByRootV2,
|
||||
BlobsByRangeV1,
|
||||
BlobsByRootV1,
|
||||
DataColumnsByRootV1,
|
||||
DataColumnsByRangeV1,
|
||||
PingV1,
|
||||
MetaDataV1,
|
||||
MetaDataV2,
|
||||
@@ -338,6 +348,8 @@ impl SupportedProtocol {
|
||||
SupportedProtocol::BlocksByRootV2 => "2",
|
||||
SupportedProtocol::BlobsByRangeV1 => "1",
|
||||
SupportedProtocol::BlobsByRootV1 => "1",
|
||||
SupportedProtocol::DataColumnsByRootV1 => "1",
|
||||
SupportedProtocol::DataColumnsByRangeV1 => "1",
|
||||
SupportedProtocol::PingV1 => "1",
|
||||
SupportedProtocol::MetaDataV1 => "1",
|
||||
SupportedProtocol::MetaDataV2 => "2",
|
||||
@@ -357,6 +369,8 @@ impl SupportedProtocol {
|
||||
SupportedProtocol::BlocksByRootV2 => Protocol::BlocksByRoot,
|
||||
SupportedProtocol::BlobsByRangeV1 => Protocol::BlobsByRange,
|
||||
SupportedProtocol::BlobsByRootV1 => Protocol::BlobsByRoot,
|
||||
SupportedProtocol::DataColumnsByRootV1 => Protocol::DataColumnsByRoot,
|
||||
SupportedProtocol::DataColumnsByRangeV1 => Protocol::DataColumnsByRange,
|
||||
SupportedProtocol::PingV1 => Protocol::Ping,
|
||||
SupportedProtocol::MetaDataV1 => Protocol::MetaData,
|
||||
SupportedProtocol::MetaDataV2 => Protocol::MetaData,
|
||||
@@ -387,6 +401,12 @@ impl SupportedProtocol {
|
||||
ProtocolId::new(SupportedProtocol::BlobsByRangeV1, Encoding::SSZSnappy),
|
||||
]);
|
||||
}
|
||||
if fork_context.spec.is_peer_das_scheduled() {
|
||||
supported.extend_from_slice(&[
|
||||
ProtocolId::new(SupportedProtocol::DataColumnsByRootV1, Encoding::SSZSnappy),
|
||||
ProtocolId::new(SupportedProtocol::DataColumnsByRangeV1, Encoding::SSZSnappy),
|
||||
]);
|
||||
}
|
||||
supported
|
||||
}
|
||||
}
|
||||
@@ -495,6 +515,11 @@ impl ProtocolId {
|
||||
<BlobsByRangeRequest as Encode>::ssz_fixed_len(),
|
||||
),
|
||||
Protocol::BlobsByRoot => RpcLimits::new(0, spec.max_blobs_by_root_request),
|
||||
Protocol::DataColumnsByRoot => RpcLimits::new(0, spec.max_data_columns_by_root_request),
|
||||
Protocol::DataColumnsByRange => RpcLimits::new(
|
||||
DataColumnsByRangeRequest::ssz_min_len(),
|
||||
DataColumnsByRangeRequest::ssz_max_len(spec),
|
||||
),
|
||||
Protocol::Ping => RpcLimits::new(
|
||||
<Ping as Encode>::ssz_fixed_len(),
|
||||
<Ping as Encode>::ssz_fixed_len(),
|
||||
@@ -521,6 +546,8 @@ impl ProtocolId {
|
||||
Protocol::BlocksByRoot => rpc_block_limits_by_fork(fork_context.current_fork()),
|
||||
Protocol::BlobsByRange => rpc_blob_limits::<E>(),
|
||||
Protocol::BlobsByRoot => rpc_blob_limits::<E>(),
|
||||
Protocol::DataColumnsByRoot => rpc_data_column_limits::<E>(),
|
||||
Protocol::DataColumnsByRange => rpc_data_column_limits::<E>(),
|
||||
Protocol::Ping => RpcLimits::new(
|
||||
<Ping as Encode>::ssz_fixed_len(),
|
||||
<Ping as Encode>::ssz_fixed_len(),
|
||||
@@ -549,6 +576,8 @@ impl ProtocolId {
|
||||
| SupportedProtocol::BlocksByRootV2
|
||||
| SupportedProtocol::BlobsByRangeV1
|
||||
| SupportedProtocol::BlobsByRootV1
|
||||
| SupportedProtocol::DataColumnsByRootV1
|
||||
| SupportedProtocol::DataColumnsByRangeV1
|
||||
| SupportedProtocol::LightClientBootstrapV1
|
||||
| SupportedProtocol::LightClientOptimisticUpdateV1
|
||||
| SupportedProtocol::LightClientFinalityUpdateV1 => true,
|
||||
@@ -589,6 +618,13 @@ pub fn rpc_blob_limits<E: EthSpec>() -> RpcLimits {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn rpc_data_column_limits<E: EthSpec>() -> RpcLimits {
|
||||
RpcLimits::new(
|
||||
DataColumnSidecar::<E>::empty().as_ssz_bytes().len(),
|
||||
DataColumnSidecar::<E>::max_size(),
|
||||
)
|
||||
}
|
||||
|
||||
/* Inbound upgrade */
|
||||
|
||||
// The inbound protocol reads the request, decodes it and returns the stream to the protocol
|
||||
@@ -668,6 +704,8 @@ pub enum InboundRequest<E: EthSpec> {
|
||||
BlocksByRoot(BlocksByRootRequest),
|
||||
BlobsByRange(BlobsByRangeRequest),
|
||||
BlobsByRoot(BlobsByRootRequest),
|
||||
DataColumnsByRoot(DataColumnsByRootRequest),
|
||||
DataColumnsByRange(DataColumnsByRangeRequest),
|
||||
LightClientBootstrap(LightClientBootstrapRequest),
|
||||
LightClientOptimisticUpdate,
|
||||
LightClientFinalityUpdate,
|
||||
@@ -688,6 +726,8 @@ impl<E: EthSpec> InboundRequest<E> {
|
||||
InboundRequest::BlocksByRoot(req) => req.block_roots().len() as u64,
|
||||
InboundRequest::BlobsByRange(req) => req.max_blobs_requested::<E>(),
|
||||
InboundRequest::BlobsByRoot(req) => req.blob_ids.len() as u64,
|
||||
InboundRequest::DataColumnsByRoot(req) => req.data_column_ids.len() as u64,
|
||||
InboundRequest::DataColumnsByRange(req) => req.max_requested::<E>(),
|
||||
InboundRequest::Ping(_) => 1,
|
||||
InboundRequest::MetaData(_) => 1,
|
||||
InboundRequest::LightClientBootstrap(_) => 1,
|
||||
@@ -711,6 +751,8 @@ impl<E: EthSpec> InboundRequest<E> {
|
||||
},
|
||||
InboundRequest::BlobsByRange(_) => SupportedProtocol::BlobsByRangeV1,
|
||||
InboundRequest::BlobsByRoot(_) => SupportedProtocol::BlobsByRootV1,
|
||||
InboundRequest::DataColumnsByRoot(_) => SupportedProtocol::DataColumnsByRootV1,
|
||||
InboundRequest::DataColumnsByRange(_) => SupportedProtocol::DataColumnsByRangeV1,
|
||||
InboundRequest::Ping(_) => SupportedProtocol::PingV1,
|
||||
InboundRequest::MetaData(req) => match req {
|
||||
MetadataRequest::V1(_) => SupportedProtocol::MetaDataV1,
|
||||
@@ -736,6 +778,8 @@ impl<E: EthSpec> InboundRequest<E> {
|
||||
InboundRequest::BlocksByRoot(_) => ResponseTermination::BlocksByRoot,
|
||||
InboundRequest::BlobsByRange(_) => ResponseTermination::BlobsByRange,
|
||||
InboundRequest::BlobsByRoot(_) => ResponseTermination::BlobsByRoot,
|
||||
InboundRequest::DataColumnsByRoot(_) => ResponseTermination::DataColumnsByRoot,
|
||||
InboundRequest::DataColumnsByRange(_) => ResponseTermination::DataColumnsByRange,
|
||||
InboundRequest::Status(_) => unreachable!(),
|
||||
InboundRequest::Goodbye(_) => unreachable!(),
|
||||
InboundRequest::Ping(_) => unreachable!(),
|
||||
@@ -846,6 +890,10 @@ impl<E: EthSpec> std::fmt::Display for InboundRequest<E> {
|
||||
InboundRequest::BlocksByRoot(req) => write!(f, "Blocks by root: {:?}", req),
|
||||
InboundRequest::BlobsByRange(req) => write!(f, "Blobs by range: {:?}", req),
|
||||
InboundRequest::BlobsByRoot(req) => write!(f, "Blobs by root: {:?}", req),
|
||||
InboundRequest::DataColumnsByRoot(req) => write!(f, "Data columns by root: {:?}", req),
|
||||
InboundRequest::DataColumnsByRange(req) => {
|
||||
write!(f, "Data columns by range: {:?}", req)
|
||||
}
|
||||
InboundRequest::Ping(ping) => write!(f, "Ping: {}", ping.data),
|
||||
InboundRequest::MetaData(_) => write!(f, "MetaData request"),
|
||||
InboundRequest::LightClientBootstrap(bootstrap) => {
|
||||
|
||||
@@ -97,6 +97,10 @@ pub struct RPCRateLimiter {
|
||||
blbrange_rl: Limiter<PeerId>,
|
||||
/// BlobsByRoot rate limiter.
|
||||
blbroot_rl: Limiter<PeerId>,
|
||||
/// DataColumnssByRoot rate limiter.
|
||||
dcbroot_rl: Limiter<PeerId>,
|
||||
/// DataColumnsByRange rate limiter.
|
||||
dcbrange_rl: Limiter<PeerId>,
|
||||
/// LightClientBootstrap rate limiter.
|
||||
lc_bootstrap_rl: Limiter<PeerId>,
|
||||
/// LightClientOptimisticUpdate rate limiter.
|
||||
@@ -133,6 +137,10 @@ pub struct RPCRateLimiterBuilder {
|
||||
blbrange_quota: Option<Quota>,
|
||||
/// Quota for the BlobsByRoot protocol.
|
||||
blbroot_quota: Option<Quota>,
|
||||
/// Quota for the DataColumnsByRoot protocol.
|
||||
dcbroot_quota: Option<Quota>,
|
||||
/// Quota for the DataColumnsByRange protocol.
|
||||
dcbrange_quota: Option<Quota>,
|
||||
/// Quota for the LightClientBootstrap protocol.
|
||||
lcbootstrap_quota: Option<Quota>,
|
||||
/// Quota for the LightClientOptimisticUpdate protocol.
|
||||
@@ -154,6 +162,8 @@ impl RPCRateLimiterBuilder {
|
||||
Protocol::BlocksByRoot => self.bbroots_quota = q,
|
||||
Protocol::BlobsByRange => self.blbrange_quota = q,
|
||||
Protocol::BlobsByRoot => self.blbroot_quota = q,
|
||||
Protocol::DataColumnsByRoot => self.dcbroot_quota = q,
|
||||
Protocol::DataColumnsByRange => self.dcbrange_quota = q,
|
||||
Protocol::LightClientBootstrap => self.lcbootstrap_quota = q,
|
||||
Protocol::LightClientOptimisticUpdate => self.lc_optimistic_update_quota = q,
|
||||
Protocol::LightClientFinalityUpdate => self.lc_finality_update_quota = q,
|
||||
@@ -191,6 +201,14 @@ impl RPCRateLimiterBuilder {
|
||||
.blbroot_quota
|
||||
.ok_or("BlobsByRoot quota not specified")?;
|
||||
|
||||
let dcbroot_quota = self
|
||||
.dcbroot_quota
|
||||
.ok_or("DataColumnsByRoot quota not specified")?;
|
||||
|
||||
let dcbrange_quota = self
|
||||
.dcbrange_quota
|
||||
.ok_or("DataColumnsByRange quota not specified")?;
|
||||
|
||||
// create the rate limiters
|
||||
let ping_rl = Limiter::from_quota(ping_quota)?;
|
||||
let metadata_rl = Limiter::from_quota(metadata_quota)?;
|
||||
@@ -200,6 +218,8 @@ 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 dcbroot_rl = Limiter::from_quota(dcbroot_quota)?;
|
||||
let dcbrange_rl = Limiter::from_quota(dcbrange_quota)?;
|
||||
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)?;
|
||||
@@ -218,6 +238,8 @@ impl RPCRateLimiterBuilder {
|
||||
bbrange_rl,
|
||||
blbrange_rl,
|
||||
blbroot_rl,
|
||||
dcbroot_rl,
|
||||
dcbrange_rl,
|
||||
lc_bootstrap_rl,
|
||||
lc_optimistic_update_rl,
|
||||
lc_finality_update_rl,
|
||||
@@ -262,6 +284,8 @@ impl RPCRateLimiter {
|
||||
blocks_by_root_quota,
|
||||
blobs_by_range_quota,
|
||||
blobs_by_root_quota,
|
||||
data_columns_by_root_quota,
|
||||
data_columns_by_range_quota,
|
||||
light_client_bootstrap_quota,
|
||||
light_client_optimistic_update_quota,
|
||||
light_client_finality_update_quota,
|
||||
@@ -276,6 +300,8 @@ impl RPCRateLimiter {
|
||||
.set_quota(Protocol::BlocksByRoot, blocks_by_root_quota)
|
||||
.set_quota(Protocol::BlobsByRange, blobs_by_range_quota)
|
||||
.set_quota(Protocol::BlobsByRoot, blobs_by_root_quota)
|
||||
.set_quota(Protocol::DataColumnsByRoot, data_columns_by_root_quota)
|
||||
.set_quota(Protocol::DataColumnsByRange, data_columns_by_range_quota)
|
||||
.set_quota(Protocol::LightClientBootstrap, light_client_bootstrap_quota)
|
||||
.set_quota(
|
||||
Protocol::LightClientOptimisticUpdate,
|
||||
@@ -312,6 +338,8 @@ impl RPCRateLimiter {
|
||||
Protocol::BlocksByRoot => &mut self.bbroots_rl,
|
||||
Protocol::BlobsByRange => &mut self.blbrange_rl,
|
||||
Protocol::BlobsByRoot => &mut self.blbroot_rl,
|
||||
Protocol::DataColumnsByRoot => &mut self.dcbroot_rl,
|
||||
Protocol::DataColumnsByRange => &mut self.dcbrange_rl,
|
||||
Protocol::LightClientBootstrap => &mut self.lc_bootstrap_rl,
|
||||
Protocol::LightClientOptimisticUpdate => &mut self.lc_optimistic_update_rl,
|
||||
Protocol::LightClientFinalityUpdate => &mut self.lc_finality_update_rl,
|
||||
|
||||
Reference in New Issue
Block a user