getting there

This commit is contained in:
fryorcraken 2025-04-11 16:23:18 +10:00
parent 020c919a75
commit 2e368e8918
11 changed files with 594 additions and 477 deletions

View File

@ -64,20 +64,20 @@ when isMainModule:
nodeHealthMonitor = WakuNodeHealthMonitor()
nodeHealthMonitor.setOverallHealth(HealthStatus.INITIALIZING)
let wakuConf = wakuNodeConf.toWakuConf().valueOr:
let conf = wakuNodeConf.toWakuConf().valueOr:
error "Waku configuration failed", error = error
quit(QuitFailure)
var restServer: WakuRestServerRef = nil
if wakuConf.restServerConf.isSome:
if conf.restServerConf.isSome:
restServer = rest_server_builder.startRestServerEssentials(
nodeHealthMonitor, wakuConf.restServerConf.get(), wakuConf.portsShift
nodeHealthMonitor, conf.restServerConf.get(), conf.portsShift
).valueOr:
error "Starting essential REST server failed.", error = $error
quit(QuitFailure)
var waku = Waku.new(wakuConf).valueOr:
var waku = Waku.new(conf).valueOr:
error "Waku initialization failed", error = error
quit(QuitFailure)
@ -89,14 +89,14 @@ when isMainModule:
error "Starting waku failed", error = error
quit(QuitFailure)
if wakuConf.restServerConf.isSome:
if conf.restServerConf.isSome:
rest_server_builder.startRestServerProtocolSupport(
restServer,
waku.node,
waku.wakuDiscv5,
wakuConf.restServerConf.get(),
conf.restServerConf.get(),
conf.relay,
conf.lightPuh,
conf.lightPush,
conf.clusterId,
conf.shards,
conf.contentTopics,
@ -104,9 +104,12 @@ when isMainModule:
error "Starting protocols support REST server failed.", error = $error
quit(QuitFailure)
waku.metricsServer = waku_metrics.startMetricsServerAndLogging(confCopy).valueOr:
error "Starting monitoring and external interfaces failed", error = error
quit(QuitFailure)
if conf.metricsServerConf.isSome:
waku.metricsServer = waku_metrics.startMetricsServerAndLogging(
conf.metricsServerConf.get(), conf.portsShift
).valueOr:
error "Starting monitoring and external interfaces failed", error = error
quit(QuitFailure)
nodeHealthMonitor.setOverallHealth(HealthStatus.READY)

View File

@ -23,7 +23,7 @@ logScope:
## Config
# TODO: merge both conf
type Discv5Conf* = object
type Discv5Conf* {.requiresInit.} = object
# TODO: This should probably be an option on the builder
# But translated to everything else "false" on the config
discv5Only*: bool

View File

@ -1,6 +1,7 @@
import
std/[strutils, strformat],
results,
chronicles,
chronos,
regex,
confutils,
@ -14,15 +15,17 @@ import
nimcrypto/utils,
secp256k1,
json
import
./waku_conf,
./waku_conf_builder,
./networks_config,
../common/confutils/envvar/defs as confEnvvarDefs,
../common/confutils/envvar/std/net as confEnvvarNet,
../common/logging,
../waku_enr,
../node/peer_manager,
../waku_core/topics/pubsub_topic,
./waku_conf,
./waku_conf_builder,
../../tools/rln_keystore_generator/rln_keystore_generator,
../../tools/rln_db_inspector/rln_db_inspector
@ -30,6 +33,9 @@ include ../waku_core/message/default_values
export confTomlDefs, confTomlNet, confEnvvarDefs, confEnvvarNet, ProtectedShard
logScope:
topics = "waku external config"
# Git version in git describe format (defined at compile time)
const git_version* {.strdefine.} = "n/a"
@ -884,27 +890,23 @@ proc toKeystoreGeneratorConf*(n: WakuNodeConf): ConfResult[RlnKeystoreGeneratorC
)
)
# b.withLogLevel(n.logLevel)
# b.withLogFormat(n.logFormat)
# b.rlnRelayConf.withCredPath(n.rlnRelayCredPath)
# b.rlnRelayConf.withEthClientAddress(n.rlnRelayEthClientAddress)
# b.rlnRelayConf.withEthContractAddress(n.rlnRelayEthContractAddress)
# b.rlnRelayConf.withChainId(n.rlnRelayChainId)
# b.rlnRelayConf.withCredPassword(n.rlnRelayCredPassword)
## TODO: Oh, actually we probably need a different conf object by command :)
# rlnRelayEthPrivateKey* {.
# desc: "Private key for broadcasting transactions",
# defaultValue: "",
# name: "rln-relay-eth-private-key"
# .}: string
# b.rlnRelayConf.withUserMessageLimit(n.rlnRelayUserMessageLimit)
proc toInspectRlnDbConf*(n: WakuNodeConf): ConfResult[InspectRlnDbConf] =
return ok(InspectRlnDbConf(treePath: n.treePath))
proc toClusterConf(preset: string, clusterId: uint16): ConfResult[ClusterConf] =
var lcPreset = toLowerAscii(preset)
if clusterId == 1:
warn(
"TWN - The Waku Network configuration will not be applied when `--cluster-id=1` is passed in future releases. Use `--preset=twn` instead."
)
lcPreset = "twn"
case lcPreset
of "twn":
ok(ClusterConf.TheWakuNetworkConf())
else:
err("Invalid --preset value passed: " & preset)
proc toWakuConf*(n: WakuNodeConf): ConfResult[WakuConf] =
var b = WakuConfBuilder.init()
b.withLogLevel(n.logLevel)
@ -916,181 +918,41 @@ proc toWakuConf*(n: WakuNodeConf): ConfResult[WakuConf] =
b.rlnRelayConf.withChainId(n.rlnRelayChainId)
b.rlnRelayConf.withCredPassword(n.rlnRelayCredPassword)
b.rlnRelayConf.withUserMessageLimit(n.rlnRelayUserMessageLimit)
# # TODO: Remove "Default is" when it's already visible on the CLI
# 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
b.rlnRelayConf.withEpochSizeSec(n.rlnEpochSizeSec)
b.withMaxMessageSize(n.maxMessageSize)
b.withProtectedShards(n.protectedShards)
b.withClusterId(n.clusterId)
# rlnEpochSizeSec* {.
# desc:
# "Epoch size in seconds used to rate limit RLN memberships. Default is 1 second.",
# defaultValue: 1,
# name: "rln-relay-epoch-sec"
# .}: uint64
let clusterConf = toClusterConf(n.preset, n.clusterId).valueOr:
return err($error)
# maxMessageSize* {.
# desc:
# "Maximum message size. Accepted units: KiB, KB, and B. e.g. 1024KiB; 1500 B; etc.",
# defaultValue: DefaultMaxWakuMessageSizeStr,
# name: "max-msg-size"
# .}: string
b.withClusterConf(clusterConf)
b.withAgentString(n.agentString)
# case cmd* {.command, defaultValue: noCommand.}: StartUpCommand
# of inspectRlnDb:
# # have to change the name here since it counts as a duplicate, within noCommand
# treePath* {.
# desc: "Path to the RLN merkle tree sled db (https://github.com/spacejam/sled)",
# defaultValue: "",
# name: "rln-relay-tree-path"
# .}: string
# of generateRlnKeystore:
# execute* {.
# desc: "Runs the registration function on-chain. By default, a dry-run will occur",
# defaultValue: false,
# name: "execute"
# .}: bool
# of noCommand:
# ## Application-level configuration
# protectedShards* {.
# desc:
# "Shards and its public keys to be used for message validation, shard:pubkey. Argument may be repeated.",
# defaultValue: newSeq[ProtectedShard](0),
# name: "protected-shard"
# .}: seq[ProtectedShard]
if n.nodeKey.isSome():
b.withNodeKey(n.nodeKey.get())
# ## General node config
# preset* {.
# desc:
# "Network preset to use. 'twn' is The RLN-protected Waku Network (cluster 1).",
# defaultValue: "",
# name: "preset"
# .}: string
b.withP2pListenAddress(n.listenAddress)
b.withP2pTcpPort(n.tcpPort)
b.withPortsShift(n.portsShift)
b.withNatStrategy(n.nat)
b.withExtMultiAddrs(n.extMultiAddrs)
b.withExtMultiAddrsOnly(n.extMultiAddrsOnly)
b.withMaxConnections(n.maxConnections)
# clusterId* {.
# desc:
# "Cluster id that the node is running in. Node in a different cluster id is disconnected.",
# defaultValue: 0,
# name: "cluster-id"
# .}: uint16
if n.maxRelayPeers.isSome():
b.withMaxRelayPeers(n.maxRelayPeers.get())
# agentString* {.
# defaultValue: "nwaku-" & external_config.git_version,
# desc: "Node agent string which is used as identifier in network",
# name: "agent-string"
# .}: string
# nodekey* {.desc: "P2P node private key as 64 char hex string.", name: "nodekey".}:
# Option[PrivateKey]
# listenAddress* {.
# defaultValue: defaultListenAddress(),
# desc: "Listening address for LibP2P (and Discovery v5, if enabled) traffic.",
# name: "listen-address"
# .}: IpAddress
# tcpPort* {.desc: "TCP listening port.", defaultValue: 60000, name: "tcp-port".}:
# Port
# portsShift* {.
# desc: "Add a shift to all port numbers.", defaultValue: 0, name: "ports-shift"
# .}: uint16
# nat* {.
# desc:
# "Specify method to use for determining public address. " &
# "Must be one of: any, none, upnp, pmp, extip:<IP>.",
# defaultValue: "any"
# .}: string
# extMultiAddrs* {.
# desc:
# "External multiaddresses to advertise to the network. Argument may be repeated.",
# name: "ext-multiaddr"
# .}: seq[string]
# extMultiAddrsOnly* {.
# desc: "Only announce external multiaddresses setup with --ext-multiaddr",
# defaultValue: false,
# name: "ext-multiaddr-only"
# .}: bool
# maxConnections* {.
# desc: "Maximum allowed number of libp2p connections.",
# defaultValue: 50,
# name: "max-connections"
# .}: int
# maxRelayPeers* {.
# desc:
# "Deprecated. Use relay-service-ratio instead. It represents the maximum allowed number of relay peers.",
# name: "max-relay-peers"
# .}: Option[int]
# relayServiceRatio* {.
# desc:
# "This percentage ratio represents the relay peers to service peers. For example, 60:40, tells that 60% of the max-connections will be used for relay protocol and the other 40% of max-connections will be reserved for other service protocols (e.g., filter, lightpush, store, metadata, etc.)",
# name: "relay-service-ratio",
# defaultValue: "60:40" # 60:40 ratio of relay to service peers
# .}: string
# colocationLimit* {.
# desc:
# "Max num allowed peers from the same IP. Set it to 0 to remove the limitation.",
# defaultValue: defaultColocationLimit(),
# name: "ip-colocation-limit"
# .}: int
# peerStoreCapacity* {.
# desc: "Maximum stored peers in the peerstore.", name: "peer-store-capacity"
# .}: Option[int]
# peerPersistence* {.
# desc: "Enable peer persistence.", defaultValue: false, name: "peer-persistence"
# .}: bool
# ## DNS addrs config
# dnsAddrs* {.
# desc: "Enable resolution of `dnsaddr`, `dns4` or `dns6` multiaddrs",
# defaultValue: true,
# name: "dns-addrs"
# .}: bool
# dnsAddrsNameServers* {.
# desc:
# "DNS name server IPs to query for DNS multiaddrs resolution. Argument may be repeated.",
# defaultValue: @[parseIpAddress("1.1.1.1"), parseIpAddress("1.0.0.1")],
# name: "dns-addrs-name-server"
# .}: seq[IpAddress]
# dns4DomainName* {.
# desc: "The domain name resolving to the node's public IPv4 address",
# defaultValue: "",
# name: "dns4-domain-name"
# .}: string
# ## Circuit-relay config
# isRelayClient* {.
# desc:
# """Set the node as a relay-client.
# Set it to true for nodes that run behind a NAT or firewall and
# hence would have reachability issues.""",
# defaultValue: false,
# name: "relay-client"
# .}: bool
# ## Relay config
# relay* {.
# desc: "Enable relay protocol: true|false", defaultValue: true, name: "relay"
# .}: bool
# relayPeerExchange* {.
# desc: "Enable gossipsub peer exchange in relay protocol: true|false",
# defaultValue: false,
# name: "relay-peer-exchange"
# .}: bool
b.withRelayServiceRatio(n.relayServiceRatio)
b.withColocationLimit(n.colocationLimit)
b.withPeerStoreCapacity(n.peerStoreCapacity)
b.peerPersistence(n.peerPersistence)
b.withDnsAddrs(n.dnsAddrs)
b.withDnsAddrsNameServers(n.dnsAddrsNameServers)
b.withDns4DomainNanme(n.dns4DomainName)
b.withCircuitRelayClient(n.isRelayClient)
b.withRelay(n.relay)
b.withRelayPeerExchange(n.relayPeerExchange)
# relayShardedPeerManagement* {.
# desc:

