nimbus-eth2/beacon_chain/spec/eth2_apis/rest_fork_config.nim

131 lines
4.1 KiB
Nim

# beacon_chain
# Copyright (c) 2018-2024 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.
{.push raises: [].}
import
std/[sequtils, strutils, tables],
stew/[base10, byteutils],
../forks
from ./rest_types import VCRuntimeConfig
export forks, tables, rest_types
type
ForkConfigItem* = object
version*: Version
epoch*: Epoch
VCForkConfig* = Table[ConsensusFork, ForkConfigItem]
func forkVersionConfigKey*(consensusFork: ConsensusFork): string =
if consensusFork > ConsensusFork.Phase0:
($consensusFork).toUpperAscii() & "_FORK_VERSION"
else:
"GENESIS_FORK_VERSION"
func forkEpochConfigKey*(consensusFork: ConsensusFork): string =
doAssert consensusFork > ConsensusFork.Phase0
($consensusFork).toUpperAscii() & "_FORK_EPOCH"
func getOrDefault*(info: VCRuntimeConfig, name: string,
defaultValue: uint64): uint64 =
let numstr =
try:
info[name]
except KeyError:
return defaultValue
Base10.decode(uint64, numstr).valueOr:
return defaultValue
func getOrDefault*(info: VCRuntimeConfig, name: string, default: Epoch): Epoch =
Epoch(info.getOrDefault(name, uint64(default)))
func getForkVersion(
info: VCRuntimeConfig,
consensusFork: ConsensusFork,
optionalForks: set[ConsensusFork] = {}
): Result[Version, string] =
let
key = consensusFork.forkVersionConfigKey()
stringValue =
try:
info[key]
except KeyError:
if consensusFork in optionalForks:
"0xFFFFFFFF"
else:
return err("Forks configuration missing value " & $consensusFork)
var value: Version
try:
hexToByteArrayStrict(stringValue, distinctBase(value))
except ValueError as exc:
return err(key & " is invalid, reason " & exc.msg)
ok(value)
func getForkEpoch(
info: VCRuntimeConfig,
consensusFork: ConsensusFork,
optionalForks: set[ConsensusFork] = {}
): Result[Epoch, string] =
if consensusFork > ConsensusFork.Phase0:
let
key = consensusFork.forkEpochConfigKey()
stringValue =
try:
info[key]
except KeyError:
if consensusFork in optionalForks:
"18446744073709551615"
else:
return err("Forks configuration missing value " & $consensusFork)
numValue = Base10.decode(uint64, stringValue).valueOr:
return err(key & " is invalid, reason " & $error)
ok(Epoch(numValue))
else:
ok(GENESIS_EPOCH)
template toString(epoch: Epoch): string =
Base10.toString(uint64(epoch))
func getConsensusForkConfig*(
info: VCRuntimeConfig,
optionalForks: set[ConsensusFork] = {}
): Result[VCForkConfig, string] =
## This extracts all `_FORK_VERSION` and `_FORK_EPOCH` constants
var
config: VCForkConfig
presence: set[ConsensusFork]
for fork in ConsensusFork:
let
forkVersion = ? info.getForkVersion(fork, optionalForks)
forkEpoch = ? info.getForkEpoch(fork, optionalForks)
config[fork] = ForkConfigItem(version: forkVersion, epoch: forkEpoch)
presence.incl(fork)
let forks = ConsensusFork.toSeq()
if len(presence) != (int(high(ConsensusFork)) + 1):
let missingForks = forks.filterIt(it notin presence)
return err(
"Some forks missing in configuration [" &
missingForks.mapIt($it).join(", ") & "]")
try:
for index, fork in forks.pairs():
if index > 0:
if config[forks[index]].epoch < config[forks[index - 1]].epoch:
return err(
"Fork epochs are inconsistent, " & $forks[index] &
" is scheduled at epoch " &
config[forks[index]].epoch.toString() &
" which is before prior fork epoch " &
config[forks[index - 1]].epoch.toString())
except KeyError:
raiseAssert "Forks configuration is missing values"
ok(config)