131 lines
4.1 KiB
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)
|