mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-10 04:01:51 +00:00
Fork aware max values in rpc (#6847)
N/A In https://github.com/sigp/lighthouse/pull/6329 we changed `max_blobs_per_block` from a preset to a config value. We weren't using the right value based on fork in that PR. This is a follow up PR to use the fork dependent values. In the proces, I also updated other places where we weren't using fork dependent values from the ChainSpec. Note to reviewer: easier to go through by commit
This commit is contained in:
@@ -576,7 +576,7 @@ fn handle_rpc_request<E: EthSpec>(
|
||||
BlocksByRootRequest::V2(BlocksByRootRequestV2 {
|
||||
block_roots: RuntimeVariableList::from_ssz_bytes(
|
||||
decoded_buffer,
|
||||
spec.max_request_blocks as usize,
|
||||
spec.max_request_blocks(current_fork),
|
||||
)?,
|
||||
}),
|
||||
))),
|
||||
@@ -584,32 +584,18 @@ fn handle_rpc_request<E: EthSpec>(
|
||||
BlocksByRootRequest::V1(BlocksByRootRequestV1 {
|
||||
block_roots: RuntimeVariableList::from_ssz_bytes(
|
||||
decoded_buffer,
|
||||
spec.max_request_blocks as usize,
|
||||
spec.max_request_blocks(current_fork),
|
||||
)?,
|
||||
}),
|
||||
))),
|
||||
SupportedProtocol::BlobsByRangeV1 => {
|
||||
let req = BlobsByRangeRequest::from_ssz_bytes(decoded_buffer)?;
|
||||
let max_requested_blobs = req
|
||||
.count
|
||||
.saturating_mul(spec.max_blobs_per_block_by_fork(current_fork));
|
||||
// TODO(pawan): change this to max_blobs_per_rpc_request in the alpha10 PR
|
||||
if max_requested_blobs > spec.max_request_blob_sidecars {
|
||||
return Err(RPCError::ErrorResponse(
|
||||
RpcErrorResponse::InvalidRequest,
|
||||
format!(
|
||||
"requested exceeded limit. allowed: {}, requested: {}",
|
||||
spec.max_request_blob_sidecars, max_requested_blobs
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(Some(RequestType::BlobsByRange(req)))
|
||||
}
|
||||
SupportedProtocol::BlobsByRangeV1 => Ok(Some(RequestType::BlobsByRange(
|
||||
BlobsByRangeRequest::from_ssz_bytes(decoded_buffer)?,
|
||||
))),
|
||||
SupportedProtocol::BlobsByRootV1 => {
|
||||
Ok(Some(RequestType::BlobsByRoot(BlobsByRootRequest {
|
||||
blob_ids: RuntimeVariableList::from_ssz_bytes(
|
||||
decoded_buffer,
|
||||
spec.max_request_blob_sidecars as usize,
|
||||
spec.max_request_blob_sidecars(current_fork),
|
||||
)?,
|
||||
})))
|
||||
}
|
||||
@@ -1097,21 +1083,21 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn bbroot_request_v1(spec: &ChainSpec) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new_v1(vec![Hash256::zero()], spec)
|
||||
fn bbroot_request_v1(fork_name: ForkName) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new_v1(vec![Hash256::zero()], &fork_context(fork_name))
|
||||
}
|
||||
|
||||
fn bbroot_request_v2(spec: &ChainSpec) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new(vec![Hash256::zero()], spec)
|
||||
fn bbroot_request_v2(fork_name: ForkName) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new(vec![Hash256::zero()], &fork_context(fork_name))
|
||||
}
|
||||
|
||||
fn blbroot_request(spec: &ChainSpec) -> BlobsByRootRequest {
|
||||
fn blbroot_request(fork_name: ForkName) -> BlobsByRootRequest {
|
||||
BlobsByRootRequest::new(
|
||||
vec![BlobIdentifier {
|
||||
block_root: Hash256::zero(),
|
||||
index: 0,
|
||||
}],
|
||||
spec,
|
||||
&fork_context(fork_name),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1909,7 +1895,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_encode_then_decode_request() {
|
||||
let chain_spec = Spec::default_spec();
|
||||
let fork_context = fork_context(ForkName::Electra);
|
||||
let chain_spec = fork_context.spec.clone();
|
||||
|
||||
let requests: &[RequestType<Spec>] = &[
|
||||
RequestType::Ping(ping_message()),
|
||||
@@ -1917,21 +1904,33 @@ mod tests {
|
||||
RequestType::Goodbye(GoodbyeReason::Fault),
|
||||
RequestType::BlocksByRange(bbrange_request_v1()),
|
||||
RequestType::BlocksByRange(bbrange_request_v2()),
|
||||
RequestType::BlocksByRoot(bbroot_request_v1(&chain_spec)),
|
||||
RequestType::BlocksByRoot(bbroot_request_v2(&chain_spec)),
|
||||
RequestType::MetaData(MetadataRequest::new_v1()),
|
||||
RequestType::BlobsByRange(blbrange_request()),
|
||||
RequestType::BlobsByRoot(blbroot_request(&chain_spec)),
|
||||
RequestType::DataColumnsByRange(dcbrange_request()),
|
||||
RequestType::DataColumnsByRoot(dcbroot_request(&chain_spec)),
|
||||
RequestType::MetaData(MetadataRequest::new_v2()),
|
||||
];
|
||||
|
||||
for req in requests.iter() {
|
||||
for fork_name in ForkName::list_all() {
|
||||
encode_then_decode_request(req.clone(), fork_name, &chain_spec);
|
||||
}
|
||||
}
|
||||
|
||||
// Request types that have different length limits depending on the fork
|
||||
// Handled separately to have consistent `ForkName` across request and responses
|
||||
let fork_dependent_requests = |fork_name| {
|
||||
[
|
||||
RequestType::BlobsByRoot(blbroot_request(fork_name)),
|
||||
RequestType::BlocksByRoot(bbroot_request_v1(fork_name)),
|
||||
RequestType::BlocksByRoot(bbroot_request_v2(fork_name)),
|
||||
]
|
||||
};
|
||||
for fork_name in ForkName::list_all() {
|
||||
let requests = fork_dependent_requests(fork_name);
|
||||
for req in requests {
|
||||
encode_then_decode_request(req.clone(), fork_name, &chain_spec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Test a malicious snappy encoding for a V1 `Status` message where the attacker
|
||||
|
||||
@@ -855,6 +855,45 @@ where
|
||||
}
|
||||
|
||||
let (req, substream) = substream;
|
||||
let current_fork = self.fork_context.current_fork();
|
||||
let spec = &self.fork_context.spec;
|
||||
|
||||
match &req {
|
||||
RequestType::BlocksByRange(request) => {
|
||||
let max_allowed = spec.max_request_blocks(current_fork) as u64;
|
||||
if *request.count() > max_allowed {
|
||||
self.events_out.push(HandlerEvent::Err(HandlerErr::Inbound {
|
||||
id: self.current_inbound_substream_id,
|
||||
proto: Protocol::BlocksByRange,
|
||||
error: RPCError::InvalidData(format!(
|
||||
"requested exceeded limit. allowed: {}, requested: {}",
|
||||
max_allowed,
|
||||
request.count()
|
||||
)),
|
||||
}));
|
||||
return self.shutdown(None);
|
||||
}
|
||||
}
|
||||
RequestType::BlobsByRange(request) => {
|
||||
let max_requested_blobs = request
|
||||
.count
|
||||
.saturating_mul(spec.max_blobs_per_block_by_fork(current_fork));
|
||||
let max_allowed = spec.max_request_blob_sidecars(current_fork) as u64;
|
||||
if max_requested_blobs > max_allowed {
|
||||
self.events_out.push(HandlerEvent::Err(HandlerErr::Inbound {
|
||||
id: self.current_inbound_substream_id,
|
||||
proto: Protocol::BlobsByRange,
|
||||
error: RPCError::InvalidData(format!(
|
||||
"requested exceeded limit. allowed: {}, requested: {}",
|
||||
max_allowed, max_requested_blobs
|
||||
)),
|
||||
}));
|
||||
return self.shutdown(None);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let max_responses =
|
||||
req.max_responses(self.fork_context.current_fork(), &self.fork_context.spec);
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ use strum::IntoStaticStr;
|
||||
use superstruct::superstruct;
|
||||
use types::blob_sidecar::BlobIdentifier;
|
||||
use types::light_client_update::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
|
||||
use types::ForkName;
|
||||
use types::{
|
||||
blob_sidecar::BlobSidecar, ChainSpec, ColumnIndex, DataColumnIdentifier, DataColumnSidecar,
|
||||
Epoch, EthSpec, Hash256, LightClientBootstrap, LightClientFinalityUpdate,
|
||||
LightClientOptimisticUpdate, LightClientUpdate, RuntimeVariableList, SignedBeaconBlock, Slot,
|
||||
};
|
||||
use types::{ForkContext, ForkName};
|
||||
|
||||
/// Maximum length of error message.
|
||||
pub type MaxErrorLen = U256;
|
||||
@@ -420,15 +420,19 @@ pub struct BlocksByRootRequest {
|
||||
}
|
||||
|
||||
impl BlocksByRootRequest {
|
||||
pub fn new(block_roots: Vec<Hash256>, spec: &ChainSpec) -> Self {
|
||||
let block_roots =
|
||||
RuntimeVariableList::from_vec(block_roots, spec.max_request_blocks as usize);
|
||||
pub fn new(block_roots: Vec<Hash256>, fork_context: &ForkContext) -> Self {
|
||||
let max_request_blocks = fork_context
|
||||
.spec
|
||||
.max_request_blocks(fork_context.current_fork());
|
||||
let block_roots = RuntimeVariableList::from_vec(block_roots, max_request_blocks);
|
||||
Self::V2(BlocksByRootRequestV2 { block_roots })
|
||||
}
|
||||
|
||||
pub fn new_v1(block_roots: Vec<Hash256>, spec: &ChainSpec) -> Self {
|
||||
let block_roots =
|
||||
RuntimeVariableList::from_vec(block_roots, spec.max_request_blocks as usize);
|
||||
pub fn new_v1(block_roots: Vec<Hash256>, fork_context: &ForkContext) -> Self {
|
||||
let max_request_blocks = fork_context
|
||||
.spec
|
||||
.max_request_blocks(fork_context.current_fork());
|
||||
let block_roots = RuntimeVariableList::from_vec(block_roots, max_request_blocks);
|
||||
Self::V1(BlocksByRootRequestV1 { block_roots })
|
||||
}
|
||||
}
|
||||
@@ -441,9 +445,11 @@ pub struct BlobsByRootRequest {
|
||||
}
|
||||
|
||||
impl BlobsByRootRequest {
|
||||
pub fn new(blob_ids: Vec<BlobIdentifier>, spec: &ChainSpec) -> Self {
|
||||
let blob_ids =
|
||||
RuntimeVariableList::from_vec(blob_ids, spec.max_request_blob_sidecars as usize);
|
||||
pub fn new(blob_ids: Vec<BlobIdentifier>, fork_context: &ForkContext) -> Self {
|
||||
let max_request_blob_sidecars = fork_context
|
||||
.spec
|
||||
.max_request_blob_sidecars(fork_context.current_fork());
|
||||
let blob_ids = RuntimeVariableList::from_vec(blob_ids, max_request_blob_sidecars);
|
||||
Self { blob_ids }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user