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

View File

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

View File

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

View File

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

2
vendor/nim-eth vendored

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