WIP Working local network sim with discovery
* The bootstrap_nodes.txt file in the node's data dir is now optional * Log more data on start-up * Use the latest ENR APIs * Fix simulation build errors
This commit is contained in:
parent
d2f59ebab9
commit
7f395e554a
|
@ -180,7 +180,11 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
|
||||||
var bootNodes: seq[ENode]
|
var bootNodes: seq[ENode]
|
||||||
for node in conf.bootstrapNodes: bootNodes.addBootstrapNode(node)
|
for node in conf.bootstrapNodes: bootNodes.addBootstrapNode(node)
|
||||||
bootNodes.loadBootstrapFile(string conf.bootstrapNodesFile)
|
bootNodes.loadBootstrapFile(string conf.bootstrapNodesFile)
|
||||||
bootNodes.loadBootstrapFile(conf.dataDir / "bootstrap_nodes.txt")
|
|
||||||
|
let persistentBootstrapFile = conf.dataDir / "bootstrap_nodes.txt"
|
||||||
|
if fileExists(persistentBootstrapFile):
|
||||||
|
bootNodes.loadBootstrapFile(persistentBootstrapFile)
|
||||||
|
|
||||||
bootNodes = filterIt(bootNodes, it.pubkey != netKeys.pubkey)
|
bootNodes = filterIt(bootNodes, it.pubkey != netKeys.pubkey)
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -1036,16 +1040,22 @@ when hasPrompt:
|
||||||
# createThread(t, processPromptCommands, addr p)
|
# createThread(t, processPromptCommands, addr p)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
when compiles(defaultChroniclesStream.output.writer):
|
||||||
|
defaultChroniclesStream.output.writer =
|
||||||
|
proc (logLevel: LogLevel, msg: LogOutputStr) {.gcsafe.} =
|
||||||
|
stdout.write(msg)
|
||||||
|
|
||||||
|
debug "Launching beacon node",
|
||||||
|
version = fullVersionStr,
|
||||||
|
cmdParams = commandLineParams()
|
||||||
|
|
||||||
randomize()
|
randomize()
|
||||||
|
|
||||||
let config = BeaconNodeConf.load(
|
let config = BeaconNodeConf.load(
|
||||||
version = clientId,
|
version = clientId,
|
||||||
copyrightBanner = clientId & "\p" & copyrights)
|
copyrightBanner = clientId & "\p" & copyrights)
|
||||||
|
|
||||||
when compiles(defaultChroniclesStream.output.writer):
|
debug "Configuration loaded", config
|
||||||
defaultChroniclesStream.output.writer =
|
|
||||||
proc (logLevel: LogLevel, msg: LogOutputStr) {.gcsafe.} =
|
|
||||||
stdout.write(msg)
|
|
||||||
|
|
||||||
if config.logLevel != LogLevel.NONE:
|
if config.logLevel != LogLevel.NONE:
|
||||||
setLogLevel(config.logLevel)
|
setLogLevel(config.logLevel)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
os, options, strformat, strutils,
|
os, options, strformat, strutils,
|
||||||
chronicles, confutils,
|
chronicles, confutils, json_serialization,
|
||||||
confutils/defs, chronicles/options as chroniclesOptions,
|
confutils/defs, chronicles/options as chroniclesOptions,
|
||||||
spec/[crypto]
|
spec/[crypto]
|
||||||
|
|
||||||
|
@ -289,3 +289,8 @@ iterator validatorKeys*(conf: BeaconNodeConf): ValidatorPrivKey =
|
||||||
yield ValidatorPrivKey.init(readFile(file).string)
|
yield ValidatorPrivKey.init(readFile(file).string)
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
warn "Failed to load a validator private key", file, err = err.msg
|
warn "Failed to load a validator private key", file, err = err.msg
|
||||||
|
|
||||||
|
template writeValue*(writer: var JsonWriter,
|
||||||
|
value: TypedInputFile|InputFile|InputDir|OutPath|OutDir|OutFile) =
|
||||||
|
writer.writeValue(string value)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
os, net, strutils, strformat, parseutils,
|
os, net, strutils, strformat, parseutils,
|
||||||
chronicles, stew/result, eth/keys, eth/trie/db, eth/p2p/enode,
|
chronicles, stew/[result, objects], eth/keys, eth/trie/db, eth/p2p/enode,
|
||||||
eth/p2p/discoveryv5/[enr, protocol, node, discovery_db, types],
|
eth/p2p/discoveryv5/[enr, protocol, node, discovery_db, types],
|
||||||
libp2p/[multiaddress, multicodec, peer],
|
libp2p/[multiaddress, multicodec, peer],
|
||||||
libp2p/crypto/crypto as libp2pCrypto,
|
libp2p/crypto/crypto as libp2pCrypto,
|
||||||
|
@ -93,18 +93,19 @@ proc parseBootstrapAddress*(address: TaintedString): Result[ENode, cstring] =
|
||||||
var enrRec: enr.Record
|
var enrRec: enr.Record
|
||||||
if enrRec.fromURI(string address):
|
if enrRec.fromURI(string address):
|
||||||
try:
|
try:
|
||||||
|
# TODO: handle IPv6
|
||||||
|
let ipBytes = enrRec.get("ip", seq[byte])
|
||||||
|
if ipBytes.len != 4:
|
||||||
|
return err "Malformed ENR IP address"
|
||||||
let
|
let
|
||||||
ip = IpAddress(family: IpAddressFamily.IPv4,
|
ip = IpAddress(family: IpAddressFamily.IPv4,
|
||||||
address_v4: cast[array[4, uint8]](enrRec.get("ip", int)))
|
address_v4: toArray(4, ipBytes))
|
||||||
tcpPort = Port enrRec.get("tcp", int)
|
udpPort = Port enrRec.get("udp", uint16)
|
||||||
udpPort = Port enrRec.get("udp", int)
|
|
||||||
var pubKey: keys.PublicKey
|
var pubKey: keys.PublicKey
|
||||||
if not enrRec.get(pubKey):
|
if not enrRec.get(pubKey):
|
||||||
return err "Failed to read public key from ENR record"
|
return err "Failed to read public key from ENR record"
|
||||||
return ok ENode(pubkey: pubkey,
|
return ok ENode(pubkey: pubkey,
|
||||||
address: Address(ip: ip,
|
address: Address(ip: ip, udpPort: udpPort))
|
||||||
tcpPort: tcpPort,
|
|
||||||
udpPort: udpPort))
|
|
||||||
except CatchableError:
|
except CatchableError:
|
||||||
# This will continue to the failure path below
|
# This will continue to the failure path below
|
||||||
discard
|
discard
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import
|
import
|
||||||
options, tables, strutils, sequtils,
|
options, tables, strutils, sequtils,
|
||||||
chronos, json_serialization, chronicles, metrics, libp2p/crypto/secp,
|
json_serialization, json_serialization/std/net,
|
||||||
|
metrics, chronos, chronicles, metrics, libp2p/crypto/secp,
|
||||||
eth/keys, eth/p2p/enode, eth/net/nat, eth/p2p/discoveryv5/enr,
|
eth/keys, eth/p2p/enode, eth/net/nat, eth/p2p/discoveryv5/enr,
|
||||||
eth2_discovery, version, conf
|
eth2_discovery, version, conf
|
||||||
|
|
||||||
|
@ -229,7 +230,7 @@ when networkBackend in [libp2p, libp2pDaemon]:
|
||||||
await node.start()
|
await node.start()
|
||||||
|
|
||||||
await sleepAsync(10.seconds)
|
await sleepAsync(10.seconds)
|
||||||
if libp2p_peers.get == 0:
|
if libp2p_peers.value == 0:
|
||||||
fatal "Failed to connect to any bootstrap node. Quitting"
|
fatal "Failed to connect to any bootstrap node. Quitting"
|
||||||
quit 1
|
quit 1
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import
|
import
|
||||||
algorithm, typetraits, net,
|
algorithm, typetraits, net as stdNet,
|
||||||
stew/[varints,base58], stew/shims/[macros, tables], chronos, chronicles,
|
stew/[varints,base58], stew/shims/[macros, tables], chronos, chronicles,
|
||||||
stint, faststreams/output_stream, serialization,
|
stint, faststreams/output_stream, serialization,
|
||||||
json_serialization/std/options, eth/p2p/p2p_protocol_dsl,
|
json_serialization/std/[net, options],
|
||||||
eth/p2p/discoveryv5/node,
|
eth/[keys, async_utils], eth/p2p/[enode, p2p_protocol_dsl],
|
||||||
|
eth/p2p/discoveryv5/[enr, node],
|
||||||
# TODO: create simpler to use libp2p modules that use re-exports
|
# TODO: create simpler to use libp2p modules that use re-exports
|
||||||
libp2p/[switch, multistream, connection,
|
libp2p/[switch, multistream, connection,
|
||||||
multiaddress, peerinfo, peer,
|
multiaddress, peerinfo, peer,
|
||||||
|
@ -208,11 +209,11 @@ proc runDiscoveryLoop*(node: Eth2Node) {.async.} =
|
||||||
await sleepAsync seconds(1)
|
await sleepAsync seconds(1)
|
||||||
|
|
||||||
proc init*(T: type Eth2Node, conf: BeaconNodeConf,
|
proc init*(T: type Eth2Node, conf: BeaconNodeConf,
|
||||||
switch: Switch, privKey: PrivateKey): T =
|
switch: Switch, privKey: keys.PrivateKey): T =
|
||||||
new result
|
new result
|
||||||
result.switch = switch
|
result.switch = switch
|
||||||
result.peers = initTable[PeerID, Peer]()
|
result.peers = initTable[PeerID, Peer]()
|
||||||
result.discovery = Eth2DiscoveryProtocol.new(conf, privKey.getBytes)
|
result.discovery = Eth2DiscoveryProtocol.new(conf, privKey.data)
|
||||||
result.wantedPeers = conf.maxPeers
|
result.wantedPeers = conf.maxPeers
|
||||||
|
|
||||||
newSeq result.protocolStates, allProtocols.len
|
newSeq result.protocolStates, allProtocols.len
|
||||||
|
|
Loading…
Reference in New Issue