Skip to content

Commit ae30480

Browse files
authored
Implement EIP-7892 BPO hardforks (#7521)
[EIP-7892: Blob Parameter Only Hardforks](https://eips.ethereum.org/EIPS/eip-7892) #7467
1 parent 94a1446 commit ae30480

File tree

9 files changed

+286
-48
lines changed

9 files changed

+286
-48
lines changed

beacon_node/beacon_chain/src/test_utils.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -516,11 +516,7 @@ where
516516
self
517517
}
518518

519-
pub fn mock_execution_layer(self) -> Self {
520-
self.mock_execution_layer_with_config()
521-
}
522-
523-
pub fn mock_execution_layer_with_config(mut self) -> Self {
519+
pub fn mock_execution_layer(mut self) -> Self {
524520
let mock = mock_execution_layer_from_parts::<E>(
525521
self.spec.clone().expect("cannot build without spec"),
526522
self.runtime.task_executor.clone(),

beacon_node/execution_layer/src/test_utils/execution_block_generator.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ pub struct ExecutionBlockGenerator<E: EthSpec> {
142142
pub pending_payloads: HashMap<ExecutionBlockHash, ExecutionPayload<E>>,
143143
pub next_payload_id: u64,
144144
pub payload_ids: HashMap<PayloadId, ExecutionPayload<E>>,
145+
min_blobs_count: usize,
145146
/*
146147
* Post-merge fork triggers
147148
*/
@@ -188,6 +189,7 @@ impl<E: EthSpec> ExecutionBlockGenerator<E> {
188189
pending_payloads: <_>::default(),
189190
next_payload_id: 0,
190191
payload_ids: <_>::default(),
192+
min_blobs_count: 0,
191193
shanghai_time,
192194
cancun_time,
193195
prague_time,
@@ -318,6 +320,10 @@ impl<E: EthSpec> ExecutionBlockGenerator<E> {
318320
Ok(())
319321
}
320322

323+
pub fn set_min_blob_count(&mut self, count: usize) {
324+
self.min_blobs_count = count;
325+
}
326+
321327
pub fn insert_pow_block(&mut self, block_number: u64) -> Result<(), String> {
322328
if let Some(finalized_block_hash) = self.finalized_block_hash {
323329
return Err(format!(
@@ -702,8 +708,10 @@ impl<E: EthSpec> ExecutionBlockGenerator<E> {
702708
if fork_name.deneb_enabled() {
703709
// get random number between 0 and Max Blobs
704710
let mut rng = self.rng.lock();
705-
let max_blobs = self.spec.max_blobs_per_block_by_fork(fork_name) as usize;
706-
let num_blobs = rng.gen::<usize>() % (max_blobs + 1);
711+
// TODO(EIP-7892): see FIXME below
712+
// FIXME: this will break with BPO forks. This function needs to calculate the epoch based on block timestamp..
713+
let max_blobs = self.spec.max_blobs_per_block_within_fork(fork_name) as usize;
714+
let num_blobs = rng.gen_range(self.min_blobs_count..=max_blobs);
707715
let (bundle, transactions) = generate_blobs(num_blobs, fork_name)?;
708716
for tx in Vec::from(transactions) {
709717
execution_payload

beacon_node/http_api/tests/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl ApiTester {
138138
.deterministic_keypairs(VALIDATOR_COUNT)
139139
.deterministic_withdrawal_keypairs(VALIDATOR_COUNT)
140140
.fresh_ephemeral_store()
141-
.mock_execution_layer_with_config()
141+
.mock_execution_layer()
142142
.build();
143143

144144
harness

beacon_node/lighthouse_network/src/rpc/handler.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::{
2828
use tokio::time::{sleep, Sleep};
2929
use tokio_util::time::{delay_queue, DelayQueue};
3030
use tracing::{debug, trace};
31-
use types::{EthSpec, ForkContext};
31+
use types::{EthSpec, ForkContext, Slot};
3232

3333
/// The number of times to retry an outbound upgrade in the case of IO errors.
3434
const IO_ERROR_RETRIES: u8 = 3;
@@ -932,9 +932,8 @@ where
932932
}
933933
}
934934
RequestType::BlobsByRange(request) => {
935-
let max_requested_blobs = request
936-
.count
937-
.saturating_mul(spec.max_blobs_per_block_by_fork(current_fork));
935+
let epoch = Slot::new(request.start_slot).epoch(E::slots_per_epoch());
936+
let max_requested_blobs = request.max_blobs_requested(epoch, spec);
938937
let max_allowed = spec.max_request_blob_sidecars(current_fork) as u64;
939938
if max_requested_blobs > max_allowed {
940939
self.events_out.push(HandlerEvent::Err(HandlerErr::Inbound {

beacon_node/lighthouse_network/src/rpc/methods.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@ use types::blob_sidecar::BlobIdentifier;
1616
use types::light_client_update::MAX_REQUEST_LIGHT_CLIENT_UPDATES;
1717
use types::{
1818
blob_sidecar::BlobSidecar, ChainSpec, ColumnIndex, DataColumnSidecar,
19-
DataColumnsByRootIdentifier, Epoch, EthSpec, Hash256, LightClientBootstrap,
19+
DataColumnsByRootIdentifier, Epoch, EthSpec, ForkContext, Hash256, LightClientBootstrap,
2020
LightClientFinalityUpdate, LightClientOptimisticUpdate, LightClientUpdate, RuntimeVariableList,
2121
SignedBeaconBlock, Slot,
2222
};
23-
use types::{ForkContext, ForkName};
2423

2524
/// Maximum length of error message.
2625
pub type MaxErrorLen = U256;
@@ -328,8 +327,8 @@ pub struct BlobsByRangeRequest {
328327
}
329328

330329
impl BlobsByRangeRequest {
331-
pub fn max_blobs_requested(&self, current_fork: ForkName, spec: &ChainSpec) -> u64 {
332-
let max_blobs_per_block = spec.max_blobs_per_block_by_fork(current_fork);
330+
pub fn max_blobs_requested(&self, epoch: Epoch, spec: &ChainSpec) -> u64 {
331+
let max_blobs_per_block = spec.max_blobs_per_block(epoch);
333332
self.count.saturating_mul(max_blobs_per_block)
334333
}
335334
}

beacon_node/lighthouse_network/src/rpc/protocol.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use types::{
2121
EmptyBlock, EthSpec, EthSpecId, ForkContext, ForkName, LightClientBootstrap,
2222
LightClientBootstrapAltair, LightClientFinalityUpdate, LightClientFinalityUpdateAltair,
2323
LightClientOptimisticUpdate, LightClientOptimisticUpdateAltair, LightClientUpdate,
24-
MainnetEthSpec, MinimalEthSpec, Signature, SignedBeaconBlock,
24+
MainnetEthSpec, MinimalEthSpec, Signature, SignedBeaconBlock, Slot,
2525
};
2626

2727
// Note: Hardcoding the `EthSpec` type for `SignedBeaconBlock` as min/max values is
@@ -633,7 +633,8 @@ pub fn rpc_blob_limits<E: EthSpec>() -> RpcLimits {
633633
pub fn rpc_data_column_limits<E: EthSpec>(fork_name: ForkName, spec: &ChainSpec) -> RpcLimits {
634634
RpcLimits::new(
635635
DataColumnSidecar::<E>::min_size(),
636-
DataColumnSidecar::<E>::max_size(spec.max_blobs_per_block_by_fork(fork_name) as usize),
636+
// TODO(EIP-7892): fix this once we change fork-version on BPO forks
637+
DataColumnSidecar::<E>::max_size(spec.max_blobs_per_block_within_fork(fork_name) as usize),
637638
)
638639
}
639640

@@ -732,13 +733,16 @@ impl<E: EthSpec> RequestType<E> {
732733
/* These functions are used in the handler for stream management */
733734

734735
/// Maximum number of responses expected for this request.
735-
pub fn max_responses(&self, current_fork: ForkName, spec: &ChainSpec) -> u64 {
736+
/// TODO(EIP-7892): refactor this to remove `_current_fork`
737+
pub fn max_responses(&self, _current_fork: ForkName, spec: &ChainSpec) -> u64 {
736738
match self {
737739
RequestType::Status(_) => 1,
738740
RequestType::Goodbye(_) => 0,
739741
RequestType::BlocksByRange(req) => *req.count(),
740742
RequestType::BlocksByRoot(req) => req.block_roots().len() as u64,
741-
RequestType::BlobsByRange(req) => req.max_blobs_requested(current_fork, spec),
743+
RequestType::BlobsByRange(req) => {
744+
req.max_blobs_requested(Slot::new(req.start_slot).epoch(E::slots_per_epoch()), spec)
745+
}
742746
RequestType::BlobsByRoot(req) => req.blob_ids.len() as u64,
743747
RequestType::DataColumnsByRoot(req) => req.max_requested() as u64,
744748
RequestType::DataColumnsByRange(req) => req.max_requested::<E>(),

beacon_node/network/src/network_beacon_processor/tests.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ use tokio::sync::mpsc;
3737
use types::blob_sidecar::FixedBlobSidecarList;
3838
use types::{
3939
Attestation, AttesterSlashing, BlobSidecar, BlobSidecarList, ChainSpec, DataColumnSidecarList,
40-
DataColumnSubnetId, Epoch, EthSpec, ForkName, Hash256, MainnetEthSpec, ProposerSlashing,
41-
SignedAggregateAndProof, SignedBeaconBlock, SignedVoluntaryExit, Slot, SubnetId,
40+
DataColumnSubnetId, Epoch, Hash256, MainnetEthSpec, ProposerSlashing, SignedAggregateAndProof,
41+
SignedBeaconBlock, SignedVoluntaryExit, Slot, SubnetId,
4242
};
4343

4444
type E = MainnetEthSpec;
@@ -129,6 +129,14 @@ impl TestRig {
129129
"precondition: current slot is one after head"
130130
);
131131

132+
// Ensure there is a blob in the next block. Required for some tests.
133+
harness
134+
.mock_execution_layer
135+
.as_ref()
136+
.unwrap()
137+
.server
138+
.execution_block_generator()
139+
.set_min_blob_count(1);
132140
let (next_block_tuple, next_state) = harness
133141
.make_block(head.beacon_state.clone(), harness.chain.slot().unwrap())
134142
.await;
@@ -799,9 +807,11 @@ async fn import_gossip_block_unacceptably_early() {
799807
/// Data columns that have already been processed but unobserved should be propagated without re-importing.
800808
#[tokio::test]
801809
async fn accept_processed_gossip_data_columns_without_import() {
802-
let processor_config = BeaconProcessorConfig::default();
803-
let fulu_genesis_spec = ForkName::Fulu.make_genesis_spec(E::default_spec());
804-
let mut rig = TestRig::new_parametric(SMALL_CHAIN, processor_config, fulu_genesis_spec).await;
810+
if test_spec::<E>().fulu_fork_epoch.is_none() {
811+
return;
812+
};
813+
814+
let mut rig = TestRig::new(SMALL_CHAIN).await;
805815

806816
// GIVEN the data columns have already been processed but unobserved.
807817
// 1. verify data column with `DoNotObserve` to create verified but unobserved data columns.

common/eth2/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,9 @@ impl BeaconNodeHttpClient {
12961296
}
12971297

12981298
self.get_fork_contextual(path, |fork| {
1299-
(fork, spec.max_blobs_per_block_by_fork(fork) as usize)
1299+
// TODO(EIP-7892): this will overestimate the max number of blobs
1300+
// It would be better if we could get an epoch passed into this function
1301+
(fork, spec.max_blobs_per_block_within_fork(fork) as usize)
13001302
})
13011303
.await
13021304
.map(|opt| opt.map(BeaconResponse::ForkVersioned))

0 commit comments

Comments
 (0)