Skip to content

Nimbus rejects custom network constants from config.yaml (SECONDS_PER_SLOT=6) on existing private testnet - requesting support! #7525

@SyedMuhamadYasir

Description

@SyedMuhamadYasir

Summary

We run a private testnet with custom consensus constants (short slot time and a few other overrides). Lighthouse accepts the config.yaml overlay and runs fine. Nimbus v25.9.0 refuses to start with a PresetFileError, indicating it won’t accept those overrides from config.yaml. We’re trying to add Nimbus clients without changing the running network.

here's the screenshot,

Image

We’re looking for either:

  • a supported way to make Nimbus work with our existing testnet (runtime flag/preset loading), or
  • an official recipe to build Nimbus against a custom preset matching our constants (maintainably, across future releases).

Environment

  • Nimbus: Nimbus beacon node v25.9.0-660ebe-stateofus (Nim 2.2.4)
  • OS/arch: Linux (amd64)
  • Execution client: Reth reth-ethereum-cli Version: 1.6.0
  • Network: Private testnet (already running in production for our course)
  • Checkpoint endpoint: <http://YOUR_CHECKPOINT_HOST:PORT> (returns healthy responses for Lighthouse)

What we’re trying to do

Run Nimbus on the existing testnet using our network config directory and checkpoint sync, similar to Lighthouse.

Launch command (flat style, redacted paths):

nimbus_beacon_node \
  --network="/path/to/consensus" \
  --data-dir="/path/to/beacon" \
  --el="http://0.0.0.0:8558" \
  --jwt-secret="/path/to/geth_or_reth/jwtsecret" \
  --udp-port=9006 \
  --tcp-port=9006 \
  --nat="extip:xxx.xxx.xxx.xxx" \
  --bootstrap-node="<ENR(s)>" \
  --rest \
  --rest-address=127.0.0.1 \
  --rest-port=8006 \
  --suggested-fee-recipient="0x..." \
  --trusted-node-url="http://YOUR_CHECKPOINT_HOST:PORT" \
  --with-deposit-snapshot \
  --backfill=false

Network config (config.yaml)

# Extends the mainnet preset
PRESET_BASE: mainnet
CONFIG_NAME: hoodiUZH
# Genesis
# ---------------------------------------------------------------
# `2**14` (= 16,384)
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16
# 2025-Mar-17 12:00:00 PM UTC
MIN_GENESIS_TIME: 1758021802
GENESIS_FORK_VERSION: 0x42424242
GENESIS_DELAY: 60
# 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: 0x01100000
ALTAIR_FORK_EPOCH: 0
# Merge
BELLATRIX_FORK_VERSION: 0x02200000
BELLATRIX_FORK_EPOCH: 0
TERMINAL_TOTAL_DIFFICULTY: 0
TERMINAL_BLOCK_HASH: 0x6e7c0ff2df5d524d346039d350a6f588b2605b660cc503811b9e02740a4e8c27
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 0
# Capella
CAPELLA_FORK_VERSION: 0x04400000
CAPELLA_FORK_EPOCH: 0
# DENEB
DENEB_FORK_VERSION: 0x05500000
DENEB_FORK_EPOCH: 0
# Electra
ELECTRA_FORK_VERSION: 0x06600000
ELECTRA_FORK_EPOCH: 0
# Time parameters
# ---------------------------------------------------------------
# 12 seconds
SECONDS_PER_SLOT: 6
# 14 (estimate from Eth1 mainnet)
SECONDS_PER_ETH1_BLOCK: 10
# 2**8 (= 256) epochs ~27 hours
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 2
# 2**8 (= 256) epochs ~27 hours
SHARD_COMMITTEE_PERIOD: 128
# 2**11 (= 2,048) Eth1 blocks ~8 hours
ETH1_FOLLOW_DISTANCE: 2048
# 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)
MIN_PER_EPOCH_CHURN_LIMIT: 1
# 2**16 (= 65,536)
CHURN_LIMIT_QUOTIENT: 2
# [New in Deneb:EIP7514] 2**3 (= 8)
MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 100
# Fork choice
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40
# 20%
REORG_HEAD_WEIGHT_THRESHOLD: 10
# 160%
REORG_PARENT_WEIGHT_THRESHOLD: 160
# `2` epochs
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 8
# Deposit contract
# ---------------------------------------------------------------
DEPOSIT_CHAIN_ID: 8888
DEPOSIT_NETWORK_ID: 8888
DEPOSIT_CONTRACT_ADDRESS: 0x4242424242424242424242424242424242424242
# Networking
# ---------------------------------------------------------------
# `10 * 2**20` (= 10485760, 10 MiB)
MAX_PAYLOAD_SIZE: 10485760
# `2**10` (= 1024)
MAX_REQUEST_BLOCKS: 256
# `2**8` (= 256)
EPOCHS_PER_SUBNET_SUBSCRIPTION: 64
# `MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2` (= 33024, ~5 months)
MIN_EPOCHS_FOR_BLOCK_REQUESTS: 33024
# 5s
TTFB_TIMEOUT: 10
# 10s
RESP_TIMEOUT: 20
ATTESTATION_PROPAGATION_SLOT_RANGE: 32
# 500ms
MAXIMUM_GOSSIP_CLOCK_DISPARITY: 1000
MESSAGE_DOMAIN_INVALID_SNAPPY: 0x00000000
MESSAGE_DOMAIN_VALID_SNAPPY: 0x01000000
# 2 subnets per node
SUBNETS_PER_NODE: 1
# 2**8 (= 64)
ATTESTATION_SUBNET_COUNT: 64
ATTESTATION_SUBNET_EXTRA_BITS: 0
# ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS
ATTESTATION_SUBNET_PREFIX_BITS: 6
# Deneb
# `2**7` (=128)
MAX_REQUEST_BLOCKS_DENEB: 128
# MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
MAX_REQUEST_BLOB_SIDECARS: 768
# `2**12` (= 4096 epochs, ~18 days)
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096
# `6`
BLOB_SIDECAR_SUBNET_COUNT: 6
# `uint64(6)`
MAX_BLOBS_PER_BLOCK: 6
# Electra
# 2**7 * 10**9 (= 128,000,000,000)
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 9600000000000
# 2**8 * 10**9 (= 256,000,000,000)
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 9600000000000
# `9`
BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: 9
# `uint64(9)`
MAX_BLOBS_PER_BLOCK_ELECTRA: 9
# MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA
MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 1152

