Address some TODO items; Handle start-up before genesis more properly

This commit is contained in:
Zahary Karadjov 2020-06-11 15:13:12 +03:00 committed by zah
parent c773e10c1a
commit cf6a869e9e
4 changed files with 41 additions and 34 deletions

View File

@ -31,6 +31,7 @@ import
const const
genesisFile* = "genesis.ssz" genesisFile* = "genesis.ssz"
timeToInitNetworkingBeforeGenesis = chronos.seconds(10)
hasPrompt = not defined(withoutPrompt) hasPrompt = not defined(withoutPrompt)
type type
@ -145,7 +146,7 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
if genesisState.isNil: if genesisState.isNil:
# Didn't work, try creating a genesis state using main chain monitor # Didn't work, try creating a genesis state using main chain monitor
# TODO Could move this to a separate "GenesisMonitor" process or task # TODO Could move this to a separate "GenesisMonitor" process or task
# that would do only this - see # that would do only this - see Paul's proposal for this.
if conf.web3Url.len > 0 and conf.depositContractAddress.len > 0: if conf.web3Url.len > 0 and conf.depositContractAddress.len > 0:
mainchainMonitor = MainchainMonitor.init( mainchainMonitor = MainchainMonitor.init(
web3Provider(conf.web3Url), web3Provider(conf.web3Url),
@ -226,8 +227,10 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
topicAggregateAndProofs: topicAggregateAndProofs, topicAggregateAndProofs: topicAggregateAndProofs,
) )
# TODO sync is called when a remote peer is connected - is that the right traceAsyncErrors res.addLocalValidators()
# time to do so?
# This merely configures the BeaconSync
# The traffic will be started when we join the network.
network.initBeaconSync(blockPool, enrForkId.forkDigest, network.initBeaconSync(blockPool, enrForkId.forkDigest,
proc(signedBlock: SignedBeaconBlock) = proc(signedBlock: SignedBeaconBlock) =
if signedBlock.message.slot.isEpoch: if signedBlock.message.slot.isEpoch:
@ -251,9 +254,6 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
return res return res
proc connectToNetwork(node: BeaconNode) {.async.} =
await node.network.connectToNetwork()
proc onAttestation(node: BeaconNode, attestation: Attestation) = proc onAttestation(node: BeaconNode, attestation: Attestation) =
# We received an attestation from the network but don't know much about it # We received an attestation from the network but don't know much about it
# yet - in particular, we haven't verified that it belongs to particular chain # yet - in particular, we haven't verified that it belongs to particular chain
@ -807,15 +807,25 @@ proc createPidFile(filename: string) =
gPidFile = filename gPidFile = filename
addQuitProc proc {.noconv.} = removeFile gPidFile addQuitProc proc {.noconv.} = removeFile gPidFile
proc initializeNetworking(node: BeaconNode) {.async.} =
node.network.startListening()
let addressFile = node.config.dataDir / "beacon_node.address"
writeFile(addressFile, node.network.announcedENR.toURI)
await node.network.startLookingForPeers()
proc start(node: BeaconNode) = proc start(node: BeaconNode) =
# TODO: while it's nice to cheat by waiting for connections here, we
# actually need to make this part of normal application flow -
# losing all connections might happen at any time and we should be
# prepared to handle it.
let let
head = node.blockPool.head head = node.blockPool.head
finalizedHead = node.blockPool.finalizedHead finalizedHead = node.blockPool.finalizedHead
let genesisTime = node.beaconClock.fromNow(toBeaconTime(Slot 0))
if genesisTime.inFuture and genesisTime.offset > timeToInitNetworkingBeforeGenesis:
info "Waiting for the genesis event", genesisIn = genesisTime.offset
waitFor sleepAsync(genesisTime.offset - timeToInitNetworkingBeforeGenesis)
info "Starting beacon node", info "Starting beacon node",
version = fullVersionStr, version = fullVersionStr,
timeSinceFinalization = timeSinceFinalization =
@ -832,21 +842,7 @@ proc start(node: BeaconNode) =
cat = "init", cat = "init",
pcs = "start_beacon_node" pcs = "start_beacon_node"
node.network.startListening() waitFor node.initializeNetworking()
let addressFile = node.config.dataDir / "beacon_node.address"
writeFile(addressFile, node.network.announcedENR.toURI)
let bs = BlockSlot(blck: head.blck, slot: head.blck.slot)
node.blockPool.withState(node.blockPool.tmpState, bs):
for validatorKey in node.config.validatorKeys:
node.addLocalValidator state, validatorKey
# Allow some network events to be processed:
waitFor sleepAsync(1)
info "Local validators attached ", count = node.attachedValidators.count
waitFor node.network.connectToNetwork()
node.run() node.run()
func formatGwei(amount: uint64): string = func formatGwei(amount: uint64): string =

View File

@ -1115,7 +1115,7 @@ proc announcedENR*(node: Eth2Node): enr.Record =
proc shortForm*(id: KeyPair): string = proc shortForm*(id: KeyPair): string =
$PeerID.init(id.pubkey) $PeerID.init(id.pubkey)
proc connectToNetwork*(node: Eth2Node) {.async.} = proc startLookingForPeers*(node: Eth2Node) {.async.} =
await node.start() await node.start()
proc checkIfConnectedToBootstrapNode {.async.} = proc checkIfConnectedToBootstrapNode {.async.} =
@ -1125,9 +1125,7 @@ proc connectToNetwork*(node: Eth2Node) {.async.} =
bootstrapEnrs = node.discovery.bootstrapRecords bootstrapEnrs = node.discovery.bootstrapRecords
quit 1 quit 1
# TODO: The initial sync forces this to time out. traceAsyncErrors checkIfConnectedToBootstrapNode()
# Revisit when the new Sync manager is integrated.
# traceAsyncErrors checkIfConnectedToBootstrapNode()
func peersCount*(node: Eth2Node): int = func peersCount*(node: Eth2Node): int =
len(node.peerPool) len(node.peerPool)

View File

@ -41,8 +41,8 @@ proc saveValidatorKey*(keyName, key: string, conf: BeaconNodeConf) =
info "Imported validator key", file = outputFile info "Imported validator key", file = outputFile
proc addLocalValidator*(node: BeaconNode, proc addLocalValidator*(node: BeaconNode,
state: BeaconState, state: BeaconState,
privKey: ValidatorPrivKey) = privKey: ValidatorPrivKey) =
let pubKey = privKey.toPubKey() let pubKey = privKey.toPubKey()
let idx = state.validators.asSeq.findIt(it.pubKey == pubKey) let idx = state.validators.asSeq.findIt(it.pubKey == pubKey)
@ -53,9 +53,22 @@ proc addLocalValidator*(node: BeaconNode,
node.attachedValidators.addLocalValidator(pubKey, privKey) node.attachedValidators.addLocalValidator(pubKey, privKey)
proc addLocalValidators*(node: BeaconNode) {.async.} =
let
head = node.blockPool.head
bs = BlockSlot(blck: head.blck, slot: head.blck.slot)
node.blockPool.withState(node.blockPool.tmpState, bs):
for validatorKey in node.config.validatorKeys:
node.addLocalValidator state, validatorKey
# Allow some network events to be processed:
await sleepAsync(0.seconds)
info "Local validators attached ", count = node.attachedValidators.count
func getAttachedValidator*(node: BeaconNode, func getAttachedValidator*(node: BeaconNode,
state: BeaconState, state: BeaconState,
idx: ValidatorIndex): AttachedValidator = idx: ValidatorIndex): AttachedValidator =
let validatorKey = state.validators[idx].pubkey let validatorKey = state.validators[idx].pubkey
node.attachedValidators.getValidator(validatorKey) node.attachedValidators.getValidator(validatorKey)

View File

@ -36,5 +36,5 @@ asyncTest "connect two nodes":
c2.nat = "none" c2.nat = "none"
var n2 = await createEth2Node(c2, ENRForkID()) var n2 = await createEth2Node(c2, ENRForkID())
await n2.connectToNetwork(@[n1PersistentAddress]) await n2.startLookingForPeers(@[n1PersistentAddress])