Add metadata for the Holesky network (#5337)

* Add metadata for the Holesky network

* Add copyright banner to the new Nim module

* Working version

* Bump Chronos to fix downloading from Github
* Add checksum check of the downloaded file
* Clean up debugging code and obsolete imports
This commit is contained in:
zah 2023-09-08 08:53:27 +03:00 committed by GitHub
parent c5a79a6f8f
commit 53589b5a7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 306 additions and 103 deletions

7
.gitmodules vendored
View File

@ -59,7 +59,7 @@
path = vendor/nim-chronos
url = https://github.com/status-im/nim-chronos.git
ignore = untracked
branch = master
branch = nimbus-v23.9.0
[submodule "vendor/nim-chronicles"]
path = vendor/nim-chronicles
url = https://github.com/status-im/nim-chronicles.git
@ -220,3 +220,8 @@
url = https://github.com/arnetheduck/nim-results.git
ignore = untracked
branch = master
[submodule "vendor/holesky"]
path = vendor/holesky
url = https://github.com/eth-clients/holesky
ignore = untracked
branch = main

View File

@ -1402,6 +1402,7 @@ proc exchangeConfigWithSingleEL(m: ELManager, connection: ELConnection) {.async.
of rinkeby: 4.Quantity
of goerli: 5.Quantity
of sepolia: 11155111.Quantity # https://chainid.network/
of holesky: 17000.Quantity
if expectedChain != providerChain:
warn "The specified EL client is connected to a different chain",
url = connection.engineUrl,

View File

@ -13,7 +13,7 @@ import
web3/[ethtypes, conversions],
chronicles,
eth/common/eth_types_json_serialization,
../spec/eth2_ssz_serialization
../spec/[eth2_ssz_serialization, forks]
# TODO(zah):
# We can compress the embedded states with snappy before embedding them here.
@ -45,6 +45,29 @@ type
rinkeby
goerli
sepolia
holesky
GenesisMetadataKind* = enum
NoGenesis
UserSuppliedFile
BakedIn
BakedInUrl
DownloadInfo* = object
url: string
digest: Eth2Digest
GenesisMetadata* = object
case kind*: GenesisMetadataKind
of NoGenesis:
discard
of UserSuppliedFile:
path*: string
of BakedIn:
networkName*: string
of BakedInUrl:
url*: string
digest*: Eth2Digest
Eth2NetworkMetadata* = object
case incompatible*: bool
@ -62,22 +85,13 @@ type
depositContractBlock*: uint64
depositContractBlockHash*: Eth2Digest
# `genesisData` will have `len == 0` for networks with a still
# unknown genesis state.
when incbinEnabled:
genesisData*: seq[byte]
else:
genesisData*: string
genesis*: GenesisMetadata
genesisDepositsSnapshot*: string
else:
incompatibilityDesc*: string
template genesisBytes*(metadata: Eth2NetworkMetadata): auto =
when incbinEnabled:
metadata.genesisData
else:
metadata.genesisData.toOpenArrayByte(0, metadata.genesisData.high)
func hasGenesis*(metadata: Eth2NetworkMetadata): bool =
metadata.genesis.kind != NoGenesis
proc readBootstrapNodes*(path: string): seq[string] {.raises: [IOError].} =
# Read a list of ENR values from a YAML file containing a flat list of entries
@ -98,7 +112,11 @@ proc readBootEnr*(path: string): seq[string] {.raises: [IOError].} =
@[]
proc loadEth2NetworkMetadata*(
path: string, eth1Network = none(Eth1Network), loadGenesis = true):
path: string,
eth1Network = none(Eth1Network),
isCompileTime = false,
downloadGenesisFrom = none(DownloadInfo),
useBakedInGenesis = none(string)):
Eth2NetworkMetadata {.raises: [CatchableError].} =
# Load data in eth2-networks format
# https://github.com/eth-clients/eth2-networks
@ -166,11 +184,6 @@ proc loadEth2NetworkMetadata*(
readBootstrapNodes(bootstrapNodesPath) &
readBootEnr(bootEnrPath))
genesisData = if loadGenesis and fileExists(genesisPath):
readFile(genesisPath)
else:
""
genesisDepositsSnapshot = if fileExists(genesisDepositsSnapshotPath):
readFile(genesisDepositsSnapshotPath)
else:
@ -183,9 +196,18 @@ proc loadEth2NetworkMetadata*(
bootstrapNodes: bootstrapNodes,
depositContractBlock: depositContractBlock,
depositContractBlockHash: depositContractBlockHash,
genesisData:
when incbinEnabled: toBytes genesisData
else: genesisData,
genesis:
if downloadGenesisFrom.isSome:
GenesisMetadata(kind: BakedInUrl,
url: downloadGenesisFrom.get.url,
digest: downloadGenesisFrom.get.digest)
elif useBakedInGenesis.isSome:
GenesisMetadata(kind: BakedIn, networkName: useBakedInGenesis.get)
elif fileExists(genesisPath) and not isCompileTime:
GenesisMetadata(kind: UserSuppliedFile, path: genesisPath)
else:
GenesisMetadata(kind: NoGenesis)
,
genesisDepositsSnapshot: genesisDepositsSnapshot)
except PresetIncompatibleError as err:
@ -195,10 +217,14 @@ proc loadEth2NetworkMetadata*(
proc loadCompileTimeNetworkMetadata(
path: string,
eth1Network = none(Eth1Network),
loadGenesis = true): Eth2NetworkMetadata {.raises: [].} =
useBakedInGenesis = none(string),
downloadGenesisFrom = none(DownloadInfo)): Eth2NetworkMetadata {.raises: [].} =
if fileExists(path & "/config.yaml"):
try:
result = loadEth2NetworkMetadata(path, eth1Network, loadGenesis)
result = loadEth2NetworkMetadata(path, eth1Network,
isCompileTime = true,
downloadGenesisFrom = downloadGenesisFrom,
useBakedInGenesis = useBakedInGenesis)
if result.incompatible:
macros.error "The current build is misconfigured. " &
"Attempt to load an incompatible network metadata: " &
@ -209,27 +235,36 @@ proc loadCompileTimeNetworkMetadata(
macros.error "config.yaml not found for network '" & path
when const_preset == "gnosis":
import stew/assign2
when incbinEnabled:
let
gnosisGenesis {.importc: "gnosis_mainnet_genesis".}: ptr UncheckedArray[byte]
gnosisGenesisSize {.importc: "gnosis_mainnet_genesis_size".}: int
gnosisGenesis* {.importc: "gnosis_mainnet_genesis".}: ptr UncheckedArray[byte]
gnosisGenesisSize* {.importc: "gnosis_mainnet_genesis_size".}: int
chiadoGenesis {.importc: "gnosis_chiado_genesis".}: ptr UncheckedArray[byte]
chiadoGenesisSize {.importc: "gnosis_chiado_genesis_size".}: int
chiadoGenesis* {.importc: "gnosis_chiado_genesis".}: ptr UncheckedArray[byte]
chiadoGenesisSize* {.importc: "gnosis_chiado_genesis_size".}: int
# let `.incbin` in assembly file find the binary file through search path
{.passc: "-I" & vendorDir.}
{.compile: "network_metadata_gnosis.S".}
else:
const
gnosisGenesis* = slurp(
vendorDir & "/gnosis-chain-configs/mainnet/genesis.ssz")
chiadoGenesis* = slurp(
vendorDir & "/gnosis-chain-configs/chiado/genesis.ssz")
const
gnosisMetadata = loadCompileTimeNetworkMetadata(
vendorDir & "/gnosis-chain-configs/mainnet",
none(Eth1Network), not incbinEnabled)
none(Eth1Network),
useBakedInGenesis = some "gnosis")
chiadoMetadata = loadCompileTimeNetworkMetadata(
vendorDir & "/gnosis-chain-configs/chiado",
none(Eth1Network), not incbinEnabled)
none(Eth1Network),
useBakedInGenesis = some "chiado")
static:
for network in [gnosisMetadata, chiadoMetadata]:
@ -242,38 +277,62 @@ when const_preset == "gnosis":
doAssert network.cfg.DENEB_FORK_EPOCH == FAR_FUTURE_EPOCH
elif const_preset == "mainnet":
import stew/assign2
when incbinEnabled:
# Nim is very inefficent at loading large constants from binary files so we
# use this trick instead which saves significant amounts of compile time
let
mainnetGenesis {.importc: "eth2_mainnet_genesis".}: ptr UncheckedArray[byte]
mainnetGenesisSize {.importc: "eth2_mainnet_genesis_size".}: int
mainnetGenesis* {.importc: "eth2_mainnet_genesis".}: ptr UncheckedArray[byte]
mainnetGenesisSize* {.importc: "eth2_mainnet_genesis_size".}: int
praterGenesis {.importc: "eth2_goerli_genesis".}: ptr UncheckedArray[byte]
praterGenesisSize {.importc: "eth2_goerli_genesis_size".}: int
praterGenesis* {.importc: "eth2_goerli_genesis".}: ptr UncheckedArray[byte]
praterGenesisSize* {.importc: "eth2_goerli_genesis_size".}: int
sepoliaGenesis {.importc: "eth2_sepolia_genesis".}: ptr UncheckedArray[byte]
sepoliaGenesisSize {.importc: "eth2_sepolia_genesis_size".}: int
sepoliaGenesis* {.importc: "eth2_sepolia_genesis".}: ptr UncheckedArray[byte]
sepoliaGenesisSize* {.importc: "eth2_sepolia_genesis_size".}: int
# let `.incbin` in assembly file find the binary file through search path
{.passc: "-I" & vendorDir.}
{.compile: "network_metadata_mainnet.S".}
else:
const
mainnetGenesis* = slurp(
vendorDir & "/eth2-networks/shared/mainnet/genesis.ssz")
praterGenesis* = slurp(
vendorDir & "/eth2-networks/shared/prater/genesis.ssz")
sepoliaGenesis* = slurp(
vendorDir & "/sepolia/bepolia/genesis.ssz")
const
mainnetMetadata = loadCompileTimeNetworkMetadata(
vendorDir & "/eth2-networks/shared/mainnet", some mainnet, not incbinEnabled)
vendorDir & "/eth2-networks/shared/mainnet",
some mainnet,
useBakedInGenesis = some "mainnet")
praterMetadata = loadCompileTimeNetworkMetadata(
vendorDir & "/eth2-networks/shared/prater", some goerli, not incbinEnabled)
vendorDir & "/eth2-networks/shared/prater",
some goerli,
useBakedInGenesis = some "prater")
holeskyMetadata = loadCompileTimeNetworkMetadata(
vendorDir & "/holesky/custom_config_data",
some holesky,
downloadGenesisFrom = some DownloadInfo(
url: "https://github.com/status-im/nimbus-eth2/releases/download/v23.8.0/holesky-genesis.ssz.snappy-framed",
digest: Eth2Digest.fromHex "0x76631cd0b9ddc5b2c766b496e23f16759ce1181446a4efb40e5540cd15b78a07"))
sepoliaMetadata = loadCompileTimeNetworkMetadata(
vendorDir & "/sepolia/bepolia", some sepolia, not incbinEnabled)
vendorDir & "/sepolia/bepolia",
some sepolia,
useBakedInGenesis = some "sepolia")
static:
for network in [mainnetMetadata, praterMetadata, sepoliaMetadata]:
for network in [mainnetMetadata, praterMetadata, sepoliaMetadata, holeskyMetadata]:
checkForkConsistency(network.cfg)
for network in [mainnetMetadata, praterMetadata, sepoliaMetadata]:
for network in [mainnetMetadata, praterMetadata, sepoliaMetadata, holeskyMetadata]:
doAssert network.cfg.ALTAIR_FORK_EPOCH < FAR_FUTURE_EPOCH
doAssert network.cfg.BELLATRIX_FORK_EPOCH < FAR_FUTURE_EPOCH
doAssert network.cfg.CAPELLA_FORK_EPOCH < FAR_FUTURE_EPOCH
@ -295,40 +354,30 @@ proc getMetadataForNetwork*(
if networkName == "ropsten":
warn "Ropsten is unsupported; https://blog.ethereum.org/2022/11/30/ropsten-shutdown-announcement suggests migrating to Goerli or Sepolia"
template withGenesis(metadata, genesis: untyped): untyped =
when incbinEnabled:
var tmp = metadata
case tmp.incompatible
of false:
assign(tmp.genesisData, genesis.toOpenArray(0, `genesis Size` - 1))
of true:
raiseAssert "Unreachable" # `loadCompileTimeNetworkMetadata`
tmp
else:
metadata
let metadata =
when const_preset == "gnosis":
case toLowerAscii(networkName)
of "gnosis":
withGenesis(gnosisMetadata, gnosisGenesis)
gnosisMetadata
of "gnosis-chain":
warn "`--network:gnosis-chain` is deprecated, " &
"use `--network:gnosis` instead"
withGenesis(gnosisMetadata, gnosisGenesis)
gnosisMetadata
of "chiado":
withGenesis(chiadoMetadata, chiadoGenesis)
chiadoMetadata
else:
loadRuntimeMetadata()
elif const_preset == "mainnet":
case toLowerAscii(networkName)
of "mainnet":
withGenesis(mainnetMetadata, mainnetGenesis)
mainnetMetadata
of "prater", "goerli":
withGenesis(praterMetadata, praterGenesis)
praterMetadata
of "holesky":
holeskyMetadata
of "sepolia":
withGenesis(sepoliaMetadata, sepoliaGenesis)
sepoliaMetadata
else:
loadRuntimeMetadata()
@ -373,3 +422,67 @@ proc getRuntimeConfig*(
of true:
# `getMetadataForNetwork` / `loadCompileTimeNetworkMetadata`
raiseAssert "Unreachable"
template bakedInGenesisStateAsBytes(networkName: untyped): untyped =
when incbinEnabled:
`networkName Genesis`.toOpenArray(0, `networkName GenesisSize` - 1)
else:
`networkName Genesis`.toOpenArrayByte(0, `networkName Genesis`.high)
const
availableOnlyInMainnetBuild =
"Baked-in genesis states for the official Ethereum " &
"networks are available only in the mainnet build of Nimbus"
availableOnlyInGnosisBuild =
"Baked-in genesis states for the Gnosis network " &
"are available only in the gnosis build of Nimbus"
when const_preset in ["mainnet", "gnosis"]:
template bakedBytes*(metadata: GenesisMetadata): auto =
case metadata.networkName
of "mainnet":
when const_preset == "mainnet":
bakedInGenesisStateAsBytes mainnet
else:
raiseAssert availableOnlyInMainnetBuild
of "prater":
when const_preset == "mainnet":
bakedInGenesisStateAsBytes prater
else:
raiseAssert availableOnlyInMainnetBuild
of "sepolia":
when const_preset == "mainnet":
bakedInGenesisStateAsBytes sepolia
else:
raiseAssert availableOnlyInMainnetBuild
of "gnosis":
when const_preset == "gnosis":
bakedInGenesisStateAsBytes gnosis
else:
raiseAssert availableOnlyInGnosisBuild
of "chiado":
when const_preset == "gnosis":
bakedInGenesisStateAsBytes chiado
else:
raiseAssert availableOnlyInGnosisBuild
else:
raiseAssert "The baked network metadata should use one of the name above"
func bakedGenesisValidatorsRoot*(metadata: Eth2NetworkMetadata): Opt[Eth2Digest] =
if metadata.genesis.kind == BakedIn:
try:
let header = SSZ.decode(
toOpenArray(metadata.genesis.bakedBytes, 0, sizeof(BeaconStateHeader) - 1),
BeaconStateHeader)
Opt.some header.genesis_validators_root
except SerializationError as err:
raiseAssert "Invalid baken-in genesis state"
else:
Opt.none Eth2Digest
else:
func bakedBytes*(metadata: GenesisMetadata): seq[byte] =
raiseAssert "Baked genesis states are not available in the current build mode"
func bakedGenesisValidatorsRoot*(metadata: Eth2NetworkMetadata): Opt[Eth2Digest] =
Opt.none Eth2Digest

View File

@ -0,0 +1,62 @@
# beacon_chain
# Copyright (c) 2023 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
std/uri,
stew/io2, chronos, chronos/apps/http/httpclient, snappy,
../spec/digest
import network_metadata
export network_metadata
type
HttpFetchError* = object of CatchableError
status*: int
DigestMismatchError* = object of CatchableError
proc downloadFile(url: Uri): Future[seq[byte]] {.async.} =
var httpSession = HttpSessionRef.new()
let response = await httpSession.fetch(url)
if response[0] == 200:
return response[1]
else:
raise (ref HttpFetchError)(
msg: "Unexpected status code " & $response[0] & " when fetching " & $url,
status: response[0])
proc fetchBytes*(metadata: GenesisMetadata): Future[seq[byte]] {.async.} =
case metadata.kind
of NoGenesis:
raiseAssert "fetchBytes should be called only when metadata.hasGenesis is true"
of BakedIn:
result = @(metadata.bakedBytes)
of BakedInUrl:
result = decodeFramed(await downloadFile(parseUri metadata.url))
if eth2digest(result) != metadata.digest:
raise (ref DigestMismatchError)(
msg: "The downloaded genesis state cannot be verified (checksum mismatch)")
of UserSuppliedFile:
result = readAllBytes(metadata.path).tryGet()
proc sourceDesc*(metadata: GenesisMetadata): string =
case metadata.kind
of NoGenesis:
"no genesis"
of BakedIn:
metadata.networkName
of BakedInUrl:
metadata.url
of UserSuppliedFile:
metadata.path
when isMainModule:
let holeskyMetadata = getMetadataForNetwork("holesky")
io2.writeFile(
"holesky-genesis.ssz",
waitFor holeskyMetadata.genesis.fetchBytes()
).expect("success")

View File

@ -15,7 +15,7 @@ import
eth/p2p/discoveryv5/[enr, random2],
./consensus_object_pools/blob_quarantine,
./consensus_object_pools/vanity_logs/vanity_logs,
./networking/topic_params,
./networking/[topic_params, network_metadata_downloads],
./rpc/[rest_api, state_ttl_cache],
./spec/datatypes/[altair, bellatrix, phase0],
./spec/[deposit_snapshots, engine_authentication, weak_subjectivity],
@ -462,8 +462,8 @@ const
proc init*(T: type BeaconNode,
rng: ref HmacDrbgContext,
config: BeaconNodeConf,
metadata: Eth2NetworkMetadata): BeaconNode
{.raises: [CatchableError].} =
metadata: Eth2NetworkMetadata): Future[BeaconNode]
{.async, raises: [CatchableError].} =
var taskpool: TaskPoolPtr
template cfg: auto = metadata.cfg
@ -541,18 +541,31 @@ proc init*(T: type BeaconNode,
if engineApiUrls.len == 0:
notice "Running without execution client - validator features disabled (see https://nimbus.guide/eth1.html)"
var genesisState =
if metadata.genesisData.len > 0:
try:
newClone readSszForkedHashedBeaconState(cfg, metadata.genesisBytes)
var networkGenesisValidatorsRoot = metadata.bakedGenesisValidatorsRoot
if not ChainDAGRef.isInitialized(db).isOk():
let genesisState =
if metadata.hasGenesis:
let genesisBytes = try:
if metadata.genesis.kind == BakedInUrl:
info "Obtaining genesis state", sourceUrl = metadata.genesis.url
await metadata.genesis.fetchBytes()
except CatchableError as err:
raiseAssert "Invalid baked-in state of length " &
$metadata.genesisBytes.len & " and eth2digest " &
$eth2digest(metadata.genesisBytes) & ": " & err.msg
error "Failed to obtain genesis state",
source = metadata.genesis.sourceDesc,
err = err.msg
quit 1
try:
newClone readSszForkedHashedBeaconState(cfg, genesisBytes)
except CatchableError as err:
error "Invalid genesis state",
size = genesisBytes.len,
digest = eth2digest(genesisBytes),
err = err.msg
quit 1
else:
nil
if not ChainDAGRef.isInitialized(db).isOk():
if genesisState == nil and checkpointState == nil:
fatal "No database and no genesis snapshot found. Please supply a genesis.ssz " &
"with the network configuration"
@ -573,6 +586,8 @@ proc init*(T: type BeaconNode,
# answering genesis queries
if not genesisState.isNil:
ChainDAGRef.preInit(db, genesisState[])
networkGenesisValidatorsRoot =
Opt.some(getStateField(genesisState[], genesis_validators_root))
if not checkpointState.isNil:
if genesisState.isNil or
@ -605,12 +620,6 @@ proc init*(T: type BeaconNode,
validatorMonitor[].addMonitor(key, Opt.none(ValidatorIndex))
let
networkGenesisValidatorsRoot =
if not genesisState.isNil:
Opt.some(getStateField(genesisState[], genesis_validators_root))
else:
Opt.none(Eth2Digest)
dag = loadChainDag(
config, cfg, db, eventBus,
validatorMonitor, networkGenesisValidatorsRoot)
@ -1893,7 +1902,7 @@ proc doRunBeaconNode(config: var BeaconNodeConf, rng: ref HmacDrbgContext) {.rai
bnStatus = BeaconNodeStatus.Stopping
c_signal(ansi_c.SIGTERM, SIGTERMHandler)
let node = BeaconNode.init(rng, config, metadata)
let node = waitFor BeaconNode.init(rng, config, metadata)
if node.dag.cfg.DENEB_FORK_EPOCH != FAR_FUTURE_EPOCH:
let res =
@ -2042,8 +2051,14 @@ proc handleStartUpCmd(config: var BeaconNodeConf) {.raises: [CatchableError].} =
kind: TrustedNodeSyncKind.StateId,
stateId: "finalized")
genesis =
if network.genesisData.len > 0:
newClone(readSszForkedHashedBeaconState(cfg, network.genesisBytes))
if network.hasGenesis:
let genesisBytes = try: waitFor network.genesis.fetchBytes()
except CatchableError as err:
error "Failed to obtain genesis state",
source = network.genesis.sourceDesc,
err = err.msg
quit 1
newClone(readSszForkedHashedBeaconState(cfg, genesisBytes))
else: nil
if config.blockId.isSome():

View File

@ -11,7 +11,7 @@ import
eth/db/kvstore_sqlite3,
./el/el_manager,
./gossip_processing/optimistic_processor,
./networking/[topic_params, network_metadata],
./networking/[topic_params, network_metadata_downloads],
./spec/beaconstate,
./spec/datatypes/[phase0, altair, bellatrix, capella, deneb],
"."/[filepath, light_client, light_client_db, nimbus_binary_common, version]
@ -63,9 +63,15 @@ programMain:
template cfg(): auto = metadata.cfg
let
genesisBytes = try: waitFor metadata.genesis.fetchBytes()
except CatchableError as err:
error "Failed to obtain genesis state",
source = metadata.genesis.sourceDesc,
err = err.msg
quit 1
genesisState =
try:
newClone(readSszForkedHashedBeaconState(cfg, metadata.genesisBytes))
newClone(readSszForkedHashedBeaconState(cfg, genesisBytes))
except CatchableError as err:
raiseAssert "Invalid baked-in state: " & err.msg

View File

@ -138,7 +138,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) =
TERMINAL_BLOCK_HASH:
$cfg.TERMINAL_BLOCK_HASH,
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH:
Base10.toString(uint64(TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH)),
Base10.toString(uint64(cfg.TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH)),
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT:
Base10.toString(cfg.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT),
MIN_GENESIS_TIME:

View File

@ -57,9 +57,6 @@ const
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/deneb/beacon-chain.md#domain-types
DOMAIN_BLOB_SIDECAR* = DomainType([byte 0x0b, 0x00, 0x00, 0x00])
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/bellatrix/beacon-chain.md#transition-settings
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH* = FAR_FUTURE_EPOCH
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/fork-choice.md#configuration
PROPOSER_SCORE_BOOST*: uint64 = 40

View File

@ -981,10 +981,10 @@ func getForkSchedule*(cfg: RuntimeConfig): array[5, Fork] =
type
# The first few fields of a state, shared across all forks
BeaconStateHeader = object
genesis_time: uint64
genesis_validators_root: Eth2Digest
slot: Slot
BeaconStateHeader* = object
genesis_time*: uint64
genesis_validators_root*: Eth2Digest
slot*: Slot
func readSszForkedHashedBeaconState*(
consensusFork: ConsensusFork, data: openArray[byte]):

View File

@ -76,6 +76,9 @@ type
DEPOSIT_NETWORK_ID*: uint64
DEPOSIT_CONTRACT_ADDRESS*: Eth1Address
# Not actively used, but part of the spec
TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH*: Epoch
PresetFile* = object
values*: Table[string, string]
missingValues*: seq[string]
@ -118,6 +121,7 @@ when const_preset == "mainnet":
# * 'prater' - testnet
# * 'ropsten' - testnet
# * 'sepolia' - testnet
# * 'holesky' - testnet
# Must match the regex: [a-z0-9\-]
CONFIG_NAME: "",
@ -221,6 +225,7 @@ elif const_preset == "gnosis":
# * 'prater' - testnet
# * 'ropsten' - testnet
# * 'sepolia' - testnet
# * 'holesky' - testnet
# Must match the regex: [a-z0-9\-]
CONFIG_NAME: "",
@ -319,6 +324,7 @@ elif const_preset == "minimal":
# * 'prater' - testnet
# * 'ropsten' - testnet
# * 'sepolia' - testnet
# * 'holesky' - testnet
# Must match the regex: [a-z0-9\-]
CONFIG_NAME: "minimal",
@ -586,9 +592,6 @@ proc readRuntimeConfig*(
checkCompatibility BLOB_SIDECAR_SUBNET_COUNT
checkCompatibility MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS
# Never pervasively implemented, still under discussion
checkCompatibility TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH
# Isn't being used as a preset in the usual way: at any time, there's one correct value
checkCompatibility PROPOSER_SCORE_BOOST

View File

@ -183,7 +183,7 @@ Each era is identified by when it ends. Thus, the genesis era is era `0`, follow
`.era` file names follow a simple convention: `<config-name>-<era-number>-<era-count>-<short-historical-root>.era`:
* `config-name` is the `CONFIG_NAME` field of the runtime configation (`mainnet`, `prater`, `sepolia`, etc)
* `config-name` is the `CONFIG_NAME` field of the runtime configation (`mainnet`, `prater`, `sepolia`, `holesky`, etc)
* `era-number` is the number of the _first_ era stored in the file - for example, the genesis era file has number 0 - as a 5-digit 0-filled decimal integer
* `short-era-root` is the first 4 bytes of the last historical root in the _last_ state in the era file, lower-case hex-encoded (8 characters), except the genesis era which instead uses the `genesis_validators_root` field from the genesis state.
* The root is available as `state.historical_roots[era - 1]` except for genesis, which is `state.genesis_validators_root`

View File

@ -301,7 +301,7 @@ proc startBeaconNode(basePort: int) {.raises: [CatchableError].} =
let
metadata = loadEth2NetworkMetadata(dataDir)
node = BeaconNode.init(rng, runNodeConf, metadata)
node = waitFor BeaconNode.init(rng, runNodeConf, metadata)
node.start() # This will run until the node is terminated by
# setting its `bnStatus` to `Stopping`.

View File

@ -17,7 +17,7 @@ template checkRoot(name, root) =
metadata = getMetadataForNetwork(name)
cfg = metadata.cfg
state = newClone(readSszForkedHashedBeaconState(
metadata.cfg, metadata.genesisBytes))
metadata.cfg, metadata.genesis.bakedBytes))
check:
$getStateRoot(state[]) == root

1
vendor/holesky vendored Submodule

@ -0,0 +1 @@
Subproject commit f1ad227a2511ea26f5d043fad15d9431fd681941

2
vendor/nim-chronos vendored

@ -1 +1 @@
Subproject commit 6c2ea675123ed0bf5c5d76c92ed4985bacd1a9ec
Subproject commit 176d462b076db24d9f71ddb40163d1ef82823771