100 lines
3.5 KiB
Nim
100 lines
3.5 KiB
Nim
|
# beacon_chain
|
||
|
# Copyright (c) 2022 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.
|
||
|
|
||
|
# This implements the pre-release proposal of the libp2p based light client sync
|
||
|
# protocol. See https://github.com/ethereum/consensus-specs/pull/2802
|
||
|
|
||
|
import
|
||
|
std/os,
|
||
|
chronicles, chronos,
|
||
|
eth/keys,
|
||
|
./spec/beaconstate,
|
||
|
"."/[light_client, nimbus_binary_common, version]
|
||
|
|
||
|
proc onFinalizedHeader(lightClient: LightClient) =
|
||
|
notice "New LC finalized header",
|
||
|
finalized_header = shortLog(lightClient.finalizedHeader.get)
|
||
|
|
||
|
proc onOptimisticHeader(lightClient: LightClient) =
|
||
|
notice "New LC optimistic header",
|
||
|
optimistic_header = shortLog(lightClient.optimisticHeader.get)
|
||
|
|
||
|
proc onSecond(
|
||
|
lightClient: LightClient,
|
||
|
config: LightClientConf,
|
||
|
getBeaconTime: GetBeaconTimeFn) =
|
||
|
## This procedure will be called once per second.
|
||
|
let wallSlot = getBeaconTime().slotOrZero()
|
||
|
checkIfShouldStopAtEpoch(wallSlot, config.stopAtEpoch)
|
||
|
|
||
|
lightClient.updateGossipStatus(wallSlot + 1)
|
||
|
|
||
|
proc runOnSecondLoop(
|
||
|
lightClient: LightClient,
|
||
|
config: LightClientConf,
|
||
|
getBeaconTime: GetBeaconTimeFn) {.async.} =
|
||
|
while true:
|
||
|
onSecond(lightClient, config, getBeaconTime)
|
||
|
await chronos.sleepAsync(chronos.seconds(1))
|
||
|
|
||
|
programMain:
|
||
|
var config = makeBannerAndConfig(
|
||
|
"Nimbus light client " & fullVersionStr, LightClientConf)
|
||
|
setupLogging(config.logLevel, config.logStdout, config.logFile)
|
||
|
|
||
|
notice "Launching light client",
|
||
|
version = fullVersionStr, cmdParams = commandLineParams(), config
|
||
|
|
||
|
let metadata = loadEth2Network(config.eth2Network)
|
||
|
for node in metadata.bootstrapNodes:
|
||
|
config.bootstrapNodes.add node
|
||
|
template cfg(): auto = metadata.cfg
|
||
|
|
||
|
let
|
||
|
genesisState =
|
||
|
try:
|
||
|
template genesisData(): auto = metadata.genesisData
|
||
|
newClone(readSszForkedHashedBeaconState(
|
||
|
cfg, genesisData.toOpenArrayByte(genesisData.low, genesisData.high)))
|
||
|
except CatchableError as err:
|
||
|
raiseAssert "Invalid baked-in state: " & err.msg
|
||
|
|
||
|
beaconClock = BeaconClock.init(
|
||
|
getStateField(genesisState[], genesis_time))
|
||
|
getBeaconTime = beaconClock.getBeaconTimeFn()
|
||
|
|
||
|
genesis_validators_root =
|
||
|
getStateField(genesisState[], genesis_validators_root)
|
||
|
forkDigests = newClone ForkDigests.init(cfg, genesis_validators_root)
|
||
|
|
||
|
genesisBlockRoot = get_initial_beacon_block(genesisState[]).root
|
||
|
|
||
|
rng = keys.newRng()
|
||
|
netKeys = optimisticgetRandomNetKeys(rng[])
|
||
|
network = createEth2Node(
|
||
|
rng, config, netKeys, cfg,
|
||
|
forkDigests, getBeaconTime, genesis_validators_root)
|
||
|
|
||
|
lightClient = createLightClient(
|
||
|
network, rng, config, cfg,
|
||
|
forkDigests, getBeaconTime, genesis_validators_root)
|
||
|
|
||
|
info "Listening to incoming network requests"
|
||
|
network.initBeaconSync(cfg, forkDigests, genesisBlockRoot, getBeaconTime)
|
||
|
lightClient.installMessageValidators()
|
||
|
waitFor network.startListening()
|
||
|
waitFor network.start()
|
||
|
|
||
|
lightClient.onFinalizedHeader = onFinalizedHeader
|
||
|
lightClient.onOptimisticHeader = onOptimisticHeader
|
||
|
lightClient.trustedBlockRoot = some config.trustedBlockRoot
|
||
|
lightClient.start()
|
||
|
|
||
|
asyncSpawn runOnSecondLoop(lightClient, config, getBeaconTime)
|
||
|
while true:
|
||
|
poll()
|