View File

@ -149,26 +149,6 @@ proc networkConfiguration*(conf: WakuConf, clientId: string): NetConfigResult =
return netConfigRes
# TODO: redefine in the right place
# proc applyPresetConfiguration*(
# srcConf: WakuNodeConf, wakuConfBuilder: var WakuConfBuilder
# ): void =
# var preset = srcConf.preset
# if srcConf.clusterId == 1:
# warn(
# "TWN - The Waku Network configuration will not be applied when `--cluster-id=1` is passed in future releases. Use `--preset=twn` instead."
# )
# preset = "twn"
# case toLowerAscii(preset)
# of "twn":
# let twnClusterConf = ClusterConf.TheWakuNetworkConf()
# wakuConfBuilder.withClusterConf(twnClusterConf)
# else:
# discard
# TODO: numShardsInNetwork should be mandatory with autosharding, and unneeded otherwise
proc getNumShardsInNetwork*(conf: WakuConf): uint32 =
if conf.numShardsInNetwork != 0:

View File

@ -1,6 +1,6 @@
{.push raises: [].}
# TODO: this file should be called cluster_conf.nim
# TODO: Rename this type to match file name
type ClusterConf* = object
maxMessageSize*: string

View File

@ -4,14 +4,17 @@ import
libp2p/crypto/crypto,
libp2p/multiaddress,
secp256k1,
results,
waku/waku_rln_relay/rln_relay,
waku/waku_api/rest/builder,
waku/discovery/waku_discv5
results
import ../common/logging
import
../waku_rln_relay/rln_relay,
../waku_api/rest/builder,
../discovery/waku_discv5,
../node/waku_metrics,
../common/logging,
./networks_config
export RlnRelayConf, RlnRelayCreds, RestServerConf, Discv5Conf
export RlnRelayConf, RlnRelayCreds, RestServerConf, Discv5Conf, MetricsServerConf
logScope:
topics = "waku conf"
@ -21,39 +24,40 @@ type
DomainName* = distinct string
# TODO: should be defined in validator_signed.nim and imported here
type ProtectedShard* = object
type ProtectedShard* {.requiresInit.} = object
shard*: uint16
key*: secp256k1.SkPublicKey
type DnsDiscoveryConf* = object
type DnsDiscoveryConf* {.requiresInit.} = object
enrTreeUrl*: string
# TODO: should probably only have one set of name servers (see dnsaddrs)
nameServers*: seq[IpAddress]
type StoreServiceConf* = object
legacy*: bool
dbURl*: string
dbVacuum*: bool
dbMigration*: bool
maxNumDbConnections*: int
retentionPolicy*: string
resume*: bool
type FilterServiceConf* = object
maxPeersToServe*: uint32
subscriptionTimeout*: uint16
maxCriteria*: uint32
type StoreSyncConf* = object
type StoreSyncConf* {.requiresInit.} = object
rangeSec*: uint32
intervalSec*: uint32
relayJitterSec*: uint32
type WebSocketSecureConf* = object
type StoreServiceConf* {.requiresInit.} = object
dbMigration*: bool
dbURl*: string
dbVacuum*: bool
legacy*: bool
maxNumDbConnections*: int
retentionPolicy*: string
resume*: bool
storeSyncConf*: Option[StoreSyncConf]
type FilterServiceConf* {.requiresInit.} = object
maxPeersToServe*: uint32
subscriptionTimeout*: uint16
maxCriteria*: uint32
type WebSocketSecureConf* {.requiresInit.} = object
keyPath*: string
certPath*: string
type WebSocketConf* = ref object
type WebSocketConf* = object
port*: Port
secureConf*: Option[WebSocketSecureConf]
@ -62,7 +66,8 @@ type WebSocketConf* = ref object
## In this object. A convenient `validate` method enables doing
## sanity checks beyond type enforcement.
## If `Option` is `some` it means the related protocol is enabled.
type WakuConf* = ref object # ref because `getRunningNetConfig` modifies it
type WakuConf* {.requiresInit.} = ref object
# ref because `getRunningNetConfig` modifies it
nodeKey*: crypto.PrivateKey
clusterId*: uint16
@ -76,7 +81,7 @@ type WakuConf* = ref object # ref because `getRunningNetConfig` modifies it
relay*: bool
lightPush*: bool
peerExchange*: bool
storeSyncConf*: Option[StoreSyncConf]
# TODO: remove relay peer exchange
relayPeerExchange*: bool
rendezvous*: bool
@ -85,13 +90,11 @@ type WakuConf* = ref object # ref because `getRunningNetConfig` modifies it
discv5Conf*: Option[Discv5Conf]
dnsDiscoveryConf*: Option[DnsDiscoveryConf]
filterServiceConf*: Option[FilterServiceConf]
storeServiceConf*: Option[StoreServiceConf]
rlnRelayConf*: Option[RlnRelayConf]
restServerConf*: Option[RestServerConf]
metricsServerConf*: Option[MetricsServerConf]
# TODO: could probably make it a `PeerRemoteInfo`
staticNodes*: seq[string]
@ -100,7 +103,7 @@ type WakuConf* = ref object # ref because `getRunningNetConfig` modifies it
remoteFilterNode*: Option[string]
remotePeerExchangeNode*: Option[string]
maxMessageSizeBytes*: int
maxMessageSizeBytes*: uint64
logLevel*: logging.LogLevel
logFormat*: logging.LogFormat
@ -156,8 +159,8 @@ proc log*(conf: WakuConf) =
for i in conf.discv5Conf.get().bootstrapNodes:
info "Configuration. Bootstrap nodes", node = i.string
if conf.rlnRelayConf.isSome:
var rlnRelayConf = conf.rlnRelayConf.geT()
if conf.rlnRelayConf.isSome():
var rlnRelayConf = conf.rlnRelayConf.get()
if rlnRelayConf.dynamic:
info "Configuration. Validation",
mechanism = "onchain rln",
@ -219,16 +222,26 @@ proc validateNoEmptyStrings(wakuConf: WakuConf): Result[void, string] =
return err ("dnsDiscoveryConf.enrTreeUrl is an empty string")
# TODO: rln relay config should validate itself
if wakuConf.rlnRelayConf.isSome and wakuConf.rlnRelayConf.get().creds.isSome:
let creds = wakuConf.rlnRelayConf.get().creds.get()
if isEmptyOrWhiteSpace(creds.path):
return err (
"rlnRelayConf.creds.path is an empty string, set rlnRelayConf.creds it to none instead"
)
if isEmptyOrWhiteSpace(creds.password):
return err (
"rlnRelayConf.creds.password is an empty string, set rlnRelayConf.creds to none instead"
)
if wakuConf.rlnRelayConf.isSome():
let rlnRelayConf = wakuConf.rlnRelayConf.get()
if isEmptyOrWhiteSpace(rlnRelayConf.treePath):
return err("rlnRelayConf.treepath is an empty string")
if isEmptyOrWhiteSpace(rlnRelayConf.ethClientAddress):
return err("rlnRelayConf.ethClientAddress is an empty string")
if isEmptyOrWhiteSpace(rlnRelayConf.ethContractAddress):
return err("rlnRelayConf.ethContractAddress is an empty string")
if rlnRelayConf.creds.isSome():
let creds = rlnRelayConf.creds.get()
if isEmptyOrWhiteSpace(creds.path):
return err (
"rlnRelayConf.creds.path is an empty string, set rlnRelayConf.creds it to none instead"
)
if isEmptyOrWhiteSpace(creds.password):
return err (
"rlnRelayConf.creds.password is an empty string, set rlnRelayConf.creds to none instead"
)
return ok()

