nimbus-eth2/beacon_chain/spec/forks.nim

442 lines
17 KiB
Nim
Raw Normal View History

# beacon_chain
# Copyright (c) 2021 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: [Defect].}
import
std/macros,
chronicles,
stew/[assign2, results],
../extras,
../spec/[beaconstate, helpers, state_transition_block, validator],
./datatypes/[phase0, altair, merge]
export extras, phase0, altair
type
BeaconStateFork* = enum
forkPhase0,
forkAltair,
forkMerge
ForkedHashedBeaconState* = object
case beaconStateFork*: BeaconStateFork
of forkPhase0: hbsPhase0*: phase0.HashedBeaconState
of forkAltair: hbsAltair*: altair.HashedBeaconState
of forkMerge: hbsMerge*: merge.HashedBeaconState
ForkedBeaconState* = object
case beaconStateFork*: BeaconStateFork
of forkPhase0: bsPhase0*: phase0.BeaconState
of forkAltair: bsAltair*: altair.BeaconState
of forkMerge: bsMerge*: merge.BeaconState
BeaconBlockFork* {.pure.} = enum
Phase0
Altair
Merge
ForkedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0:
phase0Block*: phase0.BeaconBlock
of BeaconBlockFork.Altair:
altairBlock*: altair.BeaconBlock
of BeaconBlockFork.Merge:
mergeBlock*: merge.BeaconBlock
ForkedSignedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0:
phase0Block*: phase0.SignedBeaconBlock
of BeaconBlockFork.Altair:
altairBlock*: altair.SignedBeaconBlock
of BeaconBlockFork.Merge:
mergeBlock*: merge.SignedBeaconBlock
ForkedTrustedSignedBeaconBlock* = object
case kind*: BeaconBlockFork
of BeaconBlockFork.Phase0:
phase0Block*: phase0.TrustedSignedBeaconBlock
of BeaconBlockFork.Altair:
altairBlock*: altair.TrustedSignedBeaconBlock
of BeaconBlockFork.Merge:
mergeBlock*: merge.TrustedSignedBeaconBlock
ForkDigests* = object
phase0*: ForkDigest
altair*: ForkDigest
merge*: ForkDigest # TODO where does this get filled
altairTopicPrefix*: string # Used by isAltairTopic
ForkDigestsRef* = ref ForkDigests
template init*(T: type ForkedBeaconBlock, blck: phase0.BeaconBlock): T =
T(kind: BeaconBlockFork.Phase0, phase0Block: blck)
template init*(T: type ForkedBeaconBlock, blck: altair.BeaconBlock): T =
T(kind: BeaconBlockFork.Altair, altairBlock: blck)
template init*(T: type ForkedBeaconBlock, blck: merge.BeaconBlock): T =
T(kind: BeaconBlockFork.Merge, mergeBlock: blck)
template init*(T: type ForkedSignedBeaconBlock, blck: phase0.SignedBeaconBlock): T =
T(kind: BeaconBlockFork.Phase0, phase0Block: blck)
template init*(T: type ForkedSignedBeaconBlock, blck: altair.SignedBeaconBlock): T =
T(kind: BeaconBlockFork.Altair, altairBlock: blck)
template init*(T: type ForkedSignedBeaconBlock, blck: merge.SignedBeaconBlock): T =
T(kind: BeaconBlockFork.Merge, mergeBlock: blck)
template init*(T: type ForkedBeaconState, state: phase0.BeaconState): T =
T(beaconStateFork: BeaconStateFork.forkPhase0, bsPhase0: state)
template init*(T: type ForkedBeaconState, state: altair.BeaconState): T =
T(beaconStateFork: BeaconStateFork.forkAltair, bsAltair: state)
template init*(T: type ForkedBeaconState, state: merge.BeaconState): T =
T(beaconStateFork: BeaconStateFork.forkMerge, bsMerge: state)
template init*(T: type ForkedBeaconState, state: ForkedHashedBeaconState): T =
case state.beaconStateFork
of BeaconStateFork.forkPhase0:
T(beaconStateFork: BeaconStateFork.forkPhase0,
bsPhase0: state.hbsPhase0.data)
of BeaconStateFork.forkAltair:
T(beaconStateFork: BeaconStateFork.forkAltair,
bsAltair: state.hbsAltair.data)
of BeaconStateFork.forkMerge:
T(beaconStateFork: BeaconStateFork.forkMerge,
bsMerge: state.hbsMerge.data)
template init*(T: type ForkedSignedBeaconBlock, forked: ForkedBeaconBlock,
blockRoot: Eth2Digest, signature: ValidatorSig): T =
case forked.kind
of BeaconBlockFork.Phase0:
T(kind: BeaconBlockFork.Phase0,
phase0Block: phase0.SignedBeaconBlock(message: forked.phase0Block,
root: blockRoot,
signature: signature))
of BeaconBlockFork.Altair:
T(kind: BeaconBlockFork.Altair,
altairBlock: altair.SignedBeaconBlock(message: forked.altairBlock,
root: blockRoot,
signature: signature))
of BeaconBlockFork.Merge:
T(kind: BeaconBlockFork.Merge,
mergeBlock: merge.SignedBeaconBlock(message: forked.mergeBlock,
root: blockRoot,
signature: signature))
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: phase0.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Phase0, phase0Block: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: altair.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Altair, altairBlock: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: merge.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Merge, mergeBlock: blck)
# State-related functionality based on ForkedHashedBeaconState instead of BeaconState
# Dispatch functions
func assign*(tgt: var ForkedHashedBeaconState, src: ForkedHashedBeaconState) =
if tgt.beaconStateFork == src.beaconStateFork:
if tgt.beaconStateFork == forkPhase0:
assign(tgt.hbsPhase0, src.hbsPhase0):
elif tgt.beaconStateFork == forkAltair:
assign(tgt.hbsAltair, src.hbsAltair):
else:
doAssert false
else:
# Ensure case object and discriminator get updated simultaneously, even
# with nimOldCaseObjects. This is infrequent.
tgt = src
template getStateField*(x, y: untyped): untyped =
# The use of `unsafeAddr` avoids excessive copying in certain situations, e.g.,
# ```
# for index, validator in getStateField(stateData.data, validators).pairs():
# ```
# Without `unsafeAddr`, the `validators` list would be copied to a temporary variable.
(case x.beaconStateFork
of forkPhase0: unsafeAddr (x.hbsPhase0.data.y)
of forkAltair: unsafeAddr (x.hbsAltair.data.y)
of forkMerge: unsafeAddr (x.hbsMerge.data.y))[]
template getStateRoot*(x: ForkedHashedBeaconState): Eth2Digest =
case x.beaconStateFork:
of forkPhase0: x.hbsPhase0.root
of forkAltair: x.hbsAltair.root
of forkMerge: x.hbsMerge.root
func setStateRoot*(x: var ForkedHashedBeaconState, root: Eth2Digest) =
case x.beaconStateFork:
of forkPhase0: x.hbsPhase0.root = root
of forkAltair: x.hbsAltair.root = root
of forkMerge: x.hbsMerge.root = root
template hash_tree_root*(x: ForkedHashedBeaconState): Eth2Digest =
case x.beaconStateFork:
of forkPhase0: hash_tree_root(x.hbsPhase0.data)
of forkAltair: hash_tree_root(x.hbsAltair.data)
of forkMerge: hash_tree_root(x.hbsMerge.data)
template hash_tree_root*(blk: ForkedBeaconBlock): Eth2Digest =
case blk.kind
of BeaconBlockFork.Phase0:
hash_tree_root(blk.phase0Block)
of BeaconBlockFork.Altair:
hash_tree_root(blk.altairBlock)
of BeaconBlockFork.Merge:
hash_tree_root(blk.mergeBlock)
template proposer_index*(blk: ForkedBeaconBlock): uint64 =
case blk.kind
of BeaconBlockFork.Phase0:
blk.phase0Block.proposer_index
of BeaconBlockFork.Altair:
blk.altairBlock.proposer_index
of BeaconBlockFork.Merge:
blk.mergeBlock.proposer_index
func get_active_validator_indices_len*(
state: ForkedHashedBeaconState; epoch: Epoch): uint64 =
case state.beaconStateFork:
of forkPhase0:
get_active_validator_indices_len(state.hbsPhase0.data, epoch)
of forkAltair:
get_active_validator_indices_len(state.hbsAltair.data, epoch)
of forkMerge:
get_active_validator_indices_len(state.hbsMerge.data, epoch)
func get_beacon_committee*(
state: ForkedHashedBeaconState, slot: Slot, index: CommitteeIndex,
cache: var StateCache): seq[ValidatorIndex] =
# This one is used by tests/, ncli/, and a couple of places in RPC
# TODO use the iterator version alone, to remove the risk of using
# diverging get_beacon_committee() in tests and beacon_chain/ by a
# wrapper approach (e.g., toSeq). This is a perf tradeoff for test
# correctness/consistency.
case state.beaconStateFork:
of forkPhase0: get_beacon_committee(state.hbsPhase0.data, slot, index, cache)
of forkAltair: get_beacon_committee(state.hbsAltair.data, slot, index, cache)
of forkMerge: get_beacon_committee(state.hbsMerge.data, slot, index, cache)
func get_beacon_committee_len*(
state: ForkedHashedBeaconState, slot: Slot, index: CommitteeIndex,
cache: var StateCache): uint64 =
# This one is used by tests
case state.beaconStateFork:
of forkPhase0: get_beacon_committee_len(state.hbsPhase0.data, slot, index, cache)
of forkAltair: get_beacon_committee_len(state.hbsAltair.data, slot, index, cache)
of forkMerge: get_beacon_committee_len(state.hbsMerge.data, slot, index, cache)
func get_committee_count_per_slot*(state: ForkedHashedBeaconState,
epoch: Epoch,
cache: var StateCache): uint64 =
## Return the number of committees at ``epoch``.
case state.beaconStateFork:
of forkPhase0: get_committee_count_per_slot(state.hbsPhase0.data, epoch, cache)
of forkAltair: get_committee_count_per_slot(state.hbsAltair.data, epoch, cache)
of forkMerge: get_committee_count_per_slot(state.hbsMerge.data, epoch, cache)
func get_beacon_proposer_index*(state: ForkedHashedBeaconState,
cache: var StateCache, slot: Slot):
Option[ValidatorIndex] =
case state.beaconStateFork:
of forkPhase0: get_beacon_proposer_index(state.hbsPhase0.data, cache, slot)
of forkAltair: get_beacon_proposer_index(state.hbsAltair.data, cache, slot)
of forkMerge: get_beacon_proposer_index(state.hbsMerge.data, cache, slot)
func get_shuffled_active_validator_indices*(
cache: var StateCache, state: ForkedHashedBeaconState, epoch: Epoch):
seq[ValidatorIndex] =
case state.beaconStateFork:
of forkPhase0:
cache.get_shuffled_active_validator_indices(state.hbsPhase0.data, epoch)
of forkAltair:
cache.get_shuffled_active_validator_indices(state.hbsAltair.data, epoch)
of forkMerge:
cache.get_shuffled_active_validator_indices(state.hbsMerge.data, epoch)
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_block_root_at_slot
func get_block_root_at_slot*(state: ForkedHashedBeaconState,
slot: Slot): Eth2Digest =
## Return the block root at a recent ``slot``.
case state.beaconStateFork:
of forkPhase0: get_block_root_at_slot(state.hbsPhase0.data, slot)
of forkAltair: get_block_root_at_slot(state.hbsAltair.data, slot)
of forkMerge: get_block_root_at_slot(state.hbsMerge.data, slot)
proc get_attesting_indices*(state: ForkedHashedBeaconState;
data: AttestationData;
bits: CommitteeValidatorsBits;
cache: var StateCache): seq[ValidatorIndex] =
# TODO when https://github.com/nim-lang/Nim/issues/18188 fixed, use an
# iterator
var idxBuf: seq[ValidatorIndex]
if state.beaconStateFork == forkPhase0:
for vidx in state.hbsPhase0.data.get_attesting_indices(data, bits, cache):
idxBuf.add vidx
elif state.beaconStateFork == forkAltair:
for vidx in state.hbsAltair.data.get_attesting_indices(data, bits, cache):
idxBuf.add vidx
else:
doAssert false
idxBuf
proc check_attester_slashing*(
state: var ForkedHashedBeaconState; attester_slashing: SomeAttesterSlashing;
flags: UpdateFlags): Result[seq[ValidatorIndex], cstring] =
case state.beaconStateFork:
of forkPhase0:
check_attester_slashing(state.hbsPhase0.data, attester_slashing, flags)
of forkAltair:
check_attester_slashing(state.hbsAltair.data, attester_slashing, flags)
of forkMerge:
check_attester_slashing(state.hbsMerge.data, attester_slashing, flags)
proc check_proposer_slashing*(
state: var ForkedHashedBeaconState; proposer_slashing: SomeProposerSlashing;
flags: UpdateFlags): Result[void, cstring] =
case state.beaconStateFork:
of forkPhase0:
check_proposer_slashing(state.hbsPhase0.data, proposer_slashing, flags)
of forkAltair:
check_proposer_slashing(state.hbsAltair.data, proposer_slashing, flags)
of forkMerge:
check_proposer_slashing(state.hbsMerge.data, proposer_slashing, flags)
proc check_voluntary_exit*(
Implement split preset/config support (#2710) * Implement split preset/config support This is the initial bulk refactor to introduce runtime config values in a number of places, somewhat replacing the existing mechanism of loading network metadata. It still needs more work, this is the initial refactor that introduces runtime configuration in some of the places that need it. The PR changes the way presets and constants work, to match the spec. In particular, a "preset" now refers to the compile-time configuration while a "cfg" or "RuntimeConfig" is the dynamic part. A single binary can support either mainnet or minimal, but not both. Support for other presets has been removed completely (can be readded, in case there's need). There's a number of outstanding tasks: * `SECONDS_PER_SLOT` still needs fixing * loading custom runtime configs needs redoing * checking constants against YAML file * yeerongpilly support `build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG` * load fork epoch from config * fix fork digest sent in status * nicer error string for request failures * fix tools * one more * fixup * fixup * fixup * use "standard" network definition folder in local testnet Files are loaded from their standard locations, including genesis etc, to conform to the format used in the `eth2-networks` repo. * fix launch scripts, allow unknown config values * fix base config of rest test * cleanups * bundle mainnet config using common loader * fix spec links and names * only include supported preset in binary * drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
cfg: RuntimeConfig, state: ForkedHashedBeaconState;
signed_voluntary_exit: SomeSignedVoluntaryExit;
flags: UpdateFlags): Result[void, cstring] =
case state.beaconStateFork:
of forkPhase0:
Implement split preset/config support (#2710) * Implement split preset/config support This is the initial bulk refactor to introduce runtime config values in a number of places, somewhat replacing the existing mechanism of loading network metadata. It still needs more work, this is the initial refactor that introduces runtime configuration in some of the places that need it. The PR changes the way presets and constants work, to match the spec. In particular, a "preset" now refers to the compile-time configuration while a "cfg" or "RuntimeConfig" is the dynamic part. A single binary can support either mainnet or minimal, but not both. Support for other presets has been removed completely (can be readded, in case there's need). There's a number of outstanding tasks: * `SECONDS_PER_SLOT` still needs fixing * loading custom runtime configs needs redoing * checking constants against YAML file * yeerongpilly support `build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG` * load fork epoch from config * fix fork digest sent in status * nicer error string for request failures * fix tools * one more * fixup * fixup * fixup * use "standard" network definition folder in local testnet Files are loaded from their standard locations, including genesis etc, to conform to the format used in the `eth2-networks` repo. * fix launch scripts, allow unknown config values * fix base config of rest test * cleanups * bundle mainnet config using common loader * fix spec links and names * only include supported preset in binary * drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
check_voluntary_exit(cfg, state.hbsPhase0.data, signed_voluntary_exit, flags)
of forkAltair:
Implement split preset/config support (#2710) * Implement split preset/config support This is the initial bulk refactor to introduce runtime config values in a number of places, somewhat replacing the existing mechanism of loading network metadata. It still needs more work, this is the initial refactor that introduces runtime configuration in some of the places that need it. The PR changes the way presets and constants work, to match the spec. In particular, a "preset" now refers to the compile-time configuration while a "cfg" or "RuntimeConfig" is the dynamic part. A single binary can support either mainnet or minimal, but not both. Support for other presets has been removed completely (can be readded, in case there's need). There's a number of outstanding tasks: * `SECONDS_PER_SLOT` still needs fixing * loading custom runtime configs needs redoing * checking constants against YAML file * yeerongpilly support `build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG` * load fork epoch from config * fix fork digest sent in status * nicer error string for request failures * fix tools * one more * fixup * fixup * fixup * use "standard" network definition folder in local testnet Files are loaded from their standard locations, including genesis etc, to conform to the format used in the `eth2-networks` repo. * fix launch scripts, allow unknown config values * fix base config of rest test * cleanups * bundle mainnet config using common loader * fix spec links and names * only include supported preset in binary * drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
check_voluntary_exit(cfg, state.hbsAltair.data, signed_voluntary_exit, flags)
of forkMerge:
check_voluntary_exit(cfg, state.hbsMerge.data, signed_voluntary_exit, flags)
# Derived utilities
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_current_epoch
func get_current_epoch*(stateData: ForkedHashedBeaconState): Epoch =
## Return the current epoch.
getStateField(stateData, slot).epoch
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_previous_epoch
func get_previous_epoch*(stateData: ForkedHashedBeaconState): Epoch =
## Return the previous epoch (unless the current epoch is ``GENESIS_EPOCH``).
let current_epoch = get_current_epoch(stateData)
if current_epoch == GENESIS_EPOCH:
GENESIS_EPOCH
else:
current_epoch - 1
func init*(T: type ForkDigests,
Implement split preset/config support (#2710) * Implement split preset/config support This is the initial bulk refactor to introduce runtime config values in a number of places, somewhat replacing the existing mechanism of loading network metadata. It still needs more work, this is the initial refactor that introduces runtime configuration in some of the places that need it. The PR changes the way presets and constants work, to match the spec. In particular, a "preset" now refers to the compile-time configuration while a "cfg" or "RuntimeConfig" is the dynamic part. A single binary can support either mainnet or minimal, but not both. Support for other presets has been removed completely (can be readded, in case there's need). There's a number of outstanding tasks: * `SECONDS_PER_SLOT` still needs fixing * loading custom runtime configs needs redoing * checking constants against YAML file * yeerongpilly support `build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG` * load fork epoch from config * fix fork digest sent in status * nicer error string for request failures * fix tools * one more * fixup * fixup * fixup * use "standard" network definition folder in local testnet Files are loaded from their standard locations, including genesis etc, to conform to the format used in the `eth2-networks` repo. * fix launch scripts, allow unknown config values * fix base config of rest test * cleanups * bundle mainnet config using common loader * fix spec links and names * only include supported preset in binary * drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
cfg: RuntimeConfig,
genesisValidatorsRoot: Eth2Digest): T =
let altairForkDigest = compute_fork_digest(
Implement split preset/config support (#2710) * Implement split preset/config support This is the initial bulk refactor to introduce runtime config values in a number of places, somewhat replacing the existing mechanism of loading network metadata. It still needs more work, this is the initial refactor that introduces runtime configuration in some of the places that need it. The PR changes the way presets and constants work, to match the spec. In particular, a "preset" now refers to the compile-time configuration while a "cfg" or "RuntimeConfig" is the dynamic part. A single binary can support either mainnet or minimal, but not both. Support for other presets has been removed completely (can be readded, in case there's need). There's a number of outstanding tasks: * `SECONDS_PER_SLOT` still needs fixing * loading custom runtime configs needs redoing * checking constants against YAML file * yeerongpilly support `build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG` * load fork epoch from config * fix fork digest sent in status * nicer error string for request failures * fix tools * one more * fixup * fixup * fixup * use "standard" network definition folder in local testnet Files are loaded from their standard locations, including genesis etc, to conform to the format used in the `eth2-networks` repo. * fix launch scripts, allow unknown config values * fix base config of rest test * cleanups * bundle mainnet config using common loader * fix spec links and names * only include supported preset in binary * drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
cfg.ALTAIR_FORK_VERSION,
genesisValidatorsRoot)
T(phase0: compute_fork_digest(
Implement split preset/config support (#2710) * Implement split preset/config support This is the initial bulk refactor to introduce runtime config values in a number of places, somewhat replacing the existing mechanism of loading network metadata. It still needs more work, this is the initial refactor that introduces runtime configuration in some of the places that need it. The PR changes the way presets and constants work, to match the spec. In particular, a "preset" now refers to the compile-time configuration while a "cfg" or "RuntimeConfig" is the dynamic part. A single binary can support either mainnet or minimal, but not both. Support for other presets has been removed completely (can be readded, in case there's need). There's a number of outstanding tasks: * `SECONDS_PER_SLOT` still needs fixing * loading custom runtime configs needs redoing * checking constants against YAML file * yeerongpilly support `build/nimbus_beacon_node --network=yeerongpilly --discv5:no --log-level=DEBUG` * load fork epoch from config * fix fork digest sent in status * nicer error string for request failures * fix tools * one more * fixup * fixup * fixup * use "standard" network definition folder in local testnet Files are loaded from their standard locations, including genesis etc, to conform to the format used in the `eth2-networks` repo. * fix launch scripts, allow unknown config values * fix base config of rest test * cleanups * bundle mainnet config using common loader * fix spec links and names * only include supported preset in binary * drop yeerongpilly, add altair-devnet-0, support boot_enr.yaml
2021-07-12 13:01:38 +00:00
cfg.GENESIS_FORK_VERSION,
genesisValidatorsRoot),
altair: altairForkDigest,
altairTopicPrefix: $altairForkDigest)
template asSigned*(x: phase0.TrustedSignedBeaconBlock or phase0.SigVerifiedBeaconBlock):
phase0.SignedBeaconBlock =
isomorphicCast[phase0.SignedBeaconBlock](x)
template asSigned*(x: altair.TrustedSignedBeaconBlock or altair.SigVerifiedBeaconBlock):
altair.SignedBeaconBlock =
isomorphicCast[altair.SignedBeaconBlock](x)
template asSigned*(x: ForkedTrustedSignedBeaconBlock): ForkedSignedBeaconBlock =
isomorphicCast[ForkedSignedBeaconBlock](x)
template asTrusted*(x: phase0.SignedBeaconBlock or phase0.SigVerifiedBeaconBlock):
phase0.TrustedSignedBeaconBlock =
isomorphicCast[phase0.TrustedSignedBeaconBlock](x)
template asTrusted*(x: altair.SignedBeaconBlock or altair.SigVerifiedBeaconBlock):
altair.TrustedSignedBeaconBlock =
isomorphicCast[altair.TrustedSignedBeaconBlock](x)
template asTrusted*(x: merge.SignedBeaconBlock or merge.SigVerifiedBeaconBlock):
merge.TrustedSignedBeaconBlock =
isomorphicCast[merge.TrustedSignedBeaconBlock](x)
template asTrusted*(x: ForkedSignedBeaconBlock): ForkedTrustedSignedBeaconBlock =
isomorphicCast[ForkedTrustedSignedBeaconBlock](x)
template withBlck*(x: ForkedBeaconBlock | ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock, body: untyped): untyped =
case x.kind
of BeaconBlockFork.Phase0:
template blck: untyped {.inject.} = x.phase0Block
body
of BeaconBlockFork.Altair:
template blck: untyped {.inject.} = x.altairBlock
body
of BeaconBlockFork.Merge:
template blck: untyped {.inject.} = x.mergeBlock
body
template getForkedBlockField*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock, y: untyped): untyped =
withBlck(x): blck.message.y
template signature*(x: ForkedSignedBeaconBlock): ValidatorSig =
withBlck(x): blck.signature
template signature*(x: ForkedTrustedSignedBeaconBlock): TrustedSig =
withBlck(x): blck.signature
template root*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock): Eth2Digest =
withBlck(x): blck.root
template slot*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock): Slot =
getForkedBlockField(x, slot)
template shortLog*(x: ForkedBeaconBlock): auto =
withBlck(x): shortLog(blck)
template shortLog*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock): auto =
withBlck(x): shortLog(blck)
chronicles.formatIt ForkedBeaconBlock: it.shortLog
chronicles.formatIt ForkedSignedBeaconBlock: it.shortLog
chronicles.formatIt ForkedTrustedSignedBeaconBlock: it.shortLog
proc forkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Fork =
# TODO MERGE_FORK_EPOCH
if epoch < cfg.ALTAIR_FORK_EPOCH:
genesisFork(cfg)
else:
altairFork(cfg)
proc forkVersionAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Version =
# TODO MERGE_FORK_EPOCH
if epoch < cfg.ALTAIR_FORK_EPOCH:
cfg.GENESIS_FORK_VERSION
else:
cfg.ALTAIR_FORK_VERSION
proc nextForkEpochAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Epoch =
# TODO MERGE_FORK_EPOCH
if epoch < cfg.ALTAIR_FORK_EPOCH:
cfg.ALTAIR_FORK_EPOCH
else:
FAR_FUTURE_EPOCH
func getForkSchedule*(cfg: RuntimeConfig): array[2, 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()]