2022-11-10 09:29:34 +00:00
|
|
|
|
import
|
|
|
|
|
chronicles,
|
|
|
|
|
chronicles/topics_registry,
|
|
|
|
|
confutils,
|
2024-02-16 13:06:31 +00:00
|
|
|
|
chronos,
|
|
|
|
|
std/strutils,
|
2022-11-10 09:29:34 +00:00
|
|
|
|
stew/results,
|
2024-02-16 13:06:31 +00:00
|
|
|
|
stew/shims/net,
|
|
|
|
|
regex
|
|
|
|
|
|
|
|
|
|
type EthRpcUrl = distinct string
|
2022-11-10 09:29:34 +00:00
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
|
type NetworkMonitorConf* = object
|
|
|
|
|
logLevel* {.
|
|
|
|
|
desc: "Sets the log level",
|
|
|
|
|
defaultValue: LogLevel.INFO,
|
|
|
|
|
name: "log-level",
|
|
|
|
|
abbr: "l"
|
|
|
|
|
.}: LogLevel
|
|
|
|
|
|
|
|
|
|
timeout* {.
|
|
|
|
|
desc: "Timeout to consider that the connection failed",
|
|
|
|
|
defaultValue: chronos.seconds(10),
|
|
|
|
|
name: "timeout",
|
|
|
|
|
abbr: "t"
|
|
|
|
|
.}: chronos.Duration
|
|
|
|
|
|
|
|
|
|
bootstrapNodes* {.
|
|
|
|
|
desc: "Bootstrap ENR node. Argument may be repeated.",
|
|
|
|
|
defaultValue: @[""],
|
|
|
|
|
name: "bootstrap-node",
|
|
|
|
|
abbr: "b"
|
|
|
|
|
.}: seq[string]
|
|
|
|
|
|
|
|
|
|
dnsDiscoveryUrl* {.
|
|
|
|
|
desc: "URL for DNS node list in format 'enrtree://<key>@<fqdn>'",
|
|
|
|
|
defaultValue: "",
|
|
|
|
|
name: "dns-discovery-url"
|
|
|
|
|
.}: string
|
|
|
|
|
|
|
|
|
|
pubsubTopics* {.
|
|
|
|
|
desc: "Default pubsub topic to subscribe to. Argument may be repeated.",
|
|
|
|
|
name: "pubsub-topic"
|
|
|
|
|
.}: seq[string]
|
|
|
|
|
|
|
|
|
|
refreshInterval* {.
|
|
|
|
|
desc: "How often new peers are discovered and connected to (in seconds)",
|
|
|
|
|
defaultValue: 5,
|
|
|
|
|
name: "refresh-interval",
|
|
|
|
|
abbr: "r"
|
|
|
|
|
.}: int
|
|
|
|
|
|
|
|
|
|
clusterId* {.
|
|
|
|
|
desc:
|
|
|
|
|
"Cluster id that the node is running in. Node in a different cluster id is disconnected.",
|
|
|
|
|
defaultValue: 1,
|
|
|
|
|
name: "cluster-id"
|
|
|
|
|
.}: uint32
|
|
|
|
|
|
|
|
|
|
rlnRelay* {.
|
|
|
|
|
desc: "Enable spam protection through rln-relay: true|false",
|
|
|
|
|
defaultValue: true,
|
|
|
|
|
name: "rln-relay"
|
|
|
|
|
.}: bool
|
|
|
|
|
|
|
|
|
|
rlnRelayDynamic* {.
|
|
|
|
|
desc: "Enable waku-rln-relay with on-chain dynamic group management: true|false",
|
|
|
|
|
defaultValue: true,
|
|
|
|
|
name: "rln-relay-dynamic"
|
|
|
|
|
.}: bool
|
|
|
|
|
|
|
|
|
|
rlnRelayTreePath* {.
|
|
|
|
|
desc: "Path to the RLN merkle tree sled db (https://github.com/spacejam/sled)",
|
|
|
|
|
defaultValue: "",
|
|
|
|
|
name: "rln-relay-tree-path"
|
|
|
|
|
.}: string
|
|
|
|
|
|
|
|
|
|
rlnRelayEthClientAddress* {.
|
|
|
|
|
desc: "HTTP address of an Ethereum testnet client e.g., http://localhost:8540/",
|
|
|
|
|
defaultValue: "http://localhost:8540/",
|
|
|
|
|
name: "rln-relay-eth-client-address"
|
|
|
|
|
.}: EthRpcUrl
|
|
|
|
|
|
|
|
|
|
rlnRelayEthContractAddress* {.
|
|
|
|
|
desc: "Address of membership contract on an Ethereum testnet",
|
|
|
|
|
defaultValue: "",
|
|
|
|
|
name: "rln-relay-eth-contract-address"
|
|
|
|
|
.}: string
|
|
|
|
|
|
|
|
|
|
rlnEpochSizeSec* {.
|
|
|
|
|
desc:
|
|
|
|
|
"Epoch size in seconds used to rate limit RLN memberships. Default is 1 second.",
|
|
|
|
|
defaultValue: 1,
|
|
|
|
|
name: "rln-relay-epoch-sec"
|
|
|
|
|
.}: uint64
|
|
|
|
|
|
|
|
|
|
rlnRelayUserMessageLimit* {.
|
|
|
|
|
desc:
|
|
|
|
|
"Set a user message limit for the rln membership registration. Must be a positive integer. Default is 1.",
|
|
|
|
|
defaultValue: 1,
|
|
|
|
|
name: "rln-relay-user-message-limit"
|
|
|
|
|
.}: uint64
|
|
|
|
|
|
|
|
|
|
## Prometheus metrics config
|
|
|
|
|
metricsServer* {.
|
|
|
|
|
desc: "Enable the metrics server: true|false",
|
|
|
|
|
defaultValue: true,
|
|
|
|
|
name: "metrics-server"
|
|
|
|
|
.}: bool
|
|
|
|
|
|
|
|
|
|
metricsServerAddress* {.
|
|
|
|
|
desc: "Listening address of the metrics server.",
|
|
|
|
|
defaultValue: parseIpAddress("127.0.0.1"),
|
|
|
|
|
name: "metrics-server-address"
|
|
|
|
|
.}: IpAddress
|
|
|
|
|
|
|
|
|
|
metricsServerPort* {.
|
|
|
|
|
desc: "Listening HTTP port of the metrics server.",
|
|
|
|
|
defaultValue: 8008,
|
|
|
|
|
name: "metrics-server-port"
|
|
|
|
|
.}: uint16
|
|
|
|
|
|
|
|
|
|
## Custom metrics rest server
|
|
|
|
|
metricsRestAddress* {.
|
|
|
|
|
desc: "Listening address of the metrics rest server.",
|
|
|
|
|
defaultValue: "127.0.0.1",
|
|
|
|
|
name: "metrics-rest-address"
|
|
|
|
|
.}: string
|
|
|
|
|
metricsRestPort* {.
|
|
|
|
|
desc: "Listening HTTP port of the metrics rest server.",
|
|
|
|
|
defaultValue: 8009,
|
|
|
|
|
name: "metrics-rest-port"
|
|
|
|
|
.}: uint16
|
2022-12-05 19:02:21 +00:00
|
|
|
|
|
2023-12-14 06:16:39 +00:00
|
|
|
|
proc parseCmdArg*(T: type IpAddress, p: string): T =
|
2022-11-10 09:29:34 +00:00
|
|
|
|
try:
|
2023-12-14 06:16:39 +00:00
|
|
|
|
result = parseIpAddress(p)
|
2022-11-10 09:29:34 +00:00
|
|
|
|
except CatchableError as e:
|
2023-09-21 11:12:14 +00:00
|
|
|
|
raise newException(ValueError, "Invalid IP address")
|
2022-11-10 09:29:34 +00:00
|
|
|
|
|
2023-12-14 06:16:39 +00:00
|
|
|
|
proc completeCmdArg*(T: type IpAddress, val: string): seq[string] =
|
2022-11-10 09:29:34 +00:00
|
|
|
|
return @[]
|
|
|
|
|
|
|
|
|
|
proc parseCmdArg*(T: type chronos.Duration, p: string): T =
|
|
|
|
|
try:
|
|
|
|
|
result = chronos.seconds(parseInt(p))
|
|
|
|
|
except CatchableError as e:
|
2023-09-21 11:12:14 +00:00
|
|
|
|
raise newException(ValueError, "Invalid duration value")
|
2022-11-10 09:29:34 +00:00
|
|
|
|
|
|
|
|
|
proc completeCmdArg*(T: type chronos.Duration, val: string): seq[string] =
|
|
|
|
|
return @[]
|
|
|
|
|
|
2024-02-16 13:06:31 +00:00
|
|
|
|
proc completeCmdArg*(T: type EthRpcUrl, val: string): seq[string] =
|
|
|
|
|
return @[]
|
|
|
|
|
|
|
|
|
|
proc parseCmdArg*(T: type EthRpcUrl, s: string): T =
|
|
|
|
|
## allowed patterns:
|
|
|
|
|
## http://url:port
|
|
|
|
|
## https://url:port
|
|
|
|
|
## http://url:port/path
|
|
|
|
|
## https://url:port/path
|
|
|
|
|
## http://url/with/path
|
|
|
|
|
## http://url:port/path?query
|
|
|
|
|
## https://url:port/path?query
|
|
|
|
|
## disallowed patterns:
|
|
|
|
|
## any valid/invalid ws or wss url
|
2024-03-15 23:08:47 +00:00
|
|
|
|
var httpPattern =
|
|
|
|
|
re2"^(https?):\/\/((localhost)|([\w_-]+(?:(?:\.[\w_-]+)+)))(:[0-9]{1,5})?([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])*"
|
|
|
|
|
var wsPattern =
|
|
|
|
|
re2"^(wss?):\/\/((localhost)|([\w_-]+(?:(?:\.[\w_-]+)+)))(:[0-9]{1,5})?([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])*"
|
2024-02-16 13:06:31 +00:00
|
|
|
|
if regex.match(s, wsPattern):
|
2024-03-15 23:08:47 +00:00
|
|
|
|
raise newException(
|
|
|
|
|
ValueError, "Websocket RPC URL is not supported, Please use an HTTP URL"
|
|
|
|
|
)
|
2024-02-16 13:06:31 +00:00
|
|
|
|
if not regex.match(s, httpPattern):
|
|
|
|
|
raise newException(ValueError, "Invalid HTTP RPC URL")
|
|
|
|
|
return EthRpcUrl(s)
|
|
|
|
|
|
2022-11-10 09:29:34 +00:00
|
|
|
|
proc loadConfig*(T: type NetworkMonitorConf): Result[T, string] =
|
|
|
|
|
try:
|
2024-03-15 23:08:47 +00:00
|
|
|
|
let conf = NetworkMonitorConf.load(version = git_version)
|
2022-11-10 09:29:34 +00:00
|
|
|
|
ok(conf)
|
|
|
|
|
except CatchableError:
|
2022-12-05 19:02:21 +00:00
|
|
|
|
err(getCurrentExceptionMsg())
|