nimbus-eth2/beacon_chain/beacon_node_types.nim

179 lines
6.7 KiB
Nim

# beacon_chain
# Copyright (c) 2018-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/[deques, intsets, streams, tables],
stew/endians2,
spec/[datatypes, digest, crypto],
consensus_object_pools/block_pools_types,
fork_choice/fork_choice_types,
validators/slashing_protection
from libp2p/protocols/pubsub/pubsub import ValidationResult
export block_pools_types, ValidationResult
const
ATTESTATION_LOOKBACK* =
min(24'u64, SLOTS_PER_EPOCH) + MIN_ATTESTATION_INCLUSION_DELAY
## The number of slots we'll keep track of in terms of "free" attestations
## that potentially could be added to a newly created block
type
# #############################################
#
# Attestation Pool
#
# #############################################
Validation* = object
## Validations collect a set of signatures for a distict attestation - in
## eth2, a single bit is used to keep track of which signatures have been
## added to the aggregate meaning that only non-overlapping aggregates may
## be further combined.
aggregation_bits*: CommitteeValidatorsBits
aggregate_signature*: CookedSig
aggregate_signature_raw*: ValidatorSig
AttestationEntry* = object
## Each entry holds the known signatures for a particular, distinct vote
data*: AttestationData
blck*: BlockRef
aggregation_bits*: CommitteeValidatorsBits
validations*: seq[Validation]
AttestationsSeen* = object
attestations*: seq[AttestationEntry] ## \
## Depending on the world view of the various validators, they may have
## voted on different states - here we collect all the different
## combinations that validators have come up with so that later, we can
## count how popular each world view is (fork choice)
## TODO this could be a Table[AttestationData, seq[Validation] or something
## less naive
# These provide types for attestation pool's cache attestations.
AttestationDataKey* = (Slot, uint64, Epoch, Epoch)
AttestationPool* = object
## The attestation pool keeps track of all attestations that potentially
## could be added to a block during block production.
## These attestations also contribute to the fork choice, which combines
## "free" attestations with those found in past blocks - these votes
## are tracked separately in the fork choice.
attestationAggregates*: Table[Slot, Table[Eth2Digest, Attestation]]
## An up-to-date aggregate of each (htr-ed) attestation_data we see for
## each slot. We keep aggregates up to 32 slots back from the current slot.
candidates*: array[ATTESTATION_LOOKBACK, AttestationsSeen] ## \
## We keep one item per slot such that indexing matches slot number
## together with startingSlot
startingSlot*: Slot ## \
## Generally, we keep attestations only until a slot has been finalized -
## after that, they may no longer affect fork choice.
chainDag*: ChainDAGRef
quarantine*: QuarantineRef
forkChoice*: ForkChoice
nextAttestationEpoch*: seq[tuple[subnet: Epoch, aggregate: Epoch]] ## \
## sequence based on validator indices
attestedValidators*:
Table[AttestationDataKey, CommitteeValidatorsBits] ## \
## Cache for quick lookup during beacon block construction of attestations
## which have already been included, and therefore should be skipped. This
## isn't that useful for a couple validators per node, but pays off when a
## larger number of local validators is attached.
lastPreviousEpochAttestationsLen*: int
lastCurrentEpochAttestationsLen*: int ## \
lastPreviousEpochAttestation*: PendingAttestation
lastCurrentEpochAttestation*: PendingAttestation
## Used to detect and incorporate new attestations since the last block
## created. Defaults are fine as initial values and don't need explicit
## initialization.
ExitPool* = object
## The exit pool tracks attester slashings, proposer slashings, and
## voluntary exits that could be added to a proposed block.
attester_slashings*: Deque[AttesterSlashing] ## \
## Not a function of chain DAG branch; just used as a FIFO queue for blocks
proposer_slashings*: Deque[ProposerSlashing] ## \
## Not a function of chain DAG branch; just used as a FIFO queue for blocks
voluntary_exits*: Deque[SignedVoluntaryExit] ## \
## Not a function of chain DAG branch; just used as a FIFO queue for blocks
prior_seen_attester_slashed_indices*: IntSet ##\
## Records attester-slashed indices seen.
prior_seen_proposer_slashed_indices*: IntSet ##\
## Records proposer-slashed indices seen.
prior_seen_voluntary_exit_indices*: IntSet ##\
## Records voluntary exit indices seen.
chainDag*: ChainDAGRef
quarantine*: QuarantineRef
# #############################################
#
# Validator Pool
#
# #############################################
ValidatorKind* = enum
inProcess
remote
ValidatorConnection* = object
inStream*: Stream
outStream*: Stream
pubKeyStr*: string
AttachedValidator* = ref object
pubKey*: ValidatorPubKey
case kind*: ValidatorKind
of inProcess:
privKey*: ValidatorPrivKey
else:
connection*: ValidatorConnection
# The index at which this validator has been observed in the chain -
# it does not change as long as there are no reorgs on eth1 - however, the
# index might not be valid in all eth2 histories, so it should not be
# assumed that a valid index is stored here!
index*: Option[ValidatorIndex]
ValidatorPool* = object
validators*: Table[ValidatorPubKey, AttachedValidator]
slashingProtection*: SlashingProtectionDB
AttestationSubnets* = object
enabled*: bool
stabilitySubnets*: seq[tuple[subnet: uint8, expiration: Epoch]]
nextCycleEpoch*: Epoch
# These encode states in per-subnet state machines
subscribedSubnets*: set[uint8]
subscribeSlot*: array[ATTESTATION_SUBNET_COUNT, Slot]
unsubscribeSlot*: array[ATTESTATION_SUBNET_COUNT, Slot]
# Used to track the next attestation and proposal slots using an
# epoch-relative coordinate system. Doesn't need initialization.
attestingSlots*: array[2, uint32]
proposingSlots*: array[2, uint32]
lastCalculatedEpoch*: Epoch
func shortLog*(v: AttachedValidator): string = shortLog(v.pubKey)