mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-10 06:16:25 +00:00
4e9bc7f570
* add EIP-7044 support to keymanager API When trying to sign `VoluntaryExit` via keymanager API, the logic is not yet aware of EIP-7044 (part of Deneb). This patch adds missing EIP-7044 support to the keymanager API as well. As part of this, the VC needs to become aware about: - `CAPELLA_FORK_VERSION`: To correctly form the EIP-7044 signing domain. The fork schedule does not indicate which of the results, if any, corresponds to Capella. - `CAPELLA_FORK_EPOCH`: To detect whether Capella was scheduled. If a BN does not have it in its config while other BNs have it, this leads to a log if Capella has not activated yet, or marks the BN as incompatible if Capella already activated. - `DENEB_FORK_EPOCH`: To check whether EIP-7044 logic should be used. Related PRs: - #5120 added support for processing EIP-7044 `VoluntaryExit` messages as part of the state transition functions (tested by EF spec tests). - #5953 synced the support from #5120 to gossip validation. - #5954 added support to the `nimbus_beacon_node deposits exit` command. - #5956 contains an alternative generic version of `VCForkConfig`. * address reviewer feedback: letter case, module location, double lookup --------- Co-authored-by: cheatfate <eugene.kabanov@status.im> * Update beacon_chain/rpc/rest_constants.nim * move `VCRuntimeConfig` back to `rest_types` --------- Co-authored-by: cheatfate <eugene.kabanov@status.im> * fix `getForkVersion` helper --------- Co-authored-by: cheatfate <eugene.kabanov@status.im>
98 lines
3.6 KiB
Nim
98 lines
3.6 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/strutils,
|
|
stew/[base10, byteutils],
|
|
../forks
|
|
|
|
from ./rest_types import VCRuntimeConfig
|
|
|
|
export forks, rest_types
|
|
|
|
type VCForkConfig* = object
|
|
altairEpoch*: Epoch
|
|
capellaVersion*: Opt[Version]
|
|
capellaEpoch*: Epoch
|
|
denebEpoch*: Epoch
|
|
|
|
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"
|
|
|
|
proc getOrDefault*(info: VCRuntimeConfig, name: string,
|
|
default: uint64): uint64 =
|
|
let numstr = info.getOrDefault(name, "missing")
|
|
if numstr == "missing": return default
|
|
Base10.decode(uint64, numstr).valueOr:
|
|
return default
|
|
|
|
proc getOrDefault*(info: VCRuntimeConfig, name: string, default: Epoch): Epoch =
|
|
Epoch(info.getOrDefault(name, uint64(default)))
|
|
|
|
func getForkVersion(
|
|
info: VCRuntimeConfig,
|
|
consensusFork: Consensusfork): Result[Opt[Version], string] =
|
|
let key = consensusFork.forkVersionConfigKey()
|
|
let stringValue = info.getOrDefault(key, "missing")
|
|
if stringValue == "missing": return ok Opt.none(Version)
|
|
var value: Version
|
|
try:
|
|
hexToByteArrayStrict(stringValue, distinctBase(value))
|
|
except ValueError as exc:
|
|
return err(key & " is invalid: " & exc.msg)
|
|
ok Opt.some value
|
|
|
|
func getForkEpoch(info: VCRuntimeConfig, consensusFork: ConsensusFork): Epoch =
|
|
if consensusFork > ConsensusFork.Phase0:
|
|
let key = consensusFork.forkEpochConfigKey()
|
|
info.getOrDefault(key, FAR_FUTURE_EPOCH)
|
|
else:
|
|
GENESIS_EPOCH
|
|
|
|
func getConsensusForkConfig*(
|
|
info: VCRuntimeConfig): Result[VCForkConfig, string] =
|
|
## This extracts all `_FORK_VERSION` and `_FORK_EPOCH` constants
|
|
## that are relevant for Validator Client operation.
|
|
##
|
|
## Note that the fork schedule (`/eth/v1/config/fork_schedule`) cannot be used
|
|
## because it does not indicate whether the forks refer to `ConsensusFork` or
|
|
## to a different fork sequence from an incompatible network (e.g., devnet)
|
|
let
|
|
res = VCForkConfig(
|
|
altairEpoch: info.getForkEpoch(ConsensusFork.Altair),
|
|
capellaVersion: ? info.getForkVersion(ConsensusFork.Capella),
|
|
capellaEpoch: info.getForkEpoch(ConsensusFork.Capella),
|
|
denebEpoch: info.getForkEpoch(ConsensusFork.Deneb))
|
|
|
|
if res.capellaEpoch < res.altairEpoch:
|
|
return err(
|
|
"Fork epochs are inconsistent, " & $ConsensusFork.Capella &
|
|
" is scheduled at epoch " & $res.capellaEpoch &
|
|
" which is before prior fork epoch " & $res.altairEpoch)
|
|
if res.denebEpoch < res.capellaEpoch:
|
|
return err(
|
|
"Fork epochs are inconsistent, " & $ConsensusFork.Deneb &
|
|
" is scheduled at epoch " & $res.denebEpoch &
|
|
" which is before prior fork epoch " & $res.capellaEpoch)
|
|
|
|
if res.capellaEpoch != FAR_FUTURE_EPOCH and res.capellaVersion.isNone:
|
|
return err(
|
|
"Beacon node has scheduled " &
|
|
ConsensusFork.Capella.forkEpochConfigKey() &
|
|
" but does not report " &
|
|
ConsensusFork.Capella.forkVersionConfigKey())
|
|
ok res
|