mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-21 23:08:23 +00:00
Check ChainSpec consistency with upstream config.yaml (#9008)
Closes: - https://github.com/sigp/lighthouse/issues/9002 - Commit `config.yaml` for minimal and mainnet to `consensus/types/configs`. For now we omit any auto-downloading logic, to avoid the hassles of dealing with Github rate limits etc on CI. Unfortunately these files are NOT bundled inside the spec tests. - Fix the values of `min_builder_withdrawability_delay` for minimal and mainnet. These discrepancies aren't caught by the current spec tests, because the spec tests are missing data: https://github.com/ethereum/consensus-specs/pull/5005. Will be fixed in the next release/when we update to nightly. - Fix the blob schedule for `minimal`, which should be empty, NOT inherited from mainnet. - Keep `SECONDS_PER_SLOT` for now because the Kurtosis tests fail upon their complete removal. We will be able to completely remove `SECONDS_PER_SLOT` soon. Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
This commit is contained in:
227
consensus/types/configs/mainnet.yaml
Normal file
227
consensus/types/configs/mainnet.yaml
Normal file
@@ -0,0 +1,227 @@
|
||||
# Mainnet config
|
||||
|
||||
# Extends the mainnet preset
|
||||
PRESET_BASE: 'mainnet'
|
||||
|
||||
# Free-form short name of the network that this configuration applies to - known
|
||||
# canonical network names include:
|
||||
# * 'mainnet' - there can be only one
|
||||
# * 'sepolia' - testnet
|
||||
# * 'holesky' - testnet
|
||||
# * 'hoodi' - testnet
|
||||
# Must match the regex: [a-z0-9\-]
|
||||
CONFIG_NAME: 'mainnet'
|
||||
|
||||
# Transition
|
||||
# ---------------------------------------------------------------
|
||||
# Estimated on Sept 15, 2022
|
||||
TERMINAL_TOTAL_DIFFICULTY: 58750000000000000000000
|
||||
# By default, don't use these params
|
||||
TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000
|
||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615
|
||||
|
||||
# Genesis
|
||||
# ---------------------------------------------------------------
|
||||
# 2**14 (= 16,384) validators
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384
|
||||
# Dec 1, 2020, 12pm UTC
|
||||
MIN_GENESIS_TIME: 1606824000
|
||||
# Initial fork version for mainnet
|
||||
GENESIS_FORK_VERSION: 0x00000000
|
||||
# 7 * 24 * 3,600 (= 604,800) seconds, 7 days
|
||||
GENESIS_DELAY: 604800
|
||||
|
||||
# Forking
|
||||
# ---------------------------------------------------------------
|
||||
# Some forks are disabled for now:
|
||||
# - These may be re-assigned to another fork-version later
|
||||
# - Temporarily set to max uint64 value: 2**64 - 1
|
||||
|
||||
# Altair
|
||||
ALTAIR_FORK_VERSION: 0x01000000
|
||||
ALTAIR_FORK_EPOCH: 74240 # Oct 27, 2021, 10:56:23am UTC
|
||||
# Bellatrix
|
||||
BELLATRIX_FORK_VERSION: 0x02000000
|
||||
BELLATRIX_FORK_EPOCH: 144896 # Sept 6, 2022, 11:34:47am UTC
|
||||
# Capella
|
||||
CAPELLA_FORK_VERSION: 0x03000000
|
||||
CAPELLA_FORK_EPOCH: 194048 # April 12, 2023, 10:27:35pm UTC
|
||||
# Deneb
|
||||
DENEB_FORK_VERSION: 0x04000000
|
||||
DENEB_FORK_EPOCH: 269568 # March 13, 2024, 01:55:35pm UTC
|
||||
# Electra
|
||||
ELECTRA_FORK_VERSION: 0x05000000
|
||||
ELECTRA_FORK_EPOCH: 364032 # May 7, 2025, 10:05:11am UTC
|
||||
# Fulu
|
||||
FULU_FORK_VERSION: 0x06000000
|
||||
FULU_FORK_EPOCH: 411392 # December 3, 2025, 09:49:11pm UTC
|
||||
# Gloas
|
||||
GLOAS_FORK_VERSION: 0x07000000
|
||||
GLOAS_FORK_EPOCH: 18446744073709551615
|
||||
# Heze
|
||||
HEZE_FORK_VERSION: 0x08000000
|
||||
HEZE_FORK_EPOCH: 18446744073709551615
|
||||
# EIP7928
|
||||
EIP7928_FORK_VERSION: 0xe7928000 # temporary stub
|
||||
EIP7928_FORK_EPOCH: 18446744073709551615
|
||||
|
||||
# Time parameters
|
||||
# ---------------------------------------------------------------
|
||||
# 12000 milliseconds
|
||||
SLOT_DURATION_MS: 12000
|
||||
# 14 (estimate from Eth1 mainnet)
|
||||
SECONDS_PER_ETH1_BLOCK: 14
|
||||
# 2**8 (= 256) epochs
|
||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
|
||||
# 2**8 (= 256) epochs
|
||||
SHARD_COMMITTEE_PERIOD: 256
|
||||
# 2**11 (= 2,048) Eth1 blocks
|
||||
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
|
||||
|
||||
# Gloas
|
||||
# 2**6 (= 64) epochs
|
||||
MIN_BUILDER_WITHDRAWABILITY_DELAY: 64
|
||||
# 2500 basis points, 25% of SLOT_DURATION_MS
|
||||
ATTESTATION_DUE_BPS_GLOAS: 2500
|
||||
# 5000 basis points, 50% of SLOT_DURATION_MS
|
||||
AGGREGATE_DUE_BPS_GLOAS: 5000
|
||||
# 2500 basis points, 25% of SLOT_DURATION_MS
|
||||
SYNC_MESSAGE_DUE_BPS_GLOAS: 2500
|
||||
# 5000 basis points, 50% of SLOT_DURATION_MS
|
||||
CONTRIBUTION_DUE_BPS_GLOAS: 5000
|
||||
# 7500 basis points, 75% of SLOT_DURATION_MS
|
||||
PAYLOAD_ATTESTATION_DUE_BPS: 7500
|
||||
|
||||
# Heze
|
||||
# 7500 basis points, 75% of SLOT_DURATION_MS
|
||||
VIEW_FREEZE_CUTOFF_BPS: 7500
|
||||
# 6667 basis points, ~67% of SLOT_DURATION_MS
|
||||
INCLUSION_LIST_SUBMISSION_DUE_BPS: 6667
|
||||
# 9167 basis points, ~92% of SLOT_DURATION_MS
|
||||
PROPOSER_INCLUSION_LIST_CUTOFF_BPS: 9167
|
||||
|
||||
# Validator cycle
|
||||
# ---------------------------------------------------------------
|
||||
# 2**2 (= 4)
|
||||
INACTIVITY_SCORE_BIAS: 4
|
||||
# 2**4 (= 16)
|
||||
INACTIVITY_SCORE_RECOVERY_RATE: 16
|
||||
# 2**4 * 10**9 (= 16,000,000,000) Gwei
|
||||
EJECTION_BALANCE: 16000000000
|
||||
# 2**2 (= 4) validators
|
||||
MIN_PER_EPOCH_CHURN_LIMIT: 4
|
||||
# 2**16 (= 65,536)
|
||||
CHURN_LIMIT_QUOTIENT: 65536
|
||||
|
||||
# Deneb
|
||||
# 2**3 (= 8) (*deprecated*)
|
||||
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8
|
||||
|
||||
# Electra
|
||||
# 2**7 * 10**9 (= 128,000,000,000) Gwei
|
||||
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000
|
||||
# 2**8 * 10**9 (= 256,000,000,000) Gwei
|
||||
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 256000000000
|
||||
|
||||
# Fork choice
|
||||
# ---------------------------------------------------------------
|
||||
# 40%
|
||||
PROPOSER_SCORE_BOOST: 40
|
||||
# 20%
|
||||
REORG_HEAD_WEIGHT_THRESHOLD: 20
|
||||
# 160%
|
||||
REORG_PARENT_WEIGHT_THRESHOLD: 160
|
||||
# 2 epochs
|
||||
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2
|
||||
|
||||
# Deposit contract
|
||||
# ---------------------------------------------------------------
|
||||
# Ethereum PoW Mainnet
|
||||
DEPOSIT_CHAIN_ID: 1
|
||||
DEPOSIT_NETWORK_ID: 1
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x00000000219ab540356cBB839Cbe05303d7705Fa
|
||||
|
||||
# Networking
|
||||
# ---------------------------------------------------------------
|
||||
# 10 * 2**20 (= 10,485,760) bytes, 10 MiB
|
||||
MAX_PAYLOAD_SIZE: 10485760
|
||||
# 2**10 (= 1,024) blocks
|
||||
MAX_REQUEST_BLOCKS: 1024
|
||||
# 2**8 (= 256) epochs
|
||||
EPOCHS_PER_SUBNET_SUBSCRIPTION: 256
|
||||
# 2**5 (= 32) slots
|
||||
ATTESTATION_PROPAGATION_SLOT_RANGE: 32
|
||||
# 500ms
|
||||
MAXIMUM_GOSSIP_CLOCK_DISPARITY: 500
|
||||
MESSAGE_DOMAIN_INVALID_SNAPPY: 0x00000000
|
||||
MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
|
||||
# 2 subnets per node
|
||||
SUBNETS_PER_NODE: 2
|
||||
# 2**6 (= 64) subnets
|
||||
ATTESTATION_SUBNET_COUNT: 64
|
||||
# 0 bits
|
||||
ATTESTATION_SUBNET_EXTRA_BITS: 0
|
||||
|
||||
# Deneb
|
||||
# 2**7 (= 128) blocks
|
||||
MAX_REQUEST_BLOCKS_DENEB: 128
|
||||
# 2**12 (= 4,096) epochs
|
||||
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096
|
||||
# 6 subnets
|
||||
BLOB_SIDECAR_SUBNET_COUNT: 6
|
||||
# 6 blobs
|
||||
MAX_BLOBS_PER_BLOCK: 6
|
||||
|
||||
# Electra
|
||||
# 9 subnets
|
||||
BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: 9
|
||||
# 9 blobs
|
||||
MAX_BLOBS_PER_BLOCK_ELECTRA: 9
|
||||
|
||||
# Fulu
|
||||
# 2**7 (= 128) groups
|
||||
NUMBER_OF_CUSTODY_GROUPS: 128
|
||||
# 2**7 (= 128) subnets
|
||||
DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128
|
||||
# 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
|
||||
|
||||
# Gloas
|
||||
# 2**7 (= 128) payloads
|
||||
MAX_REQUEST_PAYLOADS: 128
|
||||
|
||||
# Heze
|
||||
# 2**4 (= 16) inclusion lists
|
||||
MAX_REQUEST_INCLUSION_LIST: 16
|
||||
# 2**13 (= 8,192) bytes
|
||||
MAX_BYTES_PER_INCLUSION_LIST: 8192
|
||||
|
||||
|
||||
# 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
|
||||
220
consensus/types/configs/minimal.yaml
Normal file
220
consensus/types/configs/minimal.yaml
Normal file
@@ -0,0 +1,220 @@
|
||||
# Minimal config
|
||||
|
||||
# Extends the minimal preset
|
||||
PRESET_BASE: 'minimal'
|
||||
|
||||
# Free-form short name of the network that this configuration applies to - known
|
||||
# canonical network names include:
|
||||
# * 'minimal' - spec-testing
|
||||
# Must match the regex: [a-z0-9\-]
|
||||
CONFIG_NAME: 'minimal'
|
||||
|
||||
# Transition
|
||||
# ---------------------------------------------------------------
|
||||
# 2**256-2**10 for testing minimal network
|
||||
TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638912
|
||||
# By default, don't use these params
|
||||
TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000
|
||||
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615
|
||||
|
||||
# Genesis
|
||||
# ---------------------------------------------------------------
|
||||
# [customized] 2**6 (= 64) validators
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 64
|
||||
# [customized] Jan 3, 2020, 12am UTC
|
||||
MIN_GENESIS_TIME: 1578009600
|
||||
# [customized] Initial fork version for minimal
|
||||
GENESIS_FORK_VERSION: 0x00000001
|
||||
# [customized] 5 * 60 (= 300) seconds
|
||||
GENESIS_DELAY: 300
|
||||
|
||||
# Forking
|
||||
# ---------------------------------------------------------------
|
||||
# Values provided for illustrative purposes.
|
||||
# Individual tests/testnets may set different values.
|
||||
|
||||
# [customized] Altair
|
||||
ALTAIR_FORK_VERSION: 0x01000001
|
||||
ALTAIR_FORK_EPOCH: 18446744073709551615
|
||||
# [customized] Bellatrix
|
||||
BELLATRIX_FORK_VERSION: 0x02000001
|
||||
BELLATRIX_FORK_EPOCH: 18446744073709551615
|
||||
# [customized] Capella
|
||||
CAPELLA_FORK_VERSION: 0x03000001
|
||||
CAPELLA_FORK_EPOCH: 18446744073709551615
|
||||
# [customized] Deneb
|
||||
DENEB_FORK_VERSION: 0x04000001
|
||||
DENEB_FORK_EPOCH: 18446744073709551615
|
||||
# [customized] Electra
|
||||
ELECTRA_FORK_VERSION: 0x05000001
|
||||
ELECTRA_FORK_EPOCH: 18446744073709551615
|
||||
# [customized] Fulu
|
||||
FULU_FORK_VERSION: 0x06000001
|
||||
FULU_FORK_EPOCH: 18446744073709551615
|
||||
# [customized] Gloas
|
||||
GLOAS_FORK_VERSION: 0x07000001
|
||||
GLOAS_FORK_EPOCH: 18446744073709551615
|
||||
# [customized] Heze
|
||||
HEZE_FORK_VERSION: 0x08000001
|
||||
HEZE_FORK_EPOCH: 18446744073709551615
|
||||
# [customized] EIP7928
|
||||
EIP7928_FORK_VERSION: 0xe7928001
|
||||
EIP7928_FORK_EPOCH: 18446744073709551615
|
||||
|
||||
# Time parameters
|
||||
# ---------------------------------------------------------------
|
||||
# [customized] 6000 milliseconds
|
||||
SLOT_DURATION_MS: 6000
|
||||
# 14 (estimate from Eth1 mainnet)
|
||||
SECONDS_PER_ETH1_BLOCK: 14
|
||||
# 2**8 (= 256) epochs
|
||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
|
||||
# [customized] 2**6 (= 64) epochs
|
||||
SHARD_COMMITTEE_PERIOD: 64
|
||||
# [customized] 2**4 (= 16) Eth1 blocks
|
||||
ETH1_FOLLOW_DISTANCE: 16
|
||||
# 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
|
||||
|
||||
# Gloas
|
||||
# [customized] 2**1 (= 2) epochs
|
||||
MIN_BUILDER_WITHDRAWABILITY_DELAY: 2
|
||||
# 2500 basis points, 25% of SLOT_DURATION_MS
|
||||
ATTESTATION_DUE_BPS_GLOAS: 2500
|
||||
# 5000 basis points, 50% of SLOT_DURATION_MS
|
||||
AGGREGATE_DUE_BPS_GLOAS: 5000
|
||||
# 2500 basis points, 25% of SLOT_DURATION_MS
|
||||
SYNC_MESSAGE_DUE_BPS_GLOAS: 2500
|
||||
# 5000 basis points, 50% of SLOT_DURATION_MS
|
||||
CONTRIBUTION_DUE_BPS_GLOAS: 5000
|
||||
# 7500 basis points, 75% of SLOT_DURATION_MS
|
||||
PAYLOAD_ATTESTATION_DUE_BPS: 7500
|
||||
|
||||
# Heze
|
||||
# 7500 basis points, 75% of SLOT_DURATION_MS
|
||||
VIEW_FREEZE_CUTOFF_BPS: 7500
|
||||
# 6667 basis points, ~67% of SLOT_DURATION_MS
|
||||
INCLUSION_LIST_SUBMISSION_DUE_BPS: 6667
|
||||
# 9167 basis points, ~92% of SLOT_DURATION_MS
|
||||
PROPOSER_INCLUSION_LIST_CUTOFF_BPS: 9167
|
||||
|
||||
# Validator cycle
|
||||
# ---------------------------------------------------------------
|
||||
# 2**2 (= 4)
|
||||
INACTIVITY_SCORE_BIAS: 4
|
||||
# 2**4 (= 16)
|
||||
INACTIVITY_SCORE_RECOVERY_RATE: 16
|
||||
# 2**4 * 10**9 (= 16,000,000,000) Gwei
|
||||
EJECTION_BALANCE: 16000000000
|
||||
# [customized] 2**1 (= 2) validators
|
||||
MIN_PER_EPOCH_CHURN_LIMIT: 2
|
||||
# [customized] 2**5 (= 32)
|
||||
CHURN_LIMIT_QUOTIENT: 32
|
||||
|
||||
# Deneb
|
||||
# [customized] 2**2 (= 4) (*deprecated*)
|
||||
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 4
|
||||
|
||||
# Electra
|
||||
# [customized] 2**6 * 10**9 (= 64,000,000,000) Gwei
|
||||
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 64000000000
|
||||
# [customized] 2**7 * 10**9 (= 128,000,000,000) Gwei
|
||||
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 128000000000
|
||||
|
||||
# Fork choice
|
||||
# ---------------------------------------------------------------
|
||||
# 40%
|
||||
PROPOSER_SCORE_BOOST: 40
|
||||
# 20%
|
||||
REORG_HEAD_WEIGHT_THRESHOLD: 20
|
||||
# 160%
|
||||
REORG_PARENT_WEIGHT_THRESHOLD: 160
|
||||
# 2 epochs
|
||||
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2
|
||||
|
||||
# Deposit contract
|
||||
# ---------------------------------------------------------------
|
||||
# Ethereum Goerli testnet
|
||||
DEPOSIT_CHAIN_ID: 5
|
||||
DEPOSIT_NETWORK_ID: 5
|
||||
# Configured on a per testnet basis
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890
|
||||
|
||||
# Networking
|
||||
# ---------------------------------------------------------------
|
||||
# 10 * 2**20 (= 10,485,760) bytes, 10 MiB
|
||||
MAX_PAYLOAD_SIZE: 10485760
|
||||
# 2**10 (= 1,024) blocks
|
||||
MAX_REQUEST_BLOCKS: 1024
|
||||
# 2**8 (= 256) epochs
|
||||
EPOCHS_PER_SUBNET_SUBSCRIPTION: 256
|
||||
# 2**5 (= 32) slots
|
||||
ATTESTATION_PROPAGATION_SLOT_RANGE: 32
|
||||
# 500ms
|
||||
MAXIMUM_GOSSIP_CLOCK_DISPARITY: 500
|
||||
MESSAGE_DOMAIN_INVALID_SNAPPY: 0x00000000
|
||||
MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
|
||||
# 2 subnets per node
|
||||
SUBNETS_PER_NODE: 2
|
||||
# 2**6 (= 64) subnets
|
||||
ATTESTATION_SUBNET_COUNT: 64
|
||||
# 0 bits
|
||||
ATTESTATION_SUBNET_EXTRA_BITS: 0
|
||||
|
||||
# Deneb
|
||||
# 2**7 (= 128) blocks
|
||||
MAX_REQUEST_BLOCKS_DENEB: 128
|
||||
# 2**12 (= 4,096) epochs
|
||||
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096
|
||||
# 6 subnets
|
||||
BLOB_SIDECAR_SUBNET_COUNT: 6
|
||||
# 6 blobs
|
||||
MAX_BLOBS_PER_BLOCK: 6
|
||||
|
||||
# Electra
|
||||
# 9 subnets
|
||||
BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: 9
|
||||
# 9 blobs
|
||||
MAX_BLOBS_PER_BLOCK_ELECTRA: 9
|
||||
|
||||
# Fulu
|
||||
# 2**7 (= 128) groups
|
||||
NUMBER_OF_CUSTODY_GROUPS: 128
|
||||
# 2**7 (= 128) subnets
|
||||
DATA_COLUMN_SIDECAR_SUBNET_COUNT: 128
|
||||
# 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
|
||||
|
||||
# Gloas
|
||||
# 2**7 (= 128) payloads
|
||||
MAX_REQUEST_PAYLOADS: 128
|
||||
|
||||
# Heze
|
||||
# 2**4 (= 16) inclusion lists
|
||||
MAX_REQUEST_INCLUSION_LIST: 16
|
||||
# 2**13 (= 8,192) bytes
|
||||
MAX_BYTES_PER_INCLUSION_LIST: 8192
|
||||
|
||||
|
||||
# Blob Scheduling
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
BLOB_SCHEDULE: []
|
||||
@@ -96,8 +96,7 @@ pub struct ChainSpec {
|
||||
* Time parameters
|
||||
*/
|
||||
pub genesis_delay: u64,
|
||||
// TODO deprecate seconds_per_slot
|
||||
pub seconds_per_slot: u64,
|
||||
seconds_per_slot: u64,
|
||||
// Private so that this value can't get changed except via the `set_slot_duration_ms` function.
|
||||
slot_duration_ms: u64,
|
||||
pub min_attestation_inclusion_delay: u64,
|
||||
@@ -914,6 +913,7 @@ impl ChainSpec {
|
||||
/// Set the duration of a slot (in ms).
|
||||
pub fn set_slot_duration_ms<E: EthSpec>(mut self, slot_duration_ms: u64) -> Self {
|
||||
self.slot_duration_ms = slot_duration_ms;
|
||||
self.seconds_per_slot = slot_duration_ms.saturating_div(1000);
|
||||
self.compute_derived_values::<E>()
|
||||
}
|
||||
|
||||
@@ -1235,7 +1235,7 @@ impl ChainSpec {
|
||||
gloas_fork_epoch: None,
|
||||
builder_payment_threshold_numerator: 6,
|
||||
builder_payment_threshold_denominator: 10,
|
||||
min_builder_withdrawability_delay: Epoch::new(4096),
|
||||
min_builder_withdrawability_delay: Epoch::new(64),
|
||||
max_request_payloads: 128,
|
||||
|
||||
/*
|
||||
@@ -1381,6 +1381,7 @@ impl ChainSpec {
|
||||
// Gloas
|
||||
gloas_fork_version: [0x07, 0x00, 0x00, 0x01],
|
||||
gloas_fork_epoch: None,
|
||||
min_builder_withdrawability_delay: Epoch::new(2),
|
||||
|
||||
/*
|
||||
* Derived time values (set by `compute_derived_values()`)
|
||||
@@ -1391,6 +1392,9 @@ impl ChainSpec {
|
||||
sync_message_due: Duration::from_millis(1999),
|
||||
contribution_and_proof_due: Duration::from_millis(4000),
|
||||
|
||||
// Networking Fulu
|
||||
blob_schedule: BlobSchedule::default(),
|
||||
|
||||
// Other
|
||||
network_id: 2, // lighthouse testnet network id
|
||||
deposit_chain_id: 5,
|
||||
@@ -1631,7 +1635,7 @@ impl ChainSpec {
|
||||
gloas_fork_epoch: None,
|
||||
builder_payment_threshold_numerator: 6,
|
||||
builder_payment_threshold_denominator: 10,
|
||||
min_builder_withdrawability_delay: Epoch::new(4096),
|
||||
min_builder_withdrawability_delay: Epoch::new(64),
|
||||
max_request_payloads: 128,
|
||||
|
||||
/*
|
||||
@@ -1908,8 +1912,9 @@ pub struct Config {
|
||||
#[serde(deserialize_with = "deserialize_fork_epoch")]
|
||||
pub gloas_fork_epoch: Option<MaybeQuoted<Epoch>>,
|
||||
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
seconds_per_slot: u64,
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
seconds_per_slot: Option<MaybeQuoted<u64>>,
|
||||
#[serde(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
slot_duration_ms: Option<MaybeQuoted<u64>>,
|
||||
@@ -2064,6 +2069,10 @@ pub struct Config {
|
||||
#[serde(default = "default_contribution_due_bps")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
contribution_due_bps: u64,
|
||||
|
||||
#[serde(default = "default_min_builder_withdrawability_delay")]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
min_builder_withdrawability_delay: u64,
|
||||
}
|
||||
|
||||
fn default_bellatrix_fork_version() -> [u8; 4] {
|
||||
@@ -2289,6 +2298,10 @@ const fn default_contribution_due_bps() -> u64 {
|
||||
6667
|
||||
}
|
||||
|
||||
const fn default_min_builder_withdrawability_delay() -> u64 {
|
||||
64
|
||||
}
|
||||
|
||||
fn max_blocks_by_root_request_common(max_request_blocks: u64) -> usize {
|
||||
let max_request_blocks = max_request_blocks as usize;
|
||||
RuntimeVariableList::<Hash256>::new(
|
||||
@@ -2459,7 +2472,9 @@ impl Config {
|
||||
.gloas_fork_epoch
|
||||
.map(|epoch| MaybeQuoted { value: epoch }),
|
||||
|
||||
seconds_per_slot: spec.seconds_per_slot,
|
||||
seconds_per_slot: Some(MaybeQuoted {
|
||||
value: spec.seconds_per_slot,
|
||||
}),
|
||||
slot_duration_ms: Some(MaybeQuoted {
|
||||
value: spec.slot_duration_ms,
|
||||
}),
|
||||
@@ -2525,6 +2540,8 @@ impl Config {
|
||||
aggregate_due_bps: spec.aggregate_due_bps,
|
||||
sync_message_due_bps: spec.sync_message_due_bps,
|
||||
contribution_due_bps: spec.contribution_due_bps,
|
||||
|
||||
min_builder_withdrawability_delay: spec.min_builder_withdrawability_delay.as_u64(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2616,12 +2633,21 @@ impl Config {
|
||||
aggregate_due_bps,
|
||||
sync_message_due_bps,
|
||||
contribution_due_bps,
|
||||
min_builder_withdrawability_delay,
|
||||
} = self;
|
||||
|
||||
if preset_base != E::spec_name().to_string().as_str() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Fail if seconds_per_slot and slot_duration_ms are both set but are inconsistent.
|
||||
if let (Some(seconds_per_slot), Some(slot_duration_ms)) =
|
||||
(seconds_per_slot, slot_duration_ms)
|
||||
&& seconds_per_slot.value.saturating_mul(1000) != slot_duration_ms.value
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let spec = ChainSpec {
|
||||
config_name: config_name.clone(),
|
||||
min_genesis_active_validator_count,
|
||||
@@ -2642,10 +2668,12 @@ impl Config {
|
||||
fulu_fork_version,
|
||||
gloas_fork_version,
|
||||
gloas_fork_epoch: gloas_fork_epoch.map(|q| q.value),
|
||||
seconds_per_slot,
|
||||
seconds_per_slot: seconds_per_slot
|
||||
.map(|q| q.value)
|
||||
.or_else(|| slot_duration_ms.and_then(|q| q.value.checked_div(1000)))?,
|
||||
slot_duration_ms: slot_duration_ms
|
||||
.map(|q| q.value)
|
||||
.unwrap_or_else(|| seconds_per_slot.saturating_mul(1000)),
|
||||
.or_else(|| seconds_per_slot.map(|q| q.value.saturating_mul(1000)))?,
|
||||
seconds_per_eth1_block,
|
||||
min_validator_withdrawability_delay,
|
||||
shard_committee_period,
|
||||
@@ -2705,6 +2733,8 @@ impl Config {
|
||||
sync_message_due_bps,
|
||||
contribution_due_bps,
|
||||
|
||||
min_builder_withdrawability_delay: Epoch::new(min_builder_withdrawability_delay),
|
||||
|
||||
..chain_spec.clone()
|
||||
};
|
||||
Some(spec.compute_derived_values::<E>())
|
||||
@@ -2853,6 +2883,9 @@ mod yaml_tests {
|
||||
use super::*;
|
||||
use crate::core::MinimalEthSpec;
|
||||
use paste::paste;
|
||||
use std::collections::BTreeSet;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
@@ -2902,6 +2935,67 @@ mod yaml_tests {
|
||||
assert_eq!(from, yamlconfig);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slot_duration_fallback_both_fields() {
|
||||
let mainnet = ChainSpec::mainnet();
|
||||
let mut config = Config::from_chain_spec::<MainnetEthSpec>(&mainnet);
|
||||
config.seconds_per_slot = Some(MaybeQuoted { value: 12 });
|
||||
config.slot_duration_ms = Some(MaybeQuoted { value: 12000 });
|
||||
let spec = config
|
||||
.apply_to_chain_spec::<MainnetEthSpec>(&mainnet)
|
||||
.unwrap();
|
||||
assert_eq!(spec.seconds_per_slot, 12);
|
||||
assert_eq!(spec.slot_duration_ms, 12000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slot_duration_fallback_both_fields_inconsistent() {
|
||||
let mainnet = ChainSpec::mainnet();
|
||||
let mut config = Config::from_chain_spec::<MainnetEthSpec>(&mainnet);
|
||||
config.seconds_per_slot = Some(MaybeQuoted { value: 10 });
|
||||
config.slot_duration_ms = Some(MaybeQuoted { value: 12000 });
|
||||
assert_eq!(config.apply_to_chain_spec::<MainnetEthSpec>(&mainnet), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slot_duration_fallback_seconds_only() {
|
||||
let mainnet = ChainSpec::mainnet();
|
||||
let mut config = Config::from_chain_spec::<MainnetEthSpec>(&mainnet);
|
||||
config.seconds_per_slot = Some(MaybeQuoted { value: 12 });
|
||||
config.slot_duration_ms = None;
|
||||
let spec = config
|
||||
.apply_to_chain_spec::<MainnetEthSpec>(&mainnet)
|
||||
.unwrap();
|
||||
assert_eq!(spec.seconds_per_slot, 12);
|
||||
assert_eq!(spec.slot_duration_ms, 12000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slot_duration_fallback_ms_only() {
|
||||
let mainnet = ChainSpec::mainnet();
|
||||
let mut config = Config::from_chain_spec::<MainnetEthSpec>(&mainnet);
|
||||
config.seconds_per_slot = None;
|
||||
config.slot_duration_ms = Some(MaybeQuoted { value: 12000 });
|
||||
let spec = config
|
||||
.apply_to_chain_spec::<MainnetEthSpec>(&mainnet)
|
||||
.unwrap();
|
||||
assert_eq!(spec.seconds_per_slot, 12);
|
||||
assert_eq!(spec.slot_duration_ms, 12000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slot_duration_fallback_neither() {
|
||||
let mainnet = ChainSpec::mainnet();
|
||||
let mut config = Config::from_chain_spec::<MainnetEthSpec>(&mainnet);
|
||||
config.seconds_per_slot = None;
|
||||
config.slot_duration_ms = None;
|
||||
assert!(
|
||||
config
|
||||
.apply_to_chain_spec::<MainnetEthSpec>(&mainnet)
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blob_schedule_max_blobs_per_block() {
|
||||
let spec_contents = r#"
|
||||
@@ -3375,7 +3469,6 @@ mod yaml_tests {
|
||||
// Test slot duration
|
||||
let slot_duration = spec.get_slot_duration();
|
||||
assert_eq!(slot_duration, Duration::from_millis(12000));
|
||||
assert_eq!(slot_duration, Duration::from_secs(spec.seconds_per_slot));
|
||||
|
||||
// Test edge cases with custom spec
|
||||
let mut custom_spec = spec.clone();
|
||||
@@ -3485,4 +3578,133 @@ mod yaml_tests {
|
||||
spec.attestation_due_bps = 15000;
|
||||
spec.compute_derived_values::<MainnetEthSpec>();
|
||||
}
|
||||
|
||||
fn configs_base_path() -> PathBuf {
|
||||
env::var("CARGO_MANIFEST_DIR")
|
||||
.expect("should know manifest dir")
|
||||
.parse::<PathBuf>()
|
||||
.expect("should parse manifest dir as path")
|
||||
.join("configs")
|
||||
}
|
||||
|
||||
/// Upstream config keys that Lighthouse intentionally does not include in its
|
||||
/// `Config` struct. These are forks/features not yet implemented. Update this
|
||||
/// list as new forks are added.
|
||||
const UPSTREAM_KEYS_NOT_IN_LIGHTHOUSE: &[&str] = &[
|
||||
// Forks not yet implemented
|
||||
"HEZE_FORK_VERSION",
|
||||
"HEZE_FORK_EPOCH",
|
||||
"EIP7928_FORK_VERSION",
|
||||
"EIP7928_FORK_EPOCH",
|
||||
// Gloas params not yet in Config
|
||||
"ATTESTATION_DUE_BPS_GLOAS",
|
||||
"AGGREGATE_DUE_BPS_GLOAS",
|
||||
"SYNC_MESSAGE_DUE_BPS_GLOAS",
|
||||
"CONTRIBUTION_DUE_BPS_GLOAS",
|
||||
"PAYLOAD_ATTESTATION_DUE_BPS",
|
||||
"MAX_REQUEST_PAYLOADS",
|
||||
// Gloas fork choice params not yet in Config
|
||||
"REORG_HEAD_WEIGHT_THRESHOLD",
|
||||
"REORG_PARENT_WEIGHT_THRESHOLD",
|
||||
"REORG_MAX_EPOCHS_SINCE_FINALIZATION",
|
||||
// Heze networking
|
||||
"VIEW_FREEZE_CUTOFF_BPS",
|
||||
"INCLUSION_LIST_SUBMISSION_DUE_BPS",
|
||||
"PROPOSER_INCLUSION_LIST_CUTOFF_BPS",
|
||||
"MAX_REQUEST_INCLUSION_LIST",
|
||||
"MAX_BYTES_PER_INCLUSION_LIST",
|
||||
];
|
||||
|
||||
/// Compare a `ChainSpec` against an upstream consensus-specs config YAML file.
|
||||
///
|
||||
/// 1. Extracts keys from the raw YAML text (to avoid yaml_serde's inability
|
||||
/// to parse integers > u64 into `Value`/`Mapping` types) and checks that
|
||||
/// every key is either known to `Config` or explicitly listed in
|
||||
/// `UPSTREAM_KEYS_NOT_IN_LIGHTHOUSE`.
|
||||
/// 2. Deserializes the upstream YAML as `Config` (which has custom
|
||||
/// deserializers for large values like `TERMINAL_TOTAL_DIFFICULTY`) and
|
||||
/// compares against `Config::from_chain_spec`.
|
||||
fn config_test<E: EthSpec>(spec: &ChainSpec, config_name: &str) {
|
||||
let file_path = configs_base_path().join(format!("{config_name}.yaml"));
|
||||
let upstream_yaml = std::fs::read_to_string(&file_path)
|
||||
.unwrap_or_else(|e| panic!("failed to read {}: {e}", file_path.display()));
|
||||
|
||||
// Extract top-level keys from the raw YAML text. We can't parse as
|
||||
// yaml_serde::Mapping because yaml_serde cannot represent integers
|
||||
// exceeding u64 (e.g. TERMINAL_TOTAL_DIFFICULTY). Config YAML uses a
|
||||
// simple `KEY: value` format with no indentation for top-level keys.
|
||||
let upstream_keys: BTreeSet<String> = upstream_yaml
|
||||
.lines()
|
||||
.filter_map(|line| {
|
||||
// Skip comments, blank lines, and indented lines (nested YAML).
|
||||
if line.is_empty()
|
||||
|| line.starts_with('#')
|
||||
|| line.starts_with(' ')
|
||||
|| line.starts_with('\t')
|
||||
{
|
||||
return None;
|
||||
}
|
||||
line.split(':').next().map(|k| k.to_string())
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Get the set of keys that Config knows about by serializing and collecting
|
||||
// keys. Also include keys for optional fields that may be skipped during
|
||||
// serialization (e.g. CONFIG_NAME).
|
||||
let our_config = Config::from_chain_spec::<E>(spec);
|
||||
let our_yaml = yaml_serde::to_string(&our_config).expect("failed to serialize Config");
|
||||
let our_mapping: yaml_serde::Mapping =
|
||||
yaml_serde::from_str(&our_yaml).expect("failed to re-parse our Config");
|
||||
let mut known_keys: BTreeSet<String> = our_mapping
|
||||
.keys()
|
||||
.filter_map(|k| k.as_str().map(String::from))
|
||||
.collect();
|
||||
// Fields that Config knows but may skip during serialization.
|
||||
known_keys.insert("CONFIG_NAME".to_string());
|
||||
|
||||
// Check for upstream keys that our Config doesn't know about.
|
||||
let mut missing_keys: Vec<&String> = upstream_keys
|
||||
.iter()
|
||||
.filter(|k| {
|
||||
!known_keys.contains(k.as_str())
|
||||
&& !UPSTREAM_KEYS_NOT_IN_LIGHTHOUSE.contains(&k.as_str())
|
||||
})
|
||||
.collect();
|
||||
missing_keys.sort();
|
||||
|
||||
assert!(
|
||||
missing_keys.is_empty(),
|
||||
"Upstream {config_name} config has keys not present in Lighthouse Config \
|
||||
(add to Config or to UPSTREAM_KEYS_NOT_IN_LIGHTHOUSE): {missing_keys:?}"
|
||||
);
|
||||
|
||||
// Compare values for all fields Config knows about.
|
||||
let mut upstream_config: Config = yaml_serde::from_str(&upstream_yaml)
|
||||
.unwrap_or_else(|e| panic!("failed to parse {config_name} as Config: {e}"));
|
||||
|
||||
// CONFIG_NAME is network metadata (not a spec parameter), so align it
|
||||
// before comparing.
|
||||
upstream_config.config_name = our_config.config_name.clone();
|
||||
// SECONDS_PER_SLOT is deprecated upstream but we still emit it, so
|
||||
// fill it in if the upstream YAML omitted it.
|
||||
if upstream_config.seconds_per_slot.is_none() {
|
||||
upstream_config.seconds_per_slot = our_config.seconds_per_slot;
|
||||
}
|
||||
assert_eq!(
|
||||
upstream_config, our_config,
|
||||
"Config mismatch for {config_name}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mainnet_config_consistent() {
|
||||
let spec = ChainSpec::mainnet();
|
||||
config_test::<MainnetEthSpec>(&spec, "mainnet");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn minimal_config_consistent() {
|
||||
let spec = ChainSpec::minimal();
|
||||
config_test::<MinimalEthSpec>(&spec, "minimal");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user