mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 19:51:47 +00:00
Final changes for fusaka-devnet-2 (#7655)
Closes #7467. This PR primarily addresses [the P2P changes](https://github.com/ethereum/EIPs/pull/9840) in [fusaka-devnet-2](https://fusaka-devnet-2.ethpandaops.io/). Specifically: * [the new `nfd` parameter added to the `ENR`](https://github.com/ethereum/EIPs/pull/9840) * [the modified `compute_fork_digest()` changes for every BPO fork](https://github.com/ethereum/EIPs/pull/9840) 90% of this PR was absolutely hacked together as fast as possible during the Berlinterop as fast as I could while running between Glamsterdam debates. Luckily, it seems to work. But I was unable to be as careful in avoiding bugs as I usually am. I've cleaned up the things *I remember* wanting to come back and have a closer look at. But still working on this. Progress: * [x] get it working on `fusaka-devnet-2` * [ ] [*optional* disconnect from peers with incorrect `nfd` at the fork boundary](https://github.com/ethereum/consensus-specs/pull/4407) - Can be addressed in a future PR if necessary * [x] first pass clean-up * [x] fix up all the broken tests * [x] final self-review * [x] more thorough review from people more familiar with affected code
This commit is contained in:
@@ -193,7 +193,7 @@ impl<E: EthSpec> Decoder for SSZSnappyInboundCodec<E> {
|
||||
handle_rpc_request(
|
||||
self.protocol.versioned_protocol,
|
||||
&decoded_buffer,
|
||||
self.fork_context.current_fork(),
|
||||
self.fork_context.current_fork_name(),
|
||||
&self.fork_context.spec,
|
||||
)
|
||||
}
|
||||
@@ -469,65 +469,9 @@ fn context_bytes<E: EthSpec>(
|
||||
// Add the context bytes if required
|
||||
if protocol.has_context_bytes() {
|
||||
if let RpcResponse::Success(rpc_variant) = resp {
|
||||
match rpc_variant {
|
||||
RpcSuccessResponse::BlocksByRange(ref_box_block)
|
||||
| RpcSuccessResponse::BlocksByRoot(ref_box_block) => {
|
||||
return match **ref_box_block {
|
||||
// NOTE: If you are adding another fork type here, be sure to modify the
|
||||
// `fork_context.to_context_bytes()` function to support it as well!
|
||||
SignedBeaconBlock::Fulu { .. } => {
|
||||
fork_context.to_context_bytes(ForkName::Fulu)
|
||||
}
|
||||
SignedBeaconBlock::Electra { .. } => {
|
||||
fork_context.to_context_bytes(ForkName::Electra)
|
||||
}
|
||||
SignedBeaconBlock::Deneb { .. } => {
|
||||
fork_context.to_context_bytes(ForkName::Deneb)
|
||||
}
|
||||
SignedBeaconBlock::Capella { .. } => {
|
||||
fork_context.to_context_bytes(ForkName::Capella)
|
||||
}
|
||||
SignedBeaconBlock::Bellatrix { .. } => {
|
||||
fork_context.to_context_bytes(ForkName::Bellatrix)
|
||||
}
|
||||
SignedBeaconBlock::Altair { .. } => {
|
||||
fork_context.to_context_bytes(ForkName::Altair)
|
||||
}
|
||||
SignedBeaconBlock::Base { .. } => {
|
||||
Some(fork_context.genesis_context_bytes())
|
||||
}
|
||||
};
|
||||
}
|
||||
RpcSuccessResponse::BlobsByRange(_) | RpcSuccessResponse::BlobsByRoot(_) => {
|
||||
return fork_context.to_context_bytes(ForkName::Deneb);
|
||||
}
|
||||
RpcSuccessResponse::DataColumnsByRoot(_)
|
||||
| RpcSuccessResponse::DataColumnsByRange(_) => {
|
||||
return fork_context.to_context_bytes(ForkName::Fulu);
|
||||
}
|
||||
RpcSuccessResponse::LightClientBootstrap(lc_bootstrap) => {
|
||||
return lc_bootstrap
|
||||
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
|
||||
}
|
||||
RpcSuccessResponse::LightClientOptimisticUpdate(lc_optimistic_update) => {
|
||||
return lc_optimistic_update
|
||||
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
|
||||
}
|
||||
RpcSuccessResponse::LightClientFinalityUpdate(lc_finality_update) => {
|
||||
return lc_finality_update
|
||||
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
|
||||
}
|
||||
RpcSuccessResponse::LightClientUpdatesByRange(lc_update) => {
|
||||
return lc_update
|
||||
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
|
||||
}
|
||||
// These will not pass the has_context_bytes() check
|
||||
RpcSuccessResponse::Status(_)
|
||||
| RpcSuccessResponse::Pong(_)
|
||||
| RpcSuccessResponse::MetaData(_) => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
return rpc_variant
|
||||
.slot()
|
||||
.map(|slot| fork_context.context_bytes(slot.epoch(E::slots_per_epoch())));
|
||||
}
|
||||
}
|
||||
None
|
||||
@@ -938,7 +882,7 @@ fn context_bytes_to_fork_name(
|
||||
fork_context: Arc<ForkContext>,
|
||||
) -> Result<ForkName, RPCError> {
|
||||
fork_context
|
||||
.from_context_bytes(context_bytes)
|
||||
.get_fork_from_context_bytes(context_bytes)
|
||||
.cloned()
|
||||
.ok_or_else(|| {
|
||||
let encoded = hex::encode(context_bytes);
|
||||
@@ -966,69 +910,88 @@ mod tests {
|
||||
|
||||
type Spec = types::MainnetEthSpec;
|
||||
|
||||
fn fork_context(fork_name: ForkName) -> ForkContext {
|
||||
fn spec_with_all_forks_enabled() -> ChainSpec {
|
||||
let mut chain_spec = Spec::default_spec();
|
||||
let altair_fork_epoch = Epoch::new(1);
|
||||
let bellatrix_fork_epoch = Epoch::new(2);
|
||||
let capella_fork_epoch = Epoch::new(3);
|
||||
let deneb_fork_epoch = Epoch::new(4);
|
||||
let electra_fork_epoch = Epoch::new(5);
|
||||
let fulu_fork_epoch = Epoch::new(6);
|
||||
chain_spec.altair_fork_epoch = Some(Epoch::new(1));
|
||||
chain_spec.bellatrix_fork_epoch = Some(Epoch::new(2));
|
||||
chain_spec.capella_fork_epoch = Some(Epoch::new(3));
|
||||
chain_spec.deneb_fork_epoch = Some(Epoch::new(4));
|
||||
chain_spec.electra_fork_epoch = Some(Epoch::new(5));
|
||||
chain_spec.fulu_fork_epoch = Some(Epoch::new(6));
|
||||
|
||||
chain_spec.altair_fork_epoch = Some(altair_fork_epoch);
|
||||
chain_spec.bellatrix_fork_epoch = Some(bellatrix_fork_epoch);
|
||||
chain_spec.capella_fork_epoch = Some(capella_fork_epoch);
|
||||
chain_spec.deneb_fork_epoch = Some(deneb_fork_epoch);
|
||||
chain_spec.electra_fork_epoch = Some(electra_fork_epoch);
|
||||
chain_spec.fulu_fork_epoch = Some(fulu_fork_epoch);
|
||||
// check that we have all forks covered
|
||||
assert!(chain_spec.fork_epoch(ForkName::latest()).is_some());
|
||||
chain_spec
|
||||
}
|
||||
|
||||
let current_slot = match fork_name {
|
||||
ForkName::Base => Slot::new(0),
|
||||
ForkName::Altair => altair_fork_epoch.start_slot(Spec::slots_per_epoch()),
|
||||
ForkName::Bellatrix => bellatrix_fork_epoch.start_slot(Spec::slots_per_epoch()),
|
||||
ForkName::Capella => capella_fork_epoch.start_slot(Spec::slots_per_epoch()),
|
||||
ForkName::Deneb => deneb_fork_epoch.start_slot(Spec::slots_per_epoch()),
|
||||
ForkName::Electra => electra_fork_epoch.start_slot(Spec::slots_per_epoch()),
|
||||
ForkName::Fulu => fulu_fork_epoch.start_slot(Spec::slots_per_epoch()),
|
||||
fn fork_context(fork_name: ForkName, spec: &ChainSpec) -> ForkContext {
|
||||
let current_epoch = match fork_name {
|
||||
ForkName::Base => Some(Epoch::new(0)),
|
||||
ForkName::Altair => spec.altair_fork_epoch,
|
||||
ForkName::Bellatrix => spec.bellatrix_fork_epoch,
|
||||
ForkName::Capella => spec.capella_fork_epoch,
|
||||
ForkName::Deneb => spec.deneb_fork_epoch,
|
||||
ForkName::Electra => spec.electra_fork_epoch,
|
||||
ForkName::Fulu => spec.fulu_fork_epoch,
|
||||
};
|
||||
ForkContext::new::<Spec>(current_slot, Hash256::zero(), &chain_spec)
|
||||
let current_slot = current_epoch.unwrap().start_slot(Spec::slots_per_epoch());
|
||||
ForkContext::new::<Spec>(current_slot, Hash256::zero(), spec)
|
||||
}
|
||||
|
||||
/// Smallest sized block across all current forks. Useful for testing
|
||||
/// min length check conditions.
|
||||
fn empty_base_block() -> SignedBeaconBlock<Spec> {
|
||||
let empty_block = BeaconBlock::Base(BeaconBlockBase::<Spec>::empty(&Spec::default_spec()));
|
||||
fn empty_base_block(spec: &ChainSpec) -> SignedBeaconBlock<Spec> {
|
||||
let empty_block = BeaconBlock::Base(BeaconBlockBase::<Spec>::empty(spec));
|
||||
SignedBeaconBlock::from_block(empty_block, Signature::empty())
|
||||
}
|
||||
|
||||
fn altair_block() -> SignedBeaconBlock<Spec> {
|
||||
let full_block =
|
||||
BeaconBlock::Altair(BeaconBlockAltair::<Spec>::full(&Spec::default_spec()));
|
||||
fn altair_block(spec: &ChainSpec) -> SignedBeaconBlock<Spec> {
|
||||
// The context bytes are now derived from the block epoch, so we need to have the slot set
|
||||
// here.
|
||||
let full_block = BeaconBlock::Altair(BeaconBlockAltair::<Spec>::full(spec));
|
||||
SignedBeaconBlock::from_block(full_block, Signature::empty())
|
||||
}
|
||||
|
||||
fn empty_blob_sidecar() -> Arc<BlobSidecar<Spec>> {
|
||||
Arc::new(BlobSidecar::empty())
|
||||
fn empty_blob_sidecar(spec: &ChainSpec) -> Arc<BlobSidecar<Spec>> {
|
||||
// The context bytes are now derived from the block epoch, so we need to have the slot set
|
||||
// here.
|
||||
let mut blob_sidecar = BlobSidecar::<Spec>::empty();
|
||||
blob_sidecar.signed_block_header.message.slot = spec
|
||||
.deneb_fork_epoch
|
||||
.expect("deneb fork epoch must be set")
|
||||
.start_slot(Spec::slots_per_epoch());
|
||||
Arc::new(blob_sidecar)
|
||||
}
|
||||
|
||||
fn empty_data_column_sidecar() -> Arc<DataColumnSidecar<Spec>> {
|
||||
Arc::new(DataColumnSidecar {
|
||||
fn empty_data_column_sidecar(spec: &ChainSpec) -> Arc<DataColumnSidecar<Spec>> {
|
||||
// The context bytes are now derived from the block epoch, so we need to have the slot set
|
||||
// here.
|
||||
let data_column_sidecar = DataColumnSidecar {
|
||||
index: 0,
|
||||
column: VariableList::new(vec![Cell::<Spec>::default()]).unwrap(),
|
||||
kzg_commitments: VariableList::new(vec![KzgCommitment::empty_for_testing()]).unwrap(),
|
||||
kzg_proofs: VariableList::new(vec![KzgProof::empty()]).unwrap(),
|
||||
signed_block_header: SignedBeaconBlockHeader {
|
||||
message: BeaconBlockHeader::empty(),
|
||||
message: BeaconBlockHeader {
|
||||
slot: spec
|
||||
.fulu_fork_epoch
|
||||
.expect("fulu fork epoch must be set")
|
||||
.start_slot(Spec::slots_per_epoch()),
|
||||
..BeaconBlockHeader::empty()
|
||||
},
|
||||
signature: Signature::empty(),
|
||||
},
|
||||
kzg_commitments_inclusion_proof: Default::default(),
|
||||
})
|
||||
};
|
||||
Arc::new(data_column_sidecar)
|
||||
}
|
||||
|
||||
/// Bellatrix block with length < max_rpc_size.
|
||||
fn bellatrix_block_small(spec: &ChainSpec) -> SignedBeaconBlock<Spec> {
|
||||
// The context bytes are now derived from the block epoch, so we need to have the slot set
|
||||
// here.
|
||||
let mut block: BeaconBlockBellatrix<_, FullPayload<Spec>> =
|
||||
BeaconBlockBellatrix::empty(&Spec::default_spec());
|
||||
BeaconBlockBellatrix::empty(spec);
|
||||
|
||||
let tx = VariableList::from(vec![0; 1024]);
|
||||
let txs = VariableList::from(std::iter::repeat_n(tx, 5000).collect::<Vec<_>>());
|
||||
@@ -1044,8 +1007,10 @@ mod tests {
|
||||
/// The max limit for a Bellatrix block is in the order of ~16GiB which wouldn't fit in memory.
|
||||
/// Hence, we generate a Bellatrix block just greater than `MAX_RPC_SIZE` to test rejection on the rpc layer.
|
||||
fn bellatrix_block_large(spec: &ChainSpec) -> SignedBeaconBlock<Spec> {
|
||||
// The context bytes are now derived from the block epoch, so we need to have the slot set
|
||||
// here.
|
||||
let mut block: BeaconBlockBellatrix<_, FullPayload<Spec>> =
|
||||
BeaconBlockBellatrix::empty(&Spec::default_spec());
|
||||
BeaconBlockBellatrix::empty(spec);
|
||||
|
||||
let tx = VariableList::from(vec![0; 1024]);
|
||||
let txs = VariableList::from(std::iter::repeat_n(tx, 100000).collect::<Vec<_>>());
|
||||
@@ -1101,7 +1066,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn dcbroot_request(spec: &ChainSpec, fork_name: ForkName) -> DataColumnsByRootRequest {
|
||||
fn dcbroot_request(fork_name: ForkName, spec: &ChainSpec) -> DataColumnsByRootRequest {
|
||||
let number_of_columns = spec.number_of_columns as usize;
|
||||
DataColumnsByRootRequest {
|
||||
data_column_ids: RuntimeVariableList::new(
|
||||
@@ -1115,21 +1080,21 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn bbroot_request_v1(fork_name: ForkName) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new_v1(vec![Hash256::zero()], &fork_context(fork_name))
|
||||
fn bbroot_request_v1(fork_name: ForkName, spec: &ChainSpec) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new_v1(vec![Hash256::zero()], &fork_context(fork_name, spec))
|
||||
}
|
||||
|
||||
fn bbroot_request_v2(fork_name: ForkName) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new(vec![Hash256::zero()], &fork_context(fork_name))
|
||||
fn bbroot_request_v2(fork_name: ForkName, spec: &ChainSpec) -> BlocksByRootRequest {
|
||||
BlocksByRootRequest::new(vec![Hash256::zero()], &fork_context(fork_name, spec))
|
||||
}
|
||||
|
||||
fn blbroot_request(fork_name: ForkName) -> BlobsByRootRequest {
|
||||
fn blbroot_request(fork_name: ForkName, spec: &ChainSpec) -> BlobsByRootRequest {
|
||||
BlobsByRootRequest::new(
|
||||
vec![BlobIdentifier {
|
||||
block_root: Hash256::zero(),
|
||||
index: 0,
|
||||
}],
|
||||
&fork_context(fork_name),
|
||||
&fork_context(fork_name, spec),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1172,7 +1137,7 @@ mod tests {
|
||||
spec: &ChainSpec,
|
||||
) -> Result<BytesMut, RPCError> {
|
||||
let snappy_protocol_id = ProtocolId::new(protocol, Encoding::SSZSnappy);
|
||||
let fork_context = Arc::new(fork_context(fork_name));
|
||||
let fork_context = Arc::new(fork_context(fork_name, spec));
|
||||
let max_packet_size = spec.max_payload_size as usize;
|
||||
|
||||
let mut buf = BytesMut::new();
|
||||
@@ -1186,12 +1151,13 @@ mod tests {
|
||||
fn encode_without_length_checks(
|
||||
bytes: Vec<u8>,
|
||||
fork_name: ForkName,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<BytesMut, RPCError> {
|
||||
let fork_context = fork_context(fork_name);
|
||||
let fork_context = fork_context(fork_name, spec);
|
||||
let mut dst = BytesMut::new();
|
||||
|
||||
// Add context bytes if required
|
||||
dst.extend_from_slice(&fork_context.to_context_bytes(fork_name).unwrap());
|
||||
dst.extend_from_slice(&fork_context.context_bytes(fork_context.current_fork_epoch()));
|
||||
|
||||
let mut uvi_codec: Uvi<usize> = Uvi::default();
|
||||
|
||||
@@ -1219,7 +1185,7 @@ mod tests {
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Option<RpcSuccessResponse<Spec>>, RPCError> {
|
||||
let snappy_protocol_id = ProtocolId::new(protocol, Encoding::SSZSnappy);
|
||||
let fork_context = Arc::new(fork_context(fork_name));
|
||||
let fork_context = Arc::new(fork_context(fork_name, spec));
|
||||
let max_packet_size = spec.max_payload_size as usize;
|
||||
let mut snappy_outbound_codec =
|
||||
SSZSnappyOutboundCodec::<Spec>::new(snappy_protocol_id, max_packet_size, fork_context);
|
||||
@@ -1240,7 +1206,7 @@ mod tests {
|
||||
|
||||
/// Verifies that requests we send are encoded in a way that we would correctly decode too.
|
||||
fn encode_then_decode_request(req: RequestType<Spec>, fork_name: ForkName, spec: &ChainSpec) {
|
||||
let fork_context = Arc::new(fork_context(fork_name));
|
||||
let fork_context = Arc::new(fork_context(fork_name, spec));
|
||||
let max_packet_size = spec.max_payload_size as usize;
|
||||
let protocol = ProtocolId::new(req.versioned_protocol(), Encoding::SSZSnappy);
|
||||
// Encode a request we send
|
||||
@@ -1311,7 +1277,7 @@ mod tests {
|
||||
// Test RPCResponse encoding/decoding for V1 messages
|
||||
#[test]
|
||||
fn test_encode_then_decode_v1() {
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
@@ -1348,13 +1314,13 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRangeV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))),
|
||||
ForkName::Base,
|
||||
&chain_spec,
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))))
|
||||
);
|
||||
|
||||
@@ -1363,7 +1329,7 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRangeV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
altair_block()
|
||||
altair_block(&chain_spec)
|
||||
))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
@@ -1378,13 +1344,13 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRootV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))),
|
||||
ForkName::Base,
|
||||
&chain_spec,
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))))
|
||||
);
|
||||
|
||||
@@ -1392,9 +1358,9 @@ mod tests {
|
||||
matches!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRootV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(
|
||||
Arc::new(altair_block())
|
||||
)),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(altair_block(
|
||||
&chain_spec
|
||||
)))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
)
|
||||
@@ -1439,74 +1405,98 @@ mod tests {
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlobsByRangeV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar())),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
))),
|
||||
ForkName::Deneb,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar()))),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
)))),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlobsByRangeV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar())),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
))),
|
||||
ForkName::Electra,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar()))),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
)))),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlobsByRangeV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar())),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
))),
|
||||
ForkName::Fulu,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar()))),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRange(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
)))),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlobsByRootV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar())),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
))),
|
||||
ForkName::Deneb,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar()))),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
)))),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlobsByRootV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar())),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
))),
|
||||
ForkName::Electra,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar()))),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
)))),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlobsByRootV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar())),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
))),
|
||||
ForkName::Fulu,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar()))),
|
||||
Ok(Some(RpcSuccessResponse::BlobsByRoot(empty_blob_sidecar(
|
||||
&chain_spec
|
||||
)))),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::DataColumnsByRangeV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::DataColumnsByRange(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
)),
|
||||
ForkName::Deneb,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::DataColumnsByRange(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
))),
|
||||
);
|
||||
|
||||
@@ -1514,13 +1504,13 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::DataColumnsByRangeV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::DataColumnsByRange(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
)),
|
||||
ForkName::Electra,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::DataColumnsByRange(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
))),
|
||||
);
|
||||
|
||||
@@ -1528,13 +1518,13 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::DataColumnsByRangeV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::DataColumnsByRange(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
)),
|
||||
ForkName::Fulu,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::DataColumnsByRange(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
))),
|
||||
);
|
||||
|
||||
@@ -1542,13 +1532,13 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::DataColumnsByRootV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::DataColumnsByRoot(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
)),
|
||||
ForkName::Deneb,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::DataColumnsByRoot(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
))),
|
||||
);
|
||||
|
||||
@@ -1556,13 +1546,13 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::DataColumnsByRootV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::DataColumnsByRoot(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
)),
|
||||
ForkName::Electra,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::DataColumnsByRoot(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
))),
|
||||
);
|
||||
|
||||
@@ -1570,13 +1560,13 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::DataColumnsByRootV1,
|
||||
RpcResponse::Success(RpcSuccessResponse::DataColumnsByRoot(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
)),
|
||||
ForkName::Fulu,
|
||||
&chain_spec
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::DataColumnsByRoot(
|
||||
empty_data_column_sidecar()
|
||||
empty_data_column_sidecar(&chain_spec)
|
||||
))),
|
||||
);
|
||||
}
|
||||
@@ -1584,19 +1574,19 @@ mod tests {
|
||||
// Test RPCResponse encoding/decoding for V1 messages
|
||||
#[test]
|
||||
fn test_encode_then_decode_v2() {
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRangeV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))),
|
||||
ForkName::Base,
|
||||
&chain_spec,
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))))
|
||||
);
|
||||
|
||||
@@ -1607,25 +1597,27 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRangeV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRangeV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRange(Arc::new(altair_block()))),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRange(Arc::new(altair_block(
|
||||
&chain_spec
|
||||
)))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
altair_block()
|
||||
altair_block(&chain_spec)
|
||||
))))
|
||||
);
|
||||
|
||||
@@ -1646,9 +1638,12 @@ mod tests {
|
||||
))))
|
||||
);
|
||||
|
||||
let mut encoded =
|
||||
encode_without_length_checks(bellatrix_block_large.as_ssz_bytes(), ForkName::Bellatrix)
|
||||
.unwrap();
|
||||
let mut encoded = encode_without_length_checks(
|
||||
bellatrix_block_large.as_ssz_bytes(),
|
||||
ForkName::Bellatrix,
|
||||
&chain_spec,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(
|
||||
matches!(
|
||||
@@ -1668,13 +1663,13 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRootV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))),
|
||||
ForkName::Base,
|
||||
&chain_spec,
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
)))),
|
||||
);
|
||||
|
||||
@@ -1685,25 +1680,27 @@ mod tests {
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRootV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block()
|
||||
empty_base_block(&chain_spec)
|
||||
))))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode_then_decode_response(
|
||||
SupportedProtocol::BlocksByRootV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(altair_block()))),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(altair_block(
|
||||
&chain_spec
|
||||
)))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
),
|
||||
Ok(Some(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
altair_block()
|
||||
altair_block(&chain_spec)
|
||||
))))
|
||||
);
|
||||
|
||||
@@ -1721,9 +1718,12 @@ mod tests {
|
||||
))))
|
||||
);
|
||||
|
||||
let mut encoded =
|
||||
encode_without_length_checks(bellatrix_block_large.as_ssz_bytes(), ForkName::Bellatrix)
|
||||
.unwrap();
|
||||
let mut encoded = encode_without_length_checks(
|
||||
bellatrix_block_large.as_ssz_bytes(),
|
||||
ForkName::Bellatrix,
|
||||
&chain_spec,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(
|
||||
matches!(
|
||||
@@ -1785,15 +1785,14 @@ mod tests {
|
||||
// Test RPCResponse encoding/decoding for V2 messages
|
||||
#[test]
|
||||
fn test_context_bytes_v2() {
|
||||
let fork_context = fork_context(ForkName::Altair);
|
||||
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
let fork_context = fork_context(ForkName::Altair, &chain_spec);
|
||||
|
||||
// Removing context bytes for v2 messages should error
|
||||
let mut encoded_bytes = encode_response(
|
||||
SupportedProtocol::BlocksByRangeV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
empty_base_block(),
|
||||
empty_base_block(&chain_spec),
|
||||
))),
|
||||
ForkName::Base,
|
||||
&chain_spec,
|
||||
@@ -1816,7 +1815,7 @@ mod tests {
|
||||
let mut encoded_bytes = encode_response(
|
||||
SupportedProtocol::BlocksByRootV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block(),
|
||||
empty_base_block(&chain_spec),
|
||||
))),
|
||||
ForkName::Base,
|
||||
&chain_spec,
|
||||
@@ -1840,7 +1839,7 @@ mod tests {
|
||||
let mut encoded_bytes = encode_response(
|
||||
SupportedProtocol::BlocksByRangeV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRange(Arc::new(
|
||||
empty_base_block(),
|
||||
empty_base_block(&chain_spec),
|
||||
))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
@@ -1848,8 +1847,8 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let mut wrong_fork_bytes = BytesMut::new();
|
||||
wrong_fork_bytes
|
||||
.extend_from_slice(&fork_context.to_context_bytes(ForkName::Altair).unwrap());
|
||||
let altair_epoch = chain_spec.altair_fork_epoch.unwrap();
|
||||
wrong_fork_bytes.extend_from_slice(&fork_context.context_bytes(altair_epoch));
|
||||
wrong_fork_bytes.extend_from_slice(&encoded_bytes.split_off(4));
|
||||
|
||||
assert!(matches!(
|
||||
@@ -1866,14 +1865,18 @@ mod tests {
|
||||
// Trying to decode an altair block with base context bytes should give ssz decoding error
|
||||
let mut encoded_bytes = encode_response(
|
||||
SupportedProtocol::BlocksByRootV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(altair_block()))),
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(altair_block(
|
||||
&chain_spec,
|
||||
)))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut wrong_fork_bytes = BytesMut::new();
|
||||
wrong_fork_bytes.extend_from_slice(&fork_context.to_context_bytes(ForkName::Base).unwrap());
|
||||
wrong_fork_bytes.extend_from_slice(
|
||||
&fork_context.context_bytes(chain_spec.genesis_slot.epoch(Spec::slots_per_epoch())),
|
||||
);
|
||||
wrong_fork_bytes.extend_from_slice(&encoded_bytes.split_off(4));
|
||||
|
||||
assert!(matches!(
|
||||
@@ -1889,7 +1892,7 @@ mod tests {
|
||||
|
||||
// Adding context bytes to Protocols that don't require it should return an error
|
||||
let mut encoded_bytes = BytesMut::new();
|
||||
encoded_bytes.extend_from_slice(&fork_context.to_context_bytes(ForkName::Altair).unwrap());
|
||||
encoded_bytes.extend_from_slice(&fork_context.context_bytes(altair_epoch));
|
||||
encoded_bytes.extend_from_slice(
|
||||
&encode_response(
|
||||
SupportedProtocol::MetaDataV2,
|
||||
@@ -1912,7 +1915,7 @@ mod tests {
|
||||
let mut encoded_bytes = encode_response(
|
||||
SupportedProtocol::BlocksByRootV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block(),
|
||||
empty_base_block(&chain_spec),
|
||||
))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
@@ -1938,7 +1941,7 @@ mod tests {
|
||||
let mut encoded_bytes = encode_response(
|
||||
SupportedProtocol::BlocksByRootV2,
|
||||
RpcResponse::Success(RpcSuccessResponse::BlocksByRoot(Arc::new(
|
||||
empty_base_block(),
|
||||
empty_base_block(&chain_spec),
|
||||
))),
|
||||
ForkName::Altair,
|
||||
&chain_spec,
|
||||
@@ -1960,8 +1963,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_encode_then_decode_request() {
|
||||
let fork_context = fork_context(ForkName::Electra);
|
||||
let chain_spec = fork_context.spec.clone();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
|
||||
let requests: &[RequestType<Spec>] = &[
|
||||
RequestType::Ping(ping_message()),
|
||||
@@ -1985,10 +1987,10 @@ mod tests {
|
||||
// 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)),
|
||||
RequestType::DataColumnsByRoot(dcbroot_request(&chain_spec, fork_name)),
|
||||
RequestType::BlobsByRoot(blbroot_request(fork_name, &chain_spec)),
|
||||
RequestType::BlocksByRoot(bbroot_request_v1(fork_name, &chain_spec)),
|
||||
RequestType::BlocksByRoot(bbroot_request_v2(fork_name, &chain_spec)),
|
||||
RequestType::DataColumnsByRoot(dcbroot_request(fork_name, &chain_spec)),
|
||||
]
|
||||
};
|
||||
for fork_name in ForkName::list_all() {
|
||||
@@ -2048,7 +2050,7 @@ mod tests {
|
||||
assert_eq!(writer.get_ref().len(), 42);
|
||||
dst.extend_from_slice(writer.get_ref());
|
||||
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
// 10 (for stream identifier) + 80 + 42 = 132 > `max_compressed_len`. Hence, decoding should fail with `InvalidData`.
|
||||
assert!(matches!(
|
||||
decode_response(
|
||||
@@ -2066,7 +2068,8 @@ mod tests {
|
||||
/// sends a valid message filled with a stream of useless padding before the actual message.
|
||||
#[test]
|
||||
fn test_decode_malicious_v2_message() {
|
||||
let fork_context = Arc::new(fork_context(ForkName::Altair));
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
let fork_context = Arc::new(fork_context(ForkName::Altair, &chain_spec));
|
||||
|
||||
// 10 byte snappy stream identifier
|
||||
let stream_identifier: &'static [u8] = b"\xFF\x06\x00\x00sNaPpY";
|
||||
@@ -2078,7 +2081,7 @@ mod tests {
|
||||
let malicious_padding: &'static [u8] = b"\xFE\x00\x00\x00";
|
||||
|
||||
// Full altair block is 157916 bytes uncompressed. `max_compressed_len` is 32 + 157916 + 157916/6 = 184267.
|
||||
let block_message_bytes = altair_block().as_ssz_bytes();
|
||||
let block_message_bytes = altair_block(&fork_context.spec).as_ssz_bytes();
|
||||
|
||||
assert_eq!(block_message_bytes.len(), 157916);
|
||||
assert_eq!(
|
||||
@@ -2090,7 +2093,8 @@ mod tests {
|
||||
let mut dst = BytesMut::with_capacity(1024);
|
||||
|
||||
// Insert context bytes
|
||||
dst.extend_from_slice(&fork_context.to_context_bytes(ForkName::Altair).unwrap());
|
||||
let altair_epoch = fork_context.spec.altair_fork_epoch.unwrap();
|
||||
dst.extend_from_slice(&fork_context.context_bytes(altair_epoch));
|
||||
|
||||
// Insert length-prefix
|
||||
uvi_codec
|
||||
@@ -2105,14 +2109,14 @@ mod tests {
|
||||
dst.extend_from_slice(malicious_padding);
|
||||
}
|
||||
|
||||
// Insert payload (8103 bytes compressed)
|
||||
// Insert payload (8102 bytes compressed)
|
||||
let mut writer = FrameEncoder::new(Vec::new());
|
||||
writer.write_all(&block_message_bytes).unwrap();
|
||||
writer.flush().unwrap();
|
||||
assert_eq!(writer.get_ref().len(), 8103);
|
||||
assert_eq!(writer.get_ref().len(), 8102);
|
||||
dst.extend_from_slice(writer.get_ref());
|
||||
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
|
||||
// 10 (for stream identifier) + 176156 + 8103 = 184269 > `max_compressed_len`. Hence, decoding should fail with `InvalidData`.
|
||||
assert!(matches!(
|
||||
@@ -2148,7 +2152,7 @@ mod tests {
|
||||
let mut uvi_codec: Uvi<usize> = Uvi::default();
|
||||
let mut dst = BytesMut::with_capacity(1024);
|
||||
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
|
||||
// Insert length-prefix
|
||||
uvi_codec
|
||||
@@ -2184,9 +2188,8 @@ mod tests {
|
||||
|
||||
let snappy_protocol_id = ProtocolId::new(SupportedProtocol::StatusV1, Encoding::SSZSnappy);
|
||||
|
||||
let fork_context = Arc::new(fork_context(ForkName::Base));
|
||||
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
let fork_context = Arc::new(fork_context(ForkName::Base, &chain_spec));
|
||||
|
||||
let mut snappy_outbound_codec = SSZSnappyOutboundCodec::<Spec>::new(
|
||||
snappy_protocol_id,
|
||||
@@ -2220,9 +2223,8 @@ mod tests {
|
||||
|
||||
let snappy_protocol_id = ProtocolId::new(SupportedProtocol::StatusV1, Encoding::SSZSnappy);
|
||||
|
||||
let fork_context = Arc::new(fork_context(ForkName::Base));
|
||||
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
let fork_context = Arc::new(fork_context(ForkName::Base, &chain_spec));
|
||||
|
||||
let mut snappy_outbound_codec = SSZSnappyOutboundCodec::<Spec>::new(
|
||||
snappy_protocol_id,
|
||||
@@ -2251,9 +2253,8 @@ mod tests {
|
||||
let protocol_id = ProtocolId::new(SupportedProtocol::BlocksByRangeV1, Encoding::SSZSnappy);
|
||||
|
||||
// Response limits
|
||||
let fork_context = Arc::new(fork_context(ForkName::Base));
|
||||
|
||||
let chain_spec = Spec::default_spec();
|
||||
let chain_spec = spec_with_all_forks_enabled();
|
||||
let fork_context = Arc::new(fork_context(ForkName::Base, &chain_spec));
|
||||
|
||||
let max_rpc_size = chain_spec.max_payload_size as usize;
|
||||
let limit = protocol_id.rpc_response_limits::<Spec>(&fork_context);
|
||||
|
||||
@@ -912,7 +912,7 @@ where
|
||||
}
|
||||
|
||||
let (req, substream) = substream;
|
||||
let current_fork = self.fork_context.current_fork();
|
||||
let current_fork = self.fork_context.current_fork_name();
|
||||
let spec = &self.fork_context.spec;
|
||||
|
||||
match &req {
|
||||
@@ -950,8 +950,10 @@ where
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let max_responses =
|
||||
req.max_responses(self.fork_context.current_fork(), &self.fork_context.spec);
|
||||
let max_responses = req.max_responses(
|
||||
self.fork_context.current_fork_epoch(),
|
||||
&self.fork_context.spec,
|
||||
);
|
||||
|
||||
// store requests that expect responses
|
||||
if max_responses > 0 {
|
||||
@@ -1021,8 +1023,10 @@ where
|
||||
}
|
||||
|
||||
// add the stream to substreams if we expect a response, otherwise drop the stream.
|
||||
let max_responses =
|
||||
request.max_responses(self.fork_context.current_fork(), &self.fork_context.spec);
|
||||
let max_responses = request.max_responses(
|
||||
self.fork_context.current_fork_epoch(),
|
||||
&self.fork_context.spec,
|
||||
);
|
||||
if max_responses > 0 {
|
||||
let max_remaining_chunks = if request.expect_exactly_one_response() {
|
||||
// Currently enforced only for multiple responses
|
||||
|
||||
@@ -484,7 +484,7 @@ impl BlocksByRootRequest {
|
||||
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());
|
||||
.max_request_blocks(fork_context.current_fork_name());
|
||||
let block_roots = RuntimeVariableList::from_vec(block_roots, max_request_blocks);
|
||||
Self::V2(BlocksByRootRequestV2 { block_roots })
|
||||
}
|
||||
@@ -492,7 +492,7 @@ impl BlocksByRootRequest {
|
||||
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());
|
||||
.max_request_blocks(fork_context.current_fork_name());
|
||||
let block_roots = RuntimeVariableList::from_vec(block_roots, max_request_blocks);
|
||||
Self::V1(BlocksByRootRequestV1 { block_roots })
|
||||
}
|
||||
@@ -509,7 +509,7 @@ impl BlobsByRootRequest {
|
||||
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());
|
||||
.max_request_blob_sidecars(fork_context.current_fork_name());
|
||||
let blob_ids = RuntimeVariableList::from_vec(blob_ids, max_request_blob_sidecars);
|
||||
Self { blob_ids }
|
||||
}
|
||||
@@ -749,6 +749,23 @@ impl<E: EthSpec> RpcSuccessResponse<E> {
|
||||
RpcSuccessResponse::LightClientUpdatesByRange(_) => Protocol::LightClientUpdatesByRange,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn slot(&self) -> Option<Slot> {
|
||||
match self {
|
||||
Self::BlocksByRange(r) | Self::BlocksByRoot(r) => Some(r.slot()),
|
||||
Self::BlobsByRange(r) | Self::BlobsByRoot(r) => {
|
||||
Some(r.signed_block_header.message.slot)
|
||||
}
|
||||
Self::DataColumnsByRange(r) | Self::DataColumnsByRoot(r) => {
|
||||
Some(r.signed_block_header.message.slot)
|
||||
}
|
||||
Self::LightClientBootstrap(r) => Some(r.get_slot()),
|
||||
Self::LightClientFinalityUpdate(r) => Some(r.get_attested_header_slot()),
|
||||
Self::LightClientOptimisticUpdate(r) => Some(r.get_slot()),
|
||||
Self::LightClientUpdatesByRange(r) => Some(r.attested_header_slot()),
|
||||
Self::MetaData(_) | Self::Status(_) | Self::Pong(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for RpcErrorResponse {
|
||||
|
||||
@@ -18,10 +18,10 @@ use tokio_util::{
|
||||
};
|
||||
use types::{
|
||||
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BlobSidecar, ChainSpec, DataColumnSidecar,
|
||||
EmptyBlock, EthSpec, EthSpecId, ForkContext, ForkName, LightClientBootstrap,
|
||||
EmptyBlock, Epoch, EthSpec, EthSpecId, ForkContext, ForkName, LightClientBootstrap,
|
||||
LightClientBootstrapAltair, LightClientFinalityUpdate, LightClientFinalityUpdateAltair,
|
||||
LightClientOptimisticUpdate, LightClientOptimisticUpdateAltair, LightClientUpdate,
|
||||
MainnetEthSpec, MinimalEthSpec, Signature, SignedBeaconBlock, Slot,
|
||||
MainnetEthSpec, MinimalEthSpec, Signature, SignedBeaconBlock,
|
||||
};
|
||||
|
||||
// Note: Hardcoding the `EthSpec` type for `SignedBeaconBlock` as min/max values is
|
||||
@@ -545,15 +545,15 @@ impl ProtocolId {
|
||||
<StatusMessageV2 as Encode>::ssz_fixed_len(),
|
||||
),
|
||||
Protocol::Goodbye => RpcLimits::new(0, 0), // Goodbye request has no response
|
||||
Protocol::BlocksByRange => rpc_block_limits_by_fork(fork_context.current_fork()),
|
||||
Protocol::BlocksByRoot => rpc_block_limits_by_fork(fork_context.current_fork()),
|
||||
Protocol::BlocksByRange => rpc_block_limits_by_fork(fork_context.current_fork_name()),
|
||||
Protocol::BlocksByRoot => rpc_block_limits_by_fork(fork_context.current_fork_name()),
|
||||
Protocol::BlobsByRange => rpc_blob_limits::<E>(),
|
||||
Protocol::BlobsByRoot => rpc_blob_limits::<E>(),
|
||||
Protocol::DataColumnsByRoot => {
|
||||
rpc_data_column_limits::<E>(fork_context.current_fork(), &fork_context.spec)
|
||||
rpc_data_column_limits::<E>(fork_context.current_fork_epoch(), &fork_context.spec)
|
||||
}
|
||||
Protocol::DataColumnsByRange => {
|
||||
rpc_data_column_limits::<E>(fork_context.current_fork(), &fork_context.spec)
|
||||
rpc_data_column_limits::<E>(fork_context.current_fork_epoch(), &fork_context.spec)
|
||||
}
|
||||
Protocol::Ping => RpcLimits::new(
|
||||
<Ping as Encode>::ssz_fixed_len(),
|
||||
@@ -564,16 +564,16 @@ impl ProtocolId {
|
||||
<MetaDataV3<E> as Encode>::ssz_fixed_len(),
|
||||
),
|
||||
Protocol::LightClientBootstrap => {
|
||||
rpc_light_client_bootstrap_limits_by_fork(fork_context.current_fork())
|
||||
rpc_light_client_bootstrap_limits_by_fork(fork_context.current_fork_name())
|
||||
}
|
||||
Protocol::LightClientOptimisticUpdate => {
|
||||
rpc_light_client_optimistic_update_limits_by_fork(fork_context.current_fork())
|
||||
rpc_light_client_optimistic_update_limits_by_fork(fork_context.current_fork_name())
|
||||
}
|
||||
Protocol::LightClientFinalityUpdate => {
|
||||
rpc_light_client_finality_update_limits_by_fork(fork_context.current_fork())
|
||||
rpc_light_client_finality_update_limits_by_fork(fork_context.current_fork_name())
|
||||
}
|
||||
Protocol::LightClientUpdatesByRange => {
|
||||
rpc_light_client_updates_by_range_limits_by_fork(fork_context.current_fork())
|
||||
rpc_light_client_updates_by_range_limits_by_fork(fork_context.current_fork_name())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -635,11 +635,13 @@ pub fn rpc_blob_limits<E: EthSpec>() -> RpcLimits {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rpc_data_column_limits<E: EthSpec>(fork_name: ForkName, spec: &ChainSpec) -> RpcLimits {
|
||||
pub fn rpc_data_column_limits<E: EthSpec>(
|
||||
current_digest_epoch: Epoch,
|
||||
spec: &ChainSpec,
|
||||
) -> RpcLimits {
|
||||
RpcLimits::new(
|
||||
DataColumnSidecar::<E>::min_size(),
|
||||
// TODO(EIP-7892): fix this once we change fork-version on BPO forks
|
||||
DataColumnSidecar::<E>::max_size(spec.max_blobs_per_block_within_fork(fork_name) as usize),
|
||||
DataColumnSidecar::<E>::max_size(spec.max_blobs_per_block(current_digest_epoch) as usize),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -738,16 +740,13 @@ impl<E: EthSpec> RequestType<E> {
|
||||
/* These functions are used in the handler for stream management */
|
||||
|
||||
/// Maximum number of responses expected for this request.
|
||||
/// TODO(EIP-7892): refactor this to remove `_current_fork`
|
||||
pub fn max_responses(&self, _current_fork: ForkName, spec: &ChainSpec) -> u64 {
|
||||
pub fn max_responses(&self, digest_epoch: Epoch, spec: &ChainSpec) -> u64 {
|
||||
match self {
|
||||
RequestType::Status(_) => 1,
|
||||
RequestType::Goodbye(_) => 0,
|
||||
RequestType::BlocksByRange(req) => *req.count(),
|
||||
RequestType::BlocksByRoot(req) => req.block_roots().len() as u64,
|
||||
RequestType::BlobsByRange(req) => {
|
||||
req.max_blobs_requested(Slot::new(req.start_slot).epoch(E::slots_per_epoch()), spec)
|
||||
}
|
||||
RequestType::BlobsByRange(req) => req.max_blobs_requested(digest_epoch, spec),
|
||||
RequestType::BlobsByRoot(req) => req.blob_ids.len() as u64,
|
||||
RequestType::DataColumnsByRoot(req) => req.max_requested() as u64,
|
||||
RequestType::DataColumnsByRange(req) => req.max_requested::<E>(),
|
||||
|
||||
@@ -13,7 +13,7 @@ use std::sync::Arc;
|
||||
use std::task::{Context, Poll};
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::time::Interval;
|
||||
use types::{ChainSpec, EthSpec, ForkContext, ForkName};
|
||||
use types::{ChainSpec, Epoch, EthSpec, ForkContext};
|
||||
|
||||
/// Nanoseconds since a given time.
|
||||
// Maintained as u64 to reduce footprint
|
||||
@@ -267,7 +267,7 @@ impl RPCRateLimiterBuilder {
|
||||
|
||||
pub trait RateLimiterItem {
|
||||
fn protocol(&self) -> Protocol;
|
||||
fn max_responses(&self, current_fork: ForkName, spec: &ChainSpec) -> u64;
|
||||
fn max_responses(&self, digest_epoch: Epoch, spec: &ChainSpec) -> u64;
|
||||
}
|
||||
|
||||
impl<E: EthSpec> RateLimiterItem for super::RequestType<E> {
|
||||
@@ -275,8 +275,8 @@ impl<E: EthSpec> RateLimiterItem for super::RequestType<E> {
|
||||
self.versioned_protocol().protocol()
|
||||
}
|
||||
|
||||
fn max_responses(&self, current_fork: ForkName, spec: &ChainSpec) -> u64 {
|
||||
self.max_responses(current_fork, spec)
|
||||
fn max_responses(&self, digest_epoch: Epoch, spec: &ChainSpec) -> u64 {
|
||||
self.max_responses(digest_epoch, spec)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ impl<E: EthSpec> RateLimiterItem for (super::RpcResponse<E>, Protocol) {
|
||||
self.1
|
||||
}
|
||||
|
||||
fn max_responses(&self, _current_fork: ForkName, _spec: &ChainSpec) -> u64 {
|
||||
fn max_responses(&self, _digest_epoch: Epoch, _spec: &ChainSpec) -> u64 {
|
||||
// A response chunk consumes one token of the rate limiter.
|
||||
1
|
||||
}
|
||||
@@ -353,7 +353,10 @@ impl RPCRateLimiter {
|
||||
) -> Result<(), RateLimitedErr> {
|
||||
let time_since_start = self.init_time.elapsed();
|
||||
let tokens = request
|
||||
.max_responses(self.fork_context.current_fork(), &self.fork_context.spec)
|
||||
.max_responses(
|
||||
self.fork_context.current_fork_epoch(),
|
||||
&self.fork_context.spec,
|
||||
)
|
||||
.max(1);
|
||||
|
||||
let check =
|
||||
|
||||
Reference in New Issue
Block a user