nimbus-eth2/beacon_chain/nimbus_light_client.nim

100 lines
3.5 KiB
Nim
Raw Normal View History

# 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()