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:
Lion - dapplion
2024-08-13 08:16:14 +08:00
committed by GitHub
parent f2fdbe7fbe
commit ff15c78ced
15 changed files with 624 additions and 34 deletions

View File

@@ -119,6 +119,8 @@ pub struct BeaconProcessorQueueLengths {
bbroots_queue: usize, bbroots_queue: usize,
blbroots_queue: usize, blbroots_queue: usize,
blbrange_queue: usize, blbrange_queue: usize,
dcbroots_queue: usize,
dcbrange_queue: usize,
gossip_bls_to_execution_change_queue: usize, gossip_bls_to_execution_change_queue: usize,
lc_bootstrap_queue: usize, lc_bootstrap_queue: usize,
lc_optimistic_update_queue: usize, lc_optimistic_update_queue: usize,
@@ -172,6 +174,9 @@ impl BeaconProcessorQueueLengths {
bbroots_queue: 1024, bbroots_queue: 1024,
blbroots_queue: 1024, blbroots_queue: 1024,
blbrange_queue: 1024, blbrange_queue: 1024,
// TODO(das): pick proper values
dcbroots_queue: 1024,
dcbrange_queue: 1024,
gossip_bls_to_execution_change_queue: 16384, gossip_bls_to_execution_change_queue: 16384,
lc_bootstrap_queue: 1024, lc_bootstrap_queue: 1024,
lc_optimistic_update_queue: 512, lc_optimistic_update_queue: 512,
@@ -230,6 +235,8 @@ pub const BLOCKS_BY_RANGE_REQUEST: &str = "blocks_by_range_request";
pub const BLOCKS_BY_ROOTS_REQUEST: &str = "blocks_by_roots_request"; 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_RANGE_REQUEST: &str = "blobs_by_range_request";
pub const BLOBS_BY_ROOTS_REQUEST: &str = "blobs_by_roots_request"; pub const BLOBS_BY_ROOTS_REQUEST: &str = "blobs_by_roots_request";
pub const DATA_COLUMNS_BY_ROOTS_REQUEST: &str = "data_columns_by_roots_request";
pub const DATA_COLUMNS_BY_RANGE_REQUEST: &str = "data_columns_by_range_request";
pub const LIGHT_CLIENT_BOOTSTRAP_REQUEST: &str = "light_client_bootstrap"; 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_FINALITY_UPDATE_REQUEST: &str = "light_client_finality_update_request";
pub const LIGHT_CLIENT_OPTIMISTIC_UPDATE_REQUEST: &str = "light_client_optimistic_update_request"; pub const LIGHT_CLIENT_OPTIMISTIC_UPDATE_REQUEST: &str = "light_client_optimistic_update_request";
@@ -609,6 +616,8 @@ pub enum Work<E: EthSpec> {
BlocksByRootsRequest(AsyncFn), BlocksByRootsRequest(AsyncFn),
BlobsByRangeRequest(BlockingFn), BlobsByRangeRequest(BlockingFn),
BlobsByRootsRequest(BlockingFn), BlobsByRootsRequest(BlockingFn),
DataColumnsByRootsRequest(BlockingFn),
DataColumnsByRangeRequest(BlockingFn),
GossipBlsToExecutionChange(BlockingFn), GossipBlsToExecutionChange(BlockingFn),
LightClientBootstrapRequest(BlockingFn), LightClientBootstrapRequest(BlockingFn),
LightClientOptimisticUpdateRequest(BlockingFn), LightClientOptimisticUpdateRequest(BlockingFn),
@@ -652,6 +661,8 @@ impl<E: EthSpec> Work<E> {
Work::BlocksByRootsRequest(_) => BLOCKS_BY_ROOTS_REQUEST, Work::BlocksByRootsRequest(_) => BLOCKS_BY_ROOTS_REQUEST,
Work::BlobsByRangeRequest(_) => BLOBS_BY_RANGE_REQUEST, Work::BlobsByRangeRequest(_) => BLOBS_BY_RANGE_REQUEST,
Work::BlobsByRootsRequest(_) => BLOBS_BY_ROOTS_REQUEST, Work::BlobsByRootsRequest(_) => BLOBS_BY_ROOTS_REQUEST,
Work::DataColumnsByRootsRequest(_) => DATA_COLUMNS_BY_ROOTS_REQUEST,
Work::DataColumnsByRangeRequest(_) => DATA_COLUMNS_BY_RANGE_REQUEST,
Work::LightClientBootstrapRequest(_) => LIGHT_CLIENT_BOOTSTRAP_REQUEST, Work::LightClientBootstrapRequest(_) => LIGHT_CLIENT_BOOTSTRAP_REQUEST,
Work::LightClientOptimisticUpdateRequest(_) => LIGHT_CLIENT_OPTIMISTIC_UPDATE_REQUEST, Work::LightClientOptimisticUpdateRequest(_) => LIGHT_CLIENT_OPTIMISTIC_UPDATE_REQUEST,
Work::LightClientFinalityUpdateRequest(_) => LIGHT_CLIENT_FINALITY_UPDATE_REQUEST, Work::LightClientFinalityUpdateRequest(_) => LIGHT_CLIENT_FINALITY_UPDATE_REQUEST,
@@ -816,6 +827,8 @@ impl<E: EthSpec> BeaconProcessor<E> {
let mut bbroots_queue = FifoQueue::new(queue_lengths.bbroots_queue); let mut bbroots_queue = FifoQueue::new(queue_lengths.bbroots_queue);
let mut blbroots_queue = FifoQueue::new(queue_lengths.blbroots_queue); let mut blbroots_queue = FifoQueue::new(queue_lengths.blbroots_queue);
let mut blbrange_queue = FifoQueue::new(queue_lengths.blbrange_queue); let mut blbrange_queue = FifoQueue::new(queue_lengths.blbrange_queue);
let mut dcbroots_queue = FifoQueue::new(queue_lengths.dcbroots_queue);
let mut dcbrange_queue = FifoQueue::new(queue_lengths.dcbrange_queue);
let mut gossip_bls_to_execution_change_queue = let mut gossip_bls_to_execution_change_queue =
FifoQueue::new(queue_lengths.gossip_bls_to_execution_change_queue); FifoQueue::new(queue_lengths.gossip_bls_to_execution_change_queue);
@@ -1118,6 +1131,10 @@ impl<E: EthSpec> BeaconProcessor<E> {
self.spawn_worker(item, idle_tx); self.spawn_worker(item, idle_tx);
} else if let Some(item) = blbroots_queue.pop() { } else if let Some(item) = blbroots_queue.pop() {
self.spawn_worker(item, idle_tx); self.spawn_worker(item, idle_tx);
} else if let Some(item) = dcbroots_queue.pop() {
self.spawn_worker(item, idle_tx);
} else if let Some(item) = dcbrange_queue.pop() {
self.spawn_worker(item, idle_tx);
// Check slashings after all other consensus messages so we prioritize // Check slashings after all other consensus messages so we prioritize
// following head. // following head.
// //
@@ -1282,6 +1299,12 @@ impl<E: EthSpec> BeaconProcessor<E> {
Work::BlobsByRootsRequest { .. } => { Work::BlobsByRootsRequest { .. } => {
blbroots_queue.push(work, work_id, &self.log) blbroots_queue.push(work, work_id, &self.log)
} }
Work::DataColumnsByRootsRequest { .. } => {
dcbroots_queue.push(work, work_id, &self.log)
}
Work::DataColumnsByRangeRequest { .. } => {
dcbrange_queue.push(work, work_id, &self.log)
}
Work::UnknownLightClientOptimisticUpdate { .. } => { Work::UnknownLightClientOptimisticUpdate { .. } => {
unknown_light_client_update_queue.push(work, work_id, &self.log) unknown_light_client_update_queue.push(work, work_id, &self.log)
} }
@@ -1483,7 +1506,10 @@ impl<E: EthSpec> BeaconProcessor<E> {
| Work::GossipDataColumnSidecar(work) => task_spawner.spawn_async(async move { | Work::GossipDataColumnSidecar(work) => task_spawner.spawn_async(async move {
work.await; work.await;
}), }),
Work::BlobsByRangeRequest(process_fn) | Work::BlobsByRootsRequest(process_fn) => { Work::BlobsByRangeRequest(process_fn)
| Work::BlobsByRootsRequest(process_fn)
| Work::DataColumnsByRootsRequest(process_fn)
| Work::DataColumnsByRangeRequest(process_fn) => {
task_spawner.spawn_blocking(process_fn) task_spawner.spawn_blocking(process_fn)
} }
Work::BlocksByRangeRequest(work) | Work::BlocksByRootsRequest(work) => { Work::BlocksByRangeRequest(work) | Work::BlocksByRootsRequest(work) => {

View File

@@ -569,6 +569,8 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::LightClientOptimisticUpdate => return, Protocol::LightClientOptimisticUpdate => return,
Protocol::LightClientFinalityUpdate => return, Protocol::LightClientFinalityUpdate => return,
Protocol::BlobsByRoot => PeerAction::MidToleranceError, Protocol::BlobsByRoot => PeerAction::MidToleranceError,
Protocol::DataColumnsByRoot => PeerAction::MidToleranceError,
Protocol::DataColumnsByRange => PeerAction::MidToleranceError,
Protocol::Goodbye => PeerAction::LowToleranceError, Protocol::Goodbye => PeerAction::LowToleranceError,
Protocol::MetaData => PeerAction::LowToleranceError, Protocol::MetaData => PeerAction::LowToleranceError,
Protocol::Status => PeerAction::LowToleranceError, Protocol::Status => PeerAction::LowToleranceError,
@@ -587,6 +589,8 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::BlocksByRoot => return, Protocol::BlocksByRoot => return,
Protocol::BlobsByRange => return, Protocol::BlobsByRange => return,
Protocol::BlobsByRoot => return, Protocol::BlobsByRoot => return,
Protocol::DataColumnsByRoot => return,
Protocol::DataColumnsByRange => return,
Protocol::Goodbye => return, Protocol::Goodbye => return,
Protocol::LightClientBootstrap => return, Protocol::LightClientBootstrap => return,
Protocol::LightClientOptimisticUpdate => return, Protocol::LightClientOptimisticUpdate => return,
@@ -607,6 +611,8 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::BlocksByRoot => PeerAction::MidToleranceError, Protocol::BlocksByRoot => PeerAction::MidToleranceError,
Protocol::BlobsByRange => PeerAction::MidToleranceError, Protocol::BlobsByRange => PeerAction::MidToleranceError,
Protocol::BlobsByRoot => PeerAction::MidToleranceError, Protocol::BlobsByRoot => PeerAction::MidToleranceError,
Protocol::DataColumnsByRoot => PeerAction::MidToleranceError,
Protocol::DataColumnsByRange => PeerAction::MidToleranceError,
Protocol::LightClientBootstrap => return, Protocol::LightClientBootstrap => return,
Protocol::LightClientOptimisticUpdate => return, Protocol::LightClientOptimisticUpdate => return,
Protocol::LightClientFinalityUpdate => return, Protocol::LightClientFinalityUpdate => return,

View File

@@ -16,10 +16,11 @@ use std::marker::PhantomData;
use std::sync::Arc; use std::sync::Arc;
use tokio_util::codec::{Decoder, Encoder}; use tokio_util::codec::{Decoder, Encoder};
use types::{ use types::{
BlobSidecar, ChainSpec, EthSpec, ForkContext, ForkName, Hash256, LightClientBootstrap, BlobSidecar, ChainSpec, DataColumnSidecar, EthSpec, ForkContext, ForkName, Hash256,
LightClientFinalityUpdate, LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock, LightClientBootstrap, LightClientFinalityUpdate, LightClientOptimisticUpdate,
SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix, RuntimeVariableList, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase,
SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra, SignedBeaconBlockBellatrix, SignedBeaconBlockCapella, SignedBeaconBlockDeneb,
SignedBeaconBlockElectra,
}; };
use unsigned_varint::codec::Uvi; 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::BlocksByRoot(res) => res.as_ssz_bytes(),
RPCResponse::BlobsByRange(res) => res.as_ssz_bytes(), RPCResponse::BlobsByRange(res) => res.as_ssz_bytes(),
RPCResponse::BlobsByRoot(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::LightClientBootstrap(res) => res.as_ssz_bytes(),
RPCResponse::LightClientOptimisticUpdate(res) => res.as_ssz_bytes(), RPCResponse::LightClientOptimisticUpdate(res) => res.as_ssz_bytes(),
RPCResponse::LightClientFinalityUpdate(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::BlobsByRange(req) => req.as_ssz_bytes(),
OutboundRequest::BlobsByRoot(req) => req.blob_ids.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::Ping(req) => req.as_ssz_bytes(),
OutboundRequest::MetaData(_) => return Ok(()), // no metadata to encode 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); return fork_context.to_context_bytes(ForkName::Deneb);
} }
RPCResponse::LightClientBootstrap(lc_bootstrap) => { 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 { SupportedProtocol::PingV1 => Ok(Some(InboundRequest::Ping(Ping {
data: u64::from_ssz_bytes(decoded_buffer)?, 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 { SupportedProtocol::PingV1 => Ok(Some(RPCResponse::Pong(Ping {
data: u64::from_ssz_bytes(decoded_buffer)?, data: u64::from_ssz_bytes(decoded_buffer)?,
}))), }))),
@@ -747,7 +813,8 @@ mod tests {
use crate::types::{EnrAttestationBitfield, EnrSyncCommitteeBitfield}; use crate::types::{EnrAttestationBitfield, EnrSyncCommitteeBitfield};
use types::{ use types::{
blob_sidecar::BlobIdentifier, BeaconBlock, BeaconBlockAltair, BeaconBlockBase, blob_sidecar::BlobIdentifier, BeaconBlock, BeaconBlockAltair, BeaconBlockBase,
BeaconBlockBellatrix, EmptyBlock, Epoch, FullPayload, Signature, Slot, BeaconBlockBellatrix, DataColumnIdentifier, EmptyBlock, Epoch, FullPayload, Signature,
Slot,
}; };
type Spec = types::MainnetEthSpec; type Spec = types::MainnetEthSpec;
@@ -794,6 +861,10 @@ mod tests {
Arc::new(BlobSidecar::empty()) Arc::new(BlobSidecar::empty())
} }
fn empty_data_column_sidecar() -> Arc<DataColumnSidecar<Spec>> {
Arc::new(DataColumnSidecar::empty())
}
/// Bellatrix block with length < max_rpc_size. /// Bellatrix block with length < max_rpc_size.
fn bellatrix_block_small( fn bellatrix_block_small(
fork_context: &ForkContext, 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 { fn bbroot_request_v1(spec: &ChainSpec) -> BlocksByRootRequest {
BlocksByRootRequest::new_v1(vec![Hash256::zero()], spec) BlocksByRootRequest::new_v1(vec![Hash256::zero()], spec)
} }
@@ -1012,6 +1104,12 @@ mod tests {
OutboundRequest::BlobsByRoot(bbroot) => { OutboundRequest::BlobsByRoot(bbroot) => {
assert_eq!(decoded, InboundRequest::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) => { OutboundRequest::Ping(ping) => {
assert_eq!(decoded, InboundRequest::Ping(ping)) assert_eq!(decoded, InboundRequest::Ping(ping))
} }
@@ -1138,6 +1236,34 @@ mod tests {
), ),
Ok(Some(RPCResponse::BlobsByRoot(empty_blob_sidecar()))), 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 // Test RPCResponse encoding/decoding for V1 messages
@@ -1491,6 +1617,8 @@ mod tests {
OutboundRequest::MetaData(MetadataRequest::new_v1()), OutboundRequest::MetaData(MetadataRequest::new_v1()),
OutboundRequest::BlobsByRange(blbrange_request()), OutboundRequest::BlobsByRange(blbrange_request()),
OutboundRequest::BlobsByRoot(blbroot_request(&chain_spec)), OutboundRequest::BlobsByRoot(blbroot_request(&chain_spec)),
OutboundRequest::DataColumnsByRange(dcbrange_request()),
OutboundRequest::DataColumnsByRoot(dcbroot_request(&chain_spec)),
OutboundRequest::MetaData(MetadataRequest::new_v2()), OutboundRequest::MetaData(MetadataRequest::new_v2()),
]; ];

View File

@@ -91,6 +91,8 @@ pub struct RateLimiterConfig {
pub(super) blocks_by_root_quota: Quota, pub(super) blocks_by_root_quota: Quota,
pub(super) blobs_by_range_quota: Quota, pub(super) blobs_by_range_quota: Quota,
pub(super) blobs_by_root_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_bootstrap_quota: Quota,
pub(super) light_client_optimistic_update_quota: Quota, pub(super) light_client_optimistic_update_quota: Quota,
pub(super) light_client_finality_update_quota: Quota, pub(super) light_client_finality_update_quota: Quota,
@@ -110,6 +112,12 @@ impl RateLimiterConfig {
// measured against the maximum request size. // measured against the maximum request size.
pub const DEFAULT_BLOBS_BY_RANGE_QUOTA: Quota = Quota::n_every(6144, 10); 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); 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_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_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_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, blocks_by_root_quota: Self::DEFAULT_BLOCKS_BY_ROOT_QUOTA,
blobs_by_range_quota: Self::DEFAULT_BLOBS_BY_RANGE_QUOTA, blobs_by_range_quota: Self::DEFAULT_BLOBS_BY_RANGE_QUOTA,
blobs_by_root_quota: Self::DEFAULT_BLOBS_BY_ROOT_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_bootstrap_quota: Self::DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA,
light_client_optimistic_update_quota: light_client_optimistic_update_quota:
Self::DEFAULT_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 blocks_by_root_quota = None;
let mut blobs_by_range_quota = None; let mut blobs_by_range_quota = None;
let mut blobs_by_root_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_bootstrap_quota = None;
let mut light_client_optimistic_update_quota = None; let mut light_client_optimistic_update_quota = None;
let mut light_client_finality_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::BlocksByRoot => blocks_by_root_quota = blocks_by_root_quota.or(quota),
Protocol::BlobsByRange => blobs_by_range_quota = blobs_by_range_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::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::Ping => ping_quota = ping_quota.or(quota),
Protocol::MetaData => meta_data_quota = meta_data_quota.or(quota), Protocol::MetaData => meta_data_quota = meta_data_quota.or(quota),
Protocol::LightClientBootstrap => { Protocol::LightClientBootstrap => {
@@ -216,6 +234,10 @@ impl FromStr for RateLimiterConfig {
blobs_by_range_quota: blobs_by_range_quota blobs_by_range_quota: blobs_by_range_quota
.unwrap_or(Self::DEFAULT_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), 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 light_client_bootstrap_quota: light_client_bootstrap_quota
.unwrap_or(Self::DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA), .unwrap_or(Self::DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA),
light_client_optimistic_update_quota: light_client_optimistic_update_quota light_client_optimistic_update_quota: light_client_optimistic_update_quota

View File

@@ -14,9 +14,9 @@ use strum::IntoStaticStr;
use superstruct::superstruct; use superstruct::superstruct;
use types::blob_sidecar::BlobIdentifier; use types::blob_sidecar::BlobIdentifier;
use types::{ use types::{
blob_sidecar::BlobSidecar, ChainSpec, Epoch, EthSpec, Hash256, LightClientBootstrap, blob_sidecar::BlobSidecar, ChainSpec, ColumnIndex, DataColumnIdentifier, DataColumnSidecar,
LightClientFinalityUpdate, LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock, Epoch, EthSpec, Hash256, LightClientBootstrap, LightClientFinalityUpdate,
Slot, LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock, Slot,
}; };
/// Maximum length of error message. /// 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. /// Request a number of beacon block roots from a peer.
#[superstruct( #[superstruct(
variants(V1, V2), 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 */ /* RPC Handling and Grouping */
// Collection of enums and structs used by the Codecs to encode/decode RPC messages // 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. /// A response to a get BLOBS_BY_ROOT request.
BlobsByRoot(Arc<BlobSidecar<E>>), 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. /// A PONG response to a PING request.
Pong(Ping), Pong(Ping),
@@ -421,6 +485,12 @@ pub enum ResponseTermination {
/// Blobs by root stream termination. /// Blobs by root stream termination.
BlobsByRoot, 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 /// 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::BlocksByRoot(_) => Protocol::BlocksByRoot,
RPCResponse::BlobsByRange(_) => Protocol::BlobsByRange, RPCResponse::BlobsByRange(_) => Protocol::BlobsByRange,
RPCResponse::BlobsByRoot(_) => Protocol::BlobsByRoot, RPCResponse::BlobsByRoot(_) => Protocol::BlobsByRoot,
RPCResponse::DataColumnsByRoot(_) => Protocol::DataColumnsByRoot,
RPCResponse::DataColumnsByRange(_) => Protocol::DataColumnsByRange,
RPCResponse::Pong(_) => Protocol::Ping, RPCResponse::Pong(_) => Protocol::Ping,
RPCResponse::MetaData(_) => Protocol::MetaData, RPCResponse::MetaData(_) => Protocol::MetaData,
RPCResponse::LightClientBootstrap(_) => Protocol::LightClientBootstrap, RPCResponse::LightClientBootstrap(_) => Protocol::LightClientBootstrap,
@@ -556,6 +628,16 @@ impl<E: EthSpec> std::fmt::Display for RPCResponse<E> {
RPCResponse::BlobsByRoot(sidecar) => { RPCResponse::BlobsByRoot(sidecar) => {
write!(f, "BlobsByRoot: Blob slot: {}", sidecar.slot()) 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::Pong(ping) => write!(f, "Pong: {}", ping.data),
RPCResponse::MetaData(metadata) => write!(f, "Metadata: {}", metadata.seq_number()), RPCResponse::MetaData(metadata) => write!(f, "Metadata: {}", metadata.seq_number()),
RPCResponse::LightClientBootstrap(bootstrap) => { RPCResponse::LightClientBootstrap(bootstrap) => {

View File

@@ -471,6 +471,8 @@ where
ResponseTermination::BlocksByRoot => Protocol::BlocksByRoot, ResponseTermination::BlocksByRoot => Protocol::BlocksByRoot,
ResponseTermination::BlobsByRange => Protocol::BlobsByRange, ResponseTermination::BlobsByRange => Protocol::BlobsByRange,
ResponseTermination::BlobsByRoot => Protocol::BlobsByRoot, ResponseTermination::BlobsByRoot => Protocol::BlobsByRoot,
ResponseTermination::DataColumnsByRoot => Protocol::DataColumnsByRoot,
ResponseTermination::DataColumnsByRange => Protocol::DataColumnsByRange,
}, },
), ),
}; };

View File

@@ -36,6 +36,8 @@ pub enum OutboundRequest<E: EthSpec> {
BlocksByRoot(BlocksByRootRequest), BlocksByRoot(BlocksByRootRequest),
BlobsByRange(BlobsByRangeRequest), BlobsByRange(BlobsByRangeRequest),
BlobsByRoot(BlobsByRootRequest), BlobsByRoot(BlobsByRootRequest),
DataColumnsByRoot(DataColumnsByRootRequest),
DataColumnsByRange(DataColumnsByRangeRequest),
Ping(Ping), Ping(Ping),
MetaData(MetadataRequest<E>), MetaData(MetadataRequest<E>),
} }
@@ -79,6 +81,14 @@ impl<E: EthSpec> OutboundRequest<E> {
SupportedProtocol::BlobsByRootV1, SupportedProtocol::BlobsByRootV1,
Encoding::SSZSnappy, 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( OutboundRequest::Ping(_) => vec![ProtocolId::new(
SupportedProtocol::PingV1, SupportedProtocol::PingV1,
Encoding::SSZSnappy, Encoding::SSZSnappy,
@@ -100,6 +110,8 @@ impl<E: EthSpec> OutboundRequest<E> {
OutboundRequest::BlocksByRoot(req) => req.block_roots().len() as u64, OutboundRequest::BlocksByRoot(req) => req.block_roots().len() as u64,
OutboundRequest::BlobsByRange(req) => req.max_blobs_requested::<E>(), OutboundRequest::BlobsByRange(req) => req.max_blobs_requested::<E>(),
OutboundRequest::BlobsByRoot(req) => req.blob_ids.len() as u64, 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::Ping(_) => 1,
OutboundRequest::MetaData(_) => 1, OutboundRequest::MetaData(_) => 1,
} }
@@ -113,6 +125,8 @@ impl<E: EthSpec> OutboundRequest<E> {
OutboundRequest::BlocksByRoot(_) => false, OutboundRequest::BlocksByRoot(_) => false,
OutboundRequest::BlobsByRange(_) => false, OutboundRequest::BlobsByRange(_) => false,
OutboundRequest::BlobsByRoot(_) => false, OutboundRequest::BlobsByRoot(_) => false,
OutboundRequest::DataColumnsByRoot(_) => false,
OutboundRequest::DataColumnsByRange(_) => false,
OutboundRequest::Ping(_) => true, OutboundRequest::Ping(_) => true,
OutboundRequest::MetaData(_) => true, OutboundRequest::MetaData(_) => true,
} }
@@ -133,6 +147,8 @@ impl<E: EthSpec> OutboundRequest<E> {
}, },
OutboundRequest::BlobsByRange(_) => SupportedProtocol::BlobsByRangeV1, OutboundRequest::BlobsByRange(_) => SupportedProtocol::BlobsByRangeV1,
OutboundRequest::BlobsByRoot(_) => SupportedProtocol::BlobsByRootV1, OutboundRequest::BlobsByRoot(_) => SupportedProtocol::BlobsByRootV1,
OutboundRequest::DataColumnsByRoot(_) => SupportedProtocol::DataColumnsByRootV1,
OutboundRequest::DataColumnsByRange(_) => SupportedProtocol::DataColumnsByRangeV1,
OutboundRequest::Ping(_) => SupportedProtocol::PingV1, OutboundRequest::Ping(_) => SupportedProtocol::PingV1,
OutboundRequest::MetaData(req) => match req { OutboundRequest::MetaData(req) => match req {
MetadataRequest::V1(_) => SupportedProtocol::MetaDataV1, MetadataRequest::V1(_) => SupportedProtocol::MetaDataV1,
@@ -151,6 +167,8 @@ impl<E: EthSpec> OutboundRequest<E> {
OutboundRequest::BlocksByRoot(_) => ResponseTermination::BlocksByRoot, OutboundRequest::BlocksByRoot(_) => ResponseTermination::BlocksByRoot,
OutboundRequest::BlobsByRange(_) => ResponseTermination::BlobsByRange, OutboundRequest::BlobsByRange(_) => ResponseTermination::BlobsByRange,
OutboundRequest::BlobsByRoot(_) => ResponseTermination::BlobsByRoot, OutboundRequest::BlobsByRoot(_) => ResponseTermination::BlobsByRoot,
OutboundRequest::DataColumnsByRoot(_) => ResponseTermination::DataColumnsByRoot,
OutboundRequest::DataColumnsByRange(_) => ResponseTermination::DataColumnsByRange,
OutboundRequest::Status(_) => unreachable!(), OutboundRequest::Status(_) => unreachable!(),
OutboundRequest::Goodbye(_) => unreachable!(), OutboundRequest::Goodbye(_) => unreachable!(),
OutboundRequest::Ping(_) => 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::BlocksByRoot(req) => write!(f, "Blocks by root: {:?}", req),
OutboundRequest::BlobsByRange(req) => write!(f, "Blobs by range: {:?}", req), OutboundRequest::BlobsByRange(req) => write!(f, "Blobs by range: {:?}", req),
OutboundRequest::BlobsByRoot(req) => write!(f, "Blobs by root: {:?}", 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::Ping(ping) => write!(f, "Ping: {}", ping.data),
OutboundRequest::MetaData(_) => write!(f, "MetaData request"), OutboundRequest::MetaData(_) => write!(f, "MetaData request"),
} }

View File

@@ -18,10 +18,10 @@ use tokio_util::{
}; };
use types::{ use types::{
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockCapella, BeaconBlockElectra, BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockCapella, BeaconBlockElectra,
BlobSidecar, ChainSpec, EmptyBlock, EthSpec, ForkContext, ForkName, LightClientBootstrap, BlobSidecar, ChainSpec, DataColumnSidecar, EmptyBlock, EthSpec, ForkContext, ForkName,
LightClientBootstrapAltair, LightClientFinalityUpdate, LightClientFinalityUpdateAltair, LightClientBootstrap, LightClientBootstrapAltair, LightClientFinalityUpdate,
LightClientOptimisticUpdate, LightClientOptimisticUpdateAltair, MainnetEthSpec, Signature, LightClientFinalityUpdateAltair, LightClientOptimisticUpdate,
SignedBeaconBlock, LightClientOptimisticUpdateAltair, MainnetEthSpec, Signature, SignedBeaconBlock,
}; };
// Note: Hardcoding the `EthSpec` type for `SignedBeaconBlock` as min/max values is // Note: Hardcoding the `EthSpec` type for `SignedBeaconBlock` as min/max values is
@@ -268,6 +268,12 @@ pub enum Protocol {
/// The `BlobsByRoot` protocol name. /// The `BlobsByRoot` protocol name.
#[strum(serialize = "blob_sidecars_by_root")] #[strum(serialize = "blob_sidecars_by_root")]
BlobsByRoot, 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. /// The `Ping` protocol name.
Ping, Ping,
/// The `MetaData` protocol name. /// The `MetaData` protocol name.
@@ -293,6 +299,8 @@ impl Protocol {
Protocol::BlocksByRoot => Some(ResponseTermination::BlocksByRoot), Protocol::BlocksByRoot => Some(ResponseTermination::BlocksByRoot),
Protocol::BlobsByRange => Some(ResponseTermination::BlobsByRange), Protocol::BlobsByRange => Some(ResponseTermination::BlobsByRange),
Protocol::BlobsByRoot => Some(ResponseTermination::BlobsByRoot), Protocol::BlobsByRoot => Some(ResponseTermination::BlobsByRoot),
Protocol::DataColumnsByRoot => Some(ResponseTermination::DataColumnsByRoot),
Protocol::DataColumnsByRange => Some(ResponseTermination::DataColumnsByRange),
Protocol::Ping => None, Protocol::Ping => None,
Protocol::MetaData => None, Protocol::MetaData => None,
Protocol::LightClientBootstrap => None, Protocol::LightClientBootstrap => None,
@@ -319,6 +327,8 @@ pub enum SupportedProtocol {
BlocksByRootV2, BlocksByRootV2,
BlobsByRangeV1, BlobsByRangeV1,
BlobsByRootV1, BlobsByRootV1,
DataColumnsByRootV1,
DataColumnsByRangeV1,
PingV1, PingV1,
MetaDataV1, MetaDataV1,
MetaDataV2, MetaDataV2,
@@ -338,6 +348,8 @@ impl SupportedProtocol {
SupportedProtocol::BlocksByRootV2 => "2", SupportedProtocol::BlocksByRootV2 => "2",
SupportedProtocol::BlobsByRangeV1 => "1", SupportedProtocol::BlobsByRangeV1 => "1",
SupportedProtocol::BlobsByRootV1 => "1", SupportedProtocol::BlobsByRootV1 => "1",
SupportedProtocol::DataColumnsByRootV1 => "1",
SupportedProtocol::DataColumnsByRangeV1 => "1",
SupportedProtocol::PingV1 => "1", SupportedProtocol::PingV1 => "1",
SupportedProtocol::MetaDataV1 => "1", SupportedProtocol::MetaDataV1 => "1",
SupportedProtocol::MetaDataV2 => "2", SupportedProtocol::MetaDataV2 => "2",
@@ -357,6 +369,8 @@ impl SupportedProtocol {
SupportedProtocol::BlocksByRootV2 => Protocol::BlocksByRoot, SupportedProtocol::BlocksByRootV2 => Protocol::BlocksByRoot,
SupportedProtocol::BlobsByRangeV1 => Protocol::BlobsByRange, SupportedProtocol::BlobsByRangeV1 => Protocol::BlobsByRange,
SupportedProtocol::BlobsByRootV1 => Protocol::BlobsByRoot, SupportedProtocol::BlobsByRootV1 => Protocol::BlobsByRoot,
SupportedProtocol::DataColumnsByRootV1 => Protocol::DataColumnsByRoot,
SupportedProtocol::DataColumnsByRangeV1 => Protocol::DataColumnsByRange,
SupportedProtocol::PingV1 => Protocol::Ping, SupportedProtocol::PingV1 => Protocol::Ping,
SupportedProtocol::MetaDataV1 => Protocol::MetaData, SupportedProtocol::MetaDataV1 => Protocol::MetaData,
SupportedProtocol::MetaDataV2 => Protocol::MetaData, SupportedProtocol::MetaDataV2 => Protocol::MetaData,
@@ -387,6 +401,12 @@ impl SupportedProtocol {
ProtocolId::new(SupportedProtocol::BlobsByRangeV1, Encoding::SSZSnappy), 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 supported
} }
} }
@@ -495,6 +515,11 @@ impl ProtocolId {
<BlobsByRangeRequest as Encode>::ssz_fixed_len(), <BlobsByRangeRequest as Encode>::ssz_fixed_len(),
), ),
Protocol::BlobsByRoot => RpcLimits::new(0, spec.max_blobs_by_root_request), 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( Protocol::Ping => RpcLimits::new(
<Ping as Encode>::ssz_fixed_len(), <Ping as Encode>::ssz_fixed_len(),
<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::BlocksByRoot => rpc_block_limits_by_fork(fork_context.current_fork()),
Protocol::BlobsByRange => rpc_blob_limits::<E>(), Protocol::BlobsByRange => rpc_blob_limits::<E>(),
Protocol::BlobsByRoot => 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( Protocol::Ping => RpcLimits::new(
<Ping as Encode>::ssz_fixed_len(), <Ping as Encode>::ssz_fixed_len(),
<Ping as Encode>::ssz_fixed_len(), <Ping as Encode>::ssz_fixed_len(),
@@ -549,6 +576,8 @@ impl ProtocolId {
| SupportedProtocol::BlocksByRootV2 | SupportedProtocol::BlocksByRootV2
| SupportedProtocol::BlobsByRangeV1 | SupportedProtocol::BlobsByRangeV1
| SupportedProtocol::BlobsByRootV1 | SupportedProtocol::BlobsByRootV1
| SupportedProtocol::DataColumnsByRootV1
| SupportedProtocol::DataColumnsByRangeV1
| SupportedProtocol::LightClientBootstrapV1 | SupportedProtocol::LightClientBootstrapV1
| SupportedProtocol::LightClientOptimisticUpdateV1 | SupportedProtocol::LightClientOptimisticUpdateV1
| SupportedProtocol::LightClientFinalityUpdateV1 => true, | 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 */ /* Inbound upgrade */
// The inbound protocol reads the request, decodes it and returns the stream to the protocol // 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), BlocksByRoot(BlocksByRootRequest),
BlobsByRange(BlobsByRangeRequest), BlobsByRange(BlobsByRangeRequest),
BlobsByRoot(BlobsByRootRequest), BlobsByRoot(BlobsByRootRequest),
DataColumnsByRoot(DataColumnsByRootRequest),
DataColumnsByRange(DataColumnsByRangeRequest),
LightClientBootstrap(LightClientBootstrapRequest), LightClientBootstrap(LightClientBootstrapRequest),
LightClientOptimisticUpdate, LightClientOptimisticUpdate,
LightClientFinalityUpdate, LightClientFinalityUpdate,
@@ -688,6 +726,8 @@ impl<E: EthSpec> InboundRequest<E> {
InboundRequest::BlocksByRoot(req) => req.block_roots().len() as u64, InboundRequest::BlocksByRoot(req) => req.block_roots().len() as u64,
InboundRequest::BlobsByRange(req) => req.max_blobs_requested::<E>(), InboundRequest::BlobsByRange(req) => req.max_blobs_requested::<E>(),
InboundRequest::BlobsByRoot(req) => req.blob_ids.len() as u64, 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::Ping(_) => 1,
InboundRequest::MetaData(_) => 1, InboundRequest::MetaData(_) => 1,
InboundRequest::LightClientBootstrap(_) => 1, InboundRequest::LightClientBootstrap(_) => 1,
@@ -711,6 +751,8 @@ impl<E: EthSpec> InboundRequest<E> {
}, },
InboundRequest::BlobsByRange(_) => SupportedProtocol::BlobsByRangeV1, InboundRequest::BlobsByRange(_) => SupportedProtocol::BlobsByRangeV1,
InboundRequest::BlobsByRoot(_) => SupportedProtocol::BlobsByRootV1, InboundRequest::BlobsByRoot(_) => SupportedProtocol::BlobsByRootV1,
InboundRequest::DataColumnsByRoot(_) => SupportedProtocol::DataColumnsByRootV1,
InboundRequest::DataColumnsByRange(_) => SupportedProtocol::DataColumnsByRangeV1,
InboundRequest::Ping(_) => SupportedProtocol::PingV1, InboundRequest::Ping(_) => SupportedProtocol::PingV1,
InboundRequest::MetaData(req) => match req { InboundRequest::MetaData(req) => match req {
MetadataRequest::V1(_) => SupportedProtocol::MetaDataV1, MetadataRequest::V1(_) => SupportedProtocol::MetaDataV1,
@@ -736,6 +778,8 @@ impl<E: EthSpec> InboundRequest<E> {
InboundRequest::BlocksByRoot(_) => ResponseTermination::BlocksByRoot, InboundRequest::BlocksByRoot(_) => ResponseTermination::BlocksByRoot,
InboundRequest::BlobsByRange(_) => ResponseTermination::BlobsByRange, InboundRequest::BlobsByRange(_) => ResponseTermination::BlobsByRange,
InboundRequest::BlobsByRoot(_) => ResponseTermination::BlobsByRoot, InboundRequest::BlobsByRoot(_) => ResponseTermination::BlobsByRoot,
InboundRequest::DataColumnsByRoot(_) => ResponseTermination::DataColumnsByRoot,
InboundRequest::DataColumnsByRange(_) => ResponseTermination::DataColumnsByRange,
InboundRequest::Status(_) => unreachable!(), InboundRequest::Status(_) => unreachable!(),
InboundRequest::Goodbye(_) => unreachable!(), InboundRequest::Goodbye(_) => unreachable!(),
InboundRequest::Ping(_) => 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::BlocksByRoot(req) => write!(f, "Blocks by root: {:?}", req),
InboundRequest::BlobsByRange(req) => write!(f, "Blobs by range: {:?}", req), InboundRequest::BlobsByRange(req) => write!(f, "Blobs by range: {:?}", req),
InboundRequest::BlobsByRoot(req) => write!(f, "Blobs by root: {:?}", 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::Ping(ping) => write!(f, "Ping: {}", ping.data),
InboundRequest::MetaData(_) => write!(f, "MetaData request"), InboundRequest::MetaData(_) => write!(f, "MetaData request"),
InboundRequest::LightClientBootstrap(bootstrap) => { InboundRequest::LightClientBootstrap(bootstrap) => {

View File

@@ -97,6 +97,10 @@ pub struct RPCRateLimiter {
blbrange_rl: Limiter<PeerId>, blbrange_rl: Limiter<PeerId>,
/// BlobsByRoot rate limiter. /// BlobsByRoot rate limiter.
blbroot_rl: Limiter<PeerId>, blbroot_rl: Limiter<PeerId>,
/// DataColumnssByRoot rate limiter.
dcbroot_rl: Limiter<PeerId>,
/// DataColumnsByRange rate limiter.
dcbrange_rl: Limiter<PeerId>,
/// LightClientBootstrap rate limiter. /// LightClientBootstrap rate limiter.
lc_bootstrap_rl: Limiter<PeerId>, lc_bootstrap_rl: Limiter<PeerId>,
/// LightClientOptimisticUpdate rate limiter. /// LightClientOptimisticUpdate rate limiter.
@@ -133,6 +137,10 @@ pub struct RPCRateLimiterBuilder {
blbrange_quota: Option<Quota>, blbrange_quota: Option<Quota>,
/// Quota for the BlobsByRoot protocol. /// Quota for the BlobsByRoot protocol.
blbroot_quota: Option<Quota>, 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. /// Quota for the LightClientBootstrap protocol.
lcbootstrap_quota: Option<Quota>, lcbootstrap_quota: Option<Quota>,
/// Quota for the LightClientOptimisticUpdate protocol. /// Quota for the LightClientOptimisticUpdate protocol.
@@ -154,6 +162,8 @@ impl RPCRateLimiterBuilder {
Protocol::BlocksByRoot => self.bbroots_quota = q, Protocol::BlocksByRoot => self.bbroots_quota = q,
Protocol::BlobsByRange => self.blbrange_quota = q, Protocol::BlobsByRange => self.blbrange_quota = q,
Protocol::BlobsByRoot => self.blbroot_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::LightClientBootstrap => self.lcbootstrap_quota = q,
Protocol::LightClientOptimisticUpdate => self.lc_optimistic_update_quota = q, Protocol::LightClientOptimisticUpdate => self.lc_optimistic_update_quota = q,
Protocol::LightClientFinalityUpdate => self.lc_finality_update_quota = q, Protocol::LightClientFinalityUpdate => self.lc_finality_update_quota = q,
@@ -191,6 +201,14 @@ impl RPCRateLimiterBuilder {
.blbroot_quota .blbroot_quota
.ok_or("BlobsByRoot quota not specified")?; .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 // create the rate limiters
let ping_rl = Limiter::from_quota(ping_quota)?; let ping_rl = Limiter::from_quota(ping_quota)?;
let metadata_rl = Limiter::from_quota(metadata_quota)?; let metadata_rl = Limiter::from_quota(metadata_quota)?;
@@ -200,6 +218,8 @@ impl RPCRateLimiterBuilder {
let bbrange_rl = Limiter::from_quota(bbrange_quota)?; let bbrange_rl = Limiter::from_quota(bbrange_quota)?;
let blbrange_rl = Limiter::from_quota(blbrange_quota)?; let blbrange_rl = Limiter::from_quota(blbrange_quota)?;
let blbroot_rl = Limiter::from_quota(blbroots_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_bootstrap_rl = Limiter::from_quota(lc_bootstrap_quota)?;
let lc_optimistic_update_rl = Limiter::from_quota(lc_optimistic_update_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)?; let lc_finality_update_rl = Limiter::from_quota(lc_finality_update_quota)?;
@@ -218,6 +238,8 @@ impl RPCRateLimiterBuilder {
bbrange_rl, bbrange_rl,
blbrange_rl, blbrange_rl,
blbroot_rl, blbroot_rl,
dcbroot_rl,
dcbrange_rl,
lc_bootstrap_rl, lc_bootstrap_rl,
lc_optimistic_update_rl, lc_optimistic_update_rl,
lc_finality_update_rl, lc_finality_update_rl,
@@ -262,6 +284,8 @@ impl RPCRateLimiter {
blocks_by_root_quota, blocks_by_root_quota,
blobs_by_range_quota, blobs_by_range_quota,
blobs_by_root_quota, blobs_by_root_quota,
data_columns_by_root_quota,
data_columns_by_range_quota,
light_client_bootstrap_quota, light_client_bootstrap_quota,
light_client_optimistic_update_quota, light_client_optimistic_update_quota,
light_client_finality_update_quota, light_client_finality_update_quota,
@@ -276,6 +300,8 @@ impl RPCRateLimiter {
.set_quota(Protocol::BlocksByRoot, blocks_by_root_quota) .set_quota(Protocol::BlocksByRoot, blocks_by_root_quota)
.set_quota(Protocol::BlobsByRange, blobs_by_range_quota) .set_quota(Protocol::BlobsByRange, blobs_by_range_quota)
.set_quota(Protocol::BlobsByRoot, blobs_by_root_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::LightClientBootstrap, light_client_bootstrap_quota)
.set_quota( .set_quota(
Protocol::LightClientOptimisticUpdate, Protocol::LightClientOptimisticUpdate,
@@ -312,6 +338,8 @@ impl RPCRateLimiter {
Protocol::BlocksByRoot => &mut self.bbroots_rl, Protocol::BlocksByRoot => &mut self.bbroots_rl,
Protocol::BlobsByRange => &mut self.blbrange_rl, Protocol::BlobsByRange => &mut self.blbrange_rl,
Protocol::BlobsByRoot => &mut self.blbroot_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::LightClientBootstrap => &mut self.lc_bootstrap_rl,
Protocol::LightClientOptimisticUpdate => &mut self.lc_optimistic_update_rl, Protocol::LightClientOptimisticUpdate => &mut self.lc_optimistic_update_rl,
Protocol::LightClientFinalityUpdate => &mut self.lc_finality_update_rl, Protocol::LightClientFinalityUpdate => &mut self.lc_finality_update_rl,

View File

@@ -2,11 +2,13 @@ use std::sync::Arc;
use libp2p::swarm::ConnectionId; use libp2p::swarm::ConnectionId;
use types::{ use types::{
BlobSidecar, EthSpec, LightClientBootstrap, LightClientFinalityUpdate, BlobSidecar, DataColumnSidecar, EthSpec, LightClientBootstrap, LightClientFinalityUpdate,
LightClientOptimisticUpdate, SignedBeaconBlock, LightClientOptimisticUpdate, SignedBeaconBlock,
}; };
use crate::rpc::methods::{BlobsByRangeRequest, BlobsByRootRequest}; use crate::rpc::methods::{
BlobsByRangeRequest, BlobsByRootRequest, DataColumnsByRangeRequest, DataColumnsByRootRequest,
};
use crate::rpc::{ use crate::rpc::{
methods::{ methods::{
BlocksByRangeRequest, BlocksByRootRequest, LightClientBootstrapRequest, BlocksByRangeRequest, BlocksByRootRequest, LightClientBootstrapRequest,
@@ -27,6 +29,11 @@ pub struct SingleLookupReqId {
pub req_id: Id, pub req_id: Id,
} }
/// Request ID for data_columns_by_root requests. Block lookup do not issue this requests directly.
/// Wrapping this particular req_id, ensures not mixing this requests with a custody req_id.
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub struct DataColumnsByRootRequestId(pub Id);
/// Id of rpc requests sent by sync to the network. /// Id of rpc requests sent by sync to the network.
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub enum SyncRequestId { pub enum SyncRequestId {
@@ -34,6 +41,8 @@ pub enum SyncRequestId {
SingleBlock { id: SingleLookupReqId }, SingleBlock { id: SingleLookupReqId },
/// Request searching for a set of blobs given a hash. /// Request searching for a set of blobs given a hash.
SingleBlob { id: SingleLookupReqId }, SingleBlob { id: SingleLookupReqId },
/// Request searching for a set of data columns given a hash and list of column indices.
DataColumnsByRoot(DataColumnsByRootRequestId, SingleLookupReqId),
/// Range request that is composed by both a block range request and a blob range request. /// Range request that is composed by both a block range request and a blob range request.
RangeBlockAndBlobs { id: Id }, RangeBlockAndBlobs { id: Id },
} }
@@ -75,6 +84,10 @@ pub enum Request {
LightClientFinalityUpdate, LightClientFinalityUpdate,
/// A request blobs root request. /// A request blobs root request.
BlobsByRoot(BlobsByRootRequest), BlobsByRoot(BlobsByRootRequest),
/// A request data columns root request.
DataColumnsByRoot(DataColumnsByRootRequest),
/// A request data columns by range request.
DataColumnsByRange(DataColumnsByRangeRequest),
} }
impl<E: EthSpec> std::convert::From<Request> for OutboundRequest<E> { impl<E: EthSpec> std::convert::From<Request> for OutboundRequest<E> {
@@ -104,6 +117,8 @@ impl<E: EthSpec> std::convert::From<Request> for OutboundRequest<E> {
} }
Request::BlobsByRange(r) => OutboundRequest::BlobsByRange(r), Request::BlobsByRange(r) => OutboundRequest::BlobsByRange(r),
Request::BlobsByRoot(r) => OutboundRequest::BlobsByRoot(r), Request::BlobsByRoot(r) => OutboundRequest::BlobsByRoot(r),
Request::DataColumnsByRoot(r) => OutboundRequest::DataColumnsByRoot(r),
Request::DataColumnsByRange(r) => OutboundRequest::DataColumnsByRange(r),
Request::Status(s) => OutboundRequest::Status(s), Request::Status(s) => OutboundRequest::Status(s),
} }
} }
@@ -123,10 +138,14 @@ pub enum Response<E: EthSpec> {
BlocksByRange(Option<Arc<SignedBeaconBlock<E>>>), BlocksByRange(Option<Arc<SignedBeaconBlock<E>>>),
/// A response to a get BLOBS_BY_RANGE request. A None response signals the end of the batch. /// A response to a get BLOBS_BY_RANGE request. A None response signals the end of the batch.
BlobsByRange(Option<Arc<BlobSidecar<E>>>), BlobsByRange(Option<Arc<BlobSidecar<E>>>),
/// A response to a get DATA_COLUMN_SIDECARS_BY_Range request.
DataColumnsByRange(Option<Arc<DataColumnSidecar<E>>>),
/// A response to a get BLOCKS_BY_ROOT request. /// A response to a get BLOCKS_BY_ROOT request.
BlocksByRoot(Option<Arc<SignedBeaconBlock<E>>>), BlocksByRoot(Option<Arc<SignedBeaconBlock<E>>>),
/// A response to a get BLOBS_BY_ROOT request. /// A response to a get BLOBS_BY_ROOT request.
BlobsByRoot(Option<Arc<BlobSidecar<E>>>), BlobsByRoot(Option<Arc<BlobSidecar<E>>>),
/// A response to a get DATA_COLUMN_SIDECARS_BY_ROOT request.
DataColumnsByRoot(Option<Arc<DataColumnSidecar<E>>>),
/// A response to a LightClientUpdate request. /// A response to a LightClientUpdate request.
LightClientBootstrap(Arc<LightClientBootstrap<E>>), LightClientBootstrap(Arc<LightClientBootstrap<E>>),
/// A response to a LightClientOptimisticUpdate request. /// A response to a LightClientOptimisticUpdate request.
@@ -154,6 +173,16 @@ impl<E: EthSpec> std::convert::From<Response<E>> for RPCCodedResponse<E> {
Some(b) => RPCCodedResponse::Success(RPCResponse::BlobsByRange(b)), Some(b) => RPCCodedResponse::Success(RPCResponse::BlobsByRange(b)),
None => RPCCodedResponse::StreamTermination(ResponseTermination::BlobsByRange), None => RPCCodedResponse::StreamTermination(ResponseTermination::BlobsByRange),
}, },
Response::DataColumnsByRoot(r) => match r {
Some(d) => RPCCodedResponse::Success(RPCResponse::DataColumnsByRoot(d)),
None => RPCCodedResponse::StreamTermination(ResponseTermination::DataColumnsByRoot),
},
Response::DataColumnsByRange(r) => match r {
Some(d) => RPCCodedResponse::Success(RPCResponse::DataColumnsByRange(d)),
None => {
RPCCodedResponse::StreamTermination(ResponseTermination::DataColumnsByRange)
}
},
Response::Status(s) => RPCCodedResponse::Success(RPCResponse::Status(s)), Response::Status(s) => RPCCodedResponse::Success(RPCResponse::Status(s)),
Response::LightClientBootstrap(b) => { Response::LightClientBootstrap(b) => {
RPCCodedResponse::Success(RPCResponse::LightClientBootstrap(b)) RPCCodedResponse::Success(RPCResponse::LightClientBootstrap(b))

View File

@@ -1204,6 +1204,12 @@ impl<E: EthSpec> Network<E> {
Request::BlobsByRoot { .. } => { Request::BlobsByRoot { .. } => {
metrics::inc_counter_vec(&metrics::TOTAL_RPC_REQUESTS, &["blobs_by_root"]) metrics::inc_counter_vec(&metrics::TOTAL_RPC_REQUESTS, &["blobs_by_root"])
} }
Request::DataColumnsByRoot { .. } => {
metrics::inc_counter_vec(&metrics::TOTAL_RPC_REQUESTS, &["data_columns_by_root"])
}
Request::DataColumnsByRange { .. } => {
metrics::inc_counter_vec(&metrics::TOTAL_RPC_REQUESTS, &["data_columns_by_range"])
}
} }
NetworkEvent::RequestReceived { NetworkEvent::RequestReceived {
peer_id, peer_id,
@@ -1523,6 +1529,22 @@ impl<E: EthSpec> Network<E> {
self.build_request(peer_request_id, peer_id, Request::BlobsByRoot(req)); self.build_request(peer_request_id, peer_id, Request::BlobsByRoot(req));
Some(event) Some(event)
} }
InboundRequest::DataColumnsByRoot(req) => {
let event = self.build_request(
peer_request_id,
peer_id,
Request::DataColumnsByRoot(req),
);
Some(event)
}
InboundRequest::DataColumnsByRange(req) => {
let event = self.build_request(
peer_request_id,
peer_id,
Request::DataColumnsByRange(req),
);
Some(event)
}
InboundRequest::LightClientBootstrap(req) => { InboundRequest::LightClientBootstrap(req) => {
let event = self.build_request( let event = self.build_request(
peer_request_id, peer_request_id,
@@ -1580,6 +1602,12 @@ impl<E: EthSpec> Network<E> {
RPCResponse::BlobsByRoot(resp) => { RPCResponse::BlobsByRoot(resp) => {
self.build_response(id, peer_id, Response::BlobsByRoot(Some(resp))) self.build_response(id, peer_id, Response::BlobsByRoot(Some(resp)))
} }
RPCResponse::DataColumnsByRoot(resp) => {
self.build_response(id, peer_id, Response::DataColumnsByRoot(Some(resp)))
}
RPCResponse::DataColumnsByRange(resp) => {
self.build_response(id, peer_id, Response::DataColumnsByRange(Some(resp)))
}
// Should never be reached // Should never be reached
RPCResponse::LightClientBootstrap(bootstrap) => { RPCResponse::LightClientBootstrap(bootstrap) => {
self.build_response(id, peer_id, Response::LightClientBootstrap(bootstrap)) self.build_response(id, peer_id, Response::LightClientBootstrap(bootstrap))
@@ -1602,6 +1630,8 @@ impl<E: EthSpec> Network<E> {
ResponseTermination::BlocksByRoot => Response::BlocksByRoot(None), ResponseTermination::BlocksByRoot => Response::BlocksByRoot(None),
ResponseTermination::BlobsByRange => Response::BlobsByRange(None), ResponseTermination::BlobsByRange => Response::BlobsByRange(None),
ResponseTermination::BlobsByRoot => Response::BlobsByRoot(None), ResponseTermination::BlobsByRoot => Response::BlobsByRoot(None),
ResponseTermination::DataColumnsByRoot => Response::DataColumnsByRoot(None),
ResponseTermination::DataColumnsByRange => Response::DataColumnsByRange(None),
}; };
self.build_response(id, peer_id, response) self.build_response(id, peer_id, response)
} }

View File

@@ -8,7 +8,9 @@ use beacon_processor::{
DuplicateCache, GossipAggregatePackage, GossipAttestationPackage, Work, DuplicateCache, GossipAggregatePackage, GossipAttestationPackage, Work,
WorkEvent as BeaconWorkEvent, WorkEvent as BeaconWorkEvent,
}; };
use lighthouse_network::rpc::methods::{BlobsByRangeRequest, BlobsByRootRequest}; use lighthouse_network::rpc::methods::{
BlobsByRangeRequest, BlobsByRootRequest, DataColumnsByRangeRequest, DataColumnsByRootRequest,
};
use lighthouse_network::{ use lighthouse_network::{
rpc::{BlocksByRangeRequest, BlocksByRootRequest, LightClientBootstrapRequest, StatusMessage}, rpc::{BlocksByRangeRequest, BlocksByRootRequest, LightClientBootstrapRequest, StatusMessage},
Client, MessageId, NetworkGlobals, PeerId, PeerRequestId, Client, MessageId, NetworkGlobals, PeerId, PeerRequestId,
@@ -602,6 +604,40 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
}) })
} }
/// Create a new work event to process `DataColumnsByRootRequest`s from the RPC network.
pub fn send_data_columns_by_roots_request(
self: &Arc<Self>,
peer_id: PeerId,
request_id: PeerRequestId,
request: DataColumnsByRootRequest,
) -> Result<(), Error<T::EthSpec>> {
let processor = self.clone();
let process_fn =
move || processor.handle_data_columns_by_root_request(peer_id, request_id, request);
self.try_send(BeaconWorkEvent {
drop_during_sync: false,
work: Work::DataColumnsByRootsRequest(Box::new(process_fn)),
})
}
/// Create a new work event to process `DataColumnsByRange`s from the RPC network.
pub fn send_data_columns_by_range_request(
self: &Arc<Self>,
peer_id: PeerId,
request_id: PeerRequestId,
request: DataColumnsByRangeRequest,
) -> Result<(), Error<T::EthSpec>> {
let processor = self.clone();
let process_fn =
move || processor.handle_data_columns_by_range_request(peer_id, request_id, request);
self.try_send(BeaconWorkEvent {
drop_during_sync: false,
work: Work::DataColumnsByRangeRequest(Box::new(process_fn)),
})
}
/// Create a new work event to process `LightClientBootstrap`s from the RPC network. /// Create a new work event to process `LightClientBootstrap`s from the RPC network.
pub fn send_light_client_bootstrap_request( pub fn send_light_client_bootstrap_request(
self: &Arc<Self>, self: &Arc<Self>,

View File

@@ -4,7 +4,9 @@ use crate::status::ToStatusMessage;
use crate::sync::SyncMessage; use crate::sync::SyncMessage;
use beacon_chain::{BeaconChainError, BeaconChainTypes, HistoricalBlockError, WhenSlotSkipped}; use beacon_chain::{BeaconChainError, BeaconChainTypes, HistoricalBlockError, WhenSlotSkipped};
use itertools::process_results; use itertools::process_results;
use lighthouse_network::rpc::methods::{BlobsByRangeRequest, BlobsByRootRequest}; use lighthouse_network::rpc::methods::{
BlobsByRangeRequest, BlobsByRootRequest, DataColumnsByRangeRequest, DataColumnsByRootRequest,
};
use lighthouse_network::rpc::*; use lighthouse_network::rpc::*;
use lighthouse_network::{PeerId, PeerRequestId, ReportSource, Response, SyncInfo}; use lighthouse_network::{PeerId, PeerRequestId, ReportSource, Response, SyncInfo};
use slog::{debug, error, warn}; use slog::{debug, error, warn};
@@ -314,6 +316,20 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
Ok(()) Ok(())
} }
/// Handle a `DataColumnsByRoot` request from the peer.
pub fn handle_data_columns_by_root_request(
self: Arc<Self>,
peer_id: PeerId,
_request_id: PeerRequestId,
request: DataColumnsByRootRequest,
) {
// TODO(das): implement handler
debug!(self.log, "Received DataColumnsByRoot Request";
"peer_id" => %peer_id,
"count" => request.data_column_ids.len()
);
}
/// Handle a `LightClientBootstrap` request from the peer. /// Handle a `LightClientBootstrap` request from the peer.
pub fn handle_light_client_bootstrap( pub fn handle_light_client_bootstrap(
self: &Arc<Self>, self: &Arc<Self>,
@@ -815,6 +831,21 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
Ok(()) Ok(())
} }
/// Handle a `DataColumnsByRange` request from the peer.
pub fn handle_data_columns_by_range_request(
self: Arc<Self>,
peer_id: PeerId,
_request_id: PeerRequestId,
req: DataColumnsByRangeRequest,
) {
// TODO(das): implement handler
debug!(self.log, "Received DataColumnsByRange Request";
"peer_id" => %peer_id,
"count" => req.count,
"start_slot" => req.start_slot,
);
}
/// Helper function to ensure single item protocol always end with either a single chunk or an /// Helper function to ensure single item protocol always end with either a single chunk or an
/// error /// error
fn terminate_response_single_item<R, F: Fn(R) -> Response<T::EthSpec>>( fn terminate_response_single_item<R, F: Fn(R) -> Response<T::EthSpec>>(

View File

@@ -27,7 +27,7 @@ use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_stream::wrappers::UnboundedReceiverStream;
use types::{BlobSidecar, EthSpec, SignedBeaconBlock}; use types::{BlobSidecar, DataColumnSidecar, EthSpec, SignedBeaconBlock};
/// Handles messages from the network and routes them to the appropriate service to be handled. /// Handles messages from the network and routes them to the appropriate service to be handled.
pub struct Router<T: BeaconChainTypes> { pub struct Router<T: BeaconChainTypes> {
@@ -216,6 +216,14 @@ impl<T: BeaconChainTypes> Router<T> {
self.network_beacon_processor self.network_beacon_processor
.send_blobs_by_roots_request(peer_id, request_id, request), .send_blobs_by_roots_request(peer_id, request_id, request),
), ),
Request::DataColumnsByRoot(request) => self.handle_beacon_processor_send_result(
self.network_beacon_processor
.send_data_columns_by_roots_request(peer_id, request_id, request),
),
Request::DataColumnsByRange(request) => self.handle_beacon_processor_send_result(
self.network_beacon_processor
.send_data_columns_by_range_request(peer_id, request_id, request),
),
Request::LightClientBootstrap(request) => self.handle_beacon_processor_send_result( Request::LightClientBootstrap(request) => self.handle_beacon_processor_send_result(
self.network_beacon_processor self.network_beacon_processor
.send_light_client_bootstrap_request(peer_id, request_id, request), .send_light_client_bootstrap_request(peer_id, request_id, request),
@@ -258,6 +266,12 @@ impl<T: BeaconChainTypes> Router<T> {
Response::BlobsByRoot(blob) => { Response::BlobsByRoot(blob) => {
self.on_blobs_by_root_response(peer_id, request_id, blob); self.on_blobs_by_root_response(peer_id, request_id, blob);
} }
Response::DataColumnsByRoot(data_column) => {
self.on_data_columns_by_root_response(peer_id, request_id, data_column);
}
Response::DataColumnsByRange(data_column) => {
self.on_data_columns_by_range_response(peer_id, request_id, data_column);
}
// Light client responses should not be received // Light client responses should not be received
Response::LightClientBootstrap(_) Response::LightClientBootstrap(_)
| Response::LightClientOptimisticUpdate(_) | Response::LightClientOptimisticUpdate(_)
@@ -507,11 +521,11 @@ impl<T: BeaconChainTypes> Router<T> {
) { ) {
let request_id = match request_id { let request_id = match request_id {
AppRequestId::Sync(sync_id) => match sync_id { AppRequestId::Sync(sync_id) => match sync_id {
SyncRequestId::SingleBlock { .. } | SyncRequestId::SingleBlob { .. } => { id @ SyncRequestId::RangeBlockAndBlobs { .. } => id,
crit!(self.log, "Block lookups do not request BBRange requests"; "peer_id" => %peer_id); other => {
crit!(self.log, "BlocksByRange response on incorrect request"; "request" => ?other);
return; return;
} }
id @ SyncRequestId::RangeBlockAndBlobs { .. } => id,
}, },
AppRequestId::Router => { AppRequestId::Router => {
crit!(self.log, "All BBRange requests belong to sync"; "peer_id" => %peer_id); crit!(self.log, "All BBRange requests belong to sync"; "peer_id" => %peer_id);
@@ -570,12 +584,8 @@ impl<T: BeaconChainTypes> Router<T> {
let request_id = match request_id { let request_id = match request_id {
AppRequestId::Sync(sync_id) => match sync_id { AppRequestId::Sync(sync_id) => match sync_id {
id @ SyncRequestId::SingleBlock { .. } => id, id @ SyncRequestId::SingleBlock { .. } => id,
SyncRequestId::RangeBlockAndBlobs { .. } => { other => {
crit!(self.log, "Batch syncing do not request BBRoot requests"; "peer_id" => %peer_id); crit!(self.log, "BlocksByRoot response on incorrect request"; "request" => ?other);
return;
}
SyncRequestId::SingleBlob { .. } => {
crit!(self.log, "Blob response to block by roots request"; "peer_id" => %peer_id);
return; return;
} }
}, },
@@ -608,12 +618,8 @@ impl<T: BeaconChainTypes> Router<T> {
let request_id = match request_id { let request_id = match request_id {
AppRequestId::Sync(sync_id) => match sync_id { AppRequestId::Sync(sync_id) => match sync_id {
id @ SyncRequestId::SingleBlob { .. } => id, id @ SyncRequestId::SingleBlob { .. } => id,
SyncRequestId::SingleBlock { .. } => { other => {
crit!(self.log, "Block response to blobs by roots request"; "peer_id" => %peer_id); crit!(self.log, "BlobsByRoot response on incorrect request"; "request" => ?other);
return;
}
SyncRequestId::RangeBlockAndBlobs { .. } => {
crit!(self.log, "Batch syncing does not request BBRoot requests"; "peer_id" => %peer_id);
return; return;
} }
}, },
@@ -636,6 +642,67 @@ impl<T: BeaconChainTypes> Router<T> {
}); });
} }
/// Handle a `DataColumnsByRoot` response from the peer.
pub fn on_data_columns_by_root_response(
&mut self,
peer_id: PeerId,
request_id: AppRequestId,
data_column: Option<Arc<DataColumnSidecar<T::EthSpec>>>,
) {
let request_id = match request_id {
AppRequestId::Sync(sync_id) => match sync_id {
id @ SyncRequestId::DataColumnsByRoot { .. } => id,
other => {
crit!(self.log, "DataColumnsByRoot response on incorrect request"; "request" => ?other);
return;
}
},
AppRequestId::Router => {
crit!(self.log, "All DataColumnsByRoot requests belong to sync"; "peer_id" => %peer_id);
return;
}
};
trace!(
self.log,
"Received DataColumnsByRoot Response";
"peer" => %peer_id,
);
self.send_to_sync(SyncMessage::RpcDataColumn {
request_id,
peer_id,
data_column,
seen_timestamp: timestamp_now(),
});
}
pub fn on_data_columns_by_range_response(
&mut self,
peer_id: PeerId,
request_id: AppRequestId,
data_column: Option<Arc<DataColumnSidecar<T::EthSpec>>>,
) {
trace!(
self.log,
"Received DataColumnsByRange Response";
"peer" => %peer_id,
);
if let AppRequestId::Sync(id) = request_id {
self.send_to_sync(SyncMessage::RpcDataColumn {
peer_id,
request_id: id,
data_column,
seen_timestamp: timestamp_now(),
});
} else {
crit!(
self.log,
"All data columns by range responses should belong to sync"
);
}
}
fn handle_beacon_processor_send_result( fn handle_beacon_processor_send_result(
&mut self, &mut self,
result: Result<(), crate::network_beacon_processor::Error<T::EthSpec>>, result: Result<(), crate::network_beacon_processor::Error<T::EthSpec>>,

View File

@@ -101,6 +101,14 @@ pub enum SyncMessage<E: EthSpec> {
seen_timestamp: Duration, seen_timestamp: Duration,
}, },
/// A data columns has been received from the RPC
RpcDataColumn {
request_id: SyncRequestId,
peer_id: PeerId,
data_column: Option<Arc<DataColumnSidecar<E>>>,
seen_timestamp: Duration,
},
/// A block with an unknown parent has been received. /// A block with an unknown parent has been received.
UnknownParentBlock(PeerId, RpcBlock<E>, Hash256), UnknownParentBlock(PeerId, RpcBlock<E>, Hash256),
@@ -337,6 +345,9 @@ impl<T: BeaconChainTypes> SyncManager<T> {
SyncRequestId::SingleBlob { id } => { SyncRequestId::SingleBlob { id } => {
self.on_single_blob_response(id, peer_id, RpcEvent::RPCError(error)) self.on_single_blob_response(id, peer_id, RpcEvent::RPCError(error))
} }
SyncRequestId::DataColumnsByRoot { .. } => {
// TODO(das)
}
SyncRequestId::RangeBlockAndBlobs { id } => { SyncRequestId::RangeBlockAndBlobs { id } => {
if let Some(sender_id) = self.network.range_request_failed(id) { if let Some(sender_id) = self.network.range_request_failed(id) {
match sender_id { match sender_id {
@@ -614,6 +625,12 @@ impl<T: BeaconChainTypes> SyncManager<T> {
blob_sidecar, blob_sidecar,
seen_timestamp, seen_timestamp,
} => self.rpc_blob_received(request_id, peer_id, blob_sidecar, seen_timestamp), } => self.rpc_blob_received(request_id, peer_id, blob_sidecar, seen_timestamp),
SyncMessage::RpcDataColumn {
request_id,
peer_id,
data_column,
seen_timestamp,
} => self.rpc_data_column_received(request_id, peer_id, data_column, seen_timestamp),
SyncMessage::UnknownParentBlock(peer_id, block, block_root) => { SyncMessage::UnknownParentBlock(peer_id, block, block_root) => {
let block_slot = block.slot(); let block_slot = block.slot();
let parent_root = block.parent_root(); let parent_root = block.parent_root();
@@ -846,6 +863,9 @@ impl<T: BeaconChainTypes> SyncManager<T> {
SyncRequestId::SingleBlob { .. } => { SyncRequestId::SingleBlob { .. } => {
crit!(self.log, "Block received during blob request"; "peer_id" => %peer_id ); crit!(self.log, "Block received during blob request"; "peer_id" => %peer_id );
} }
SyncRequestId::DataColumnsByRoot { .. } => {
// TODO(das)
}
SyncRequestId::RangeBlockAndBlobs { id } => { SyncRequestId::RangeBlockAndBlobs { id } => {
self.range_block_and_blobs_response(id, peer_id, block.into()) self.range_block_and_blobs_response(id, peer_id, block.into())
} }
@@ -888,12 +908,25 @@ impl<T: BeaconChainTypes> SyncManager<T> {
None => RpcEvent::StreamTermination, None => RpcEvent::StreamTermination,
}, },
), ),
SyncRequestId::DataColumnsByRoot { .. } => {
// TODO(das)
}
SyncRequestId::RangeBlockAndBlobs { id } => { SyncRequestId::RangeBlockAndBlobs { id } => {
self.range_block_and_blobs_response(id, peer_id, blob.into()) self.range_block_and_blobs_response(id, peer_id, blob.into())
} }
} }
} }
fn rpc_data_column_received(
&mut self,
_request_id: SyncRequestId,
_peer_id: PeerId,
_data_column: Option<Arc<DataColumnSidecar<T::EthSpec>>>,
_seen_timestamp: Duration,
) {
// TODO(das): implement handler
}
fn on_single_blob_response( fn on_single_blob_response(
&mut self, &mut self,
id: SingleLookupReqId, id: SingleLookupReqId,