2019-10-01 13:52:28 +00:00
|
|
|
# beacon_chain
|
2024-01-06 14:26:56 +00:00
|
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
2019-10-01 13:52:28 +00:00
|
|
|
# Licensed and distributed under either of
|
2019-11-25 15:30:02 +00:00
|
|
|
# * 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).
|
2019-10-01 13:52:28 +00:00
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2023-01-20 14:14:37 +00:00
|
|
|
{.push raises: [].}
|
2020-04-22 05:53:02 +00:00
|
|
|
|
2020-04-15 02:41:22 +00:00
|
|
|
import
|
2021-08-12 13:08:20 +00:00
|
|
|
"."/[helpers, forks],
|
2021-06-21 08:35:24 +00:00
|
|
|
"."/datatypes/base
|
2020-02-21 12:16:58 +00:00
|
|
|
|
2021-08-12 13:08:20 +00:00
|
|
|
export base
|
|
|
|
|
2019-10-01 13:52:28 +00:00
|
|
|
const
|
2024-08-21 12:25:19 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/p2p-interface.md#topics-and-messages
|
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/p2p-interface.md#topics-and-messages
|
2021-10-21 13:09:19 +00:00
|
|
|
topicBeaconBlocksSuffix* = "beacon_block/ssz_snappy"
|
|
|
|
topicVoluntaryExitsSuffix* = "voluntary_exit/ssz_snappy"
|
|
|
|
topicProposerSlashingsSuffix* = "proposer_slashing/ssz_snappy"
|
|
|
|
topicAttesterSlashingsSuffix* = "attester_slashing/ssz_snappy"
|
|
|
|
topicAggregateAndProofsSuffix* = "beacon_aggregate_and_proof/ssz_snappy"
|
2022-11-24 14:38:07 +00:00
|
|
|
topicBlsToExecutionChangeSuffix* = "bls_to_execution_change/ssz_snappy"
|
2020-02-21 12:16:58 +00:00
|
|
|
|
2023-09-14 12:37:35 +00:00
|
|
|
const
|
|
|
|
# The spec now includes this as a bare uint64 as `RESP_TIMEOUT`
|
|
|
|
RESP_TIMEOUT_DUR* = RESP_TIMEOUT.int64.seconds
|
2020-08-19 11:33:52 +00:00
|
|
|
|
2024-08-21 12:25:19 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/light-client/p2p-interface.md#configuration
|
2023-04-17 17:18:54 +00:00
|
|
|
MAX_REQUEST_LIGHT_CLIENT_UPDATES* = 128
|
|
|
|
|
2023-12-06 22:16:55 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#configuration
|
2023-09-14 12:37:35 +00:00
|
|
|
MAX_REQUEST_BLOB_SIDECARS*: uint64 =
|
|
|
|
MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
|
2023-04-17 17:18:54 +00:00
|
|
|
|
2020-03-16 22:28:54 +00:00
|
|
|
defaultEth2TcpPort* = 9000
|
2022-07-20 18:17:21 +00:00
|
|
|
defaultEth2TcpPortDesc* = $defaultEth2TcpPort
|
2020-03-16 22:28:54 +00:00
|
|
|
|
2022-12-04 07:42:03 +00:00
|
|
|
# This is not part of the spec! But it's port which Lighthouse uses
|
2022-07-20 18:17:21 +00:00
|
|
|
defaultEth2RestPort* = 5052
|
|
|
|
defaultEth2RestPortDesc* = $defaultEth2RestPort
|
2021-03-29 10:59:39 +00:00
|
|
|
|
2021-08-10 06:19:13 +00:00
|
|
|
enrAttestationSubnetsField* = "attnets"
|
|
|
|
enrSyncSubnetsField* = "syncnets"
|
|
|
|
enrForkIdField* = "eth2"
|
|
|
|
|
2021-05-04 15:28:48 +00:00
|
|
|
template eth2Prefix(forkDigest: ForkDigest): string =
|
|
|
|
"/eth2/" & $forkDigest & "/"
|
|
|
|
|
2020-04-15 02:41:22 +00:00
|
|
|
func getBeaconBlocksTopic*(forkDigest: ForkDigest): string =
|
2021-05-04 15:28:48 +00:00
|
|
|
eth2Prefix(forkDigest) & topicBeaconBlocksSuffix
|
2020-04-15 02:41:22 +00:00
|
|
|
|
2020-04-15 03:11:45 +00:00
|
|
|
func getVoluntaryExitsTopic*(forkDigest: ForkDigest): string =
|
2021-05-04 15:28:48 +00:00
|
|
|
eth2Prefix(forkDigest) & topicVoluntaryExitsSuffix
|
2020-04-15 02:41:22 +00:00
|
|
|
|
|
|
|
func getProposerSlashingsTopic*(forkDigest: ForkDigest): string =
|
2021-05-04 15:28:48 +00:00
|
|
|
eth2Prefix(forkDigest) & topicProposerSlashingsSuffix
|
2020-04-15 02:41:22 +00:00
|
|
|
|
|
|
|
func getAttesterSlashingsTopic*(forkDigest: ForkDigest): string =
|
2021-05-04 15:28:48 +00:00
|
|
|
eth2Prefix(forkDigest) & topicAttesterSlashingsSuffix
|
2020-04-15 02:41:22 +00:00
|
|
|
|
|
|
|
func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string =
|
2021-05-04 15:28:48 +00:00
|
|
|
eth2Prefix(forkDigest) & topicAggregateAndProofsSuffix
|
2020-04-15 02:41:22 +00:00
|
|
|
|
2024-08-21 12:25:19 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/capella/p2p-interface.md#topics-and-messages
|
2022-11-24 14:38:07 +00:00
|
|
|
func getBlsToExecutionChangeTopic*(forkDigest: ForkDigest): string =
|
|
|
|
eth2Prefix(forkDigest) & topicBlsToExecutionChangeSuffix
|
|
|
|
|
2024-08-23 10:43:54 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/phase0/validator.md#broadcast-attestation
|
2020-06-29 18:08:58 +00:00
|
|
|
func compute_subnet_for_attestation*(
|
2020-07-22 08:04:21 +00:00
|
|
|
committees_per_slot: uint64, slot: Slot, committee_index: CommitteeIndex):
|
2021-05-10 07:13:36 +00:00
|
|
|
SubnetId =
|
2022-09-10 17:16:38 +00:00
|
|
|
## Compute the correct subnet for an attestation for Phase 0.
|
|
|
|
# Note, this mimics expected future behavior where attestations will be
|
2020-06-29 18:08:58 +00:00
|
|
|
# mapped to their shard subnet.
|
|
|
|
let
|
2022-01-11 10:01:54 +00:00
|
|
|
slots_since_epoch_start = slot.since_epoch_start()
|
2020-06-29 18:08:58 +00:00
|
|
|
committees_since_epoch_start =
|
2020-07-22 08:04:21 +00:00
|
|
|
committees_per_slot * slots_since_epoch_start
|
2020-06-29 18:08:58 +00:00
|
|
|
|
2021-05-10 07:13:36 +00:00
|
|
|
SubnetId(
|
2022-01-11 10:01:54 +00:00
|
|
|
(committees_since_epoch_start + committee_index.asUInt64) mod
|
2021-05-10 07:13:36 +00:00
|
|
|
ATTESTATION_SUBNET_COUNT)
|
2020-06-29 18:08:58 +00:00
|
|
|
|
2024-03-14 06:26:36 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#broadcast-attestation
|
2021-08-10 06:19:13 +00:00
|
|
|
func getAttestationTopic*(forkDigest: ForkDigest,
|
|
|
|
subnetId: SubnetId): string =
|
2020-08-17 12:07:29 +00:00
|
|
|
## For subscribing and unsubscribing to/from a subnet.
|
2021-10-21 13:09:19 +00:00
|
|
|
eth2Prefix(forkDigest) & "beacon_attestation_" & $(subnetId) & "/ssz_snappy"
|
2021-05-04 15:28:48 +00:00
|
|
|
|
2024-03-14 06:26:36 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/p2p-interface.md#topics-and-messages
|
2021-08-15 14:50:31 +00:00
|
|
|
func getSyncCommitteeTopic*(forkDigest: ForkDigest,
|
2021-11-05 15:39:47 +00:00
|
|
|
subcommitteeIdx: SyncSubcommitteeIndex): string =
|
2021-08-15 14:50:31 +00:00
|
|
|
## For subscribing and unsubscribing to/from a subnet.
|
2022-01-08 23:28:49 +00:00
|
|
|
eth2Prefix(forkDigest) & "sync_committee_" & $subcommitteeIdx & "/ssz_snappy"
|
2021-08-15 14:50:31 +00:00
|
|
|
|
2024-03-14 06:26:36 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/p2p-interface.md#topics-and-messages
|
2021-08-15 14:50:31 +00:00
|
|
|
func getSyncCommitteeContributionAndProofTopic*(forkDigest: ForkDigest): string =
|
|
|
|
## For subscribing and unsubscribing to/from a subnet.
|
2021-10-21 13:09:19 +00:00
|
|
|
eth2Prefix(forkDigest) & "sync_committee_contribution_and_proof/ssz_snappy"
|
2021-08-15 14:50:31 +00:00
|
|
|
|
2023-12-06 22:16:55 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#blob_sidecar_subnet_id
|
2023-04-04 15:12:34 +00:00
|
|
|
func getBlobSidecarTopic*(forkDigest: ForkDigest,
|
2023-11-04 14:20:34 +00:00
|
|
|
subnet_id: BlobId): string =
|
2023-06-28 17:55:31 +00:00
|
|
|
eth2Prefix(forkDigest) & "blob_sidecar_" & $subnet_id & "/ssz_snappy"
|
|
|
|
|
2024-03-14 06:26:36 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/validator.md#sidecar
|
2023-11-04 14:20:34 +00:00
|
|
|
func compute_subnet_for_blob_sidecar*(blob_index: BlobIndex): BlobId =
|
|
|
|
BlobId(blob_index mod BLOB_SIDECAR_SUBNET_COUNT)
|
2023-04-04 15:12:34 +00:00
|
|
|
|
2023-12-05 02:34:45 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/p2p-interface.md#light_client_finality_update
|
2022-05-23 12:02:54 +00:00
|
|
|
func getLightClientFinalityUpdateTopic*(forkDigest: ForkDigest): string =
|
|
|
|
## For broadcasting or obtaining the latest `LightClientFinalityUpdate`.
|
2022-07-29 08:45:39 +00:00
|
|
|
eth2Prefix(forkDigest) & "light_client_finality_update/ssz_snappy"
|
2022-05-23 12:02:54 +00:00
|
|
|
|
2023-12-05 02:34:45 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/p2p-interface.md#light_client_optimistic_update
|
2022-05-23 12:02:54 +00:00
|
|
|
func getLightClientOptimisticUpdateTopic*(forkDigest: ForkDigest): string =
|
|
|
|
## For broadcasting or obtaining the latest `LightClientOptimisticUpdate`.
|
2022-07-29 08:45:39 +00:00
|
|
|
eth2Prefix(forkDigest) & "light_client_optimistic_update/ssz_snappy"
|
2022-03-14 13:05:38 +00:00
|
|
|
|
2021-08-10 06:19:13 +00:00
|
|
|
func getENRForkID*(cfg: RuntimeConfig,
|
|
|
|
epoch: Epoch,
|
2021-07-07 09:09:47 +00:00
|
|
|
genesis_validators_root: Eth2Digest): ENRForkID =
|
2021-05-04 15:28:48 +00:00
|
|
|
let
|
2021-08-10 06:19:13 +00:00
|
|
|
current_fork_version = cfg.forkVersionAtEpoch(epoch)
|
2021-09-30 01:07:24 +00:00
|
|
|
next_fork_version = if cfg.nextForkEpochAtEpoch(epoch) == FAR_FUTURE_EPOCH:
|
2021-08-20 13:04:29 +00:00
|
|
|
current_fork_version
|
|
|
|
else:
|
2021-09-30 01:07:24 +00:00
|
|
|
cfg.forkVersionAtEpoch(cfg.nextForkEpochAtEpoch(epoch))
|
2021-08-10 06:19:13 +00:00
|
|
|
fork_digest = compute_fork_digest(current_fork_version,
|
|
|
|
genesis_validators_root)
|
2021-05-04 15:28:48 +00:00
|
|
|
ENRForkID(
|
|
|
|
fork_digest: fork_digest,
|
2021-08-20 13:04:29 +00:00
|
|
|
next_fork_version: next_fork_version,
|
2021-08-10 06:19:13 +00:00
|
|
|
next_fork_epoch: cfg.nextForkEpochAtEpoch(epoch))
|
2021-09-29 11:06:16 +00:00
|
|
|
|
|
|
|
func getDiscoveryForkID*(cfg: RuntimeConfig,
|
2022-08-21 17:36:46 +00:00
|
|
|
epoch: Epoch,
|
|
|
|
genesis_validators_root: Eth2Digest): ENRForkID =
|
|
|
|
# Until 1 epoch from fork, return pre-fork value.
|
|
|
|
if cfg.nextForkEpochAtEpoch(epoch) - epoch <= 1:
|
2021-09-29 11:06:16 +00:00
|
|
|
getENRForkID(cfg, epoch, genesis_validators_root)
|
|
|
|
else:
|
|
|
|
let
|
|
|
|
current_fork_version = cfg.forkVersionAtEpoch(epoch)
|
|
|
|
fork_digest = compute_fork_digest(current_fork_version,
|
|
|
|
genesis_validators_root)
|
|
|
|
ENRForkID(
|
|
|
|
fork_digest: fork_digest,
|
|
|
|
next_fork_version: current_fork_version,
|
|
|
|
next_fork_epoch: FAR_FUTURE_EPOCH)
|
2021-12-21 14:24:23 +00:00
|
|
|
|
2024-03-14 06:26:36 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/p2p-interface.md#transitioning-the-gossip
|
2023-01-28 19:53:41 +00:00
|
|
|
type GossipState* = set[ConsensusFork]
|
2021-12-21 14:24:23 +00:00
|
|
|
func getTargetGossipState*(
|
2022-12-06 16:43:11 +00:00
|
|
|
epoch, ALTAIR_FORK_EPOCH, BELLATRIX_FORK_EPOCH, CAPELLA_FORK_EPOCH,
|
2024-05-15 13:30:49 +00:00
|
|
|
DENEB_FORK_EPOCH: Epoch, ELECTRA_FORK_EPOCH: Epoch, isBehind: bool):
|
|
|
|
GossipState =
|
2021-12-21 14:24:23 +00:00
|
|
|
if isBehind:
|
2022-12-04 07:42:03 +00:00
|
|
|
return {}
|
|
|
|
|
|
|
|
doAssert BELLATRIX_FORK_EPOCH >= ALTAIR_FORK_EPOCH
|
|
|
|
doAssert CAPELLA_FORK_EPOCH >= BELLATRIX_FORK_EPOCH
|
2023-02-15 14:44:09 +00:00
|
|
|
doAssert DENEB_FORK_EPOCH >= CAPELLA_FORK_EPOCH
|
2024-05-15 13:30:49 +00:00
|
|
|
doAssert ELECTRA_FORK_EPOCH >= DENEB_FORK_EPOCH
|
2022-12-04 07:42:03 +00:00
|
|
|
|
|
|
|
# https://github.com/ethereum/consensus-specs/issues/2902
|
|
|
|
# Don't care whether ALTAIR_FORK_EPOCH == BELLATRIX_FORK_EPOCH or
|
|
|
|
# BELLATRIX_FORK_EPOCH == CAPELLA_FORK_EPOCH works, because those
|
|
|
|
# theoretically possible networks are ill-defined regardless, and
|
|
|
|
# consequently prohibited by checkForkConsistency(). Therefore, a
|
|
|
|
# transitional epoch always exists, for every fork.
|
|
|
|
var targetForks: GossipState
|
|
|
|
|
|
|
|
template maybeIncludeFork(
|
2023-01-28 19:53:41 +00:00
|
|
|
targetFork: ConsensusFork, targetForkEpoch: Epoch,
|
2022-12-04 07:42:03 +00:00
|
|
|
successiveForkEpoch: Epoch) =
|
|
|
|
# Subscribe one epoch ahead
|
|
|
|
if epoch + 1 >= targetForkEpoch and epoch < successiveForkEpoch:
|
|
|
|
targetForks.incl targetFork
|
|
|
|
|
|
|
|
maybeIncludeFork(
|
2023-01-28 19:53:41 +00:00
|
|
|
ConsensusFork.Phase0, GENESIS_EPOCH, ALTAIR_FORK_EPOCH)
|
2022-12-04 07:42:03 +00:00
|
|
|
maybeIncludeFork(
|
2023-01-28 19:53:41 +00:00
|
|
|
ConsensusFork.Altair, ALTAIR_FORK_EPOCH, BELLATRIX_FORK_EPOCH)
|
2022-12-04 07:42:03 +00:00
|
|
|
maybeIncludeFork(
|
2023-01-28 19:53:41 +00:00
|
|
|
ConsensusFork.Bellatrix, BELLATRIX_FORK_EPOCH, CAPELLA_FORK_EPOCH)
|
2022-12-04 07:42:03 +00:00
|
|
|
maybeIncludeFork(
|
2023-02-15 14:44:09 +00:00
|
|
|
ConsensusFork.Capella, CAPELLA_FORK_EPOCH, DENEB_FORK_EPOCH)
|
2022-12-06 16:43:11 +00:00
|
|
|
maybeIncludeFork(
|
2024-05-15 13:30:49 +00:00
|
|
|
ConsensusFork.Deneb, DENEB_FORK_EPOCH, ELECTRA_FORK_EPOCH)
|
|
|
|
maybeIncludeFork(
|
|
|
|
ConsensusFork.Electra, ELECTRA_FORK_EPOCH, FAR_FUTURE_EPOCH)
|
2022-12-04 07:42:03 +00:00
|
|
|
|
|
|
|
doAssert len(targetForks) <= 2
|
|
|
|
targetForks
|
2022-01-24 20:40:59 +00:00
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
func nearSyncCommitteePeriod*(epoch: Epoch): Opt[uint64] =
|
2024-08-21 12:25:19 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#sync-committee-subnet-stability
|
2022-01-24 20:40:59 +00:00
|
|
|
if epoch.is_sync_committee_period():
|
2023-01-11 12:29:21 +00:00
|
|
|
return Opt.some 0'u64
|
2022-01-24 20:40:59 +00:00
|
|
|
let epochsBefore =
|
|
|
|
EPOCHS_PER_SYNC_COMMITTEE_PERIOD - epoch.since_sync_committee_period_start()
|
|
|
|
if epoch.is_sync_committee_period() or epochsBefore <= SYNC_COMMITTEE_SUBNET_COUNT:
|
2023-01-11 12:29:21 +00:00
|
|
|
return Opt.some epochsBefore
|
2022-01-24 20:40:59 +00:00
|
|
|
|
2023-01-11 12:29:21 +00:00
|
|
|
Opt.none(uint64)
|
2022-01-24 20:40:59 +00:00
|
|
|
|
|
|
|
func getSyncSubnets*(
|
|
|
|
nodeHasPubkey: proc(pubkey: ValidatorPubKey):
|
2023-08-25 09:29:07 +00:00
|
|
|
bool {.noSideEffect, raises: [].},
|
2022-01-24 20:40:59 +00:00
|
|
|
syncCommittee: SyncCommittee): SyncnetBits =
|
|
|
|
var res: SyncnetBits
|
|
|
|
for i, pubkey in syncCommittee.pubkeys:
|
2022-04-08 16:22:49 +00:00
|
|
|
if not nodeHasPubkey(pubkey):
|
2022-01-24 20:40:59 +00:00
|
|
|
continue
|
|
|
|
|
2024-08-21 12:25:19 +00:00
|
|
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/altair/validator.md#broadcast-sync-committee-message
|
2022-01-24 20:40:59 +00:00
|
|
|
# The first quarter of the pubkeys map to subnet 0, the second quarter to
|
|
|
|
# subnet 1, the third quarter to subnet 2 and the final quarter to subnet
|
|
|
|
# 3.
|
|
|
|
res.setBit(i div (SYNC_COMMITTEE_SIZE div SYNC_COMMITTEE_SUBNET_COUNT))
|
|
|
|
res
|
2023-08-23 19:31:41 +00:00
|
|
|
|
|
|
|
iterator blobSidecarTopics*(forkDigest: ForkDigest): string =
|
2023-11-04 14:20:34 +00:00
|
|
|
for subnet_id in BlobId:
|
|
|
|
yield getBlobSidecarTopic(forkDigest, subnet_id)
|