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:
parent
c5a79a6f8f
commit
53589b5a7d
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
|
@ -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)
|
||||
except CatchableError as err:
|
||||
raiseAssert "Invalid baked-in state of length " &
|
||||
$metadata.genesisBytes.len & " and eth2digest " &
|
||||
$eth2digest(metadata.genesisBytes) & ": " & err.msg
|
||||
else:
|
||||
nil
|
||||
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:
|
||||
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 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():
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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]):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit f1ad227a2511ea26f5d043fad15d9431fd681941
|
|
@ -1 +1 @@
|
|||
Subproject commit 6c2ea675123ed0bf5c5d76c92ed4985bacd1a9ec
|
||||
Subproject commit 176d462b076db24d9f71ddb40163d1ef82823771
|
Loading…
Reference in New Issue