Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions beacon_node/beacon_chain/src/data_column_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,22 @@ mod test {
.build();
harness.advance_slot();

// Check block generator timestamp conversion sanity.
{
let exec_block_generator = harness.execution_block_generator();
assert_eq!(
exec_block_generator
.timestamp_to_slot_post_capella(exec_block_generator.osaka_time.unwrap()),
0
);
assert_eq!(
exec_block_generator.timestamp_to_slot_post_capella(
exec_block_generator.osaka_time.unwrap() + harness.spec.seconds_per_slot
),
1
);
}

let verify_fn = |column_sidecar: DataColumnSidecar<E>| {
GossipVerifiedDataColumn::<_>::new_for_block_publishing(
column_sidecar.into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use types::{
Blob, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadBellatrix,
ExecutionPayloadCapella, ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
ExecutionPayloadGloas, ExecutionPayloadHeader, FixedBytesExtended, ForkName, Hash256,
KzgProofs, Transaction, Transactions, Uint256,
KzgProofs, Slot, Transaction, Transactions, Uint256,
};

use super::DEFAULT_TERMINAL_BLOCK;
Expand Down Expand Up @@ -265,6 +265,37 @@ impl<E: EthSpec> ExecutionBlockGenerator<E> {
ForkName::Bellatrix
}

/// Get the timestamp at which `fork` activates.
///
/// This function will panic if the `fork` is not enabled or is `<= ForkName::Bellatrix`.
pub fn get_fork_timestamp_post_capella(&self, fork: ForkName) -> u64 {
match fork {
ForkName::Gloas => self.amsterdam_time,
ForkName::Fulu => self.osaka_time,
ForkName::Electra => self.prague_time,
ForkName::Deneb => self.cancun_time,
ForkName::Capella => self.shanghai_time,
_ => panic!("only the Capella fork or later is supported"),
}
.unwrap_or_else(|| panic!("fork is {fork} but no corresponding timestamp is set"))
}

/// This is a slightly nasty method for converting timestamps to slots, but it will suffice
/// until we can plumb through a slot clock.
pub fn timestamp_to_slot_post_capella(&self, timestamp: u64) -> Slot {
let fork = self.get_fork_at_timestamp(timestamp);
let fork_epoch = self.spec.fork_epoch(fork).unwrap();
let fork_timestamp = self.get_fork_timestamp_post_capella(fork);

// Number of slots since fork.
let slot_offset = timestamp
.checked_sub(fork_timestamp)
.expect("timestamp should be >= fork timestamp")
/ self.spec.seconds_per_slot;

fork_epoch.start_slot(E::slots_per_epoch()) + Slot::new(slot_offset)
}

pub fn execution_block_by_number(&self, number: u64) -> Option<ExecutionBlock> {
self.block_by_number(number)
.map(|block| block.as_execution_block(self.terminal_total_difficulty))
Expand Down Expand Up @@ -734,9 +765,10 @@ impl<E: EthSpec> ExecutionBlockGenerator<E> {
if fork_name.deneb_enabled() {
// get random number between 0 and Max Blobs
let mut rng = self.rng.lock();
// TODO(EIP-7892): see FIXME below
// FIXME: this will break with BPO forks. This function needs to calculate the epoch based on block timestamp..
let max_blobs = self.spec.max_blobs_per_block_within_fork(fork_name) as usize;
let epoch = self
.timestamp_to_slot_post_capella(execution_payload.timestamp())
.epoch(E::slots_per_epoch());
let max_blobs = self.spec.max_blobs_per_block(epoch) as usize;
let num_blobs = rng.random_range(self.min_blobs_count..=max_blobs);
let (bundle, transactions) = generate_blobs(num_blobs, fork_name)?;
for tx in Vec::from(transactions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ ELECTRA_FORK_VERSION: 0x05000000
ELECTRA_FORK_EPOCH: 364032 # May 7, 2025, 10:05:11am UTC
# Fulu
FULU_FORK_VERSION: 0x06000000
FULU_FORK_EPOCH: 18446744073709551615
FULU_FORK_EPOCH: 411392 # December 3, 2025, 09:49:11pm UTC
# Gloas
GLOAS_FORK_VERSION: 0x07000000
GLOAS_FORK_EPOCH: 18446744073709551615
Expand All @@ -61,6 +61,8 @@ GLOAS_FORK_EPOCH: 18446744073709551615
# ---------------------------------------------------------------
# 12 seconds
SECONDS_PER_SLOT: 12
# 12000 milliseconds
SLOT_DURATION_MS: 12000
# 14 (estimate from Eth1 mainnet)
SECONDS_PER_ETH1_BLOCK: 14
# 2**8 (= 256) epochs ~27 hours
Expand All @@ -69,6 +71,18 @@ MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
SHARD_COMMITTEE_PERIOD: 256
# 2**11 (= 2,048) Eth1 blocks ~8 hours
ETH1_FOLLOW_DISTANCE: 2048
# 1667 basis points, ~17% of SLOT_DURATION_MS
PROPOSER_REORG_CUTOFF_BPS: 1667
# 3333 basis points, ~33% of SLOT_DURATION_MS
ATTESTATION_DUE_BPS: 3333
# 6667 basis points, ~67% of SLOT_DURATION_MS
AGGREGATE_DUE_BPS: 6667

# Altair
# 3333 basis points, ~33% of SLOT_DURATION_MS
SYNC_MESSAGE_DUE_BPS: 3333
# 6667 basis points, ~67% of SLOT_DURATION_MS
CONTRIBUTION_DUE_BPS: 6667

# Validator cycle
# ---------------------------------------------------------------
Expand Down Expand Up @@ -156,13 +170,30 @@ MAX_BLOBS_PER_BLOCK_ELECTRA: 9
MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152

# Fulu
# 2**7 (= 128) groups
NUMBER_OF_CUSTODY_GROUPS: 128
# 2**7 (= 128) subnets
DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128
# MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS (= 128 * 128) sidecars
MAX_REQUEST_DATA_COLUMN_SIDECARS: 16384
# 2**3 (= 8) samples
SAMPLES_PER_SLOT: 8
# 2**2 (= 4) sidecars
CUSTODY_REQUIREMENT: 4
# 2**3 (= 8) sidecars
VALIDATOR_CUSTODY_REQUIREMENT: 8
# 2**5 * 10**9 (= 32,000,000,000) Gwei
BALANCE_PER_ADDITIONAL_CUSTODY_GROUP: 32000000000
# 2**12 (= 4,096) epochs
MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS: 4096

# Blob Scheduling
# ---------------------------------------------------------------

BLOB_SCHEDULE:
- EPOCH: 412672 # December 9, 2025, 02:21:11pm UTC
MAX_BLOBS_PER_BLOCK: 15
- EPOCH: 419072 # January 7, 2026, 01:01:11am UTC
MAX_BLOBS_PER_BLOCK: 21

# Gloas
31 changes: 29 additions & 2 deletions consensus/types/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,18 @@ pub struct ChainSpec {
*/
pub genesis_delay: u64,
pub seconds_per_slot: u64,
pub slot_duration_ms: u64,
pub min_attestation_inclusion_delay: u64,
pub min_seed_lookahead: Epoch,
pub max_seed_lookahead: Epoch,
pub min_epochs_to_inactivity_penalty: u64,
pub min_validator_withdrawability_delay: Epoch,
pub shard_committee_period: u64,
pub proposer_reorg_cutoff_bps: u64,
pub attestation_due_bps: u64,
pub aggregate_due_bps: u64,
pub sync_message_due_bps: u64,
pub contribution_due_bps: u64,

/*
* Reward and penalty quotients
Expand Down Expand Up @@ -964,12 +970,18 @@ impl ChainSpec {
*/
genesis_delay: 604800, // 7 days
seconds_per_slot: 12,
slot_duration_ms: 12000,
min_attestation_inclusion_delay: 1,
min_seed_lookahead: Epoch::new(1),
max_seed_lookahead: Epoch::new(4),
min_epochs_to_inactivity_penalty: 4,
min_validator_withdrawability_delay: Epoch::new(256),
shard_committee_period: 256,
proposer_reorg_cutoff_bps: 1667,
attestation_due_bps: 3333,
aggregate_due_bps: 6667,
sync_message_due_bps: 3333,
contribution_due_bps: 6667,

/*
* Reward and penalty quotients
Expand Down Expand Up @@ -1098,7 +1110,7 @@ impl ChainSpec {
* Fulu hard fork params
*/
fulu_fork_version: [0x06, 0x00, 0x00, 0x00],
fulu_fork_epoch: None,
fulu_fork_epoch: Some(Epoch::new(411392)),
custody_requirement: 4,
number_of_custody_groups: 128,
data_column_sidecar_subnet_count: 128,
Expand Down Expand Up @@ -1158,7 +1170,16 @@ impl ChainSpec {
/*
* Networking Fulu specific
*/
blob_schedule: BlobSchedule::default(),
blob_schedule: BlobSchedule::new(vec![
BlobParameters {
epoch: Epoch::new(412672),
max_blobs_per_block: 15,
},
BlobParameters {
epoch: Epoch::new(419072),
max_blobs_per_block: 21,
},
]),
min_epochs_for_data_column_sidecars_requests:
default_min_epochs_for_data_column_sidecars_requests(),
max_data_columns_by_root_request: default_data_columns_by_root_request(),
Expand Down Expand Up @@ -1310,12 +1331,18 @@ impl ChainSpec {
*/
genesis_delay: 6000, // 100 minutes
seconds_per_slot: 5,
slot_duration_ms: 5000,
min_attestation_inclusion_delay: 1,
min_seed_lookahead: Epoch::new(1),
max_seed_lookahead: Epoch::new(4),
min_epochs_to_inactivity_penalty: 4,
min_validator_withdrawability_delay: Epoch::new(256),
shard_committee_period: 256,
proposer_reorg_cutoff_bps: 1667,
attestation_due_bps: 3333,
aggregate_due_bps: 6667,
sync_message_due_bps: 3333,
contribution_due_bps: 6667,

/*
* Reward and penalty quotients
Expand Down
Loading