Add cli option for providing bootstrap and static peers by ENR (#1634)

* Add cli option for providing bootstrap and static peers by ENR

* Minor bootstrap and static peers loading clean-up
This commit is contained in:
Kim De Mey 2023-07-07 09:47:26 +02:00 committed by GitHub
parent 217068790d
commit d0e46d9075
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -24,7 +24,7 @@ import
confutils/std/net
],
stew/shims/net as stewNet,
eth/[common, net/nat, p2p/bootnodes, p2p/enode],
eth/[common, net/nat, p2p/bootnodes, p2p/enode, p2p/discoveryv5/enr],
"."/[db/select_backend,
constants, vm_compile_info, version
],
@ -278,6 +278,12 @@ type
defaultValue: ""
name: "bootstrap-file" }: InputFile
bootstrapEnrs {.
desc: "ENR URI of node to bootstrap discovery from. Argument may be repeated"
defaultValue: @[]
defaultValueDesc: ""
name: "bootstrap-enr" }: seq[enr.Record]
staticPeers {.
desc: "Connect to one or more trusted peers(as enode URL)"
defaultValue: @[]
@ -291,6 +297,12 @@ type
defaultValue: ""
name: "static-peers-file" }: InputFile
staticPeersEnrs {.
desc: "ENR URI of node to connect to as trusted peer. Argument may be repeated"
defaultValue: @[]
defaultValueDesc: ""
name: "static-peer-enr" }: seq[enr.Record]
reconnectMaxRetry* {.
desc: "Specifies max number of retries if static peers disconnected/not connected. " &
"0 = infinite."
@ -541,6 +553,13 @@ proc parseCmdArg(T: type EthAddress, p: string): T
proc completeCmdArg(T: type EthAddress, val: string): seq[string] =
return @[]
proc parseCmdArg*(T: type enr.Record, p: string): T {.raises: [ValueError].} =
if not fromURI(result, p):
raise newException(ValueError, "Invalid ENR")
proc completeCmdArg*(T: type enr.Record, val: string): seq[string] =
return @[]
proc processList(v: string, o: var seq[string])
=
## Process comma-separated list of strings.
@ -560,11 +579,10 @@ proc parseCmdArg(T: type NetworkParams, p: string): T
proc completeCmdArg(T: type NetworkParams, val: string): seq[string] =
return @[]
proc setBootnodes(output: var seq[ENode], nodeUris: openArray[string])
{.gcsafe, raises: [CatchableError].} =
proc setBootnodes(output: var seq[ENode], nodeUris: openArray[string]) =
output = newSeqOfCap[ENode](nodeUris.len)
for item in nodeUris:
output.add(ENode.fromString(item).tryGet())
output.add(ENode.fromString(item).expect("valid hardcoded ENode"))
iterator repeatingList(listOfList: openArray[string]): string
=
@ -679,39 +697,83 @@ proc getRpcFlags*(conf: NimbusConf): set[RpcFlag] =
proc getWsFlags*(conf: NimbusConf): set[RpcFlag] =
getRpcFlags(conf.wsApi)
proc getBootNodes*(conf: NimbusConf): seq[ENode]
{.gcsafe, raises: [CatchableError].} =
proc fromEnr*(T: type ENode, r: enr.Record): ENodeResult[ENode] =
let
# TODO: there must always be a public key, else no signature verification
# could have been done and no Record would exist here.
# TypedRecord should be reworked not to have public key as an option.
pk = r.get(PublicKey).get()
tr = r.toTypedRecord().expect("id in valid record")
if tr.ip.isNone():
return err(IncorrectIP)
if tr.udp.isNone():
return err(IncorrectDiscPort)
if tr.tcp.isNone():
return err(IncorrectPort)
ok(ENode(
pubkey: pk,
address: Address(
ip: ipv4(tr.ip.get()),
udpPort: Port(tr.udp.get()),
tcpPort: Port(tr.tcp.get())
)
))
proc getBootNodes*(conf: NimbusConf): seq[ENode] =
var bootstrapNodes: seq[ENode]
# Ignore standard bootnodes if customNetwork is loaded
if conf.customNetwork.isNone:
case conf.networkId
of MainNet:
result.setBootnodes(MainnetBootnodes)
bootstrapNodes.setBootnodes(MainnetBootnodes)
of RopstenNet:
result.setBootnodes(RopstenBootnodes)
bootstrapNodes.setBootnodes(RopstenBootnodes)
of RinkebyNet:
result.setBootnodes(RinkebyBootnodes)
bootstrapNodes.setBootnodes(RinkebyBootnodes)
of GoerliNet:
result.setBootnodes(GoerliBootnodes)
bootstrapNodes.setBootnodes(GoerliBootnodes)
of KovanNet:
result.setBootnodes(KovanBootnodes)
bootstrapNodes.setBootnodes(KovanBootnodes)
of SepoliaNet:
result.setBootnodes(SepoliaBootnodes)
bootstrapNodes.setBootnodes(SepoliaBootnodes)
else:
# custom network id
discard
# always allow custom boostrap nodes
# if it is set by user
# always allow bootstrap nodes provided by the user
if conf.bootstrapNodes.len > 0:
result.append(conf.bootstrapNodes)
bootstrapNodes.append(conf.bootstrapNodes)
# bootstrap nodes loaded from file might append or
# override built-in bootnodes
loadBootstrapFile(string conf.bootstrapFile, result)
loadBootstrapFile(string conf.bootstrapFile, bootstrapNodes)
# Bootstrap nodes provided as ENRs
for enr in conf.bootstrapEnrs:
let enode = Enode.fromEnr(enr).valueOr:
fatal "Invalid bootstrap ENR provided", error
quit 1
bootstrapNodes.add(enode)
bootstrapNodes
proc getStaticPeers*(conf: NimbusConf): seq[ENode] =
result.append(conf.staticPeers)
loadStaticPeersFile(string conf.staticPeersFile, result)
var staticPeers: seq[ENode]
staticPeers.append(conf.staticPeers)
loadStaticPeersFile(string conf.staticPeersFile, staticPeers)
# Static peers provided as ENRs
for enr in conf.staticPeersEnrs:
let enode = Enode.fromEnr(enr).valueOr:
fatal "Invalid static peer ENR provided", error
quit 1
staticPeers.add(enode)
staticPeers
proc getAllowedOrigins*(conf: NimbusConf): seq[Uri] =
for item in repeatingList(conf.allowedOrigins):