2021-06-11 17:51:46 +00:00
|
|
|
# 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,
|
2021-09-28 18:08:03 +00:00
|
|
|
../spec/[
|
|
|
|
beaconstate, eth2_merkleization, helpers, state_transition_block, validator],
|
2021-09-27 14:22:58 +00:00
|
|
|
./datatypes/[phase0, altair, merge]
|
2021-06-11 17:51:46 +00:00
|
|
|
|
2021-09-28 18:08:03 +00:00
|
|
|
export extras, phase0, altair, eth2_merkleization
|
2021-08-12 13:08:20 +00:00
|
|
|
|
2021-06-11 17:51:46 +00:00
|
|
|
type
|
|
|
|
BeaconStateFork* = enum
|
|
|
|
forkPhase0,
|
2021-09-27 14:22:58 +00:00
|
|
|
forkAltair,
|
|
|
|
forkMerge
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
ForkedHashedBeaconState* = object
|
|
|
|
case beaconStateFork*: BeaconStateFork
|
|
|
|
of forkPhase0: hbsPhase0*: phase0.HashedBeaconState
|
|
|
|
of forkAltair: hbsAltair*: altair.HashedBeaconState
|
2021-09-27 14:22:58 +00:00
|
|
|
of forkMerge: hbsMerge*: merge.HashedBeaconState
|
2021-06-11 17:51:46 +00:00
|
|
|
|
2021-09-16 13:32:32 +00:00
|
|
|
ForkedBeaconState* = object
|
|
|
|
case beaconStateFork*: BeaconStateFork
|
|
|
|
of forkPhase0: bsPhase0*: phase0.BeaconState
|
|
|
|
of forkAltair: bsAltair*: altair.BeaconState
|
2021-09-27 14:22:58 +00:00
|
|
|
of forkMerge: bsMerge*: merge.BeaconState
|
2021-09-16 13:32:32 +00:00
|
|
|
|
2021-07-07 09:09:47 +00:00
|
|
|
BeaconBlockFork* {.pure.} = enum
|
|
|
|
Phase0
|
|
|
|
Altair
|
2021-09-27 14:22:58 +00:00
|
|
|
Merge
|
2021-07-07 09:09:47 +00:00
|
|
|
|
2021-08-27 09:00:06 +00:00
|
|
|
ForkedBeaconBlock* = object
|
|
|
|
case kind*: BeaconBlockFork
|
|
|
|
of BeaconBlockFork.Phase0:
|
|
|
|
phase0Block*: phase0.BeaconBlock
|
|
|
|
of BeaconBlockFork.Altair:
|
|
|
|
altairBlock*: altair.BeaconBlock
|
2021-09-27 14:22:58 +00:00
|
|
|
of BeaconBlockFork.Merge:
|
|
|
|
mergeBlock*: merge.BeaconBlock
|
2021-08-27 09:00:06 +00:00
|
|
|
|
2021-07-07 09:09:47 +00:00
|
|
|
ForkedSignedBeaconBlock* = object
|
|
|
|
case kind*: BeaconBlockFork
|
|
|
|
of BeaconBlockFork.Phase0:
|
|
|
|
phase0Block*: phase0.SignedBeaconBlock
|
|
|
|
of BeaconBlockFork.Altair:
|
|
|
|
altairBlock*: altair.SignedBeaconBlock
|
2021-09-27 14:22:58 +00:00
|
|
|
of BeaconBlockFork.Merge:
|
|
|
|
mergeBlock*: merge.SignedBeaconBlock
|
2021-07-07 09:09:47 +00:00
|
|
|
|
|
|
|
ForkedTrustedSignedBeaconBlock* = object
|
|
|
|
case kind*: BeaconBlockFork
|
|
|
|
of BeaconBlockFork.Phase0:
|
|
|
|
phase0Block*: phase0.TrustedSignedBeaconBlock
|
|
|
|
of BeaconBlockFork.Altair:
|
|
|
|
altairBlock*: altair.TrustedSignedBeaconBlock
|
2021-09-27 14:22:58 +00:00
|
|
|
of BeaconBlockFork.Merge:
|
|
|
|
mergeBlock*: merge.TrustedSignedBeaconBlock
|
2021-07-07 09:09:47 +00:00
|
|
|
|
2021-10-13 14:24:36 +00:00
|
|
|
EpochInfoFork* {.pure.} = enum
|
|
|
|
Phase0
|
|
|
|
Altair
|
|
|
|
|
|
|
|
ForkedEpochInfo* = object
|
|
|
|
case kind*: EpochInfoFork
|
|
|
|
of EpochInfoFork.Phase0:
|
|
|
|
phase0Info*: phase0.EpochInfo
|
|
|
|
of EpochInfoFork.Altair:
|
|
|
|
altairInfo*: altair.EpochInfo
|
|
|
|
|
|
|
|
ForkyEpochInfo* = phase0.EpochInfo | altair.EpochInfo
|
|
|
|
|
2021-10-07 13:19:47 +00:00
|
|
|
ForkDigests* = object
|
2021-07-07 09:09:47 +00:00
|
|
|
phase0*: ForkDigest
|
|
|
|
altair*: ForkDigest
|
2021-10-06 15:47:11 +00:00
|
|
|
merge*: ForkDigest
|
2021-07-07 09:09:47 +00:00
|
|
|
|
|
|
|
ForkDigestsRef* = ref ForkDigests
|
|
|
|
|
2021-08-27 09:00:06 +00:00
|
|
|
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)
|
2021-09-27 14:22:58 +00:00
|
|
|
template init*(T: type ForkedBeaconBlock, blck: merge.BeaconBlock): T =
|
|
|
|
T(kind: BeaconBlockFork.Merge, mergeBlock: blck)
|
2021-08-27 09:00:06 +00:00
|
|
|
|
2021-07-14 12:18:52 +00:00
|
|
|
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)
|
2021-09-27 14:22:58 +00:00
|
|
|
template init*(T: type ForkedSignedBeaconBlock, blck: merge.SignedBeaconBlock): T =
|
|
|
|
T(kind: BeaconBlockFork.Merge, mergeBlock: blck)
|
2021-07-14 12:18:52 +00:00
|
|
|
|
2021-09-16 13:32:32 +00:00
|
|
|
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)
|
2021-09-27 14:22:58 +00:00
|
|
|
template init*(T: type ForkedBeaconState, state: merge.BeaconState): T =
|
|
|
|
T(beaconStateFork: BeaconStateFork.forkMerge, bsMerge: state)
|
2021-09-16 13:32:32 +00:00
|
|
|
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)
|
2021-09-27 14:22:58 +00:00
|
|
|
of BeaconStateFork.forkMerge:
|
|
|
|
T(beaconStateFork: BeaconStateFork.forkMerge,
|
|
|
|
bsMerge: state.hbsMerge.data)
|
2021-09-16 13:32:32 +00:00
|
|
|
|
2021-08-27 09:00:06 +00:00
|
|
|
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))
|
2021-09-27 14:22:58 +00:00
|
|
|
of BeaconBlockFork.Merge:
|
|
|
|
T(kind: BeaconBlockFork.Merge,
|
|
|
|
mergeBlock: merge.SignedBeaconBlock(message: forked.mergeBlock,
|
|
|
|
root: blockRoot,
|
|
|
|
signature: signature))
|
2021-08-27 09:00:06 +00:00
|
|
|
|
2021-07-14 12:18:52 +00:00
|
|
|
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)
|
2021-09-27 14:22:58 +00:00
|
|
|
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: merge.TrustedSignedBeaconBlock): T =
|
|
|
|
T(kind: BeaconBlockFork.Merge, mergeBlock: blck)
|
2021-07-14 12:18:52 +00:00
|
|
|
|
2021-10-13 14:24:36 +00:00
|
|
|
template init*(T: type ForkedEpochInfo, info: phase0.EpochInfo): T =
|
|
|
|
T(kind: EpochInfoFork.Phase0, phase0Info: info)
|
|
|
|
template init*(T: type ForkedEpochInfo, info: altair.EpochInfo): T =
|
|
|
|
T(kind: EpochInfoFork.Altair, altairInfo: info)
|
|
|
|
|
2021-09-28 18:08:03 +00:00
|
|
|
# State-related functionality based on ForkedHashedBeaconState instead of HashedBeaconState
|
|
|
|
|
|
|
|
template withState*(x: ForkedHashedBeaconState, body: untyped): untyped =
|
|
|
|
case x.beaconStateFork
|
2021-10-06 17:05:06 +00:00
|
|
|
of forkMerge:
|
|
|
|
const stateFork {.inject.} = forkMerge
|
|
|
|
template state: untyped {.inject.} = x.hbsMerge
|
2021-09-28 18:08:03 +00:00
|
|
|
body
|
|
|
|
of forkAltair:
|
2021-10-06 17:05:06 +00:00
|
|
|
const stateFork {.inject.} = forkAltair
|
2021-09-28 18:08:03 +00:00
|
|
|
template state: untyped {.inject.} = x.hbsAltair
|
|
|
|
body
|
2021-10-06 17:05:06 +00:00
|
|
|
of forkPhase0:
|
|
|
|
const stateFork {.inject.} = forkPhase0
|
|
|
|
template state: untyped {.inject.} = x.hbsPhase0
|
2021-09-28 18:08:03 +00:00
|
|
|
body
|
2021-06-11 17:51:46 +00:00
|
|
|
|
2021-10-13 14:24:36 +00:00
|
|
|
template withEpochInfo*(x: ForkedEpochInfo, body: untyped): untyped =
|
|
|
|
case x.kind
|
|
|
|
of EpochInfoFork.Phase0:
|
|
|
|
template info: untyped {.inject.} = x.phase0Info
|
|
|
|
body
|
|
|
|
of EpochInfoFork.Altair:
|
|
|
|
template info: untyped {.inject.} = x.altairInfo
|
|
|
|
body
|
|
|
|
|
|
|
|
template withEpochInfo*(
|
|
|
|
state: phase0.BeaconState, x: var ForkedEpochInfo, body: untyped): untyped =
|
|
|
|
x.kind = EpochInfoFork.Phase0
|
|
|
|
template info: untyped {.inject.} = x.phase0Info
|
|
|
|
body
|
|
|
|
|
|
|
|
template withEpochInfo*(
|
|
|
|
state: altair.BeaconState | merge.BeaconState, x: var ForkedEpochInfo,
|
|
|
|
body: untyped): untyped =
|
|
|
|
x.kind = EpochInfoFork.Altair
|
|
|
|
template info: untyped {.inject.} = x.altairInfo
|
|
|
|
body
|
|
|
|
|
2021-06-11 17:51:46 +00:00
|
|
|
# Dispatch functions
|
|
|
|
func assign*(tgt: var ForkedHashedBeaconState, src: ForkedHashedBeaconState) =
|
|
|
|
if tgt.beaconStateFork == src.beaconStateFork:
|
2021-10-06 17:05:06 +00:00
|
|
|
case tgt.beaconStateFork
|
|
|
|
of forkMerge:
|
2021-09-30 01:07:24 +00:00
|
|
|
assign(tgt.hbsMerge, src.hbsMerge):
|
2021-10-06 17:05:06 +00:00
|
|
|
of forkAltair:
|
|
|
|
assign(tgt.hbsAltair, src.hbsAltair):
|
|
|
|
of forkPhase0:
|
|
|
|
assign(tgt.hbsPhase0, src.hbsPhase0):
|
2021-06-11 17:51:46 +00:00
|
|
|
else:
|
|
|
|
# Ensure case object and discriminator get updated simultaneously, even
|
|
|
|
# with nimOldCaseObjects. This is infrequent.
|
|
|
|
tgt = src
|
|
|
|
|
2021-09-28 18:08:03 +00:00
|
|
|
template getStateField*(x: ForkedHashedBeaconState, y: untyped): untyped =
|
2021-09-22 20:06:50 +00:00
|
|
|
# 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
|
2021-10-06 17:05:06 +00:00
|
|
|
of forkMerge: unsafeAddr x.hbsMerge.data.y
|
2021-09-28 18:08:03 +00:00
|
|
|
of forkAltair: unsafeAddr x.hbsAltair.data.y
|
2021-10-06 17:05:06 +00:00
|
|
|
of forkPhase0: unsafeAddr x.hbsPhase0.data.y)[]
|
2021-06-11 17:51:46 +00:00
|
|
|
|
2021-09-28 18:08:03 +00:00
|
|
|
func getStateRoot*(x: ForkedHashedBeaconState): Eth2Digest =
|
|
|
|
withState(x): state.root
|
2021-06-17 17:13:14 +00:00
|
|
|
|
|
|
|
func setStateRoot*(x: var ForkedHashedBeaconState, root: Eth2Digest) =
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(x): state.root = root
|
2021-08-27 09:00:06 +00:00
|
|
|
|
2021-09-28 18:08:03 +00:00
|
|
|
func hash_tree_root*(x: ForkedHashedBeaconState): Eth2Digest =
|
|
|
|
# This is a bit of a hack because we drill into data here, unlike other places
|
|
|
|
withState(x): hash_tree_root(state.data)
|
2021-08-27 09:00:06 +00:00
|
|
|
|
2021-06-21 08:35:24 +00:00
|
|
|
func get_active_validator_indices_len*(
|
|
|
|
state: ForkedHashedBeaconState; epoch: Epoch): uint64 =
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
get_active_validator_indices_len(state.data, epoch)
|
2021-06-21 08:35:24 +00:00
|
|
|
|
2021-06-11 17:51:46 +00:00
|
|
|
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.
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
get_beacon_committee(state.data, slot, index, cache)
|
2021-06-21 08:35:24 +00:00
|
|
|
|
2021-08-27 09:00:06 +00:00
|
|
|
func get_beacon_committee_len*(
|
|
|
|
state: ForkedHashedBeaconState, slot: Slot, index: CommitteeIndex,
|
|
|
|
cache: var StateCache): uint64 =
|
|
|
|
# This one is used by tests
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
get_beacon_committee_len(state.data, slot, index, cache)
|
2021-08-27 09:00:06 +00:00
|
|
|
|
2021-06-11 17:51:46 +00:00
|
|
|
func get_committee_count_per_slot*(state: ForkedHashedBeaconState,
|
|
|
|
epoch: Epoch,
|
|
|
|
cache: var StateCache): uint64 =
|
|
|
|
## Return the number of committees at ``epoch``.
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
get_committee_count_per_slot(state.data, epoch, cache)
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
func get_beacon_proposer_index*(state: ForkedHashedBeaconState,
|
|
|
|
cache: var StateCache, slot: Slot):
|
|
|
|
Option[ValidatorIndex] =
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
get_beacon_proposer_index(state.data, cache, slot)
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
func get_shuffled_active_validator_indices*(
|
|
|
|
cache: var StateCache, state: ForkedHashedBeaconState, epoch: Epoch):
|
|
|
|
seq[ValidatorIndex] =
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
cache.get_shuffled_active_validator_indices(state.data, epoch)
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
# 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``.
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
get_block_root_at_slot(state.data, slot)
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
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]
|
2021-10-06 17:05:06 +00:00
|
|
|
withState(state):
|
|
|
|
for vidx in state.data.get_attesting_indices(data, bits, cache):
|
2021-09-30 01:07:24 +00:00
|
|
|
idxBuf.add vidx
|
2021-06-11 17:51:46 +00:00
|
|
|
idxBuf
|
|
|
|
|
|
|
|
proc check_attester_slashing*(
|
|
|
|
state: var ForkedHashedBeaconState; attester_slashing: SomeAttesterSlashing;
|
|
|
|
flags: UpdateFlags): Result[seq[ValidatorIndex], cstring] =
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
check_attester_slashing(state.data, attester_slashing, flags)
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
proc check_proposer_slashing*(
|
|
|
|
state: var ForkedHashedBeaconState; proposer_slashing: SomeProposerSlashing;
|
|
|
|
flags: UpdateFlags): Result[void, cstring] =
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
check_proposer_slashing(state.data, proposer_slashing, flags)
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
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;
|
2021-06-11 17:51:46 +00:00
|
|
|
flags: UpdateFlags): Result[void, cstring] =
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(state):
|
|
|
|
check_voluntary_exit(cfg, state.data, signed_voluntary_exit, flags)
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
# Derived utilities
|
|
|
|
|
2021-10-04 08:31:21 +00:00
|
|
|
func stateForkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): BeaconStateFork =
|
|
|
|
## Return the current fork for the given epoch.
|
|
|
|
static:
|
|
|
|
doAssert forkMerge > forkAltair
|
|
|
|
doAssert forkAltair > forkPhase0
|
|
|
|
doAssert GENESIS_EPOCH == 0
|
|
|
|
|
|
|
|
if epoch >= cfg.MERGE_FORK_EPOCH: forkMerge
|
|
|
|
elif epoch >= cfg.ALTAIR_FORK_EPOCH: forkAltair
|
|
|
|
else: forkPhase0
|
|
|
|
|
2021-06-11 17:51:46 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_current_epoch
|
2021-09-28 18:08:03 +00:00
|
|
|
func get_current_epoch*(x: ForkedHashedBeaconState): Epoch =
|
2021-06-11 17:51:46 +00:00
|
|
|
## Return the current epoch.
|
2021-09-28 18:08:03 +00:00
|
|
|
withState(x): state.data.slot.epoch
|
2021-06-11 17:51:46 +00:00
|
|
|
|
|
|
|
# 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
|
2021-07-07 09:09:47 +00:00
|
|
|
|
|
|
|
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,
|
2021-07-07 09:09:47 +00:00
|
|
|
genesisValidatorsRoot: Eth2Digest): T =
|
2021-10-06 15:47:11 +00:00
|
|
|
T(
|
|
|
|
phase0:
|
|
|
|
compute_fork_digest(cfg.GENESIS_FORK_VERSION, genesisValidatorsRoot),
|
|
|
|
altair:
|
|
|
|
compute_fork_digest(cfg.ALTAIR_FORK_VERSION, genesisValidatorsRoot),
|
|
|
|
merge:
|
|
|
|
compute_fork_digest(cfg.MERGE_FORK_VERSION, genesisValidatorsRoot),
|
|
|
|
)
|
2021-07-07 09:09:47 +00:00
|
|
|
|
|
|
|
template asSigned*(x: phase0.TrustedSignedBeaconBlock or phase0.SigVerifiedBeaconBlock):
|
|
|
|
phase0.SignedBeaconBlock =
|
2021-07-14 12:18:52 +00:00
|
|
|
isomorphicCast[phase0.SignedBeaconBlock](x)
|
2021-07-07 09:09:47 +00:00
|
|
|
|
|
|
|
template asSigned*(x: altair.TrustedSignedBeaconBlock or altair.SigVerifiedBeaconBlock):
|
|
|
|
altair.SignedBeaconBlock =
|
2021-07-14 12:18:52 +00:00
|
|
|
isomorphicCast[altair.SignedBeaconBlock](x)
|
2021-07-07 09:09:47 +00:00
|
|
|
|
|
|
|
template asSigned*(x: ForkedTrustedSignedBeaconBlock): ForkedSignedBeaconBlock =
|
2021-07-14 12:18:52 +00:00
|
|
|
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)
|
|
|
|
|
2021-09-27 14:22:58 +00:00
|
|
|
template asTrusted*(x: merge.SignedBeaconBlock or merge.SigVerifiedBeaconBlock):
|
|
|
|
merge.TrustedSignedBeaconBlock =
|
|
|
|
isomorphicCast[merge.TrustedSignedBeaconBlock](x)
|
|
|
|
|
2021-09-27 09:24:58 +00:00
|
|
|
template asTrusted*(x: ForkedSignedBeaconBlock): ForkedTrustedSignedBeaconBlock =
|
2021-07-14 12:18:52 +00:00
|
|
|
isomorphicCast[ForkedTrustedSignedBeaconBlock](x)
|
|
|
|
|
2021-10-06 17:05:06 +00:00
|
|
|
template withBlck*(
|
|
|
|
x: ForkedBeaconBlock | ForkedSignedBeaconBlock |
|
|
|
|
ForkedTrustedSignedBeaconBlock,
|
|
|
|
body: untyped): untyped =
|
2021-07-14 12:18:52 +00:00
|
|
|
case x.kind
|
|
|
|
of BeaconBlockFork.Phase0:
|
2021-10-06 17:05:06 +00:00
|
|
|
const stateFork {.inject.} = forkPhase0
|
2021-08-27 09:00:06 +00:00
|
|
|
template blck: untyped {.inject.} = x.phase0Block
|
2021-07-14 12:18:52 +00:00
|
|
|
body
|
|
|
|
of BeaconBlockFork.Altair:
|
2021-10-06 17:05:06 +00:00
|
|
|
const stateFork {.inject.} = forkAltair
|
2021-08-27 09:00:06 +00:00
|
|
|
template blck: untyped {.inject.} = x.altairBlock
|
2021-07-14 12:18:52 +00:00
|
|
|
body
|
2021-09-27 14:22:58 +00:00
|
|
|
of BeaconBlockFork.Merge:
|
2021-10-06 17:05:06 +00:00
|
|
|
const stateFork {.inject.} = forkMerge
|
2021-09-27 14:22:58 +00:00
|
|
|
template blck: untyped {.inject.} = x.mergeBlock
|
|
|
|
body
|
2021-07-14 12:18:52 +00:00
|
|
|
|
2021-09-28 18:08:03 +00:00
|
|
|
func proposer_index*(x: ForkedBeaconBlock): uint64 =
|
|
|
|
withBlck(x): blck.proposer_index
|
|
|
|
|
|
|
|
func hash_tree_root*(x: ForkedBeaconBlock): Eth2Digest =
|
|
|
|
withBlck(x): hash_tree_root(blck)
|
|
|
|
|
2021-07-14 12:18:52 +00:00
|
|
|
template getForkedBlockField*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock, y: untyped): untyped =
|
2021-09-28 18:08:03 +00:00
|
|
|
# unsafeAddr avoids a copy of the field in some cases
|
|
|
|
(case x.kind
|
|
|
|
of BeaconBlockFork.Phase0: unsafeAddr x.phase0Block.message.y
|
|
|
|
of BeaconBlockFork.Altair: unsafeAddr x.altairBlock.message.y
|
|
|
|
of BeaconBlockFork.Merge: unsafeAddr x.mergeBlock.message.y)[]
|
2021-07-14 12:18:52 +00:00
|
|
|
|
|
|
|
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 =
|
2021-09-28 18:08:03 +00:00
|
|
|
withBlck(x): blck.message.slot
|
2021-07-07 09:09:47 +00:00
|
|
|
|
2021-08-27 09:00:06 +00:00
|
|
|
template shortLog*(x: ForkedBeaconBlock): auto =
|
|
|
|
withBlck(x): shortLog(blck)
|
|
|
|
|
|
|
|
template shortLog*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock): auto =
|
|
|
|
withBlck(x): shortLog(blck)
|
2021-07-07 09:09:47 +00:00
|
|
|
|
2021-08-27 09:00:06 +00:00
|
|
|
chronicles.formatIt ForkedBeaconBlock: it.shortLog
|
2021-07-14 12:18:52 +00:00
|
|
|
chronicles.formatIt ForkedSignedBeaconBlock: it.shortLog
|
|
|
|
chronicles.formatIt ForkedTrustedSignedBeaconBlock: it.shortLog
|
2021-08-09 12:54:45 +00:00
|
|
|
|
2021-10-06 17:05:06 +00:00
|
|
|
template withStateAndBlck*(
|
|
|
|
s: ForkedHashedBeaconState,
|
|
|
|
b: ForkedBeaconBlock | ForkedSignedBeaconBlock |
|
|
|
|
ForkedTrustedSignedBeaconBlock,
|
|
|
|
body: untyped): untyped =
|
|
|
|
case s.beaconStateFork
|
|
|
|
of forkMerge:
|
|
|
|
const stateFork {.inject.} = forkMerge
|
|
|
|
template state: untyped {.inject.} = s.hbsMerge
|
|
|
|
template blck: untyped {.inject.} = b.mergeBlock
|
|
|
|
body
|
|
|
|
of forkAltair:
|
|
|
|
const stateFork {.inject.} = forkAltair
|
|
|
|
template state: untyped {.inject.} = s.hbsAltair
|
|
|
|
template blck: untyped {.inject.} = b.altairBlock
|
|
|
|
body
|
|
|
|
of forkPhase0:
|
|
|
|
const stateFork {.inject.} = forkPhase0
|
|
|
|
template state: untyped {.inject.} = s.hbsPhase0
|
|
|
|
template blck: untyped {.inject.} = b.phase0Block
|
|
|
|
body
|
|
|
|
|
2021-08-09 12:54:45 +00:00
|
|
|
proc forkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Fork =
|
2021-10-04 08:31:21 +00:00
|
|
|
case cfg.stateForkAtEpoch(epoch)
|
|
|
|
of forkMerge: cfg.mergeFork
|
|
|
|
of forkAltair: cfg.altairFork
|
|
|
|
of forkPhase0: cfg.genesisFork
|
2021-08-09 12:54:45 +00:00
|
|
|
|
|
|
|
proc forkVersionAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Version =
|
2021-10-04 08:31:21 +00:00
|
|
|
case cfg.stateForkAtEpoch(epoch)
|
|
|
|
of forkMerge: cfg.MERGE_FORK_VERSION
|
|
|
|
of forkAltair: cfg.ALTAIR_FORK_VERSION
|
|
|
|
of forkPhase0: cfg.GENESIS_FORK_VERSION
|
2021-08-09 12:54:45 +00:00
|
|
|
|
|
|
|
proc nextForkEpochAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Epoch =
|
2021-10-04 08:31:21 +00:00
|
|
|
case cfg.stateForkAtEpoch(epoch)
|
|
|
|
of forkMerge: FAR_FUTURE_EPOCH
|
|
|
|
of forkAltair: cfg.MERGE_FORK_EPOCH
|
|
|
|
of forkPhase0: cfg.ALTAIR_FORK_EPOCH
|
2021-08-23 10:41:48 +00:00
|
|
|
|
|
|
|
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()]
|