Actual behavior / logs

Nimbus exits immediately with:

FAT Cannot load network: PresetFileError
    msg="Cannot override config (required: SECONDS_PER_SLOT==12 - config: SECONDS_PER_SLOT=6)"
    networkName=/path/to/consensus

Expected behavior

  1. Nimbus accepts custom constants provided via config.yaml (similar to Lighthouse’s behavior), or
  2. Nimbus documents an official, supported build-time method to set these constants (e.g., preset files or -d:CONST=… overrides) so we can ship a Nimbus binary that matches our already-running network in a maintainable way.

Why we can’t change the network

  • The testnet is already live with students participating.
  • We need to add Nimbus as an additional client; we cannot re-genesis or switch the network to mainnet/minimal presets at this stage.

What works today

  • Lighthouse runs with the same config.yaml and joins our testnet (produces/attests).
  • Reth (EL) + Lighthouse are currently our mains, but Lighthouse is heavier on student laptops; Nimbus would be better for resource constraints.

Questions

  1. Is there a supported runtime approach to run Nimbus against a network with non-standard preset constants, without changing the network?

  2. If the correct path is compile-time customization:

    • What’s the recommended + documented recipe? (e.g., adding a custom preset directory and building Nimbus to use it; or passing -d:SECONDS_PER_SLOT=... / similar defines.)
    • Which constants are safely overridable via NIMFLAGS, and which require editing preset files?
    • Any caveats we should be aware of across releases so we can upgrade Nimbus versions cleanly while keeping our testnet constants?
  3. Would Nimbus consider a feature/flag to accept explicit constant overrides from config.yaml at operator risk (off by default), to align behavior with CLs that allow this? Even a “strict/unsafe” toggle would help operators of existing devnets.

Impact

  • University course: we need a lightweight CL for dozens of student laptops.
  • We’d like Nimbus to join the existing network without a network reset.
  • Clear guidance unlocks adoption and prevents forks/divergence.

Attachments

  • Full config.yaml: provided above
  • Full Nimbus startup logs (screenshot provided)

Thanks for taking a look. Any guidance or a pointer to the recommended “custom preset” workflow would be hugely appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions