Code Cleanup. Specific config for app (#1206)
* Code Cleanup. Specific config for app
This commit is contained in:
parent
1ab5c29530
commit
0353803012
|
@ -20,27 +20,44 @@ import
|
||||||
beacon_chain/spec/beaconstate,
|
beacon_chain/spec/beaconstate,
|
||||||
beacon_chain/spec/datatypes/[phase0, altair, bellatrix],
|
beacon_chain/spec/datatypes/[phase0, altair, bellatrix],
|
||||||
beacon_chain/[light_client, nimbus_binary_common, version],
|
beacon_chain/[light_client, nimbus_binary_common, version],
|
||||||
./rpc/rpc_eth_lc_api
|
./rpc/rpc_eth_lc_api,
|
||||||
|
./lc_proxy_conf
|
||||||
|
|
||||||
from beacon_chain/consensus_object_pools/consensus_manager import runForkchoiceUpdated
|
from beacon_chain/consensus_object_pools/consensus_manager import runForkchoiceUpdated
|
||||||
from beacon_chain/gossip_processing/block_processor import newExecutionPayload
|
from beacon_chain/gossip_processing/block_processor import newExecutionPayload
|
||||||
from beacon_chain/gossip_processing/eth2_processor import toValidationResult
|
from beacon_chain/gossip_processing/eth2_processor import toValidationResult
|
||||||
|
|
||||||
|
proc initRpcProxy(config: LcProxyConf): RpcProxy {.raises: [CatchableError, Defect].} =
|
||||||
|
let ta = initTAddress(config.rpcAddress, config.rpcPort)
|
||||||
|
let clientConfig =
|
||||||
|
case config.web3ClientConfig.kind
|
||||||
|
of WsClient:
|
||||||
|
getWebSocketClientConfig(config.web3ClientConfig.url)
|
||||||
|
of HttpClient:
|
||||||
|
getHttpClientConfig(config.web3ClientConfig.url)
|
||||||
|
|
||||||
|
return RpcProxy.new([ta], clientConfig)
|
||||||
|
|
||||||
# TODO Find what can throw exception
|
# TODO Find what can throw exception
|
||||||
proc run() {.raises: [Exception, Defect].}=
|
proc run() {.raises: [Exception, Defect].} =
|
||||||
{.pop.}
|
{.pop.}
|
||||||
var config = makeBannerAndConfig(
|
var config = makeBannerAndConfig(
|
||||||
"Nimbus light client " & fullVersionStr, LightClientConf)
|
"Nimbus light client " & fullVersionStr, LcProxyConf)
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
|
# Required as both Eth2Node and LightClient requires correct config type
|
||||||
|
var lcConfig = config.asLightClientConf()
|
||||||
|
|
||||||
setupLogging(config.logLevel, config.logStdout, config.logFile)
|
setupLogging(config.logLevel, config.logStdout, config.logFile)
|
||||||
|
|
||||||
notice "Launching light client",
|
notice "Launching light client proxy",
|
||||||
version = fullVersionStr, cmdParams = commandLineParams(), config
|
version = fullVersionStr, cmdParams = commandLineParams(), config
|
||||||
|
|
||||||
let metadata = loadEth2Network(config.eth2Network)
|
let metadata = loadEth2Network(config.eth2Network)
|
||||||
|
|
||||||
for node in metadata.bootstrapNodes:
|
for node in metadata.bootstrapNodes:
|
||||||
config.bootstrapNodes.add node
|
lcConfig.bootstrapNodes.add node
|
||||||
|
|
||||||
template cfg(): auto = metadata.cfg
|
template cfg(): auto = metadata.cfg
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -67,56 +84,13 @@ proc run() {.raises: [Exception, Defect].}=
|
||||||
netKeys = getRandomNetKeys(rng[])
|
netKeys = getRandomNetKeys(rng[])
|
||||||
|
|
||||||
network = createEth2Node(
|
network = createEth2Node(
|
||||||
rng, config, netKeys, cfg,
|
rng, lcConfig, netKeys, cfg,
|
||||||
forkDigests, getBeaconTime, genesis_validators_root)
|
forkDigests, getBeaconTime, genesis_validators_root
|
||||||
|
)
|
||||||
|
|
||||||
eth1Mon =
|
rpcServerWithProxy = initRpcProxy(config)
|
||||||
if config.web3Urls.len > 0:
|
|
||||||
let res = Eth1Monitor.init(
|
|
||||||
cfg, db = nil, getBeaconTime, config.web3Urls,
|
|
||||||
none(DepositContractSnapshot), metadata.eth1Network,
|
|
||||||
forcePolling = false,
|
|
||||||
rng[].loadJwtSecret(config, allowCreate = false),
|
|
||||||
true)
|
|
||||||
waitFor res.ensureDataProvider()
|
|
||||||
res
|
|
||||||
else:
|
|
||||||
nil
|
|
||||||
|
|
||||||
rpcServerWithProxy =
|
lcProxy = LightClientRpcProxy(proxy: rpcServerWithProxy)
|
||||||
if config.web3Urls.len > 0:
|
|
||||||
var web3Url = config.web3Urls[0]
|
|
||||||
fixupWeb3Urls web3Url
|
|
||||||
|
|
||||||
let proxyUri = some web3Url
|
|
||||||
|
|
||||||
if proxyUri.isSome:
|
|
||||||
info "Initializing LC eth API proxy", proxyUri = proxyUri.get
|
|
||||||
let
|
|
||||||
ta = initTAddress("127.0.0.1:8545")
|
|
||||||
clientConfig =
|
|
||||||
case parseUri(proxyUri.get).scheme.toLowerAscii():
|
|
||||||
of "http", "https":
|
|
||||||
getHttpClientConfig(proxyUri.get)
|
|
||||||
of "ws", "wss":
|
|
||||||
getWebSocketClientConfig(proxyUri.get)
|
|
||||||
else:
|
|
||||||
fatal "Unsupported scheme", proxyUri = proxyUri.get
|
|
||||||
quit QuitFailure
|
|
||||||
RpcProxy.new([ta], clientConfig)
|
|
||||||
else:
|
|
||||||
warn "Ignoring `rpcEnabled`, no `proxyUri` provided"
|
|
||||||
nil
|
|
||||||
else:
|
|
||||||
nil
|
|
||||||
|
|
||||||
lcProxy =
|
|
||||||
if rpcServerWithProxy != nil:
|
|
||||||
let res = LightClientRpcProxy(proxy: rpcServerWithProxy)
|
|
||||||
res.installEthApiHandlers()
|
|
||||||
res
|
|
||||||
else:
|
|
||||||
nil
|
|
||||||
|
|
||||||
optimisticHandler = proc(signedBlock: ForkedMsgTrustedSignedBeaconBlock):
|
optimisticHandler = proc(signedBlock: ForkedMsgTrustedSignedBeaconBlock):
|
||||||
Future[void] {.async.} =
|
Future[void] {.async.} =
|
||||||
|
@ -127,21 +101,7 @@ proc run() {.raises: [Exception, Defect].}=
|
||||||
when stateFork >= BeaconStateFork.Bellatrix:
|
when stateFork >= BeaconStateFork.Bellatrix:
|
||||||
if blck.message.is_execution_block:
|
if blck.message.is_execution_block:
|
||||||
template payload(): auto = blck.message.body.execution_payload
|
template payload(): auto = blck.message.body.execution_payload
|
||||||
|
lcProxy.executionPayload.ok payload.asEngineExecutionPayload()
|
||||||
if eth1Mon != nil:
|
|
||||||
await eth1Mon.ensureDataProvider()
|
|
||||||
|
|
||||||
# engine_newPayloadV1
|
|
||||||
discard await eth1Mon.newExecutionPayload(payload)
|
|
||||||
|
|
||||||
# engine_forkchoiceUpdatedV1
|
|
||||||
discard await eth1Mon.runForkchoiceUpdated(
|
|
||||||
headBlockRoot = payload.block_hash,
|
|
||||||
safeBlockRoot = payload.block_hash, # stub value
|
|
||||||
finalizedBlockRoot = ZERO_HASH)
|
|
||||||
|
|
||||||
if lcProxy != nil:
|
|
||||||
lcProxy.executionPayload.ok payload.asEngineExecutionPayload()
|
|
||||||
else: discard
|
else: discard
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -149,9 +109,11 @@ proc run() {.raises: [Exception, Defect].}=
|
||||||
getBeaconTime, optimisticHandler)
|
getBeaconTime, optimisticHandler)
|
||||||
|
|
||||||
lightClient = createLightClient(
|
lightClient = createLightClient(
|
||||||
network, rng, config, cfg, forkDigests, getBeaconTime,
|
network, rng, lcConfig, cfg, forkDigests, getBeaconTime,
|
||||||
genesis_validators_root, LightClientFinalizationMode.Optimistic)
|
genesis_validators_root, LightClientFinalizationMode.Optimistic)
|
||||||
|
|
||||||
|
lcProxy.installEthApiHandlers()
|
||||||
|
|
||||||
info "Listening to incoming network requests"
|
info "Listening to incoming network requests"
|
||||||
network.initBeaconSync(cfg, forkDigests, genesisBlockRoot, getBeaconTime)
|
network.initBeaconSync(cfg, forkDigests, genesisBlockRoot, getBeaconTime)
|
||||||
network.addValidator(
|
network.addValidator(
|
||||||
|
@ -170,16 +132,14 @@ proc run() {.raises: [Exception, Defect].}=
|
||||||
toValidationResult(
|
toValidationResult(
|
||||||
optimisticProcessor.processSignedBeaconBlock(signedBlock)))
|
optimisticProcessor.processSignedBeaconBlock(signedBlock)))
|
||||||
lightClient.installMessageValidators()
|
lightClient.installMessageValidators()
|
||||||
|
|
||||||
waitFor network.startListening()
|
waitFor network.startListening()
|
||||||
waitFor network.start()
|
waitFor network.start()
|
||||||
|
waitFor lcProxy.proxy.start()
|
||||||
if lcProxy != nil:
|
|
||||||
waitFor lcProxy.proxy.start()
|
|
||||||
|
|
||||||
proc onFinalizedHeader(
|
proc onFinalizedHeader(
|
||||||
lightClient: LightClient, finalizedHeader: BeaconBlockHeader) =
|
lightClient: LightClient, finalizedHeader: BeaconBlockHeader) =
|
||||||
info "New LC finalized header",
|
info "New LC finalized header", finalized_header = shortLog(finalizedHeader)
|
||||||
finalized_header = shortLog(finalizedHeader)
|
|
||||||
optimisticProcessor.setFinalizedHeader(finalizedHeader)
|
optimisticProcessor.setFinalizedHeader(finalizedHeader)
|
||||||
|
|
||||||
proc onOptimisticHeader(
|
proc onOptimisticHeader(
|
||||||
|
@ -193,10 +153,6 @@ proc run() {.raises: [Exception, Defect].}=
|
||||||
lightClient.trustedBlockRoot = some config.trustedBlockRoot
|
lightClient.trustedBlockRoot = some config.trustedBlockRoot
|
||||||
|
|
||||||
func shouldSyncOptimistically(wallSlot: Slot): bool =
|
func shouldSyncOptimistically(wallSlot: Slot): bool =
|
||||||
# Check whether an EL is connected
|
|
||||||
if eth1Mon == nil and lcProxy == nil:
|
|
||||||
return false
|
|
||||||
|
|
||||||
# Check whether light client is used
|
# Check whether light client is used
|
||||||
let optimisticHeader = lightClient.optimisticHeader.valueOr:
|
let optimisticHeader = lightClient.optimisticHeader.valueOr:
|
||||||
return false
|
return false
|
||||||
|
@ -249,15 +205,8 @@ proc run() {.raises: [Exception, Defect].}=
|
||||||
var nextExchangeTransitionConfTime: Moment
|
var nextExchangeTransitionConfTime: Moment
|
||||||
|
|
||||||
proc onSecond(time: Moment) =
|
proc onSecond(time: Moment) =
|
||||||
# engine_exchangeTransitionConfigurationV1
|
|
||||||
if time > nextExchangeTransitionConfTime and eth1Mon != nil:
|
|
||||||
nextExchangeTransitionConfTime = time + chronos.minutes(1)
|
|
||||||
traceAsyncErrors eth1Mon.exchangeTransitionConfiguration()
|
|
||||||
|
|
||||||
let wallSlot = getBeaconTime().slotOrZero()
|
let wallSlot = getBeaconTime().slotOrZero()
|
||||||
if checkIfShouldStopAtEpoch(wallSlot, config.stopAtEpoch):
|
updateBlocksGossipStatus(wallSlot + 1)
|
||||||
quit(0)
|
|
||||||
|
|
||||||
lightClient.updateGossipStatus(wallSlot + 1)
|
lightClient.updateGossipStatus(wallSlot + 1)
|
||||||
|
|
||||||
proc runOnSecondLoop() {.async.} =
|
proc runOnSecondLoop() {.async.} =
|
||||||
|
|
|
@ -0,0 +1,212 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
when (NimMajor, NimMinor) < (1, 4):
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
else:
|
||||||
|
{.push raises: [].}
|
||||||
|
|
||||||
|
import
|
||||||
|
std/os,
|
||||||
|
json_serialization/std/net,
|
||||||
|
beacon_chain/light_client,
|
||||||
|
beacon_chain/conf
|
||||||
|
|
||||||
|
export net, conf
|
||||||
|
|
||||||
|
proc defaultLCPDataDir*(): string =
|
||||||
|
let dataDir = when defined(windows):
|
||||||
|
"AppData" / "Roaming" / "LightClientProxy"
|
||||||
|
elif defined(macosx):
|
||||||
|
"Library" / "Application Support" / "LightClientProxy"
|
||||||
|
else:
|
||||||
|
".cache" / "lightclientproxy"
|
||||||
|
|
||||||
|
getHomeDir() / dataDir
|
||||||
|
|
||||||
|
|
||||||
|
type Web3ClientType* = enum
|
||||||
|
WsClient, HttpClient
|
||||||
|
|
||||||
|
type Web3ClientConfig* = object
|
||||||
|
kind*: Web3ClientType
|
||||||
|
url*: string
|
||||||
|
|
||||||
|
const
|
||||||
|
defaultWeb3Address* = (static "http://127.0.0.1:8546")
|
||||||
|
defaultWeb3ClientConfig* = Web3ClientConfig(url: defaultWeb3Address, kind: HttpClient)
|
||||||
|
defaultDataLCPDirDesc* = defaultLCPDataDir()
|
||||||
|
|
||||||
|
type LcProxyConf* = object
|
||||||
|
# Config
|
||||||
|
configFile* {.
|
||||||
|
desc: "Loads the configuration from a TOML file"
|
||||||
|
name: "config-file" .}: Option[InputFile]
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
logLevel* {.
|
||||||
|
desc: "Sets the log level"
|
||||||
|
defaultValue: "INFO"
|
||||||
|
name: "log-level" .}: string
|
||||||
|
|
||||||
|
logStdout* {.
|
||||||
|
hidden
|
||||||
|
desc: "Specifies what kind of logs should be written to stdout (auto, colors, nocolors, json)"
|
||||||
|
defaultValueDesc: "auto"
|
||||||
|
defaultValue: StdoutLogKind.Auto
|
||||||
|
name: "log-format" .}: StdoutLogKind
|
||||||
|
|
||||||
|
logFile* {.
|
||||||
|
desc: "Specifies a path for the written Json log file (deprecated)"
|
||||||
|
name: "log-file" .}: Option[OutFile]
|
||||||
|
|
||||||
|
# Storage
|
||||||
|
dataDir* {.
|
||||||
|
desc: "The directory where nimbus will store all blockchain data"
|
||||||
|
defaultValue: defaultLCPDataDir()
|
||||||
|
defaultValueDesc: $defaultDataLCPDirDesc
|
||||||
|
abbr: "d"
|
||||||
|
name: "data-dir" .}: OutDir
|
||||||
|
|
||||||
|
# Network
|
||||||
|
eth2Network* {.
|
||||||
|
desc: "The Eth2 network to join"
|
||||||
|
defaultValueDesc: "mainnet"
|
||||||
|
name: "network" .}: Option[string]
|
||||||
|
|
||||||
|
# Libp2p
|
||||||
|
bootstrapNodes* {.
|
||||||
|
desc: "Specifies one or more bootstrap nodes to use when connecting to the network"
|
||||||
|
abbr: "b"
|
||||||
|
name: "bootstrap-node" .}: seq[string]
|
||||||
|
|
||||||
|
bootstrapNodesFile* {.
|
||||||
|
desc: "Specifies a line-delimited file of bootstrap Ethereum network addresses"
|
||||||
|
defaultValue: ""
|
||||||
|
name: "bootstrap-file" .}: InputFile
|
||||||
|
|
||||||
|
listenAddress* {.
|
||||||
|
desc: "Listening address for the Ethereum LibP2P and Discovery v5 traffic"
|
||||||
|
defaultValue: defaultListenAddress
|
||||||
|
defaultValueDesc: $defaultListenAddressDesc
|
||||||
|
name: "listen-address" .}: ValidIpAddress
|
||||||
|
|
||||||
|
tcpPort* {.
|
||||||
|
desc: "Listening TCP port for Ethereum LibP2P traffic"
|
||||||
|
defaultValue: defaultEth2TcpPort
|
||||||
|
defaultValueDesc: $defaultEth2TcpPortDesc
|
||||||
|
name: "tcp-port" .}: Port
|
||||||
|
|
||||||
|
udpPort* {.
|
||||||
|
desc: "Listening UDP port for node discovery"
|
||||||
|
defaultValue: defaultEth2TcpPort
|
||||||
|
defaultValueDesc: $defaultEth2TcpPortDesc
|
||||||
|
name: "udp-port" .}: Port
|
||||||
|
|
||||||
|
maxPeers* {.
|
||||||
|
desc: "The target number of peers to connect to"
|
||||||
|
defaultValue: 160 # 5 (fanout) * 64 (subnets) / 2 (subs) for a heathy mesh
|
||||||
|
name: "max-peers" .}: int
|
||||||
|
|
||||||
|
hardMaxPeers* {.
|
||||||
|
desc: "The maximum number of peers to connect to. Defaults to maxPeers * 1.5"
|
||||||
|
name: "hard-max-peers" .}: Option[int]
|
||||||
|
|
||||||
|
nat* {.
|
||||||
|
desc: "Specify method to use for determining public address. " &
|
||||||
|
"Must be one of: any, none, upnp, pmp, extip:<IP>"
|
||||||
|
defaultValue: NatConfig(hasExtIp: false, nat: NatAny)
|
||||||
|
defaultValueDesc: "any"
|
||||||
|
name: "nat" .}: NatConfig
|
||||||
|
|
||||||
|
enrAutoUpdate* {.
|
||||||
|
desc: "Discovery can automatically update its ENR with the IP address " &
|
||||||
|
"and UDP port as seen by other nodes it communicates with. " &
|
||||||
|
"This option allows to enable/disable this functionality"
|
||||||
|
defaultValue: false
|
||||||
|
name: "enr-auto-update" .}: bool
|
||||||
|
|
||||||
|
agentString* {.
|
||||||
|
defaultValue: "nimbus",
|
||||||
|
desc: "Node agent string which is used as identifier in network"
|
||||||
|
name: "agent-string" .}: string
|
||||||
|
|
||||||
|
discv5Enabled* {.
|
||||||
|
desc: "Enable Discovery v5"
|
||||||
|
defaultValue: true
|
||||||
|
name: "discv5" .}: bool
|
||||||
|
|
||||||
|
directPeers* {.
|
||||||
|
desc: "The list of priviledged, secure and known peers to connect and" &
|
||||||
|
"maintain the connection to, this requires a not random netkey-file." &
|
||||||
|
"In the complete multiaddress format like:" &
|
||||||
|
"/ip4/<address>/tcp/<port>/p2p/<peerId-public-key>." &
|
||||||
|
"Peering agreements are established out of band and must be reciprocal."
|
||||||
|
name: "direct-peer" .}: seq[string]
|
||||||
|
|
||||||
|
# Light client
|
||||||
|
trustedBlockRoot* {.
|
||||||
|
desc: "Recent trusted finalized block root to initialize light client from"
|
||||||
|
name: "trusted-block-root" .}: Eth2Digest
|
||||||
|
|
||||||
|
rpcPort* {.
|
||||||
|
desc: "HTTP port for the JSON-RPC server"
|
||||||
|
defaultValue: 8545
|
||||||
|
name: "rpc-port" .}: Port
|
||||||
|
|
||||||
|
rpcAddress* {.
|
||||||
|
desc: "Listening address of the RPC server"
|
||||||
|
defaultValue: defaultAdminListenAddress
|
||||||
|
defaultValueDesc: $defaultAdminListenAddressDesc
|
||||||
|
name: "rpc-address" .}: ValidIpAddress
|
||||||
|
|
||||||
|
web3ClientConfig* {.
|
||||||
|
desc: "url of web3 data provider"
|
||||||
|
defaultValue: defaultWeb3ClientConfig
|
||||||
|
name: "web3-url" .}: Web3ClientConfig
|
||||||
|
|
||||||
|
proc parseCmdArg*(T: type Web3ClientConfig, p: TaintedString): T
|
||||||
|
{.raises: [Defect, ConfigurationError].} =
|
||||||
|
let url = parseUri(p)
|
||||||
|
let normalizedScheme = url.scheme.toLowerAscii()
|
||||||
|
if (normalizedScheme == "http" or normalizedScheme == "https"):
|
||||||
|
Web3ClientConfig(kind: HttpClient, url: p)
|
||||||
|
elif (normalizedScheme == "ws" or normalizedScheme == "wss"):
|
||||||
|
Web3ClientConfig(kind: WsClient, url: p)
|
||||||
|
else:
|
||||||
|
raise newException(
|
||||||
|
ConfigurationError, "Web3 client uri should have defined scheme (http/https/ws/wss)"
|
||||||
|
)
|
||||||
|
|
||||||
|
proc completeCmdArg*(T: type Web3ClientConfig, val: TaintedString): seq[string] =
|
||||||
|
return @[]
|
||||||
|
|
||||||
|
func asLightClientConf*(pc: LcProxyConf): LightClientConf =
|
||||||
|
return LightClientConf(
|
||||||
|
configFile: pc.configFile,
|
||||||
|
logLevel: pc.logLevel,
|
||||||
|
logStdout: pc.logStdout,
|
||||||
|
logFile: pc.logFile,
|
||||||
|
dataDir: pc.dataDir,
|
||||||
|
eth2Network: pc.eth2Network,
|
||||||
|
bootstrapNodes: pc.bootstrapNodes,
|
||||||
|
bootstrapNodesFile: pc.bootstrapNodesFile,
|
||||||
|
listenAddress: pc.listenAddress,
|
||||||
|
tcpPort: pc.tcpPort,
|
||||||
|
udpPort: pc.udpPort,
|
||||||
|
maxPeers: pc.maxPeers,
|
||||||
|
hardMaxPeers: pc.hardMaxPeers,
|
||||||
|
nat: pc.nat,
|
||||||
|
enrAutoUpdate: pc.enrAutoUpdate,
|
||||||
|
agentString: pc.agentString,
|
||||||
|
discv5Enabled: pc.discv5Enabled,
|
||||||
|
directPeers: pc.directPeers,
|
||||||
|
trustedBlockRoot: pc.trustedBlockRoot,
|
||||||
|
web3Urls: @[],
|
||||||
|
jwtSecret: none(string),
|
||||||
|
stopAtEpoch: 0
|
||||||
|
)
|
Loading…
Reference in New Issue