Temporary switch to supporting only ENR bootstrap addresses

Turns out the DiscV5 code relies heavily on the presence of ENR
records at the moment, so we cannot drive it with ENodes. @kdeme
is working on refactoring that will relax these requirements.
This commit is contained in:
Zahary Karadjov 2020-02-12 15:41:07 +02:00 committed by zah
parent 7f395e554a
commit 2c814db750
5 changed files with 33 additions and 17 deletions

View File

@ -49,6 +49,7 @@ type
netKeys: DiscKeyPair
requestManager: RequestManager
bootstrapNodes: seq[ENode]
bootstrapEnrs: seq[enr.Record]
db: BeaconChainDB
config: BeaconNodeConf
attachedValidators: ValidatorPool
@ -178,12 +179,13 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
mainchainMonitor.start()
var bootNodes: seq[ENode]
for node in conf.bootstrapNodes: bootNodes.addBootstrapNode(node)
bootNodes.loadBootstrapFile(string conf.bootstrapNodesFile)
var bootEnrs: seq[enr.Record]
for node in conf.bootstrapNodes: addBootstrapNode(node, bootNodes, bootEnrs)
loadBootstrapFile(string conf.bootstrapNodesFile, bootNodes, bootEnrs)
let persistentBootstrapFile = conf.dataDir / "bootstrap_nodes.txt"
if fileExists(persistentBootstrapFile):
bootNodes.loadBootstrapFile(persistentBootstrapFile)
loadBootstrapFile(persistentBootstrapFile, bootNodes, bootEnrs)
bootNodes = filterIt(bootNodes, it.pubkey != netKeys.pubkey)
@ -199,6 +201,7 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
netKeys: netKeys,
requestManager: RequestManager.init(network),
bootstrapNodes: bootNodes,
bootstrapEnrs: bootEnrs,
db: db,
config: conf,
attachedValidators: ValidatorPool.init(),
@ -240,7 +243,8 @@ proc connectToNetwork(node: BeaconNode) {.async.} =
else:
info "Waiting for connections"
await node.network.connectToNetwork(node.bootstrapNodes)
await node.network.connectToNetwork(node.bootstrapNodes,
node.bootstrapEnrs)
template findIt(s: openarray, predicate: untyped): int =
var res = -1

View File

@ -73,7 +73,7 @@ proc toMultiAddressStr*(enode: ENode): string =
skkey: enode.pubkey))
&"/ip4/{enode.address.ip}/tcp/{enode.address.tcpPort}/p2p/{peerId.pretty}"
proc parseBootstrapAddress*(address: TaintedString): Result[ENode, cstring] =
proc parseBootstrapAddress*(address: TaintedString): Result[enr.Record, cstring] =
if address.len == 0:
return err "an empty string is not a valid bootstrap node"
@ -81,17 +81,21 @@ proc parseBootstrapAddress*(address: TaintedString): Result[ENode, cstring] =
address = string(address)
if address[0] == '/':
return err "MultiAddress bootstrap addresses are not supported"
#[
try:
let ma = MultiAddress.init(address)
return toENode(ma)
except CatchableError:
return err "Invalid bootstrap multiaddress"
]#
else:
let lowerCaseAddress = toLowerAscii(string address)
if lowerCaseAddress.startsWith("enr:"):
var enrRec: enr.Record
if enrRec.fromURI(string address):
return ok enrRec
#[[
try:
# TODO: handle IPv6
let ipBytes = enrRec.get("ip", seq[byte])
@ -109,36 +113,42 @@ proc parseBootstrapAddress*(address: TaintedString): Result[ENode, cstring] =
except CatchableError:
# This will continue to the failure path below
discard
]]#
return err "Invalid ENR bootstrap record"
elif lowerCaseAddress.startsWith("enode:"):
return err "ENode bootstrap addresses are not supported"
#[
try:
return ok initEnode(string address)
except CatchableError as err:
return err "Ignoring invalid enode bootstrap address"
]#
else:
return err "Ignoring unrecognized bootstrap address type"
proc addBootstrapNode*(bootNodes: var seq[ENode],
bootstrapAddr: string) =
proc addBootstrapNode*(bootstrapAddr: string,
bootNodes: var seq[ENode],
bootEnrs: var seq[enr.Record]) =
let enodeRes = parseBootstrapAddress(bootstrapAddr)
if enodeRes.isOk:
bootNodes.add enodeRes.value
bootEnrs.add enodeRes.value
else:
warn "Ignoring invalid bootstrap address",
bootstrapAddr, reason = enodeRes.error
proc loadBootstrapFile*(bootNodes: var seq[ENode],
bootstrapFile: string) =
proc loadBootstrapFile*(bootstrapFile: string,
bootNodes: var seq[ENode],
bootEnrs: var seq[enr.Record]) =
if bootstrapFile.len == 0: return
let ext = splitFile(bootstrapFile).ext
if cmpIgnoreCase(ext, ".txt") == 0:
for ln in lines(bootstrapFile):
bootNodes.addBootstrapNode(ln)
addBootstrapNode(ln, bootNodes, bootEnrs)
elif cmpIgnoreCase(ext, ".yaml") == 0:
# TODO. This is very ugly, but let's try to negotiate the
# removal of YAML metadata.
for ln in lines(bootstrapFile):
bootNodes.addBootstrapNode(string(ln[3..^2]))
addBootstrapNode(string(ln[3..^2]), bootNodes, bootEnrs)
else:
error "Unknown bootstrap file format", ext
quit 1

View File

@ -203,7 +203,8 @@ when networkBackend in [libp2p, libp2pDaemon]:
return PeerInfo(peer: peerId, addresses: addresses)
proc connectToNetwork*(node: Eth2Node,
bootstrapNodes: seq[ENode]) {.async.} =
bootstrapNodes: seq[ENode],
bootstrapEnrs: seq[enr.Record]) {.async.} =
when networkBackend == libp2pDaemon:
var connected = false
for bootstrapNode in bootstrapNodes:
@ -225,7 +226,8 @@ when networkBackend in [libp2p, libp2pDaemon]:
fatal "Failed to connect to any bootstrap node. Quitting."
quit 1
elif networkBackend == libp2p:
for bootstrapNode in bootstrapNodes:
for bootstrapNode in bootstrapEnrs:
debug "Adding known peer", peer = bootstrapNode
node.addKnownPeer bootstrapNode
await node.start()

View File

@ -225,7 +225,7 @@ proc init*(T: type Eth2Node, conf: BeaconNodeConf,
if msg.protocolMounter != nil:
msg.protocolMounter result
proc addKnownPeer*(node: Eth2Node, peer: ENode) =
template addKnownPeer*(node: Eth2Node, peer: ENode|enr.Record) =
node.discovery.addNode peer
proc start*(node: Eth2Node) {.async.} =

2
vendor/nim-eth vendored

@ -1 +1 @@
Subproject commit 019df303b437f082e01a173a280ee3c5dc10844d
Subproject commit 31a4e8f959c1ce7de0ef5544753009d3b6b46e25