File diff suppressed because it is too large Load Diff

View File

@ -5,14 +5,18 @@ import
../waku_rln_relay/protocol_metrics as rln_metrics,
../utils/collector,
./peer_manager,
./waku_node,
../factory/external_config
./waku_node
const LogInterval = 10.minutes
logScope:
topics = "waku node metrics"
type MetricsServerConf* = object
httpAddress*: IpAddress
httpPort*: Port
logging*: bool
proc startMetricsLog*() =
var logMetrics: CallbackFunc
@ -70,17 +74,15 @@ proc startMetricsServer(
return ok(server)
proc startMetricsServerAndLogging*(
conf: WakuNodeConf
conf: MetricsServerConf, portsShift: uint16
): Result[MetricsHttpServerRef, string] =
var metricsServer: MetricsHttpServerRef
if conf.metricsServer:
metricsServer = startMetricsServer(
conf.metricsServerAddress, Port(conf.metricsServerPort + conf.portsShift)
).valueOr:
return
err("Starting metrics server failed. Continuing in current state:" & $error)
metricsServer = startMetricsServer(
conf.httpAddress, Port(conf.httpPort.uint16 + portsShift)
).valueOr:
return err("Starting metrics server failed. Continuing in current state:" & $error)
if conf.metricsLogging:
if conf.logging:
startMetricsLog()
return ok(metricsServer)

View File

@ -5,7 +5,6 @@ import presto
import
waku/waku_node,
waku/discovery/waku_discv5,
waku/factory/external_config,
waku/waku_api/message_cache,
waku/waku_api/handlers,
waku/waku_api/rest/server,
@ -33,7 +32,7 @@ restServerNotInstalledTab = newTable[string, string]()
export WakuRestServerRef
type RestServerConf* = object
allowOrigin*: string
allowOrigin*: seq[string]
listenAddress*: IpAddress
port*: Port
admin*: bool

View File

@ -23,7 +23,7 @@ type
### Configuration
type RestServerConf* = object
type RestServerConf* {.requiresInit.} = object
cacheSize*: Natural
## \
## The maximum number of recently accessed states that are kept in \

View File

@ -32,11 +32,11 @@ import
logScope:
topics = "waku rln_relay"
type RlnRelayCreds* = object
type RlnRelayCreds* {.requiresInit.} = object
path*: string
password*: string
type RlnRelayConf* = object of RootObj
type RlnRelayConf* {.requiresInit.} = object of RootObj
dynamic*: bool
credIndex*: Option[uint]
ethContractAddress*: string
@ -47,7 +47,7 @@ type RlnRelayConf* = object of RootObj
epochSizeSec*: uint64
userMessageLimit*: uint64
type WakuRlnConfig* = object of RlnRelayConf
type WakuRlnConfig* {.requiresInit.} = object of RlnRelayConf
onFatalErrorAction*: OnFatalErrorHandler
proc createMembershipList*(