mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-09 13:56:23 +00:00
7e276937dc
In a future fork, light client data will be extended with execution info to support more use cases. To anticipate such an upgrade, introduce `Forky` and `Forked` types, and ready the database schema. Because the mapping of sync committee periods to fork versions is not necessarily unique (fork schedule not in sync with period boundaries), an additional column is added to `period` -> `LightClientUpdate` table.
985 lines
39 KiB
Nim
985 lines
39 KiB
Nim
# beacon_chain
|
|
# Copyright (c) 2021-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.
|
|
|
|
when (NimMajor, NimMinor) < (1, 4):
|
|
{.push raises: [Defect].}
|
|
else:
|
|
{.push raises: [].}
|
|
|
|
import
|
|
stew/assign2,
|
|
chronicles,
|
|
../extras,
|
|
"."/[
|
|
block_id, eth2_merkleization, eth2_ssz_serialization,
|
|
forks_light_client, presets],
|
|
./datatypes/[phase0, altair, bellatrix, capella, eip4844],
|
|
./mev/bellatrix_mev
|
|
|
|
# TODO re-export capella, but for now it could cause knock-on effects, so stage
|
|
# it sequentially
|
|
export
|
|
extras, block_id, phase0, altair, bellatrix, eth2_merkleization,
|
|
eth2_ssz_serialization, forks_light_client, presets, bellatrix_mev
|
|
|
|
# This file contains helpers for dealing with forks - we have two ways we can
|
|
# deal with forks:
|
|
# * generics - this means using the static typing and differentiating forks
|
|
# at compile time - this is preferred in fork-specific code where the fork
|
|
# is known up-front, for example spec functions.
|
|
# * variants - this means using a variant object and determining the fork at
|
|
# runtime - this carries the obvious risk and complexity of dealing with
|
|
# runtime checking, but is of course needed for external data that may be
|
|
# of any fork kind.
|
|
#
|
|
# For generics, we define `Forky*` type classes that cover "similar" objects
|
|
# across forks - for variants, they're called `Forked*` instead.
|
|
# See withXxx and `init` for convenient ways of moving between these two worlds.
|
|
# A clever programmer would use templates, macros and dark magic to create all
|
|
# these types and converters :)
|
|
|
|
type
|
|
BeaconStateFork* {.pure.} = enum
|
|
Phase0,
|
|
Altair,
|
|
Bellatrix,
|
|
Capella,
|
|
EIP4844
|
|
|
|
ForkyBeaconState* =
|
|
phase0.BeaconState |
|
|
altair.BeaconState |
|
|
bellatrix.BeaconState |
|
|
capella.BeaconState |
|
|
eip4844.BeaconState
|
|
|
|
ForkyHashedBeaconState* =
|
|
phase0.HashedBeaconState |
|
|
altair.HashedBeaconState |
|
|
bellatrix.HashedBeaconState |
|
|
capella.HashedBeaconState |
|
|
eip4844.HashedBeaconState
|
|
|
|
ForkedHashedBeaconState* = object
|
|
case kind*: BeaconStateFork
|
|
of BeaconStateFork.Phase0: phase0Data*: phase0.HashedBeaconState
|
|
of BeaconStateFork.Altair: altairData*: altair.HashedBeaconState
|
|
of BeaconStateFork.Bellatrix: bellatrixData*: bellatrix.HashedBeaconState
|
|
of BeaconStateFork.Capella: capellaData*: capella.HashedBeaconState
|
|
of BeaconStateFork.EIP4844: eip4844Data*: eip4844.HashedBeaconState
|
|
|
|
BeaconBlockFork* {.pure.} = enum
|
|
Phase0,
|
|
Altair,
|
|
Bellatrix,
|
|
Capella,
|
|
EIP4844
|
|
|
|
ForkyExecutionPayload* =
|
|
bellatrix.ExecutionPayload |
|
|
capella.ExecutionPayload |
|
|
eip4844.ExecutionPayload
|
|
|
|
ForkyBeaconBlockBody* =
|
|
phase0.BeaconBlockBody |
|
|
altair.BeaconBlockBody |
|
|
bellatrix.BeaconBlockBody |
|
|
capella.BeaconBlockBody |
|
|
eip4844.BeaconBlockBody
|
|
|
|
ForkySigVerifiedBeaconBlockBody* =
|
|
phase0.SigVerifiedBeaconBlockBody |
|
|
altair.SigVerifiedBeaconBlockBody |
|
|
bellatrix.SigVerifiedBeaconBlockBody |
|
|
capella.SigVerifiedBeaconBlockBody |
|
|
eip4844.SigVerifiedBeaconBlockBody
|
|
|
|
ForkyTrustedBeaconBlockBody* =
|
|
phase0.TrustedBeaconBlockBody |
|
|
altair.TrustedBeaconBlockBody |
|
|
bellatrix.TrustedBeaconBlockBody |
|
|
capella.TrustedBeaconBlockBody |
|
|
eip4844.TrustedBeaconBlockBody
|
|
|
|
SomeForkyBeaconBlockBody* =
|
|
ForkyBeaconBlockBody |
|
|
ForkySigVerifiedBeaconBlockBody |
|
|
ForkyTrustedBeaconBlockBody
|
|
|
|
ForkyBeaconBlock* =
|
|
phase0.BeaconBlock |
|
|
altair.BeaconBlock |
|
|
bellatrix.BeaconBlock |
|
|
capella.BeaconBlock |
|
|
eip4844.BeaconBlock
|
|
|
|
ForkySigVerifiedBeaconBlock* =
|
|
phase0.SigVerifiedBeaconBlock |
|
|
altair.SigVerifiedBeaconBlock |
|
|
bellatrix.SigVerifiedBeaconBlock |
|
|
capella.SigVerifiedBeaconBlock |
|
|
eip4844.SigVerifiedBeaconBlock
|
|
|
|
ForkyTrustedBeaconBlock* =
|
|
phase0.TrustedBeaconBlock |
|
|
altair.TrustedBeaconBlock |
|
|
bellatrix.TrustedBeaconBlock |
|
|
capella.TrustedBeaconBlock |
|
|
eip4844.TrustedBeaconBlock
|
|
|
|
SomeForkyBeaconBlock* =
|
|
ForkyBeaconBlock |
|
|
ForkySigVerifiedBeaconBlock |
|
|
ForkyTrustedBeaconBlock
|
|
|
|
ForkedBeaconBlock* = object
|
|
case kind*: BeaconBlockFork
|
|
of BeaconBlockFork.Phase0: phase0Data*: phase0.BeaconBlock
|
|
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
|
|
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.BeaconBlock
|
|
of BeaconBlockFork.Capella: capellaData*: capella.BeaconBlock
|
|
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.BeaconBlock
|
|
|
|
Web3SignerForkedBeaconBlock* = object
|
|
case kind*: BeaconBlockFork
|
|
of BeaconBlockFork.Phase0: phase0Data*: phase0.BeaconBlock
|
|
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
|
|
of BeaconBlockFork.Bellatrix: bellatrixData*: BeaconBlockHeader
|
|
of BeaconBlockFork.Capella: capellaData*: BeaconBlockHeader
|
|
of BeaconBlockFork.EIP4844: eip4844Data*: BeaconBlockHeader
|
|
|
|
ForkedBlindedBeaconBlock* = object
|
|
case kind*: BeaconBlockFork
|
|
of BeaconBlockFork.Phase0: phase0Data*: phase0.BeaconBlock
|
|
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
|
|
of BeaconBlockFork.Bellatrix: bellatrixData*: BlindedBeaconBlock
|
|
of BeaconBlockFork.Capella: capellaData*: BlindedBeaconBlock
|
|
of BeaconBlockFork.EIP4844: eip4844Data*: BlindedBeaconBlock
|
|
|
|
ForkedTrustedBeaconBlock* = object
|
|
case kind*: BeaconBlockFork
|
|
of BeaconBlockFork.Phase0: phase0Data*: phase0.TrustedBeaconBlock
|
|
of BeaconBlockFork.Altair: altairData*: altair.TrustedBeaconBlock
|
|
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.TrustedBeaconBlock
|
|
of BeaconBlockFork.Capella: capellaData*: capella.TrustedBeaconBlock
|
|
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.TrustedBeaconBlock
|
|
|
|
ForkySignedBeaconBlock* =
|
|
phase0.SignedBeaconBlock |
|
|
altair.SignedBeaconBlock |
|
|
bellatrix.SignedBeaconBlock |
|
|
capella.SignedBeaconBlock |
|
|
eip4844.SignedBeaconBlock
|
|
|
|
ForkedSignedBeaconBlock* = object
|
|
case kind*: BeaconBlockFork
|
|
of BeaconBlockFork.Phase0: phase0Data*: phase0.SignedBeaconBlock
|
|
of BeaconBlockFork.Altair: altairData*: altair.SignedBeaconBlock
|
|
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.SignedBeaconBlock
|
|
of BeaconBlockFork.Capella: capellaData*: capella.SignedBeaconBlock
|
|
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.SignedBeaconBlock
|
|
|
|
ForkySignedBlindedBeaconBlock* =
|
|
phase0.SignedBeaconBlock |
|
|
altair.SignedBeaconBlock |
|
|
SignedBlindedBeaconBlock
|
|
|
|
ForkedSignedBlindedBeaconBlock* = object
|
|
case kind*: BeaconBlockFork
|
|
of BeaconBlockFork.Phase0: phase0Data*: phase0.SignedBeaconBlock
|
|
of BeaconBlockFork.Altair: altairData*: altair.SignedBeaconBlock
|
|
of BeaconBlockFork.Bellatrix: bellatrixData*: SignedBlindedBeaconBlock
|
|
of BeaconBlockFork.Capella: capellaData*: SignedBlindedBeaconBlock
|
|
of BeaconBlockFork.EIP4844: eip4844Data*: SignedBlindedBeaconBlock
|
|
|
|
ForkySigVerifiedSignedBeaconBlock* =
|
|
phase0.SigVerifiedSignedBeaconBlock |
|
|
altair.SigVerifiedSignedBeaconBlock |
|
|
bellatrix.SigVerifiedSignedBeaconBlock |
|
|
capella.SigVerifiedSignedBeaconBlock |
|
|
eip4844.SigVerifiedSignedBeaconBlock
|
|
|
|
ForkyMsgTrustedSignedBeaconBlock* =
|
|
phase0.MsgTrustedSignedBeaconBlock |
|
|
altair.MsgTrustedSignedBeaconBlock |
|
|
bellatrix.MsgTrustedSignedBeaconBlock |
|
|
capella.MsgTrustedSignedBeaconBlock |
|
|
eip4844.MsgTrustedSignedBeaconBlock
|
|
|
|
ForkyTrustedSignedBeaconBlock* =
|
|
phase0.TrustedSignedBeaconBlock |
|
|
altair.TrustedSignedBeaconBlock |
|
|
bellatrix.TrustedSignedBeaconBlock |
|
|
capella.TrustedSignedBeaconBlock |
|
|
eip4844.TrustedSignedBeaconBlock
|
|
|
|
ForkedMsgTrustedSignedBeaconBlock* = object
|
|
case kind*: BeaconBlockFork
|
|
of BeaconBlockFork.Phase0: phase0Data*: phase0.MsgTrustedSignedBeaconBlock
|
|
of BeaconBlockFork.Altair: altairData*: altair.MsgTrustedSignedBeaconBlock
|
|
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.MsgTrustedSignedBeaconBlock
|
|
of BeaconBlockFork.Capella: capellaData*: capella.MsgTrustedSignedBeaconBlock
|
|
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.MsgTrustedSignedBeaconBlock
|
|
|
|
ForkedTrustedSignedBeaconBlock* = object
|
|
case kind*: BeaconBlockFork
|
|
of BeaconBlockFork.Phase0: phase0Data*: phase0.TrustedSignedBeaconBlock
|
|
of BeaconBlockFork.Altair: altairData*: altair.TrustedSignedBeaconBlock
|
|
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.TrustedSignedBeaconBlock
|
|
of BeaconBlockFork.Capella: capellaData*: capella.TrustedSignedBeaconBlock
|
|
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.TrustedSignedBeaconBlock
|
|
|
|
SomeForkySignedBeaconBlock* =
|
|
ForkySignedBeaconBlock |
|
|
ForkySigVerifiedSignedBeaconBlock |
|
|
ForkyMsgTrustedSignedBeaconBlock |
|
|
ForkyTrustedSignedBeaconBlock
|
|
|
|
EpochInfoFork* {.pure.} = enum
|
|
Phase0
|
|
Altair
|
|
|
|
ForkedEpochInfo* = object
|
|
case kind*: EpochInfoFork
|
|
of EpochInfoFork.Phase0: phase0Data*: phase0.EpochInfo
|
|
of EpochInfoFork.Altair: altairData*: altair.EpochInfo
|
|
|
|
ForkyEpochInfo* = phase0.EpochInfo | altair.EpochInfo
|
|
|
|
ForkDigests* = object
|
|
phase0*: ForkDigest
|
|
altair*: ForkDigest
|
|
bellatrix*: ForkDigest
|
|
capella*: ForkDigest
|
|
eip4844*: ForkDigest
|
|
|
|
template toFork*[T: phase0.BeaconState | phase0.HashedBeaconState](
|
|
t: type T): BeaconStateFork =
|
|
BeaconStateFork.Phase0
|
|
template toFork*[T: altair.BeaconState | altair.HashedBeaconState](
|
|
t: type T): BeaconStateFork =
|
|
BeaconStateFork.Altair
|
|
template toFork*[T: bellatrix.BeaconState | bellatrix.HashedBeaconState](
|
|
t: type T): BeaconStateFork =
|
|
BeaconStateFork.Bellatrix
|
|
template toFork*[T: capella.BeaconState | capella.HashedBeaconState](
|
|
t: type T): BeaconStateFork =
|
|
BeaconStateFork.Capella
|
|
template toFork*[T: eip4844.BeaconState | eip4844.HashedBeaconState](
|
|
t: type T): BeaconStateFork =
|
|
BeaconStateFork.EIP4844
|
|
|
|
# TODO when https://github.com/nim-lang/Nim/issues/21086 fixed, use return type
|
|
# `ref T`
|
|
func new*(T: type ForkedHashedBeaconState, data: phase0.BeaconState):
|
|
ref ForkedHashedBeaconState =
|
|
(ref T)(kind: BeaconStateFork.Phase0, phase0Data: phase0.HashedBeaconState(
|
|
data: data, root: hash_tree_root(data)))
|
|
func new*(T: type ForkedHashedBeaconState, data: altair.BeaconState):
|
|
ref ForkedHashedBeaconState =
|
|
(ref T)(kind: BeaconStateFork.Altair, altairData: altair.HashedBeaconState(
|
|
data: data, root: hash_tree_root(data)))
|
|
func new*(T: type ForkedHashedBeaconState, data: bellatrix.BeaconState):
|
|
ref ForkedHashedBeaconState =
|
|
(ref T)(kind: BeaconStateFork.Bellatrix, bellatrixData: bellatrix.HashedBeaconState(
|
|
data: data, root: hash_tree_root(data)))
|
|
func new*(T: type ForkedHashedBeaconState, data: capella.BeaconState):
|
|
ref ForkedHashedBeaconState =
|
|
(ref T)(kind: BeaconStateFork.Capella, capellaData: capella.HashedBeaconState(
|
|
data: data, root: hash_tree_root(data)))
|
|
func new*(T: type ForkedHashedBeaconState, data: eip4844.BeaconState):
|
|
ref ForkedHashedBeaconState =
|
|
(ref T)(kind: BeaconStateFork.EIP4844, eip4844Data: eip4844.HashedBeaconState(
|
|
data: data, root: hash_tree_root(data)))
|
|
|
|
template init*(T: type ForkedBeaconBlock, blck: phase0.BeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
|
|
template init*(T: type ForkedBeaconBlock, blck: altair.BeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Altair, altairData: blck)
|
|
template init*(T: type ForkedBeaconBlock, blck: bellatrix.BeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
|
|
template init*(T: type ForkedBeaconBlock, blck: capella.BeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Capella, capellaData: blck)
|
|
|
|
template init*(T: type ForkedTrustedBeaconBlock, blck: phase0.TrustedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
|
|
template init*(T: type ForkedTrustedBeaconBlock, blck: altair.TrustedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Altair, altairData: blck)
|
|
template init*(T: type ForkedTrustedBeaconBlock, blck: bellatrix.TrustedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
|
|
template init*(T: type ForkedTrustedBeaconBlock, blck: capella.TrustedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Capella, capellaData: blck)
|
|
|
|
template init*(T: type ForkedSignedBeaconBlock, blck: phase0.SignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
|
|
template init*(T: type ForkedSignedBeaconBlock, blck: altair.SignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Altair, altairData: blck)
|
|
template init*(T: type ForkedSignedBeaconBlock, blck: bellatrix.SignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
|
|
template init*(T: type ForkedSignedBeaconBlock, blck: capella.SignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Capella, capellaData: blck)
|
|
template init*(T: type ForkedSignedBeaconBlock, blck: eip4844.SignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.EIP4844, eip4844Data: blck)
|
|
|
|
func init*(T: type ForkedSignedBeaconBlock, forked: ForkedBeaconBlock,
|
|
blockRoot: Eth2Digest, signature: ValidatorSig): T =
|
|
case forked.kind
|
|
of BeaconBlockFork.Phase0:
|
|
T(kind: BeaconBlockFork.Phase0,
|
|
phase0Data: phase0.SignedBeaconBlock(message: forked.phase0Data,
|
|
root: blockRoot,
|
|
signature: signature))
|
|
of BeaconBlockFork.Altair:
|
|
T(kind: BeaconBlockFork.Altair,
|
|
altairData: altair.SignedBeaconBlock(message: forked.altairData,
|
|
root: blockRoot,
|
|
signature: signature))
|
|
of BeaconBlockFork.Bellatrix:
|
|
T(kind: BeaconBlockFork.Bellatrix,
|
|
bellatrixData: bellatrix.SignedBeaconBlock(message: forked.bellatrixData,
|
|
root: blockRoot,
|
|
signature: signature))
|
|
of BeaconBlockFork.Capella:
|
|
T(kind: BeaconBlockFork.Capella,
|
|
capellaData: capella.SignedBeaconBlock(message: forked.capellaData,
|
|
root: blockRoot,
|
|
signature: signature))
|
|
of BeaconBlockFork.EIP4844:
|
|
T(kind: BeaconBlockFork.EIP4844,
|
|
eip4844Data: eip4844.SignedBeaconBlock(message: forked.eip4844Data,
|
|
root: blockRoot,
|
|
signature: signature))
|
|
|
|
func init*(T: type ForkedSignedBlindedBeaconBlock,
|
|
forked: ForkedBlindedBeaconBlock, blockRoot: Eth2Digest,
|
|
signature: ValidatorSig): T =
|
|
case forked.kind
|
|
of BeaconBlockFork.Phase0:
|
|
T(kind: BeaconBlockFork.Phase0,
|
|
phase0Data: phase0.SignedBeaconBlock(message: forked.phase0Data,
|
|
root: blockRoot,
|
|
signature: signature))
|
|
of BeaconBlockFork.Altair:
|
|
T(kind: BeaconBlockFork.Altair,
|
|
altairData: altair.SignedBeaconBlock(message: forked.altairData,
|
|
root: blockRoot,
|
|
signature: signature))
|
|
of BeaconBlockFork.Bellatrix:
|
|
T(kind: BeaconBlockFork.Bellatrix,
|
|
bellatrixData: SignedBlindedBeaconBlock(message: forked.bellatrixData,
|
|
signature: signature))
|
|
of BeaconBlockFork.Capella:
|
|
T(kind: BeaconBlockFork.Capella,
|
|
capellaData: SignedBlindedBeaconBlock(message: forked.capellaData,
|
|
signature: signature))
|
|
of BeaconBlockFork.EIP4844:
|
|
T(kind: BeaconBlockFork.EIP4844,
|
|
eip4844Data: SignedBlindedBeaconBlock(message: forked.eip4844Data,
|
|
signature: signature))
|
|
|
|
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: phase0.MsgTrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
|
|
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: altair.MsgTrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Altair, altairData: blck)
|
|
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: bellatrix.MsgTrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
|
|
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: capella.MsgTrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Capella, capellaData: blck)
|
|
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: eip4844.MsgTrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.EIP4844, eip4844Data: blck)
|
|
|
|
|
|
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: phase0.TrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
|
|
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: altair.TrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Altair, altairData: blck)
|
|
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: bellatrix.TrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
|
|
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: capella.TrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.Capella, capellaData: blck)
|
|
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: eip4844.TrustedSignedBeaconBlock): T =
|
|
T(kind: BeaconBlockFork.EIP4844, eip4844Data: blck)
|
|
|
|
template toString*(kind: BeaconBlockFork): string =
|
|
case kind
|
|
of BeaconBlockFork.Phase0:
|
|
"phase0"
|
|
of BeaconBlockFork.Altair:
|
|
"altair"
|
|
of BeaconBlockFork.Bellatrix:
|
|
"bellatrix"
|
|
of BeaconBlockFork.Capella:
|
|
"capella"
|
|
of BeaconBlockFork.EIP4844:
|
|
"eip4844"
|
|
|
|
template toString*(kind: BeaconStateFork): string =
|
|
case kind
|
|
of BeaconStateFork.Phase0:
|
|
"phase0"
|
|
of BeaconStateFork.Altair:
|
|
"altair"
|
|
of BeaconStateFork.Bellatrix:
|
|
"bellatrix"
|
|
of BeaconStateFork.Capella:
|
|
"capella"
|
|
of BeaconStateFork.EIP4844:
|
|
"eip4844"
|
|
|
|
template toFork*[T:
|
|
phase0.BeaconBlock |
|
|
phase0.SignedBeaconBlock |
|
|
phase0.TrustedBeaconBlock |
|
|
phase0.SigVerifiedSignedBeaconBlock |
|
|
phase0.MsgTrustedSignedBeaconBlock |
|
|
phase0.TrustedSignedBeaconBlock](
|
|
t: type T): BeaconBlockFork =
|
|
BeaconBlockFork.Phase0
|
|
|
|
template toFork*[T:
|
|
altair.BeaconBlock |
|
|
altair.SignedBeaconBlock |
|
|
altair.TrustedBeaconBlock |
|
|
altair.SigVerifiedSignedBeaconBlock |
|
|
altair.MsgTrustedSignedBeaconBlock |
|
|
altair.TrustedSignedBeaconBlock](
|
|
t: type T): BeaconBlockFork =
|
|
BeaconBlockFork.Altair
|
|
|
|
template toFork*[T:
|
|
bellatrix.ExecutionPayload |
|
|
bellatrix.BeaconBlock |
|
|
bellatrix.SignedBeaconBlock |
|
|
bellatrix.TrustedBeaconBlock |
|
|
bellatrix.SigVerifiedSignedBeaconBlock |
|
|
bellatrix.MsgTrustedSignedBeaconBlock |
|
|
bellatrix.TrustedSignedBeaconBlock](
|
|
t: type T): BeaconBlockFork =
|
|
BeaconBlockFork.Bellatrix
|
|
|
|
template toFork*[T:
|
|
capella.ExecutionPayload |
|
|
capella.BeaconBlock |
|
|
capella.SignedBeaconBlock |
|
|
capella.TrustedBeaconBlock |
|
|
capella.SigVerifiedSignedBeaconBlock |
|
|
capella.MsgTrustedSignedBeaconBlock |
|
|
capella.TrustedSignedBeaconBlock](
|
|
t: type T): BeaconBlockFork =
|
|
BeaconBlockFork.Capella
|
|
|
|
template toFork*[T:
|
|
eip4844.ExecutionPayload |
|
|
eip4844.BeaconBlock |
|
|
eip4844.SignedBeaconBlock |
|
|
eip4844.TrustedBeaconBlock |
|
|
eip4844.SigVerifiedSignedBeaconBlock |
|
|
eip4844.MsgTrustedSignedBeaconBlock |
|
|
eip4844.TrustedSignedBeaconBlock](
|
|
t: type T): BeaconBlockFork =
|
|
BeaconBlockFork.EIP4844
|
|
|
|
template init*(T: type ForkedEpochInfo, info: phase0.EpochInfo): T =
|
|
T(kind: EpochInfoFork.Phase0, phase0Data: info)
|
|
template init*(T: type ForkedEpochInfo, info: altair.EpochInfo): T =
|
|
T(kind: EpochInfoFork.Altair, altairData: info)
|
|
|
|
template withState*(x: ForkedHashedBeaconState, body: untyped): untyped =
|
|
case x.kind
|
|
of BeaconStateFork.EIP4844:
|
|
const stateFork {.inject, used.} = BeaconStateFork.EIP4844
|
|
template forkyState: untyped {.inject, used.} = x.eip4844Data
|
|
body
|
|
of BeaconStateFork.Capella:
|
|
const stateFork {.inject, used.} = BeaconStateFork.Capella
|
|
template forkyState: untyped {.inject, used.} = x.capellaData
|
|
body
|
|
of BeaconStateFork.Bellatrix:
|
|
const stateFork {.inject, used.} = BeaconStateFork.Bellatrix
|
|
template forkyState: untyped {.inject, used.} = x.bellatrixData
|
|
body
|
|
of BeaconStateFork.Altair:
|
|
const stateFork {.inject, used.} = BeaconStateFork.Altair
|
|
template forkyState: untyped {.inject, used.} = x.altairData
|
|
body
|
|
of BeaconStateFork.Phase0:
|
|
const stateFork {.inject, used.} = BeaconStateFork.Phase0
|
|
template forkyState: untyped {.inject, used.} = x.phase0Data
|
|
body
|
|
|
|
template withEpochInfo*(x: ForkedEpochInfo, body: untyped): untyped =
|
|
case x.kind
|
|
of EpochInfoFork.Phase0:
|
|
const infoFork {.inject.} = EpochInfoFork.Phase0
|
|
template info: untyped {.inject.} = x.phase0Data
|
|
body
|
|
of EpochInfoFork.Altair:
|
|
const infoFork {.inject.} = EpochInfoFork.Altair
|
|
template info: untyped {.inject.} = x.altairData
|
|
body
|
|
|
|
template withEpochInfo*(
|
|
state: phase0.BeaconState, x: var ForkedEpochInfo, body: untyped): untyped =
|
|
if x.kind != EpochInfoFork.Phase0:
|
|
# Rare, should never happen even, so efficiency a non-issue
|
|
x = ForkedEpochInfo(kind: EpochInfoFork.Phase0)
|
|
template info: untyped {.inject.} = x.phase0Data
|
|
body
|
|
|
|
template withEpochInfo*(
|
|
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
|
eip4844.BeaconState,
|
|
x: var ForkedEpochInfo, body: untyped): untyped =
|
|
if x.kind != EpochInfoFork.Altair:
|
|
# Rare, so efficiency not critical
|
|
x = ForkedEpochInfo(kind: EpochInfoFork.Altair)
|
|
template info: untyped {.inject.} = x.altairData
|
|
body
|
|
|
|
func assign*(tgt: var ForkedHashedBeaconState, src: ForkedHashedBeaconState) =
|
|
if tgt.kind == src.kind:
|
|
case tgt.kind
|
|
of BeaconStateFork.EIP4844:
|
|
assign(tgt.eip4844Data, src.eip4844Data):
|
|
of BeaconStateFork.Capella:
|
|
assign(tgt.capellaData, src.capellaData):
|
|
of BeaconStateFork.Bellatrix:
|
|
assign(tgt.bellatrixData, src.bellatrixData):
|
|
of BeaconStateFork.Altair:
|
|
assign(tgt.altairData, src.altairData):
|
|
of BeaconStateFork.Phase0:
|
|
assign(tgt.phase0Data, src.phase0Data):
|
|
else:
|
|
# Ensure case object and discriminator get updated simultaneously, even
|
|
# with nimOldCaseObjects. This is infrequent.
|
|
tgt = src
|
|
|
|
template getStateField*(x: ForkedHashedBeaconState, y: untyped): untyped =
|
|
# The use of `unsafeAddr` avoids excessive copying in certain situations, e.g.,
|
|
# ```
|
|
# for index, validator in getStateField(stateData.data, validators):
|
|
# ```
|
|
# Without `unsafeAddr`, the `validators` list would be copied to a temporary variable.
|
|
(case x.kind
|
|
of BeaconStateFork.EIP4844: unsafeAddr x.eip4844Data.data.y
|
|
of BeaconStateFork.Capella: unsafeAddr x.capellaData.data.y
|
|
of BeaconStateFork.Bellatrix: unsafeAddr x.bellatrixData.data.y
|
|
of BeaconStateFork.Altair: unsafeAddr x.altairData.data.y
|
|
of BeaconStateFork.Phase0: unsafeAddr x.phase0Data.data.y)[]
|
|
|
|
func getStateRoot*(x: ForkedHashedBeaconState): Eth2Digest =
|
|
withState(x): forkyState.root
|
|
|
|
func setStateRoot*(x: var ForkedHashedBeaconState, root: Eth2Digest) =
|
|
withState(x): forkyState.root = root
|
|
|
|
func stateForkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): BeaconStateFork =
|
|
## Return the current fork for the given epoch.
|
|
static:
|
|
doAssert high(BeaconStateFork) == BeaconStateFork.EIP4844
|
|
doAssert BeaconStateFork.EIP4844 > BeaconStateFork.Capella
|
|
doAssert BeaconStateFork.Capella > BeaconStateFork.Bellatrix
|
|
doAssert BeaconStateFork.Bellatrix > BeaconStateFork.Altair
|
|
doAssert BeaconStateFork.Altair > BeaconStateFork.Phase0
|
|
doAssert GENESIS_EPOCH == 0
|
|
|
|
if epoch >= cfg.EIP4844_FORK_EPOCH: BeaconStateFork.EIP4844
|
|
elif epoch >= cfg.CAPELLA_FORK_EPOCH: BeaconStateFork.Capella
|
|
elif epoch >= cfg.BELLATRIX_FORK_EPOCH: BeaconStateFork.Bellatrix
|
|
elif epoch >= cfg.ALTAIR_FORK_EPOCH: BeaconStateFork.Altair
|
|
else: BeaconStateFork.Phase0
|
|
|
|
func blockForkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): BeaconBlockFork =
|
|
## Return the current fork for the given epoch.
|
|
static: doAssert high(BeaconBlockFork) == BeaconBlockFork.EIP4844
|
|
if epoch >= cfg.EIP4844_FORK_EPOCH: BeaconBlockFork.EIP4844
|
|
elif epoch >= cfg.CAPELLA_FORK_EPOCH: BeaconBlockFork.Capella
|
|
elif epoch >= cfg.BELLATRIX_FORK_EPOCH: BeaconBlockFork.Bellatrix
|
|
elif epoch >= cfg.ALTAIR_FORK_EPOCH: BeaconBlockFork.Altair
|
|
else: BeaconBlockFork.Phase0
|
|
|
|
func stateForkForDigest*(
|
|
forkDigests: ForkDigests, forkDigest: ForkDigest): Opt[BeaconStateFork] =
|
|
static: doAssert high(BeaconStateFork) == BeaconStateFork.EIP4844
|
|
if forkDigest == forkDigests.eip4844:
|
|
ok BeaconStateFork.EIP4844
|
|
elif forkDigest == forkDigests.capella:
|
|
ok BeaconStateFork.Capella
|
|
elif forkDigest == forkDigests.bellatrix:
|
|
ok BeaconStateFork.Bellatrix
|
|
elif forkDigest == forkDigests.altair:
|
|
ok BeaconStateFork.Altair
|
|
elif forkDigest == forkDigests.phase0:
|
|
ok BeaconStateFork.Phase0
|
|
else:
|
|
err()
|
|
|
|
func atStateFork*(
|
|
forkDigests: ForkDigests, stateFork: BeaconStateFork): ForkDigest =
|
|
case stateFork
|
|
of BeaconStateFork.EIP4844:
|
|
forkDigests.eip4844
|
|
of BeaconStateFork.Capella:
|
|
forkDigests.capella
|
|
of BeaconStateFork.Bellatrix:
|
|
forkDigests.bellatrix
|
|
of BeaconStateFork.Altair:
|
|
forkDigests.altair
|
|
of BeaconStateFork.Phase0:
|
|
forkDigests.phase0
|
|
|
|
template atEpoch*(
|
|
forkDigests: ForkDigests, epoch: Epoch, cfg: RuntimeConfig): ForkDigest =
|
|
forkDigests.atStateFork(cfg.stateForkAtEpoch(epoch))
|
|
|
|
template asSigned*(
|
|
x: ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock
|
|
): ForkedSignedBeaconBlock =
|
|
isomorphicCast[ForkedSignedBeaconBlock](x)
|
|
|
|
template asSigned*(
|
|
x: ref ForkedMsgTrustedSignedBeaconBlock |
|
|
ref ForkedTrustedSignedBeaconBlock
|
|
): ref ForkedSignedBeaconBlock =
|
|
isomorphicCast[ref ForkedSignedBeaconBlock](x)
|
|
|
|
template asMsgTrusted*(
|
|
x: ForkedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock
|
|
): ForkedMsgTrustedSignedBeaconBlock =
|
|
isomorphicCast[ForkedMsgTrustedSignedBeaconBlock](x)
|
|
|
|
template asMsgTrusted*(
|
|
x: ref ForkedSignedBeaconBlock |
|
|
ref ForkedTrustedSignedBeaconBlock
|
|
): ref ForkedMsgTrustedSignedBeaconBlock =
|
|
isomorphicCast[ref ForkedMsgTrustedSignedBeaconBlock](x)
|
|
|
|
template asTrusted*(
|
|
x: ForkedSignedBeaconBlock |
|
|
ForkedMsgTrustedSignedBeaconBlock
|
|
): ForkedTrustedSignedBeaconBlock =
|
|
isomorphicCast[ForkedTrustedSignedBeaconBlock](x)
|
|
|
|
template asTrusted*(
|
|
x: ref ForkedSignedBeaconBlock |
|
|
ref ForkedMsgTrustedSignedBeaconBlock
|
|
): ref ForkedTrustedSignedBeaconBlock =
|
|
isomorphicCast[ref ForkedTrustedSignedBeaconBlock](x)
|
|
|
|
template withBlck*(
|
|
x: ForkedBeaconBlock | Web3SignerForkedBeaconBlock |
|
|
ForkedSignedBeaconBlock | ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock | ForkedBlindedBeaconBlock |
|
|
ForkedSignedBlindedBeaconBlock,
|
|
body: untyped): untyped =
|
|
case x.kind
|
|
of BeaconBlockFork.Phase0:
|
|
const stateFork {.inject, used.} = BeaconStateFork.Phase0
|
|
template blck: untyped {.inject.} = x.phase0Data
|
|
body
|
|
of BeaconBlockFork.Altair:
|
|
const stateFork {.inject, used.} = BeaconStateFork.Altair
|
|
template blck: untyped {.inject.} = x.altairData
|
|
body
|
|
of BeaconBlockFork.Bellatrix:
|
|
const stateFork {.inject, used.} = BeaconStateFork.Bellatrix
|
|
template blck: untyped {.inject.} = x.bellatrixData
|
|
body
|
|
of BeaconBlockFork.Capella:
|
|
const stateFork {.inject, used.} = BeaconStateFork.Capella
|
|
template blck: untyped {.inject.} = x.capellaData
|
|
body
|
|
of BeaconBlockFork.EIP4844:
|
|
const stateFork {.inject, used.} = BeaconStateFork.EIP4844
|
|
template blck: untyped {.inject.} = x.eip4844Data
|
|
body
|
|
|
|
func proposer_index*(x: ForkedBeaconBlock): uint64 =
|
|
withBlck(x): blck.proposer_index
|
|
|
|
func hash_tree_root*(x: ForkedBeaconBlock | Web3SignerForkedBeaconBlock):
|
|
Eth2Digest =
|
|
withBlck(x): hash_tree_root(blck)
|
|
|
|
template getForkedBlockField*(
|
|
x: ForkedSignedBeaconBlock |
|
|
ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock,
|
|
y: untyped): untyped =
|
|
# unsafeAddr avoids a copy of the field in some cases
|
|
(case x.kind
|
|
of BeaconBlockFork.Phase0: unsafeAddr x.phase0Data.message.y
|
|
of BeaconBlockFork.Altair: unsafeAddr x.altairData.message.y
|
|
of BeaconBlockFork.Bellatrix: unsafeAddr x.bellatrixData.message.y
|
|
of BeaconBlockFork.Capella: unsafeAddr x.capellaData.message.y
|
|
of BeaconBlockFork.EIP4844: unsafeAddr x.eip4844Data.message.y)[]
|
|
|
|
template signature*(x: ForkedSignedBeaconBlock |
|
|
ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedSignedBlindedBeaconBlock): ValidatorSig =
|
|
withBlck(x): blck.signature
|
|
|
|
template signature*(x: ForkedTrustedSignedBeaconBlock): TrustedSig =
|
|
withBlck(x): blck.signature
|
|
|
|
template root*(x: ForkedSignedBeaconBlock |
|
|
ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock): Eth2Digest =
|
|
withBlck(x): blck.root
|
|
|
|
template slot*(x: ForkedSignedBeaconBlock |
|
|
ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock): Slot =
|
|
withBlck(x): blck.message.slot
|
|
|
|
template shortLog*(x: ForkedBeaconBlock | ForkedBlindedBeaconBlock): auto =
|
|
withBlck(x): shortLog(blck)
|
|
|
|
template shortLog*(x: ForkedSignedBeaconBlock |
|
|
ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock |
|
|
ForkedSignedBlindedBeaconBlock): auto =
|
|
withBlck(x): shortLog(blck)
|
|
|
|
chronicles.formatIt ForkedBeaconBlock: it.shortLog
|
|
chronicles.formatIt ForkedSignedBeaconBlock: it.shortLog
|
|
chronicles.formatIt ForkedMsgTrustedSignedBeaconBlock: it.shortLog
|
|
chronicles.formatIt ForkedTrustedSignedBeaconBlock: it.shortLog
|
|
|
|
template withStateAndBlck*(
|
|
s: ForkedHashedBeaconState,
|
|
b: ForkedBeaconBlock | ForkedSignedBeaconBlock |
|
|
ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock,
|
|
body: untyped): untyped =
|
|
case s.kind
|
|
of BeaconStateFork.EIP4844:
|
|
const stateFork {.inject.} = BeaconStateFork.EIP4844
|
|
template forkyState: untyped {.inject.} = s.eip4844Data
|
|
template blck: untyped {.inject.} = b.eip4844Data
|
|
body
|
|
of BeaconStateFork.Capella:
|
|
const stateFork {.inject.} = BeaconStateFork.Capella
|
|
template forkyState: untyped {.inject.} = s.capellaData
|
|
template blck: untyped {.inject.} = b.capellaData
|
|
body
|
|
of BeaconStateFork.Bellatrix:
|
|
const stateFork {.inject.} = BeaconStateFork.Bellatrix
|
|
template forkyState: untyped {.inject.} = s.bellatrixData
|
|
template blck: untyped {.inject.} = b.bellatrixData
|
|
body
|
|
of BeaconStateFork.Altair:
|
|
const stateFork {.inject.} = BeaconStateFork.Altair
|
|
template forkyState: untyped {.inject.} = s.altairData
|
|
template blck: untyped {.inject.} = b.altairData
|
|
body
|
|
of BeaconStateFork.Phase0:
|
|
const stateFork {.inject.} = BeaconStateFork.Phase0
|
|
template forkyState: untyped {.inject.} = s.phase0Data
|
|
template blck: untyped {.inject.} = b.phase0Data
|
|
body
|
|
|
|
func toBeaconBlockHeader*(
|
|
blck: SomeForkyBeaconBlock | BlindedBeaconBlock): BeaconBlockHeader =
|
|
## Reduce a given `BeaconBlock` to its `BeaconBlockHeader`.
|
|
BeaconBlockHeader(
|
|
slot: blck.slot,
|
|
proposer_index: blck.proposer_index,
|
|
parent_root: blck.parent_root,
|
|
state_root: blck.state_root,
|
|
body_root: blck.body.hash_tree_root())
|
|
|
|
template toBeaconBlockHeader*(
|
|
blck: SomeForkySignedBeaconBlock): BeaconBlockHeader =
|
|
## Reduce a given `SignedBeaconBlock` to its `BeaconBlockHeader`.
|
|
blck.message.toBeaconBlockHeader
|
|
|
|
template toBeaconBlockHeader*(
|
|
blckParam: ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock): BeaconBlockHeader =
|
|
## Reduce a given signed beacon block to its `BeaconBlockHeader`.
|
|
withBlck(blckParam): blck.toBeaconBlockHeader()
|
|
|
|
func genesisFork*(cfg: RuntimeConfig): Fork =
|
|
Fork(
|
|
previous_version: cfg.GENESIS_FORK_VERSION,
|
|
current_version: cfg.GENESIS_FORK_VERSION,
|
|
epoch: GENESIS_EPOCH)
|
|
|
|
func altairFork*(cfg: RuntimeConfig): Fork =
|
|
Fork(
|
|
previous_version: cfg.GENESIS_FORK_VERSION,
|
|
current_version: cfg.ALTAIR_FORK_VERSION,
|
|
epoch: cfg.ALTAIR_FORK_EPOCH)
|
|
|
|
func bellatrixFork*(cfg: RuntimeConfig): Fork =
|
|
Fork(
|
|
previous_version: cfg.ALTAIR_FORK_VERSION,
|
|
current_version: cfg.BELLATRIX_FORK_VERSION,
|
|
epoch: cfg.BELLATRIX_FORK_EPOCH)
|
|
|
|
func capellaFork*(cfg: RuntimeConfig): Fork =
|
|
Fork(
|
|
previous_version: cfg.BELLATRIX_FORK_VERSION,
|
|
current_version: cfg.CAPELLA_FORK_VERSION,
|
|
epoch: cfg.CAPELLA_FORK_EPOCH)
|
|
|
|
func eip4844Fork*(cfg: RuntimeConfig): Fork =
|
|
Fork(
|
|
previous_version: cfg.CAPELLA_FORK_VERSION,
|
|
current_version: cfg.EIP4844_FORK_VERSION,
|
|
epoch: cfg.EIP4844_FORK_EPOCH)
|
|
|
|
func forkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Fork =
|
|
case cfg.stateForkAtEpoch(epoch)
|
|
of BeaconStateFork.EIP4844: cfg.eip4844Fork
|
|
of BeaconStateFork.Capella: cfg.capellaFork
|
|
of BeaconStateFork.Bellatrix: cfg.bellatrixFork
|
|
of BeaconStateFork.Altair: cfg.altairFork
|
|
of BeaconStateFork.Phase0: cfg.genesisFork
|
|
|
|
func forkVersionAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Version =
|
|
case cfg.stateForkAtEpoch(epoch)
|
|
of BeaconStateFork.EIP4844: cfg.EIP4844_FORK_VERSION
|
|
of BeaconStateFork.Capella: cfg.CAPELLA_FORK_VERSION
|
|
of BeaconStateFork.Bellatrix: cfg.BELLATRIX_FORK_VERSION
|
|
of BeaconStateFork.Altair: cfg.ALTAIR_FORK_VERSION
|
|
of BeaconStateFork.Phase0: cfg.GENESIS_FORK_VERSION
|
|
|
|
func nextForkEpochAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Epoch =
|
|
case cfg.stateForkAtEpoch(epoch)
|
|
of BeaconStateFork.EIP4844: FAR_FUTURE_EPOCH
|
|
of BeaconStateFork.Capella: cfg.EIP4844_FORK_EPOCH
|
|
of BeaconStateFork.Bellatrix: cfg.CAPELLA_FORK_EPOCH
|
|
of BeaconStateFork.Altair: cfg.BELLATRIX_FORK_EPOCH
|
|
of BeaconStateFork.Phase0: cfg.ALTAIR_FORK_EPOCH
|
|
|
|
func getForkSchedule*(cfg: RuntimeConfig): array[5, Fork] =
|
|
## This procedure returns list of known and/or scheduled forks.
|
|
##
|
|
## This procedure is used by HTTP REST framework and validator client.
|
|
##
|
|
## NOTE: Update this procedure when new fork will be scheduled.
|
|
[cfg.genesisFork(), cfg.altairFork(), cfg.bellatrixFork(), cfg.capellaFork(),
|
|
cfg.eip4844Fork()]
|
|
|
|
type
|
|
# The first few fields of a state, shared across all forks
|
|
BeaconStateHeader = object
|
|
genesis_time: uint64
|
|
genesis_validators_root: Eth2Digest
|
|
slot: Slot
|
|
|
|
func readSszForkedHashedBeaconState*(
|
|
cfg: RuntimeConfig, slot: Slot, data: openArray[byte]):
|
|
ForkedHashedBeaconState {.raises: [Defect, SszError].} =
|
|
# TODO https://github.com/nim-lang/Nim/issues/19357
|
|
result = ForkedHashedBeaconState(
|
|
kind: cfg.stateForkAtEpoch(slot.epoch()))
|
|
|
|
withState(result):
|
|
readSszBytes(data, forkyState.data)
|
|
forkyState.root = hash_tree_root(forkyState.data)
|
|
|
|
func readSszForkedHashedBeaconState*(cfg: RuntimeConfig, data: openArray[byte]):
|
|
ForkedHashedBeaconState {.raises: [Defect, SszError].} =
|
|
## Read a state picking the right fork by first reading the slot from the byte
|
|
## source
|
|
if data.len() < sizeof(BeaconStateHeader):
|
|
raise (ref MalformedSszError)(msg: "Not enough data for BeaconState header")
|
|
let header = SSZ.decode(
|
|
data.toOpenArray(0, sizeof(BeaconStateHeader) - 1),
|
|
BeaconStateHeader)
|
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/19357
|
|
result = readSszForkedHashedBeaconState(cfg, header.slot, data)
|
|
|
|
type
|
|
ForkedBeaconBlockHeader = object
|
|
message*: uint32 # message offset
|
|
signature*: ValidatorSig
|
|
slot: Slot # start of BeaconBlock
|
|
|
|
func readSszForkedSignedBeaconBlock*(
|
|
cfg: RuntimeConfig, data: openArray[byte]):
|
|
ForkedSignedBeaconBlock {.raises: [Defect, SszError].} =
|
|
## Helper to read a header from bytes when it's not certain what kind of block
|
|
## it is
|
|
if data.len() < sizeof(ForkedBeaconBlockHeader):
|
|
raise (ref MalformedSszError)(msg: "Not enough data for SignedBeaconBlock header")
|
|
let header = SSZ.decode(
|
|
data.toOpenArray(0, sizeof(ForkedBeaconBlockHeader) - 1),
|
|
ForkedBeaconBlockHeader)
|
|
|
|
# TODO https://github.com/nim-lang/Nim/issues/19357
|
|
result = ForkedSignedBeaconBlock(
|
|
kind: cfg.blockForkAtEpoch(header.slot.epoch()))
|
|
|
|
withBlck(result):
|
|
readSszBytes(data, blck)
|
|
|
|
func toBeaconBlockFork*(fork: BeaconStateFork): BeaconBlockFork =
|
|
case fork
|
|
of BeaconStateFork.Phase0: BeaconBlockFork.Phase0
|
|
of BeaconStateFork.Altair: BeaconBlockFork.Altair
|
|
of BeaconStateFork.Bellatrix: BeaconBlockFork.Bellatrix
|
|
of BeaconStateFork.Capella: BeaconBlockFork.Capella
|
|
of BeaconStateFork.EIP4844: BeaconBlockFork.EIP4844
|
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.0/specs/phase0/beacon-chain.md#compute_fork_data_root
|
|
func compute_fork_data_root*(current_version: Version,
|
|
genesis_validators_root: Eth2Digest): Eth2Digest =
|
|
## Return the 32-byte fork data root for the ``current_version`` and
|
|
## ``genesis_validators_root``.
|
|
## This is used primarily in signature domains to avoid collisions across
|
|
## forks/chains.
|
|
hash_tree_root(ForkData(
|
|
current_version: current_version,
|
|
genesis_validators_root: genesis_validators_root
|
|
))
|
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-rc.0/specs/phase0/beacon-chain.md#compute_fork_digest
|
|
func compute_fork_digest*(current_version: Version,
|
|
genesis_validators_root: Eth2Digest): ForkDigest =
|
|
## Return the 4-byte fork digest for the ``current_version`` and
|
|
## ``genesis_validators_root``.
|
|
## This is a digest primarily used for domain separation on the p2p layer.
|
|
## 4-bytes suffices for practical separation of forks/chains.
|
|
array[4, byte](result)[0..3] =
|
|
compute_fork_data_root(
|
|
current_version, genesis_validators_root).data.toOpenArray(0, 3)
|
|
|
|
func init*(T: type ForkDigests,
|
|
cfg: RuntimeConfig,
|
|
genesis_validators_root: Eth2Digest): T =
|
|
static: doAssert high(BeaconStateFork) == BeaconStateFork.EIP4844
|
|
T(
|
|
phase0:
|
|
compute_fork_digest(cfg.GENESIS_FORK_VERSION, genesis_validators_root),
|
|
altair:
|
|
compute_fork_digest(cfg.ALTAIR_FORK_VERSION, genesis_validators_root),
|
|
bellatrix:
|
|
compute_fork_digest(cfg.BELLATRIX_FORK_VERSION, genesis_validators_root),
|
|
capella:
|
|
compute_fork_digest(cfg.CAPELLA_FORK_VERSION, genesis_validators_root),
|
|
eip4844:
|
|
compute_fork_digest(cfg.EIP4844_FORK_VERSION, genesis_validators_root)
|
|
)
|
|
|
|
func toBlockId*(header: BeaconBlockHeader): BlockId =
|
|
BlockId(root: header.hash_tree_root(), slot: header.slot)
|
|
|
|
func toBlockId*(blck: SomeForkySignedBeaconBlock): BlockId =
|
|
BlockId(root: blck.root, slot: blck.message.slot)
|
|
|
|
func toBlockId*(blck: ForkedSignedBeaconBlock |
|
|
ForkedMsgTrustedSignedBeaconBlock |
|
|
ForkedTrustedSignedBeaconBlock): BlockId =
|
|
withBlck(blck): BlockId(root: blck.root, slot: blck.message.slot)
|