Fix issue when VC crashes on invalid `beacon-node` argument. (#4765)
Make `beacon-node` URL argument less strict and more UX friendly.
This commit is contained in:
parent
464e680efc
commit
e2bf58a6f2
|
@ -205,19 +205,19 @@ proc new*(T: type ValidatorClientRef,
|
||||||
url = $url, error = res.error()
|
url = $url, error = res.error()
|
||||||
else:
|
else:
|
||||||
debug "Beacon node was initialized", node = res.get()
|
debug "Beacon node was initialized", node = res.get()
|
||||||
servers.add(res.get())
|
servers.add(res.get())
|
||||||
let missingRoles = getMissingRoles(servers)
|
let missingRoles = getMissingRoles(servers)
|
||||||
if len(missingRoles) != 0:
|
if len(missingRoles) != 0:
|
||||||
fatal "Beacon nodes do not use all required roles",
|
if len(servers) == 0:
|
||||||
missing_roles = $missingRoles, nodes_count = len(servers)
|
fatal "Not enough beacon nodes available",
|
||||||
quit 1
|
nodes_count = len(servers)
|
||||||
|
quit 1
|
||||||
|
else:
|
||||||
|
fatal "Beacon nodes do not cover all required roles",
|
||||||
|
missing_roles = $missingRoles, nodes_count = len(servers)
|
||||||
|
quit 1
|
||||||
servers
|
servers
|
||||||
|
|
||||||
if len(beaconNodes) == 0:
|
|
||||||
# This should not happen, thanks to defaults in `conf.nim`
|
|
||||||
fatal "Not enough beacon nodes in command line"
|
|
||||||
quit 1
|
|
||||||
|
|
||||||
when declared(waitSignal):
|
when declared(waitSignal):
|
||||||
ValidatorClientRef(
|
ValidatorClientRef(
|
||||||
rng: rng,
|
rng: rng,
|
||||||
|
@ -255,6 +255,9 @@ proc asyncInit(vc: ValidatorClientRef): Future[ValidatorClientRef] {.async.} =
|
||||||
config = vc.config,
|
config = vc.config,
|
||||||
beacon_nodes_count = len(vc.beaconNodes)
|
beacon_nodes_count = len(vc.beaconNodes)
|
||||||
|
|
||||||
|
for node in vc.beaconNodes:
|
||||||
|
notice "Beacon node initialized", node = node
|
||||||
|
|
||||||
vc.beaconGenesis = await vc.initGenesis()
|
vc.beaconGenesis = await vc.initGenesis()
|
||||||
info "Genesis information", genesis_time = vc.beaconGenesis.genesis_time,
|
info "Genesis information", genesis_time = vc.beaconGenesis.genesis_time,
|
||||||
genesis_fork_version = vc.beaconGenesis.genesis_fork_version,
|
genesis_fork_version = vc.beaconGenesis.genesis_fork_version,
|
||||||
|
|
|
@ -492,26 +492,58 @@ proc parseRoles*(data: string): Result[set[BeaconNodeRole], cstring] =
|
||||||
return err("Invalid beacon node role string found")
|
return err("Invalid beacon node role string found")
|
||||||
ok(res)
|
ok(res)
|
||||||
|
|
||||||
|
proc normalizeUri*(remoteUri: Uri): Uri =
|
||||||
|
var r = remoteUri
|
||||||
|
if (len(r.scheme) == 0) and (len(r.username) == 0) and
|
||||||
|
(len(r.password) == 0) and (len(r.hostname) == 0) and
|
||||||
|
(len(r.port) == 0) and (len(r.path) > 0):
|
||||||
|
# When `scheme` is not specified and `port` is not specified - whole
|
||||||
|
# hostname is stored in `path`.`query` and `anchor` could still be present.
|
||||||
|
# test.com
|
||||||
|
# test.com?q=query
|
||||||
|
# test.com?q=query#anchor=anchor
|
||||||
|
parseUri("http://" & $remoteUri & ":" & $defaultEth2RestPort)
|
||||||
|
elif (len(r.scheme) > 0) and (len(r.username) == 0) and
|
||||||
|
(len(r.password) == 0) and (len(r.hostname) == 0) and
|
||||||
|
(len(r.port) == 0) and (len(r.path) > 0):
|
||||||
|
# When `scheme` is not specified but `port` is specified - whole
|
||||||
|
# hostname is stored in `scheme` and `port` is in `path`.
|
||||||
|
# 192.168.0.1:5052
|
||||||
|
# test.com:5052
|
||||||
|
# test.com:5052?q=query
|
||||||
|
# test.com:5052?q=query#anchor=anchor
|
||||||
|
parseUri("http://" & $remoteUri)
|
||||||
|
elif (len(r.scheme) > 0) and (len(r.hostname) > 0):
|
||||||
|
# When `scheme` is specified, but `port` is not we use default.
|
||||||
|
# http://192.168.0.1
|
||||||
|
# http://test.com
|
||||||
|
# http://test.com?q=query
|
||||||
|
# http://test.com?q=query#anchor=anchor
|
||||||
|
if len(r.port) == 0: r.port = $defaultEth2RestPort
|
||||||
|
r
|
||||||
|
else:
|
||||||
|
remoteUri
|
||||||
|
|
||||||
proc init*(t: typedesc[BeaconNodeServerRef], remote: Uri,
|
proc init*(t: typedesc[BeaconNodeServerRef], remote: Uri,
|
||||||
index: int): Result[BeaconNodeServerRef, string] =
|
index: int): Result[BeaconNodeServerRef, string] =
|
||||||
doAssert(index >= 0)
|
doAssert(index >= 0)
|
||||||
let
|
let
|
||||||
flags = {RestClientFlag.CommaSeparatedArray}
|
flags = {RestClientFlag.CommaSeparatedArray}
|
||||||
|
remoteUri = normalizeUri(remote)
|
||||||
client =
|
client =
|
||||||
block:
|
block:
|
||||||
let res = RestClientRef.new($remote, flags = flags)
|
let res = RestClientRef.new($remoteUri, flags = flags)
|
||||||
if res.isErr(): return err($res.error())
|
if res.isErr(): return err($res.error())
|
||||||
res.get()
|
res.get()
|
||||||
roles =
|
roles =
|
||||||
block:
|
block:
|
||||||
let res = parseRoles(remote.anchor)
|
let res = parseRoles(remoteUri.anchor)
|
||||||
if res.isErr(): return err($res.error())
|
if res.isErr(): return err($res.error())
|
||||||
res.get()
|
res.get()
|
||||||
|
|
||||||
let server = BeaconNodeServerRef(
|
let server = BeaconNodeServerRef(
|
||||||
client: client, endpoint: $remote, index: index, roles: roles,
|
client: client, endpoint: $remoteUri, index: index, roles: roles,
|
||||||
logIdent: client.address.hostname & ":" &
|
logIdent: $client.address.getUri(),
|
||||||
Base10.toString(client.address.port),
|
|
||||||
status: RestBeaconNodeStatus.Offline
|
status: RestBeaconNodeStatus.Offline
|
||||||
)
|
)
|
||||||
ok(server)
|
ok(server)
|
||||||
|
|
Loading…
Reference in New Issue