move ENRForkID into `spec` (#2538)

* move ENRForkID into `spec`

also get rid of strformat in topic formation and fix some case
discrepancies

* also move `Eth2Metadata`
This commit is contained in:
Jacek Sieka 2021-05-04 17:28:48 +02:00 committed by GitHub
parent efdf759cc0
commit 4d74c742da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 77 deletions

View File

@ -74,7 +74,7 @@ type
peerPool*: PeerPool[Peer, PeerID] peerPool*: PeerPool[Peer, PeerID]
protocolStates*: seq[RootRef] protocolStates*: seq[RootRef]
libp2pTransportLoops*: seq[Future[void]] libp2pTransportLoops*: seq[Future[void]]
metadata*: Eth2Metadata metadata*: MetaData
connectTimeout*: chronos.Duration connectTimeout*: chronos.Duration
seenThreshold*: chronos.Duration seenThreshold*: chronos.Duration
connQueue: AsyncQueue[PeerAddr] connQueue: AsyncQueue[PeerAddr]
@ -88,15 +88,6 @@ type
EthereumNode = Eth2Node # needed for the definitions in p2p_backends_helpers EthereumNode = Eth2Node # needed for the definitions in p2p_backends_helpers
Eth2MetaData* = object
seq_number*: uint64
attnets*: BitArray[ATTESTATION_SUBNET_COUNT]
ENRForkID* = object
fork_digest*: ForkDigest
next_fork_version*: Version
next_fork_epoch*: Epoch
AverageThroughput* = object AverageThroughput* = object
count*: uint64 count*: uint64
average*: float average*: float
@ -968,10 +959,10 @@ proc runDiscoveryLoop*(node: Eth2Node) {.async.} =
# when no peers are in the routing table. Don't run it in continuous loop. # when no peers are in the routing table. Don't run it in continuous loop.
await sleepAsync(1.seconds) await sleepAsync(1.seconds)
proc getPersistentNetMetadata*(config: BeaconNodeConf): Eth2Metadata {.raises: [Defect, IOError, SerializationError].} = proc getPersistentNetMetadata*(config: BeaconNodeConf): MetaData {.raises: [Defect, IOError, SerializationError].} =
let metadataPath = config.dataDir / nodeMetadataFilename let metadataPath = config.dataDir / nodeMetadataFilename
if not fileExists(metadataPath): if not fileExists(metadataPath):
result = Eth2Metadata() result = MetaData()
for i in 0 ..< ATTESTATION_SUBNET_COUNT: for i in 0 ..< ATTESTATION_SUBNET_COUNT:
# TODO: # TODO:
# Persistent (stability) subnets should be stored with their expiration # Persistent (stability) subnets should be stored with their expiration
@ -979,7 +970,7 @@ proc getPersistentNetMetadata*(config: BeaconNodeConf): Eth2Metadata {.raises: [
result.attnets[i] = false result.attnets[i] = false
Json.saveFile(metadataPath, result) Json.saveFile(metadataPath, result)
else: else:
result = Json.loadFile(metadataPath, Eth2Metadata) result = Json.loadFile(metadataPath, MetaData)
proc resolvePeer(peer: Peer) = proc resolvePeer(peer: Peer) =
# Resolve task which performs searching of peer's public key and recovery of # Resolve task which performs searching of peer's public key and recovery of

View File

@ -90,16 +90,6 @@ declareGauge next_action_wait,
logScope: topics = "beacnde" logScope: topics = "beacnde"
func getEnrForkId(fork: Fork, genesis_validators_root: Eth2Digest): ENRForkID =
let
forkVer = fork.current_version
forkDigest = compute_fork_digest(forkVer, genesis_validators_root)
ENRForkID(
fork_digest: forkDigest,
next_fork_version: forkVer,
next_fork_epoch: FAR_FUTURE_EPOCH)
proc init*(T: type BeaconNode, proc init*(T: type BeaconNode,
runtimePreset: RuntimePreset, runtimePreset: RuntimePreset,
rng: ref BrHmacDrbgContext, rng: ref BrHmacDrbgContext,
@ -313,11 +303,11 @@ proc init*(T: type BeaconNode,
netKeys = getPersistentNetKeys(rng[], config) netKeys = getPersistentNetKeys(rng[], config)
nickname = if config.nodeName == "auto": shortForm(netKeys) nickname = if config.nodeName == "auto": shortForm(netKeys)
else: config.nodeName else: config.nodeName
enrForkId = getEnrForkId( enrForkId = getENRForkID(
getStateField(chainDag.headState, fork), getStateField(chainDag.headState, fork),
getStateField(chainDag.headState, genesis_validators_root)) getStateField(chainDag.headState, genesis_validators_root))
topicBeaconBlocks = getBeaconBlocksTopic(enrForkId.forkDigest) topicBeaconBlocks = getBeaconBlocksTopic(enrForkId.fork_digest)
topicAggregateAndProofs = getAggregateAndProofsTopic(enrForkId.forkDigest) topicAggregateAndProofs = getAggregateAndProofsTopic(enrForkId.fork_digest)
network = createEth2Node(rng, config, netKeys, enrForkId) network = createEth2Node(rng, config, netKeys, enrForkId)
attestationPool = newClone(AttestationPool.init(chainDag, quarantine)) attestationPool = newClone(AttestationPool.init(chainDag, quarantine))
exitPool = newClone(ExitPool.init(chainDag, quarantine)) exitPool = newClone(ExitPool.init(chainDag, quarantine))
@ -357,7 +347,7 @@ proc init*(T: type BeaconNode,
rng, rng,
proc(): BeaconTime = beaconClock.now()) proc(): BeaconTime = beaconClock.now())
var res = BeaconNode( var node = BeaconNode(
nickname: nickname, nickname: nickname,
graffitiBytes: if config.graffiti.isSome: config.graffiti.get.GraffitiBytes graffitiBytes: if config.graffiti.isSome: config.graffiti.get.GraffitiBytes
else: defaultGraffitiBytes(), else: defaultGraffitiBytes(),
@ -374,7 +364,7 @@ proc init*(T: type BeaconNode,
beaconClock: beaconClock, beaconClock: beaconClock,
rpcServer: rpcServer, rpcServer: rpcServer,
restServer: restServer, restServer: restServer,
forkDigest: enrForkId.forkDigest, forkDigest: enrForkId.fork_digest,
topicBeaconBlocks: topicBeaconBlocks, topicBeaconBlocks: topicBeaconBlocks,
topicAggregateAndProofs: topicAggregateAndProofs, topicAggregateAndProofs: topicAggregateAndProofs,
processor: processor, processor: processor,
@ -389,33 +379,33 @@ proc init*(T: type BeaconNode,
var var
topics = @[ topics = @[
topicBeaconBlocks, topicBeaconBlocks,
getAttesterSlashingsTopic(enrForkId.forkDigest), getAttesterSlashingsTopic(enrForkId.fork_digest),
getProposerSlashingsTopic(enrForkId.forkDigest), getProposerSlashingsTopic(enrForkId.fork_digest),
getVoluntaryExitsTopic(enrForkId.forkDigest), getVoluntaryExitsTopic(enrForkId.fork_digest),
getAggregateAndProofsTopic(enrForkId.forkDigest) getAggregateAndProofsTopic(enrForkId.fork_digest)
] ]
for subnet in 0'u64 ..< ATTESTATION_SUBNET_COUNT: for subnet in 0'u64 ..< ATTESTATION_SUBNET_COUNT:
topics &= getAttestationTopic(enrForkId.forkDigest, subnet) topics &= getAttestationTopic(enrForkId.fork_digest, subnet)
topics) topics)
if res.config.inProcessValidators: if node.config.inProcessValidators:
res.addLocalValidators() node.addLocalValidators()
else: else:
let cmd = getAppDir() / "nimbus_signing_process".addFileExt(ExeExt) let cmd = getAppDir() / "nimbus_signing_process".addFileExt(ExeExt)
let args = [$res.config.validatorsDir, $res.config.secretsDir] let args = [$node.config.validatorsDir, $node.config.secretsDir]
let workdir = io2.getCurrentDir().tryGet() let workdir = io2.getCurrentDir().tryGet()
res.vcProcess = try: startProcess(cmd, workdir, args) node.vcProcess = try: startProcess(cmd, workdir, args)
except CatchableError as exc: raise exc except CatchableError as exc: raise exc
except Exception as exc: raiseAssert exc.msg except Exception as exc: raiseAssert exc.msg
res.addRemoteValidators() node.addRemoteValidators()
# This merely configures the BeaconSync # This merely configures the BeaconSync
# The traffic will be started when we join the network. # The traffic will be started when we join the network.
network.initBeaconSync(chainDag, enrForkId.forkDigest) network.initBeaconSync(chainDag, enrForkId.fork_digest)
res.updateValidatorMetrics() node.updateValidatorMetrics()
return res return node
func verifyFinalization(node: BeaconNode, slot: Slot) = func verifyFinalization(node: BeaconNode, slot: Slot) =
# Epoch must be >= 4 to check finalization # Epoch must be >= 4 to check finalization
@ -1767,7 +1757,7 @@ proc doCreateTestnet(config: BeaconNodeConf, rng: var BrHmacDrbgContext) {.raise
some(config.bootstrapAddress), some(config.bootstrapAddress),
some(config.bootstrapPort), some(config.bootstrapPort),
some(config.bootstrapPort), some(config.bootstrapPort),
[toFieldPair("eth2", SSZ.encode(getEnrForkId( [toFieldPair("eth2", SSZ.encode(getENRForkID(
initialState[].fork, initialState[].genesis_validators_root))), initialState[].fork, initialState[].genesis_validators_root))),
toFieldPair("attnets", SSZ.encode(netMetadata.attnets))]) toFieldPair("attnets", SSZ.encode(netMetadata.attnets))])

View File

@ -607,6 +607,17 @@ type
withdrawable_epoch*: Epoch ##\ withdrawable_epoch*: Epoch ##\
## When validator can withdraw or transfer funds ## When validator can withdraw or transfer funds
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#metadata
MetaData* = object
seq_number*: uint64
attnets*: BitArray[ATTESTATION_SUBNET_COUNT]
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#eth2-field
ENRForkID* = object
fork_digest*: ForkDigest
next_fork_version*: Version
next_fork_epoch*: Epoch
BeaconStateDiff* = object BeaconStateDiff* = object
# Small and/or static; always include # Small and/or static; always include
slot*: Slot slot*: Slot

View File

@ -8,8 +8,7 @@
{.push raises: [Defect].} {.push raises: [Defect].}
import import
std/strformat, "."/[datatypes, digest, helpers]
./datatypes
const const
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#topics-and-messages # https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#topics-and-messages
@ -33,35 +32,23 @@ const
# This is not part of the spec! But its port which uses Lighthouse # This is not part of the spec! But its port which uses Lighthouse
DefaultEth2RestPort* = 5052 DefaultEth2RestPort* = 5052
template eth2Prefix(forkDigest: ForkDigest): string =
"/eth2/" & $forkDigest & "/"
func getBeaconBlocksTopic*(forkDigest: ForkDigest): string = func getBeaconBlocksTopic*(forkDigest: ForkDigest): string =
try: eth2Prefix(forkDigest) & topicBeaconBlocksSuffix
&"/eth2/{$forkDigest}/{topicBeaconBlocksSuffix}"
except ValueError as e:
raiseAssert e.msg
func getVoluntaryExitsTopic*(forkDigest: ForkDigest): string = func getVoluntaryExitsTopic*(forkDigest: ForkDigest): string =
try: eth2Prefix(forkDigest) & topicVoluntaryExitsSuffix
&"/eth2/{$forkDigest}/{topicVoluntaryExitsSuffix}"
except ValueError as e:
raiseAssert e.msg
func getProposerSlashingsTopic*(forkDigest: ForkDigest): string = func getProposerSlashingsTopic*(forkDigest: ForkDigest): string =
try: eth2Prefix(forkDigest) & topicProposerSlashingsSuffix
&"/eth2/{$forkDigest}/{topicProposerSlashingsSuffix}"
except ValueError as e:
raiseAssert e.msg
func getAttesterSlashingsTopic*(forkDigest: ForkDigest): string = func getAttesterSlashingsTopic*(forkDigest: ForkDigest): string =
try: eth2Prefix(forkDigest) & topicAttesterSlashingsSuffix
&"/eth2/{$forkDigest}/{topicAttesterSlashingsSuffix}"
except ValueError as e:
raiseAssert e.msg
func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string = func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string =
try: eth2Prefix(forkDigest) & topicAggregateAndProofsSuffix
&"/eth2/{$forkDigest}/{topicAggregateAndProofsSuffix}"
except ValueError as e:
raiseAssert e.msg
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/validator.md#broadcast-attestation # https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/validator.md#broadcast-attestation
func compute_subnet_for_attestation*( func compute_subnet_for_attestation*(
@ -84,7 +71,15 @@ func getAttestationTopic*(forkDigest: ForkDigest, subnetIndex: uint64):
## For subscribing and unsubscribing to/from a subnet. ## For subscribing and unsubscribing to/from a subnet.
doAssert subnetIndex < ATTESTATION_SUBNET_COUNT doAssert subnetIndex < ATTESTATION_SUBNET_COUNT
try: eth2Prefix(forkDigest) & "beacon_attestation_" & $subnetIndex & "/ssz"
&"/eth2/{$forkDigest}/beacon_attestation_{subnetIndex}/ssz"
except ValueError as e: func getENRForkID*(fork: Fork, genesis_validators_root: Eth2Digest): ENRForkID =
raiseAssert e.msg let
current_fork_version = fork.current_version
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)

View File

@ -143,7 +143,7 @@ p2pProtocol BeaconSync(version = 1,
{.libp2pProtocol("ping", 1).} = {.libp2pProtocol("ping", 1).} =
return peer.network.metadata.seq_number return peer.network.metadata.seq_number
proc getMetadata(peer: Peer): Eth2Metadata proc getMetaData(peer: Peer): MetaData
{.libp2pProtocol("metadata", 1).} = {.libp2pProtocol("metadata", 1).} =
return peer.network.metadata return peer.network.metadata

View File

@ -48,11 +48,6 @@ type
eth2: seq[byte] eth2: seq[byte]
attnets: seq[byte] attnets: seq[byte]
ENRForkID* = object
fork_digest*: ForkDigest
next_fork_version*: Version
next_fork_epoch*: Epoch
TopicFilter* {.pure.} = enum TopicFilter* {.pure.} = enum
Blocks, Attestations, Exits, ProposerSlashing, AttesterSlashings Blocks, Attestations, Exits, ProposerSlashing, AttesterSlashings
@ -242,11 +237,10 @@ proc getBootstrapAddress(bootnode: string): Option[BootstrapAddress] =
warn "Incorrect bootstrap address", address = bootnode, errMsg = exc.msg warn "Incorrect bootstrap address", address = bootnode, errMsg = exc.msg
func tryGetForkDigest(bootnode: enr.Record): Option[ForkDigest] = func tryGetForkDigest(bootnode: enr.Record): Option[ForkDigest] =
var forkId: ENRForkID let sszForkData = bootnode.tryGet("eth2", seq[byte])
var sszForkData = bootnode.tryGet("eth2", seq[byte])
if sszForkData.isSome(): if sszForkData.isSome():
try: try:
forkId = SSZ.decode(sszForkData.get(), ENRForkID) let forkId = SSZ.decode(sszForkData.get(), ENRForkID)
result = some(forkId.fork_digest) result = some(forkId.fork_digest)
except CatchableError: except CatchableError:
discard discard