mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-01-08 00:43:06 +00:00
feat(wakunode2): support log format format selection
This commit is contained in:
parent
c90a1be7c6
commit
6f21b33831
@ -1,8 +1,19 @@
|
|||||||
import
|
import
|
||||||
confutils, confutils/defs, confutils/std/net, chronicles, chronos,
|
stew/results,
|
||||||
libp2p/crypto/[crypto, secp],
|
chronos,
|
||||||
|
confutils,
|
||||||
|
confutils/defs,
|
||||||
|
confutils/std/net,
|
||||||
|
libp2p/crypto/crypto,
|
||||||
|
libp2p/crypto/secp,
|
||||||
eth/keys
|
eth/keys
|
||||||
|
|
||||||
|
import
|
||||||
|
../../waku/common/logging
|
||||||
|
|
||||||
|
|
||||||
|
type ConfResult*[T] = Result[T, string]
|
||||||
|
|
||||||
type
|
type
|
||||||
FleetV1* = enum
|
FleetV1* = enum
|
||||||
none
|
none
|
||||||
@ -10,14 +21,21 @@ type
|
|||||||
staging
|
staging
|
||||||
test
|
test
|
||||||
|
|
||||||
WakuNodeConf* = object
|
WakuBridgeConf* = object
|
||||||
|
## Log configuration
|
||||||
logLevel* {.
|
logLevel* {.
|
||||||
desc: "Sets the log level"
|
desc: "Sets the log level for process. Supported levels: TRACE, DEBUG, INFO, NOTICE, WARN, ERROR or FATAL",
|
||||||
defaultValue: LogLevel.INFO
|
defaultValue: logging.LogLevel.INFO,
|
||||||
name: "log-level" .}: LogLevel
|
name: "log-level" .}: logging.LogLevel
|
||||||
|
|
||||||
|
logFormat* {.
|
||||||
|
desc: "Specifies what kind of logs should be written to stdout. Suported formats: Text, JSON",
|
||||||
|
defaultValue: logging.LogFormat.Text,
|
||||||
|
name: "log-format" .}: logging.LogFormat
|
||||||
|
|
||||||
|
## General node config
|
||||||
listenAddress* {.
|
listenAddress* {.
|
||||||
defaultValue: defaultListenAddress(config)
|
defaultValue: defaultListenAddress()
|
||||||
desc: "Listening address for the LibP2P traffic"
|
desc: "Listening address for the LibP2P traffic"
|
||||||
name: "listen-address"}: ValidIpAddress
|
name: "listen-address"}: ValidIpAddress
|
||||||
|
|
||||||
@ -72,16 +90,16 @@ type
|
|||||||
name: "metrics-server-port" .}: uint16
|
name: "metrics-server-port" .}: uint16
|
||||||
|
|
||||||
### Waku v1 options
|
### Waku v1 options
|
||||||
|
|
||||||
fleetV1* {.
|
fleetV1* {.
|
||||||
desc: "Select the Waku v1 fleet to connect to"
|
desc: "Select the Waku v1 fleet to connect to"
|
||||||
defaultValue: FleetV1.none
|
defaultValue: FleetV1.none
|
||||||
name: "fleet-v1" .}: FleetV1
|
name: "fleet-v1" .}: FleetV1
|
||||||
|
|
||||||
staticnodesV1* {.
|
staticnodesV1* {.
|
||||||
desc: "Enode URL to directly connect with. Argument may be repeated"
|
desc: "Enode URL to directly connect with. Argument may be repeated"
|
||||||
name: "staticnode-v1" .}: seq[string]
|
name: "staticnode-v1" .}: seq[string]
|
||||||
|
|
||||||
nodekeyV1* {.
|
nodekeyV1* {.
|
||||||
desc: "DevP2P node private key as hex",
|
desc: "DevP2P node private key as hex",
|
||||||
# TODO: can the rng be passed in somehow via Load?
|
# TODO: can the rng be passed in somehow via Load?
|
||||||
@ -92,7 +110,7 @@ type
|
|||||||
desc: "PoW requirement of Waku v1 node.",
|
desc: "PoW requirement of Waku v1 node.",
|
||||||
defaultValue: 0.002
|
defaultValue: 0.002
|
||||||
name: "waku-v1-pow" .}: float64
|
name: "waku-v1-pow" .}: float64
|
||||||
|
|
||||||
wakuV1TopicInterest* {.
|
wakuV1TopicInterest* {.
|
||||||
desc: "Run as Waku v1 node with a topic-interest",
|
desc: "Run as Waku v1 node with a topic-interest",
|
||||||
defaultValue: false
|
defaultValue: false
|
||||||
@ -133,17 +151,17 @@ type
|
|||||||
desc: "Multiaddr of peer to connect with for waku filter protocol"
|
desc: "Multiaddr of peer to connect with for waku filter protocol"
|
||||||
defaultValue: ""
|
defaultValue: ""
|
||||||
name: "filternode" }: string
|
name: "filternode" }: string
|
||||||
|
|
||||||
dnsAddrs* {.
|
dnsAddrs* {.
|
||||||
desc: "Enable resolution of `dnsaddr`, `dns4` or `dns6` multiaddrs"
|
desc: "Enable resolution of `dnsaddr`, `dns4` or `dns6` multiaddrs"
|
||||||
defaultValue: true
|
defaultValue: true
|
||||||
name: "dns-addrs" }: bool
|
name: "dns-addrs" }: bool
|
||||||
|
|
||||||
dnsAddrsNameServers* {.
|
dnsAddrsNameServers* {.
|
||||||
desc: "DNS name server IPs to query for DNS multiaddrs resolution. Argument may be repeated."
|
desc: "DNS name server IPs to query for DNS multiaddrs resolution. Argument may be repeated."
|
||||||
defaultValue: @[ValidIpAddress.init("1.1.1.1"), ValidIpAddress.init("1.0.0.1")]
|
defaultValue: @[ValidIpAddress.init("1.1.1.1"), ValidIpAddress.init("1.0.0.1")]
|
||||||
name: "dns-addrs-name-server" }: seq[ValidIpAddress]
|
name: "dns-addrs-name-server" }: seq[ValidIpAddress]
|
||||||
|
|
||||||
### Bridge options
|
### Bridge options
|
||||||
|
|
||||||
bridgePubsubTopic* {.
|
bridgePubsubTopic* {.
|
||||||
@ -151,9 +169,10 @@ type
|
|||||||
defaultValue: "/waku/2/default-waku/proto"
|
defaultValue: "/waku/2/default-waku/proto"
|
||||||
name: "bridge-pubsub-topic" }: string
|
name: "bridge-pubsub-topic" }: string
|
||||||
|
|
||||||
|
|
||||||
proc parseCmdArg*(T: type keys.KeyPair, p: string): T =
|
proc parseCmdArg*(T: type keys.KeyPair, p: string): T =
|
||||||
try:
|
try:
|
||||||
let privkey = keys.PrivateKey.fromHex(string(p)).tryGet()
|
let privkey = keys.PrivateKey.fromHex(p).tryGet()
|
||||||
result = privkey.toKeyPair()
|
result = privkey.toKeyPair()
|
||||||
except CatchableError:
|
except CatchableError:
|
||||||
raise newException(ConfigurationError, "Invalid private key")
|
raise newException(ConfigurationError, "Invalid private key")
|
||||||
@ -180,5 +199,20 @@ proc parseCmdArg*(T: type ValidIpAddress, p: string): T =
|
|||||||
proc completeCmdArg*(T: type ValidIpAddress, val: string): seq[string] =
|
proc completeCmdArg*(T: type ValidIpAddress, val: string): seq[string] =
|
||||||
return @[]
|
return @[]
|
||||||
|
|
||||||
func defaultListenAddress*(conf: WakuNodeConf): ValidIpAddress =
|
func defaultListenAddress*(): ValidIpAddress =
|
||||||
(static ValidIpAddress.init("0.0.0.0"))
|
(static ValidIpAddress.init("0.0.0.0"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Load
|
||||||
|
|
||||||
|
{.push warning[ProveInit]: off.}
|
||||||
|
|
||||||
|
proc load*(T: type WakuBridgeConf, version=""): ConfResult[T] =
|
||||||
|
try:
|
||||||
|
let conf = confutils.load(WakuBridgeConf, version=version)
|
||||||
|
ok(conf)
|
||||||
|
except CatchableError:
|
||||||
|
err(getCurrentExceptionMsg())
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
@ -1,3 +1,13 @@
|
|||||||
-d:chronicles_line_numbers
|
-d:chronicles_line_numbers
|
||||||
-d:chronicles_runtime_filtering:on
|
-d:chronicles_runtime_filtering:on
|
||||||
-d:discv5_protocol_id:d5waku
|
-d:discv5_protocol_id:d5waku
|
||||||
|
-d:chronicles_line_numbers
|
||||||
|
-d:discv5_protocol_id="d5waku"
|
||||||
|
-d:chronicles_runtime_filtering=on
|
||||||
|
-d:chronicles_sinks="textlines,json"
|
||||||
|
-d:chronicles_default_output_device=dynamic
|
||||||
|
# Disabling the following topics from nim-eth and nim-dnsdisc since some types cannot be serialized
|
||||||
|
-d:chronicles_disabled_topics="eth,dnsdisc.client"
|
||||||
|
# Results in empty output for some reason
|
||||||
|
#-d:"chronicles_enabled_topics=GossipSub:TRACE,WakuRelay:TRACE"
|
||||||
|
|
||||||
|
|||||||
@ -4,11 +4,14 @@ else:
|
|||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[tables, hashes, sequtils],
|
std/[os, tables, hashes, sequtils],
|
||||||
chronos, confutils, chronicles, chronicles/topics_registry, chronos/streams/tlsstream,
|
|
||||||
metrics, metrics/chronos_httpserver,
|
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
stew/shims/net as stewNet, json_rpc/rpcserver,
|
stew/shims/net as stewNet, json_rpc/rpcserver,
|
||||||
|
chronicles,
|
||||||
|
chronos,
|
||||||
|
chronos/streams/tlsstream,
|
||||||
|
metrics,
|
||||||
|
metrics/chronos_httpserver,
|
||||||
libp2p/errors,
|
libp2p/errors,
|
||||||
libp2p/peerstore,
|
libp2p/peerstore,
|
||||||
eth/[keys, p2p],
|
eth/[keys, p2p],
|
||||||
@ -30,8 +33,7 @@ import
|
|||||||
filter_api,
|
filter_api,
|
||||||
relay_api,
|
relay_api,
|
||||||
store_api],
|
store_api],
|
||||||
# Common cli config
|
./config
|
||||||
./config_bridge
|
|
||||||
|
|
||||||
declarePublicCounter waku_bridge_transfers, "Number of messages transferred between Waku v1 and v2 networks", ["type"]
|
declarePublicCounter waku_bridge_transfers, "Number of messages transferred between Waku v1 and v2 networks", ["type"]
|
||||||
declarePublicCounter waku_bridge_dropped, "Number of messages dropped", ["type"]
|
declarePublicCounter waku_bridge_dropped, "Number of messages dropped", ["type"]
|
||||||
@ -187,7 +189,7 @@ proc connectToV1(bridge: WakuBridge, target: int) =
|
|||||||
randIndex = rand(bridge.rng[], candidates.len() - 1)
|
randIndex = rand(bridge.rng[], candidates.len() - 1)
|
||||||
randPeer = candidates[randIndex]
|
randPeer = candidates[randIndex]
|
||||||
|
|
||||||
debug "Attempting to connect to random peer", randPeer
|
debug "Attempting to connect to random peer", randPeer= $randPeer
|
||||||
asyncSpawn bridge.nodev1.peerPool.connectToNode(randPeer)
|
asyncSpawn bridge.nodev1.peerPool.connectToNode(randPeer)
|
||||||
|
|
||||||
candidates.delete(randIndex, randIndex)
|
candidates.delete(randIndex, randIndex)
|
||||||
@ -328,7 +330,7 @@ proc stop*(bridge: WakuBridge) {.async.} =
|
|||||||
await bridge.nodev2.stop()
|
await bridge.nodev2.stop()
|
||||||
|
|
||||||
|
|
||||||
proc setupV2Rpc(node: WakuNode, rpcServer: RpcHttpServer, conf: WakuNodeConf) =
|
proc setupV2Rpc(node: WakuNode, rpcServer: RpcHttpServer, conf: WakuBridgeConf) =
|
||||||
installDebugApiHandlers(node, rpcServer)
|
installDebugApiHandlers(node, rpcServer)
|
||||||
|
|
||||||
# Install enabled API handlers:
|
# Install enabled API handlers:
|
||||||
@ -347,19 +349,35 @@ proc setupV2Rpc(node: WakuNode, rpcServer: RpcHttpServer, conf: WakuNodeConf) =
|
|||||||
{.pop.} # @TODO confutils.nim(775, 17) Error: can raise an unlisted exception: ref IOError
|
{.pop.} # @TODO confutils.nim(775, 17) Error: can raise an unlisted exception: ref IOError
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
import
|
import
|
||||||
libp2p/nameresolving/dnsresolver,
|
libp2p/nameresolving/dnsresolver
|
||||||
|
import
|
||||||
|
../../waku/common/logging,
|
||||||
../../waku/common/utils/nat,
|
../../waku/common/utils/nat,
|
||||||
../../waku/whisper/whispernodes,
|
../../waku/whisper/whispernodes,
|
||||||
../../waku/v1/node/rpc/wakusim,
|
../../waku/v1/node/rpc/wakusim,
|
||||||
../../waku/v1/node/rpc/waku,
|
../../waku/v1/node/rpc/waku,
|
||||||
../../waku/v1/node/rpc/key_storage
|
../../waku/v1/node/rpc/key_storage
|
||||||
|
|
||||||
let
|
const versionString = "version / git commit hash: " & git_version
|
||||||
rng = keys.newRng()
|
|
||||||
conf = WakuNodeConf.load()
|
let rng = keys.newRng()
|
||||||
|
|
||||||
|
let confRes = WakuBridgeConf.load(version=versionString)
|
||||||
|
if confRes.isErr():
|
||||||
|
error "failure while loading the configuration", error=confRes.error
|
||||||
|
quit(QuitFailure)
|
||||||
|
|
||||||
|
let conf = confRes.get()
|
||||||
|
|
||||||
|
## Logging setup
|
||||||
|
|
||||||
|
# Adhere to NO_COLOR initiative: https://no-color.org/
|
||||||
|
let color = try: not parseBool(os.getEnv("NO_COLOR", "false"))
|
||||||
|
except: true
|
||||||
|
|
||||||
|
logging.setupLogLevel(conf.logLevel)
|
||||||
|
logging.setupLogFormat(conf.logFormat, color)
|
||||||
|
|
||||||
if conf.logLevel != LogLevel.NONE:
|
|
||||||
setLogLevel(conf.logLevel)
|
|
||||||
|
|
||||||
## `udpPort` is only supplied to satisfy underlying APIs but is not
|
## `udpPort` is only supplied to satisfy underlying APIs but is not
|
||||||
## actually a supported transport.
|
## actually a supported transport.
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import
|
import
|
||||||
std/strutils,
|
std/strutils,
|
||||||
stew/results,
|
stew/results,
|
||||||
chronicles,
|
|
||||||
chronos,
|
chronos,
|
||||||
regex,
|
regex,
|
||||||
confutils,
|
confutils,
|
||||||
@ -14,7 +13,8 @@ import
|
|||||||
nimcrypto/utils
|
nimcrypto/utils
|
||||||
import
|
import
|
||||||
../../waku/common/confutils/envvar/defs as confEnvvarDefs,
|
../../waku/common/confutils/envvar/defs as confEnvvarDefs,
|
||||||
../../waku/common/confutils/envvar/std/net as confEnvvarNet
|
../../waku/common/confutils/envvar/std/net as confEnvvarNet,
|
||||||
|
../../waku/common/logging
|
||||||
|
|
||||||
export
|
export
|
||||||
confTomlDefs,
|
confTomlDefs,
|
||||||
@ -27,22 +27,24 @@ type ConfResult*[T] = Result[T, string]
|
|||||||
|
|
||||||
type
|
type
|
||||||
WakuNodeConf* = object
|
WakuNodeConf* = object
|
||||||
## General node config
|
|
||||||
|
|
||||||
configFile* {.
|
configFile* {.
|
||||||
desc: "Loads configuration from a TOML file (cmd-line parameters take precedence)"
|
desc: "Loads configuration from a TOML file (cmd-line parameters take precedence)"
|
||||||
name: "config-file" }: Option[InputFile]
|
name: "config-file" }: Option[InputFile]
|
||||||
|
|
||||||
|
|
||||||
|
## Log configuration
|
||||||
logLevel* {.
|
logLevel* {.
|
||||||
desc: "Sets the log level."
|
desc: "Sets the log level for process. Supported levels: TRACE, DEBUG, INFO, NOTICE, WARN, ERROR or FATAL",
|
||||||
defaultValue: LogLevel.INFO
|
defaultValue: logging.LogLevel.INFO,
|
||||||
name: "log-level" }: LogLevel
|
name: "log-level" .}: logging.LogLevel
|
||||||
|
|
||||||
version* {.
|
logFormat* {.
|
||||||
desc: "prints the version"
|
desc: "Specifies what kind of logs should be written to stdout. Suported formats: TEXT, JSON",
|
||||||
defaultValue: false
|
defaultValue: logging.LogFormat.TEXT,
|
||||||
name: "version" }: bool
|
name: "log-format" .}: logging.LogFormat
|
||||||
|
|
||||||
|
|
||||||
|
## General node config
|
||||||
agentString* {.
|
agentString* {.
|
||||||
defaultValue: "nwaku",
|
defaultValue: "nwaku",
|
||||||
desc: "Node agent string which is used as identifier in network"
|
desc: "Node agent string which is used as identifier in network"
|
||||||
@ -446,42 +448,46 @@ type
|
|||||||
defaultValue: ""
|
defaultValue: ""
|
||||||
name: "websocket-secure-cert-path"}: string
|
name: "websocket-secure-cert-path"}: string
|
||||||
|
|
||||||
|
## Parsing
|
||||||
|
|
||||||
# NOTE: Keys are different in nim-libp2p
|
# NOTE: Keys are different in nim-libp2p
|
||||||
proc parseCmdArg*(T: type crypto.PrivateKey, p: string): T =
|
proc parseCmdArg*(T: type crypto.PrivateKey, p: string): T =
|
||||||
try:
|
try:
|
||||||
let key = SkPrivateKey.init(utils.fromHex(p)).tryGet()
|
let key = SkPrivateKey.init(utils.fromHex(p)).tryGet()
|
||||||
crypto.PrivateKey(scheme: Secp256k1, skkey: key)
|
crypto.PrivateKey(scheme: Secp256k1, skkey: key)
|
||||||
except CatchableError:
|
except:
|
||||||
raise newException(ConfigurationError, "Invalid private key")
|
raise newException(ConfigurationError, "Invalid private key")
|
||||||
|
|
||||||
proc completeCmdArg*(T: type crypto.PrivateKey, val: string): seq[string] =
|
proc completeCmdArg*(T: type crypto.PrivateKey, val: string): seq[string] =
|
||||||
return @[]
|
return @[]
|
||||||
|
|
||||||
|
proc defaultPrivateKey*(): PrivateKey =
|
||||||
|
crypto.PrivateKey.random(Secp256k1, crypto.newRng()[]).value
|
||||||
|
|
||||||
|
|
||||||
proc parseCmdArg*(T: type ValidIpAddress, p: string): T =
|
proc parseCmdArg*(T: type ValidIpAddress, p: string): T =
|
||||||
try:
|
try:
|
||||||
ValidIpAddress.init(p)
|
ValidIpAddress.init(p)
|
||||||
except CatchableError as e:
|
except:
|
||||||
raise newException(ConfigurationError, "Invalid IP address")
|
raise newException(ConfigurationError, "Invalid IP address")
|
||||||
|
|
||||||
proc completeCmdArg*(T: type ValidIpAddress, val: string): seq[string] =
|
proc completeCmdArg*(T: type ValidIpAddress, val: string): seq[string] =
|
||||||
return @[]
|
return @[]
|
||||||
|
|
||||||
proc parseCmdArg*(T: type Port, p: string): T =
|
|
||||||
try:
|
|
||||||
Port(parseInt(p))
|
|
||||||
except CatchableError as e:
|
|
||||||
raise newException(ConfigurationError, "Invalid Port number")
|
|
||||||
|
|
||||||
proc completeCmdArg*(T: type Port, val: string): seq[string] =
|
|
||||||
return @[]
|
|
||||||
|
|
||||||
proc defaultListenAddress*(): ValidIpAddress =
|
proc defaultListenAddress*(): ValidIpAddress =
|
||||||
# TODO: How should we select between IPv4 and IPv6
|
# TODO: How should we select between IPv4 and IPv6
|
||||||
# Maybe there should be a config option for this.
|
# Maybe there should be a config option for this.
|
||||||
(static ValidIpAddress.init("0.0.0.0"))
|
(static ValidIpAddress.init("0.0.0.0"))
|
||||||
|
|
||||||
proc defaultPrivateKey*(): PrivateKey =
|
|
||||||
crypto.PrivateKey.random(Secp256k1, crypto.newRng()[]).value
|
proc parseCmdArg*(T: type Port, p: string): T =
|
||||||
|
try:
|
||||||
|
Port(parseInt(p))
|
||||||
|
except:
|
||||||
|
raise newException(ConfigurationError, "Invalid Port number")
|
||||||
|
|
||||||
|
proc completeCmdArg*(T: type Port, val: string): seq[string] =
|
||||||
|
return @[]
|
||||||
|
|
||||||
|
|
||||||
## Configuration validation
|
## Configuration validation
|
||||||
@ -516,6 +522,7 @@ proc readValue*(r: var TomlReader, value: var crypto.PrivateKey) {.raises: [Seri
|
|||||||
except CatchableError:
|
except CatchableError:
|
||||||
raise newException(SerializationError, getCurrentExceptionMsg())
|
raise newException(SerializationError, getCurrentExceptionMsg())
|
||||||
|
|
||||||
|
|
||||||
proc readValue*(r: var EnvvarReader, value: var crypto.PrivateKey) {.raises: [SerializationError].} =
|
proc readValue*(r: var EnvvarReader, value: var crypto.PrivateKey) {.raises: [SerializationError].} =
|
||||||
try:
|
try:
|
||||||
value = parseCmdArg(crypto.PrivateKey, r.readValue(string))
|
value = parseCmdArg(crypto.PrivateKey, r.readValue(string))
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
-d:chronicles_line_numbers
|
-d:chronicles_line_numbers
|
||||||
-d:chronicles_runtime_filtering:on
|
-d:discv5_protocol_id="d5waku"
|
||||||
-d:discv5_protocol_id:d5waku
|
-d:chronicles_runtime_filtering=on
|
||||||
|
-d:chronicles_sinks="textlines,json"
|
||||||
|
-d:chronicles_default_output_device=dynamic
|
||||||
|
# Disabling the following topics from nim-eth and nim-dnsdisc since some types cannot be serialized
|
||||||
|
-d:chronicles_disabled_topics="eth,dnsdisc.client"
|
||||||
# Results in empty output for some reason
|
# Results in empty output for some reason
|
||||||
#-d:"chronicles_enabled_topics=GossipSub:TRACE,WakuRelay:TRACE"
|
#-d:"chronicles_enabled_topics=GossipSub:TRACE,WakuRelay:TRACE"
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import
|
|||||||
import
|
import
|
||||||
../../waku/common/sqlite,
|
../../waku/common/sqlite,
|
||||||
../../waku/common/utils/nat,
|
../../waku/common/utils/nat,
|
||||||
|
../../waku/common/logging,
|
||||||
../../waku/v2/node/peer_manager/peer_manager,
|
../../waku/v2/node/peer_manager/peer_manager,
|
||||||
../../waku/v2/node/peer_manager/peer_store/waku_peer_storage,
|
../../waku/v2/node/peer_manager/peer_store/waku_peer_storage,
|
||||||
../../waku/v2/node/peer_manager/peer_store/migrations as peer_store_sqlite_migrations,
|
../../waku/v2/node/peer_manager/peer_store/migrations as peer_store_sqlite_migrations,
|
||||||
@ -560,9 +561,14 @@ when isMainModule:
|
|||||||
|
|
||||||
let conf = confRes.get()
|
let conf = confRes.get()
|
||||||
|
|
||||||
# set log level
|
## Logging setup
|
||||||
if conf.logLevel != LogLevel.NONE:
|
|
||||||
setLogLevel(conf.logLevel)
|
# Adhere to NO_COLOR initiative: https://no-color.org/
|
||||||
|
let color = try: not parseBool(os.getEnv("NO_COLOR", "false"))
|
||||||
|
except: true
|
||||||
|
|
||||||
|
logging.setupLogLevel(conf.logLevel)
|
||||||
|
logging.setupLogFormat(conf.logFormat, color)
|
||||||
|
|
||||||
|
|
||||||
##############
|
##############
|
||||||
|
|||||||
@ -1,48 +0,0 @@
|
|||||||
## Here's a basic example of how you would start a Waku node, subscribe to
|
|
||||||
## topics, and publish to them.
|
|
||||||
|
|
||||||
import
|
|
||||||
std/[os,options],
|
|
||||||
confutils, chronicles, chronos,
|
|
||||||
stew/shims/net as stewNet,
|
|
||||||
stew/byteutils,
|
|
||||||
libp2p/crypto/[crypto,secp],
|
|
||||||
eth/keys,
|
|
||||||
json_rpc/[rpcclient, rpcserver],
|
|
||||||
../../waku/v2/node/waku_node,
|
|
||||||
../../apps/wakunode2/config,
|
|
||||||
../../waku/common/utils/nat,
|
|
||||||
../../waku/v2/protocol/waku_message
|
|
||||||
|
|
||||||
# Node operations happens asynchronously
|
|
||||||
proc runBackground() {.async.} =
|
|
||||||
let
|
|
||||||
conf = WakuNodeConf.load().tryGet()
|
|
||||||
(extIp, extTcpPort, extUdpPort) = setupNat(conf.nat, clientId,
|
|
||||||
Port(uint16(conf.tcpPort) + conf.portsShift),
|
|
||||||
# This is actually a UDP port but we're only supplying this value
|
|
||||||
# To satisfy the API.
|
|
||||||
Port(uint16(conf.tcpPort) + conf.portsShift))
|
|
||||||
node = WakuNode.new(conf.nodeKey, conf.listenAddress,
|
|
||||||
Port(uint16(conf.tcpPort) + conf.portsShift), extIp, extTcpPort)
|
|
||||||
|
|
||||||
await node.start()
|
|
||||||
await node.mountRelay()
|
|
||||||
|
|
||||||
# Subscribe to a topic
|
|
||||||
let topic = PubsubTopic("foobar")
|
|
||||||
proc handler(topic: PubsubTopic, data: seq[byte]) {.async, gcsafe.} =
|
|
||||||
let message = WakuMessage.decode(data).value
|
|
||||||
let payload = cast[string](message.payload)
|
|
||||||
info "Hit subscribe handler", topic=topic, payload=payload, contentTopic=message.contentTopic
|
|
||||||
node.subscribe(topic, handler)
|
|
||||||
|
|
||||||
# Publish to a topic
|
|
||||||
let payload = toBytes("hello world")
|
|
||||||
let message = WakuMessage(payload: payload, contentTopic: ContentTopic("/waku/2/default-content/proto"))
|
|
||||||
await node.publish(topic, message)
|
|
||||||
|
|
||||||
# TODO Await with try/except here
|
|
||||||
discard runBackground()
|
|
||||||
|
|
||||||
runForever()
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
relay=true
|
|
||||||
store=true
|
|
||||||
filter=true
|
|
||||||
db-path="./dbs/db1"
|
|
||||||
rpc-admin=true
|
|
||||||
persist-peers=true
|
|
||||||
keep-alive=true
|
|
||||||
persist-messages=true
|
|
||||||
lightpush=true
|
|
||||||
nodekey="f157b19b13e9ee818acfc9d3d7eec6b81f70c0a978dec19def261172acbe26e6"
|
|
||||||
ports-shift=1
|
|
||||||
@ -1,3 +1,4 @@
|
|||||||
-d:chronicles_line_numbers
|
-d:chronicles_line_numbers
|
||||||
-d:chronicles_runtime_filtering:on
|
-d:chronicles_log_level="DEBUG"
|
||||||
-d:discv5_protocol_id:d5waku
|
-d:chronicles_runtime_filtering=on
|
||||||
|
-d:discv5_protocol_id="d5waku"
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import
|
|||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
stew/shims/net,
|
stew/shims/net,
|
||||||
chronicles,
|
chronicles,
|
||||||
chronicles/topics_registry,
|
|
||||||
chronos,
|
chronos,
|
||||||
confutils,
|
confutils,
|
||||||
libp2p/crypto/crypto,
|
libp2p/crypto/crypto,
|
||||||
@ -11,6 +10,7 @@ import
|
|||||||
eth/p2p/discoveryv5/enr
|
eth/p2p/discoveryv5/enr
|
||||||
|
|
||||||
import
|
import
|
||||||
|
../../../waku/common/logging,
|
||||||
../../../waku/v2/node/discv5/waku_discv5,
|
../../../waku/v2/node/discv5/waku_discv5,
|
||||||
../../../waku/v2/node/peer_manager/peer_manager,
|
../../../waku/v2/node/peer_manager/peer_manager,
|
||||||
../../../waku/v2/node/waku_node,
|
../../../waku/v2/node/waku_node,
|
||||||
@ -30,7 +30,7 @@ const discv5Port = 9000
|
|||||||
|
|
||||||
proc setupAndPublish() {.async.} =
|
proc setupAndPublish() {.async.} =
|
||||||
# use notice to filter all waku messaging
|
# use notice to filter all waku messaging
|
||||||
setLogLevel(LogLevel.NOTICE)
|
setupLogLevel(logging.LogLevel.NOTICE)
|
||||||
notice "starting publisher", wakuPort=wakuPort, discv5Port=discv5Port
|
notice "starting publisher", wakuPort=wakuPort, discv5Port=discv5Port
|
||||||
let
|
let
|
||||||
nodeKey = crypto.PrivateKey.random(Secp256k1, crypto.newRng()[])[]
|
nodeKey = crypto.PrivateKey.random(Secp256k1, crypto.newRng()[])[]
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import
|
|||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
stew/shims/net,
|
stew/shims/net,
|
||||||
chronicles,
|
chronicles,
|
||||||
chronicles/topics_registry,
|
|
||||||
chronos,
|
chronos,
|
||||||
confutils,
|
confutils,
|
||||||
libp2p/crypto/crypto,
|
libp2p/crypto/crypto,
|
||||||
@ -11,6 +10,7 @@ import
|
|||||||
eth/p2p/discoveryv5/enr
|
eth/p2p/discoveryv5/enr
|
||||||
|
|
||||||
import
|
import
|
||||||
|
../../../waku/common/logging,
|
||||||
../../../waku/v2/node/discv5/waku_discv5,
|
../../../waku/v2/node/discv5/waku_discv5,
|
||||||
../../../waku/v2/node/peer_manager/peer_manager,
|
../../../waku/v2/node/peer_manager/peer_manager,
|
||||||
../../../waku/v2/node/waku_node,
|
../../../waku/v2/node/waku_node,
|
||||||
@ -26,7 +26,7 @@ const discv5Port = 8000
|
|||||||
|
|
||||||
proc setupAndSubscribe() {.async.} =
|
proc setupAndSubscribe() {.async.} =
|
||||||
# use notice to filter all waku messaging
|
# use notice to filter all waku messaging
|
||||||
setLogLevel(LogLevel.NOTICE)
|
setupLogLevel(logging.LogLevel.NOTICE)
|
||||||
notice "starting subscriber", wakuPort=wakuPort, discv5Port=discv5Port
|
notice "starting subscriber", wakuPort=wakuPort, discv5Port=discv5Port
|
||||||
let
|
let
|
||||||
nodeKey = crypto.PrivateKey.random(Secp256k1, crypto.newRng()[])[]
|
nodeKey = crypto.PrivateKey.random(Secp256k1, crypto.newRng()[])[]
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
-d:chronicles_line_numbers
|
-d:chronicles_line_numbers
|
||||||
-d:discv5_protocol_id:d5waku
|
-d:discv5_protocol_id=d5waku
|
||||||
|
|||||||
2
vendor/nim-eth
vendored
2
vendor/nim-eth
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 833818e9c7f068388c1aebf29122a5cc59e53e3f
|
Subproject commit 5c46220e721069f8b8ac43a7ec006a599a8d33f0
|
||||||
@ -81,9 +81,8 @@ task sim2, "Build Waku v2 simulation tools":
|
|||||||
buildBinary "start_network2", "tools/simulation/", "-d:chronicles_log_level=TRACE"
|
buildBinary "start_network2", "tools/simulation/", "-d:chronicles_log_level=TRACE"
|
||||||
|
|
||||||
task example2, "Build Waku v2 example":
|
task example2, "Build Waku v2 example":
|
||||||
buildBinary "basic2", "examples/v2/", "-d:chronicles_log_level=DEBUG"
|
buildBinary "publisher", "examples/v2/"
|
||||||
buildBinary "publisher", "examples/v2/", "-d:chronicles_log_level=DEBUG"
|
buildBinary "subscriber", "examples/v2/"
|
||||||
buildBinary "subscriber", "examples/v2/", "-d:chronicles_log_level=DEBUG"
|
|
||||||
|
|
||||||
task scripts2, "Build Waku v2 scripts":
|
task scripts2, "Build Waku v2 scripts":
|
||||||
buildBinary "rpc_publish", "tools/scripts/", "-d:chronicles_log_level=DEBUG"
|
buildBinary "rpc_publish", "tools/scripts/", "-d:chronicles_log_level=DEBUG"
|
||||||
|
|||||||
108
waku/common/logging.nim
Normal file
108
waku/common/logging.nim
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
## This code has been copied and addapted from `status-im/nimbu-eth2` project.
|
||||||
|
## Link: https://github.com/status-im/nimbus-eth2/blob/c585b0a5b1ae4d55af38ad7f4715ad455e791552/beacon_chain/nimbus_binary_common.nim
|
||||||
|
import
|
||||||
|
std/[strutils, typetraits],
|
||||||
|
chronicles,
|
||||||
|
chronicles/log_output,
|
||||||
|
chronicles/topics_registry
|
||||||
|
|
||||||
|
|
||||||
|
when (NimMajor, NimMinor) < (1, 4):
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
else:
|
||||||
|
{.push raises: [].}
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
LogLevel* = enum
|
||||||
|
TRACE, DEBUG, INFO, NOTICE, WARN, ERROR, FATAL
|
||||||
|
|
||||||
|
LogFormat* = enum
|
||||||
|
TEXT, JSON
|
||||||
|
|
||||||
|
converter toChroniclesLogLevel(level: LogLevel): chronicles.LogLevel =
|
||||||
|
## Map logging log levels to the corresponding nim-chronicles' log level
|
||||||
|
try:
|
||||||
|
parseEnum[chronicles.LogLevel]($level)
|
||||||
|
except:
|
||||||
|
chronicles.LogLevel.NONE
|
||||||
|
|
||||||
|
|
||||||
|
## Utils
|
||||||
|
|
||||||
|
proc stripAnsi(v: string): string =
|
||||||
|
## Copied from: https://github.com/status-im/nimbus-eth2/blob/stable/beacon_chain/nimbus_binary_common.nim#L41
|
||||||
|
## Silly chronicles, colors is a compile-time property
|
||||||
|
var
|
||||||
|
res = newStringOfCap(v.len)
|
||||||
|
i: int
|
||||||
|
|
||||||
|
while i < v.len:
|
||||||
|
let c = v[i]
|
||||||
|
if c == '\x1b':
|
||||||
|
var
|
||||||
|
x = i + 1
|
||||||
|
found = false
|
||||||
|
|
||||||
|
while x < v.len: # look for [..m
|
||||||
|
let c2 = v[x]
|
||||||
|
if x == i + 1:
|
||||||
|
if c2 != '[':
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if c2 in {'0'..'9'} + {';'}:
|
||||||
|
discard # keep looking
|
||||||
|
elif c2 == 'm':
|
||||||
|
i = x + 1
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
inc x
|
||||||
|
|
||||||
|
if found: # skip adding c
|
||||||
|
continue
|
||||||
|
res.add c
|
||||||
|
inc i
|
||||||
|
|
||||||
|
res
|
||||||
|
|
||||||
|
proc writeAndFlush(f: File, s: LogOutputStr) =
|
||||||
|
try:
|
||||||
|
f.write(s)
|
||||||
|
f.flushFile()
|
||||||
|
except:
|
||||||
|
logLoggingFailure(cstring(s), getCurrentException())
|
||||||
|
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
proc setupLogLevel*(level: LogLevel) =
|
||||||
|
# TODO: Support per topic level configuratio
|
||||||
|
topics_registry.setLogLevel(level)
|
||||||
|
|
||||||
|
proc setupLogFormat*(format: LogFormat, color=true) =
|
||||||
|
proc noOutputWriter(logLevel: chronicles.LogLevel, msg: LogOutputStr) = discard
|
||||||
|
|
||||||
|
proc stdoutOutputWriter(logLevel: chronicles.LogLevel, msg: LogOutputStr) =
|
||||||
|
writeAndFlush(io.stdout, msg)
|
||||||
|
|
||||||
|
proc stdoutNoColorOutputWriter(logLevel: chronicles.LogLevel, msg: LogOutputStr) =
|
||||||
|
writeAndFlush(io.stdout, stripAnsi(msg))
|
||||||
|
|
||||||
|
|
||||||
|
when defaultChroniclesStream.outputs.type.arity == 2:
|
||||||
|
case format:
|
||||||
|
of LogFormat.Text:
|
||||||
|
defaultChroniclesStream.outputs[0].writer = if color: stdoutOutputWriter
|
||||||
|
else: stdoutNoColorOutputWriter
|
||||||
|
defaultChroniclesStream.outputs[1].writer = noOutputWriter
|
||||||
|
|
||||||
|
of LogFormat.Json:
|
||||||
|
defaultChroniclesStream.outputs[0].writer = noOutputWriter
|
||||||
|
defaultChroniclesStream.outputs[1].writer = stdoutOutputWriter
|
||||||
|
|
||||||
|
else:
|
||||||
|
{.warning:
|
||||||
|
"the present module should be compiled with '-d:chronicles_default_output_device=dynamic' " &
|
||||||
|
"and '-d:chronicles_sinks=\"textlines,json\"' options" .}
|
||||||
@ -63,7 +63,7 @@ proc addBootstrapNode*(bootstrapAddr: string,
|
|||||||
|
|
||||||
proc isWakuNode(node: Node): bool =
|
proc isWakuNode(node: Node): bool =
|
||||||
let wakuField = node.record.tryGet(WAKU_ENR_FIELD, uint8)
|
let wakuField = node.record.tryGet(WAKU_ENR_FIELD, uint8)
|
||||||
|
|
||||||
if wakuField.isSome:
|
if wakuField.isSome:
|
||||||
return wakuField.get().WakuEnrBitfield != 0x00 # True if any flag set to true
|
return wakuField.get().WakuEnrBitfield != 0x00 # True if any flag set to true
|
||||||
|
|
||||||
@ -75,10 +75,10 @@ proc isWakuNode(node: Node): bool =
|
|||||||
|
|
||||||
proc findRandomPeers*(wakuDiscv5: WakuDiscoveryV5): Future[Result[seq[RemotePeerInfo], cstring]] {.async.} =
|
proc findRandomPeers*(wakuDiscv5: WakuDiscoveryV5): Future[Result[seq[RemotePeerInfo], cstring]] {.async.} =
|
||||||
## Find random peers to connect to using Discovery v5
|
## Find random peers to connect to using Discovery v5
|
||||||
|
|
||||||
## Query for a random target and collect all discovered nodes
|
## Query for a random target and collect all discovered nodes
|
||||||
let discoveredNodes = await wakuDiscv5.protocol.queryRandom()
|
let discoveredNodes = await wakuDiscv5.protocol.queryRandom()
|
||||||
|
|
||||||
## Filter based on our needs
|
## Filter based on our needs
|
||||||
# let filteredNodes = discoveredNodes.filter(isWakuNode) # Currently only a single predicate
|
# let filteredNodes = discoveredNodes.filter(isWakuNode) # Currently only a single predicate
|
||||||
# TODO: consider node filtering based on ENR; we do not filter based on ENR in the first waku discv5 beta stage
|
# TODO: consider node filtering based on ENR; we do not filter based on ENR in the first waku discv5 beta stage
|
||||||
@ -92,7 +92,7 @@ proc findRandomPeers*(wakuDiscv5: WakuDiscoveryV5): Future[Result[seq[RemotePeer
|
|||||||
if res.isOk():
|
if res.isOk():
|
||||||
discoveredPeers.add(res.get())
|
discoveredPeers.add(res.get())
|
||||||
else:
|
else:
|
||||||
error "Failed to convert ENR to peer info", enr=node.record, err=res.error()
|
error "Failed to convert ENR to peer info", enr= $node.record, err=res.error()
|
||||||
waku_discv5_errors.inc(labelValues = ["peer_info_failure"])
|
waku_discv5_errors.inc(labelValues = ["peer_info_failure"])
|
||||||
|
|
||||||
if discoveredPeers.len > 0:
|
if discoveredPeers.len > 0:
|
||||||
@ -114,11 +114,11 @@ proc new*(T: type WakuDiscoveryV5,
|
|||||||
rng: ref HmacDrbgContext,
|
rng: ref HmacDrbgContext,
|
||||||
discv5Config: protocol.DiscoveryConfig = protocol.defaultDiscoveryConfig): T =
|
discv5Config: protocol.DiscoveryConfig = protocol.defaultDiscoveryConfig): T =
|
||||||
## TODO: consider loading from a configurable bootstrap file
|
## TODO: consider loading from a configurable bootstrap file
|
||||||
|
|
||||||
## We always add the waku field as specified
|
## We always add the waku field as specified
|
||||||
var enrInitFields = @[(WAKU_ENR_FIELD, @[flags.byte])]
|
var enrInitFields = @[(WAKU_ENR_FIELD, @[flags.byte])]
|
||||||
enrInitFields.add(enrFields)
|
enrInitFields.add(enrFields)
|
||||||
|
|
||||||
let protocol = newProtocol(
|
let protocol = newProtocol(
|
||||||
privateKey,
|
privateKey,
|
||||||
enrIp = extIp, enrTcpPort = extTcpPort, enrUdpPort = extUdpPort, # We use the external IP & ports for ENR
|
enrIp = extIp, enrTcpPort = extTcpPort, enrUdpPort = extUdpPort, # We use the external IP & ports for ENR
|
||||||
@ -129,7 +129,7 @@ proc new*(T: type WakuDiscoveryV5,
|
|||||||
enrAutoUpdate = enrAutoUpdate,
|
enrAutoUpdate = enrAutoUpdate,
|
||||||
config = discv5Config,
|
config = discv5Config,
|
||||||
rng = rng)
|
rng = rng)
|
||||||
|
|
||||||
return WakuDiscoveryV5(protocol: protocol, listening: false)
|
return WakuDiscoveryV5(protocol: protocol, listening: false)
|
||||||
|
|
||||||
# constructor that takes bootstrap Enrs in Enr Uri form
|
# constructor that takes bootstrap Enrs in Enr Uri form
|
||||||
@ -145,11 +145,11 @@ proc new*(T: type WakuDiscoveryV5,
|
|||||||
enrFields: openArray[(string, seq[byte])],
|
enrFields: openArray[(string, seq[byte])],
|
||||||
rng: ref HmacDrbgContext,
|
rng: ref HmacDrbgContext,
|
||||||
discv5Config: protocol.DiscoveryConfig = protocol.defaultDiscoveryConfig): T =
|
discv5Config: protocol.DiscoveryConfig = protocol.defaultDiscoveryConfig): T =
|
||||||
|
|
||||||
var bootstrapEnrs: seq[enr.Record]
|
var bootstrapEnrs: seq[enr.Record]
|
||||||
for node in bootstrapNodes:
|
for node in bootstrapNodes:
|
||||||
addBootstrapNode(node, bootstrapEnrs)
|
addBootstrapNode(node, bootstrapEnrs)
|
||||||
|
|
||||||
return WakuDiscoveryV5.new(
|
return WakuDiscoveryV5.new(
|
||||||
extIP, extTcpPort, extUdpPort,
|
extIP, extTcpPort, extUdpPort,
|
||||||
bindIP,
|
bindIP,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ else:
|
|||||||
|
|
||||||
## A set of utilities to integrate EIP-1459 DNS-based discovery
|
## A set of utilities to integrate EIP-1459 DNS-based discovery
|
||||||
## for Waku v2 nodes.
|
## for Waku v2 nodes.
|
||||||
##
|
##
|
||||||
## EIP-1459 is defined in https://eips.ethereum.org/EIPS/eip-1459
|
## EIP-1459 is defined in https://eips.ethereum.org/EIPS/eip-1459
|
||||||
|
|
||||||
import
|
import
|
||||||
@ -46,9 +46,9 @@ proc emptyResolver*(domain: string): Future[string] {.async, gcsafe.} =
|
|||||||
|
|
||||||
proc findPeers*(wdd: var WakuDnsDiscovery): Result[seq[RemotePeerInfo], cstring] =
|
proc findPeers*(wdd: var WakuDnsDiscovery): Result[seq[RemotePeerInfo], cstring] =
|
||||||
## Find peers to connect to using DNS based discovery
|
## Find peers to connect to using DNS based discovery
|
||||||
|
|
||||||
info "Finding peers using Waku DNS discovery"
|
info "Finding peers using Waku DNS discovery"
|
||||||
|
|
||||||
# Synchronise client tree using configured resolver
|
# Synchronise client tree using configured resolver
|
||||||
var tree: Tree
|
var tree: Tree
|
||||||
try:
|
try:
|
||||||
@ -74,7 +74,7 @@ proc findPeers*(wdd: var WakuDnsDiscovery): Result[seq[RemotePeerInfo], cstring]
|
|||||||
if res.isOk():
|
if res.isOk():
|
||||||
discoveredNodes.add(res.get())
|
discoveredNodes.add(res.get())
|
||||||
else:
|
else:
|
||||||
error "Failed to convert ENR to peer info", enr=enr, err=res.error()
|
error "Failed to convert ENR to peer info", enr= $enr, err=res.error()
|
||||||
waku_dnsdisc_errors.inc(labelValues = ["peer_info_failure"])
|
waku_dnsdisc_errors.inc(labelValues = ["peer_info_failure"])
|
||||||
|
|
||||||
if discoveredNodes.len > 0:
|
if discoveredNodes.len > 0:
|
||||||
@ -87,9 +87,9 @@ proc init*(T: type WakuDnsDiscovery,
|
|||||||
locationUrl: string,
|
locationUrl: string,
|
||||||
resolver: Resolver): Result[T, cstring] =
|
resolver: Resolver): Result[T, cstring] =
|
||||||
## Initialise Waku peer discovery via DNS
|
## Initialise Waku peer discovery via DNS
|
||||||
|
|
||||||
debug "init WakuDnsDiscovery", locationUrl=locationUrl
|
debug "init WakuDnsDiscovery", locationUrl=locationUrl
|
||||||
|
|
||||||
let
|
let
|
||||||
client = ? Client.init(locationUrl)
|
client = ? Client.init(locationUrl)
|
||||||
wakuDnsDisc = WakuDnsDiscovery(client: client, resolver: resolver)
|
wakuDnsDisc = WakuDnsDiscovery(client: client, resolver: resolver)
|
||||||
|
|||||||
@ -87,7 +87,7 @@ proc loadFromStorage(pm: PeerManager) =
|
|||||||
debug "loading peers from storage"
|
debug "loading peers from storage"
|
||||||
# Load peers from storage, if available
|
# Load peers from storage, if available
|
||||||
proc onData(peerId: PeerID, storedInfo: StoredInfo, connectedness: Connectedness, disconnectTime: int64) =
|
proc onData(peerId: PeerID, storedInfo: StoredInfo, connectedness: Connectedness, disconnectTime: int64) =
|
||||||
trace "loading peer", peerId=peerId, storedInfo=storedInfo, connectedness=connectedness
|
trace "loading peer", peerId= $peerId, storedInfo= $storedInfo, connectedness=connectedness
|
||||||
|
|
||||||
if peerId == pm.switch.peerInfo.peerId:
|
if peerId == pm.switch.peerInfo.peerId:
|
||||||
# Do not manage self
|
# Do not manage self
|
||||||
@ -217,7 +217,7 @@ proc reconnectPeers*(pm: PeerManager,
|
|||||||
# We disconnected recently and still need to wait for a backoff period before connecting
|
# We disconnected recently and still need to wait for a backoff period before connecting
|
||||||
await sleepAsync(backoffTime)
|
await sleepAsync(backoffTime)
|
||||||
|
|
||||||
trace "Reconnecting to peer", peerId=storedInfo.peerId
|
trace "Reconnecting to peer", peerId= $storedInfo.peerId
|
||||||
discard await pm.dialPeer(storedInfo.peerId, toSeq(storedInfo.addrs), proto)
|
discard await pm.dialPeer(storedInfo.peerId, toSeq(storedInfo.addrs), proto)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
@ -230,7 +230,7 @@ proc dialPeer*(pm: PeerManager, remotePeerInfo: RemotePeerInfo, proto: string, d
|
|||||||
|
|
||||||
# First add dialed peer info to peer store, if it does not exist yet...
|
# First add dialed peer info to peer store, if it does not exist yet...
|
||||||
if not pm.peerStore.hasPeer(remotePeerInfo.peerId, proto):
|
if not pm.peerStore.hasPeer(remotePeerInfo.peerId, proto):
|
||||||
trace "Adding newly dialed peer to manager", peerId = remotePeerInfo.peerId, addr = remotePeerInfo.addrs[0], proto = proto
|
trace "Adding newly dialed peer to manager", peerId= $remotePeerInfo.peerId, address= $remotePeerInfo.addrs[0], proto= proto
|
||||||
pm.addPeer(remotePeerInfo, proto)
|
pm.addPeer(remotePeerInfo, proto)
|
||||||
|
|
||||||
if remotePeerInfo.peerId == pm.switch.peerInfo.peerId:
|
if remotePeerInfo.peerId == pm.switch.peerInfo.peerId:
|
||||||
@ -262,7 +262,7 @@ proc connectToNode(pm: PeerManager, remotePeer: RemotePeerInfo, proto: string, s
|
|||||||
info "Successfully connected to peer", wireAddr = remotePeer.addrs[0], peerId = remotePeer.peerId
|
info "Successfully connected to peer", wireAddr = remotePeer.addrs[0], peerId = remotePeer.peerId
|
||||||
waku_node_conns_initiated.inc(labelValues = [source])
|
waku_node_conns_initiated.inc(labelValues = [source])
|
||||||
else:
|
else:
|
||||||
error "Failed to connect to peer", wireAddr = remotePeer.addrs[0], peerId = remotePeer.peerId
|
error "Failed to connect to peer", wireAddr= $remotePeer.addrs[0], peerId= $remotePeer.peerId
|
||||||
waku_peers_errors.inc(labelValues = ["conn_init_failure"])
|
waku_peers_errors.inc(labelValues = ["conn_init_failure"])
|
||||||
|
|
||||||
proc connectToNodes*(pm: PeerManager, nodes: seq[string], proto: string, source = "api") {.async.} =
|
proc connectToNodes*(pm: PeerManager, nodes: seq[string], proto: string, source = "api") {.async.} =
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import
|
|||||||
metrics/chronos_httpserver
|
metrics/chronos_httpserver
|
||||||
import
|
import
|
||||||
../protocol/waku_filter/protocol_metrics as filter_metrics,
|
../protocol/waku_filter/protocol_metrics as filter_metrics,
|
||||||
../protocol/waku_swap/waku_swap,
|
|
||||||
../utils/collector,
|
../utils/collector,
|
||||||
./peer_manager/peer_manager,
|
./peer_manager/peer_manager,
|
||||||
./waku_node
|
./waku_node
|
||||||
@ -27,14 +26,14 @@ logScope:
|
|||||||
|
|
||||||
|
|
||||||
proc startMetricsServer*(serverIp: ValidIpAddress, serverPort: Port) =
|
proc startMetricsServer*(serverIp: ValidIpAddress, serverPort: Port) =
|
||||||
info "Starting metrics HTTP server", serverIp, serverPort
|
info "Starting metrics HTTP server", serverIp= $serverIp, serverPort= $serverPort
|
||||||
|
|
||||||
try:
|
try:
|
||||||
startMetricsHttpServer($serverIp, serverPort)
|
startMetricsHttpServer($serverIp, serverPort)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raiseAssert("Exception while starting metrics HTTP server: " & e.msg)
|
raiseAssert("Exception while starting metrics HTTP server: " & e.msg)
|
||||||
|
|
||||||
info "Metrics HTTP server started", serverIp, serverPort
|
info "Metrics HTTP server started", serverIp= $serverIp, serverPort= $serverPort
|
||||||
|
|
||||||
type
|
type
|
||||||
# https://github.com/nim-lang/Nim/issues/17369
|
# https://github.com/nim-lang/Nim/issues/17369
|
||||||
@ -58,20 +57,26 @@ proc startMetricsLog*() =
|
|||||||
let freshErrorCount = parseAndAccumulate(waku_node_errors, cumulativeErrors)
|
let freshErrorCount = parseAndAccumulate(waku_node_errors, cumulativeErrors)
|
||||||
let freshConnCount = parseAndAccumulate(waku_node_conns_initiated, cumulativeConns)
|
let freshConnCount = parseAndAccumulate(waku_node_conns_initiated, cumulativeConns)
|
||||||
|
|
||||||
info "Total connections initiated", count = freshConnCount
|
let totalMessages = collectorAsF64(waku_node_messages)
|
||||||
info "Total messages", count = collectorAsF64(waku_node_messages)
|
let storePeers = collectorAsF64(waku_store_peers)
|
||||||
info "Total swap peers", count = collectorAsF64(waku_swap_peers_count)
|
let pxPeers = collectorAsF64(waku_px_peers)
|
||||||
info "Total filter peers", count = collectorAsF64(waku_filter_peers)
|
let lightpushPeers = collectorAsF64(waku_lightpush_peers)
|
||||||
info "Total store peers", count = collectorAsF64(waku_store_peers)
|
let filterPeers = collectorAsF64(waku_filter_peers)
|
||||||
info "Total lightpush peers", count = collectorAsF64(waku_lightpush_peers)
|
let filterSubscribers = collectorAsF64(waku_filter_subscribers)
|
||||||
info "Total peer exchange peers", count = collectorAsF64(waku_px_peers)
|
|
||||||
info "Total errors", count = freshErrorCount
|
info "Total connections initiated", count = $freshConnCount
|
||||||
info "Total active filter subscriptions", count = collectorAsF64(waku_filter_subscribers)
|
info "Total messages", count = totalMessages
|
||||||
|
info "Total store peers", count = storePeers
|
||||||
|
info "Total peer exchange peers", count = pxPeers
|
||||||
|
info "Total lightpush peers", count = lightpushPeers
|
||||||
|
info "Total filter peers", count = filterPeers
|
||||||
|
info "Total active filter subscriptions", count = filterSubscribers
|
||||||
|
info "Total errors", count = $freshErrorCount
|
||||||
|
|
||||||
# Start protocol specific metrics logging
|
# Start protocol specific metrics logging
|
||||||
when defined(rln):
|
when defined(rln):
|
||||||
logRlnMetrics()
|
logRlnMetrics()
|
||||||
|
|
||||||
discard setTimer(Moment.fromNow(LogInterval), logMetrics)
|
discard setTimer(Moment.fromNow(LogInterval), logMetrics)
|
||||||
|
|
||||||
discard setTimer(Moment.fromNow(LogInterval), logMetrics)
|
discard setTimer(Moment.fromNow(LogInterval), logMetrics)
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import
|
|||||||
stew/results,
|
stew/results,
|
||||||
stew/[byteutils, arrayops, endians2]
|
stew/[byteutils, arrayops, endians2]
|
||||||
import
|
import
|
||||||
./rln,
|
./rln,
|
||||||
./constants,
|
./constants,
|
||||||
./protocol_types,
|
./protocol_types,
|
||||||
./protocol_metrics
|
./protocol_metrics
|
||||||
@ -40,11 +40,11 @@ type WakuRlnConfig* = object
|
|||||||
rlnRelayEthAccountAddress*: string
|
rlnRelayEthAccountAddress*: string
|
||||||
rlnRelayCredPath*: string
|
rlnRelayCredPath*: string
|
||||||
rlnRelayCredentialsPassword*: string
|
rlnRelayCredentialsPassword*: string
|
||||||
|
|
||||||
type
|
type
|
||||||
SpamHandler* = proc(wakuMessage: WakuMessage): void {.gcsafe, closure, raises: [Defect].}
|
SpamHandler* = proc(wakuMessage: WakuMessage): void {.gcsafe, closure, raises: [Defect].}
|
||||||
RegistrationHandler* = proc(txHash: string): void {.gcsafe, closure, raises: [Defect].}
|
RegistrationHandler* = proc(txHash: string): void {.gcsafe, closure, raises: [Defect].}
|
||||||
GroupUpdateHandler* = proc(blockNumber: BlockNumber,
|
GroupUpdateHandler* = proc(blockNumber: BlockNumber,
|
||||||
members: seq[MembershipTuple]): RlnRelayResult[void] {.gcsafe.}
|
members: seq[MembershipTuple]): RlnRelayResult[void] {.gcsafe.}
|
||||||
MembershipTuple* = tuple[index: MembershipIndex, idComm: IDCommitment]
|
MembershipTuple* = tuple[index: MembershipIndex, idComm: IDCommitment]
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ proc toIDCommitment*(idCommitmentUint: UInt256): IDCommitment =
|
|||||||
let pk = IDCommitment(idCommitmentUint.toBytesLE())
|
let pk = IDCommitment(idCommitmentUint.toBytesLE())
|
||||||
return pk
|
return pk
|
||||||
|
|
||||||
proc inHex*(value: IDKey or IDCommitment or MerkleNode or Nullifier or Epoch or RlnIdentifier): string =
|
proc inHex*(value: IDKey or IDCommitment or MerkleNode or Nullifier or Epoch or RlnIdentifier): string =
|
||||||
var valueHex = (UInt256.fromBytesLE(value)).toHex
|
var valueHex = (UInt256.fromBytesLE(value)).toHex
|
||||||
# We pad leading zeroes
|
# We pad leading zeroes
|
||||||
while valueHex.len < value.len * 2:
|
while valueHex.len < value.len * 2:
|
||||||
@ -144,7 +144,7 @@ proc toMembershipIndex(v: UInt256): MembershipIndex =
|
|||||||
proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAccountPrivKey: keys.PrivateKey, ethClientAddress: string, membershipContractAddress: Address, registrationHandler: Option[RegistrationHandler] = none(RegistrationHandler)): Future[Result[MembershipIndex, string]] {.async.} =
|
proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAccountPrivKey: keys.PrivateKey, ethClientAddress: string, membershipContractAddress: Address, registrationHandler: Option[RegistrationHandler] = none(RegistrationHandler)): Future[Result[MembershipIndex, string]] {.async.} =
|
||||||
# TODO may need to also get eth Account Private Key as PrivateKey
|
# TODO may need to also get eth Account Private Key as PrivateKey
|
||||||
## registers the idComm into the membership contract whose address is in rlnPeer.membershipContractAddress
|
## registers the idComm into the membership contract whose address is in rlnPeer.membershipContractAddress
|
||||||
|
|
||||||
var web3: Web3
|
var web3: Web3
|
||||||
try: # check if the Ethereum client is reachable
|
try: # check if the Ethereum client is reachable
|
||||||
web3 = await newWeb3(ethClientAddress)
|
web3 = await newWeb3(ethClientAddress)
|
||||||
@ -157,7 +157,7 @@ proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAcco
|
|||||||
web3.privateKey = some(ethAccountPrivKey)
|
web3.privateKey = some(ethAccountPrivKey)
|
||||||
# set the gas price twice the suggested price in order for the fast mining
|
# set the gas price twice the suggested price in order for the fast mining
|
||||||
let gasPrice = int(await web3.provider.eth_gasPrice()) * 2
|
let gasPrice = int(await web3.provider.eth_gasPrice()) * 2
|
||||||
|
|
||||||
# when the private key is set in a web3 instance, the send proc (sender.register(pk).send(MembershipFee))
|
# when the private key is set in a web3 instance, the send proc (sender.register(pk).send(MembershipFee))
|
||||||
# does the signing using the provided key
|
# does the signing using the provided key
|
||||||
# web3.privateKey = some(ethAccountPrivateKey)
|
# web3.privateKey = some(ethAccountPrivateKey)
|
||||||
@ -173,7 +173,7 @@ proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAcco
|
|||||||
return err("registration transaction failed: " & e.msg)
|
return err("registration transaction failed: " & e.msg)
|
||||||
|
|
||||||
let tsReceipt = await web3.getMinedTransactionReceipt(txHash)
|
let tsReceipt = await web3.getMinedTransactionReceipt(txHash)
|
||||||
|
|
||||||
# the receipt topic holds the hash of signature of the raised events
|
# the receipt topic holds the hash of signature of the raised events
|
||||||
let firstTopic = tsReceipt.logs[0].topics[0]
|
let firstTopic = tsReceipt.logs[0].topics[0]
|
||||||
# the hash of the signature of MemberRegistered(uint256,uint256) event is equal to the following hex value
|
# the hash of the signature of MemberRegistered(uint256,uint256) event is equal to the following hex value
|
||||||
@ -184,7 +184,7 @@ proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAcco
|
|||||||
# data = pk encoded as 256 bits || index encoded as 256 bits
|
# data = pk encoded as 256 bits || index encoded as 256 bits
|
||||||
let arguments = tsReceipt.logs[0].data
|
let arguments = tsReceipt.logs[0].data
|
||||||
debug "tx log data", arguments=arguments
|
debug "tx log data", arguments=arguments
|
||||||
let
|
let
|
||||||
argumentsBytes = arguments.hexToSeqByte()
|
argumentsBytes = arguments.hexToSeqByte()
|
||||||
# In TX log data, uints are encoded in big endian
|
# In TX log data, uints are encoded in big endian
|
||||||
eventIdCommUint = UInt256.fromBytesBE(argumentsBytes[0..31])
|
eventIdCommUint = UInt256.fromBytesBE(argumentsBytes[0..31])
|
||||||
@ -261,7 +261,7 @@ proc proofGen*(rlnInstance: ptr RLN, data: openArray[byte],
|
|||||||
msg = data)
|
msg = data)
|
||||||
var inputBuffer = toBuffer(serializedInputs)
|
var inputBuffer = toBuffer(serializedInputs)
|
||||||
|
|
||||||
debug "input buffer ", inputBuffer
|
debug "input buffer ", inputBuffer= repr(inputBuffer)
|
||||||
|
|
||||||
# generate the proof
|
# generate the proof
|
||||||
var proof: Buffer
|
var proof: Buffer
|
||||||
@ -299,7 +299,7 @@ proc proofGen*(rlnInstance: ptr RLN, data: openArray[byte],
|
|||||||
discard shareY.copyFrom(proofBytes[shareXOffset..shareYOffset-1])
|
discard shareY.copyFrom(proofBytes[shareXOffset..shareYOffset-1])
|
||||||
discard nullifier.copyFrom(proofBytes[shareYOffset..nullifierOffset-1])
|
discard nullifier.copyFrom(proofBytes[shareYOffset..nullifierOffset-1])
|
||||||
discard rlnIdentifier.copyFrom(proofBytes[nullifierOffset..rlnIdentifierOffset-1])
|
discard rlnIdentifier.copyFrom(proofBytes[nullifierOffset..rlnIdentifierOffset-1])
|
||||||
|
|
||||||
let output = RateLimitProof(proof: zkproof,
|
let output = RateLimitProof(proof: zkproof,
|
||||||
merkleRoot: proofRoot,
|
merkleRoot: proofRoot,
|
||||||
epoch: epoch,
|
epoch: epoch,
|
||||||
@ -335,9 +335,9 @@ proc serialize(roots: seq[MerkleNode]): seq[byte] =
|
|||||||
|
|
||||||
# validRoots should contain a sequence of roots in the acceptable windows.
|
# validRoots should contain a sequence of roots in the acceptable windows.
|
||||||
# As default, it is set to an empty sequence of roots. This implies that the validity check for the proof's root is skipped
|
# As default, it is set to an empty sequence of roots. This implies that the validity check for the proof's root is skipped
|
||||||
proc proofVerify*(rlnInstance: ptr RLN,
|
proc proofVerify*(rlnInstance: ptr RLN,
|
||||||
data: openArray[byte],
|
data: openArray[byte],
|
||||||
proof: RateLimitProof,
|
proof: RateLimitProof,
|
||||||
validRoots: seq[MerkleNode] = @[]): RlnRelayResult[bool] =
|
validRoots: seq[MerkleNode] = @[]): RlnRelayResult[bool] =
|
||||||
## verifies the proof, returns an error if the proof verification fails
|
## verifies the proof, returns an error if the proof verification fails
|
||||||
## returns true if the proof is valid
|
## returns true if the proof is valid
|
||||||
@ -397,7 +397,7 @@ proc insertMembers*(rlnInstance: ptr RLN,
|
|||||||
|
|
||||||
# serialize the idComms
|
# serialize the idComms
|
||||||
let idCommsBytes = serializeIdCommitments(idComms)
|
let idCommsBytes = serializeIdCommitments(idComms)
|
||||||
|
|
||||||
var idCommsBuffer = idCommsBytes.toBuffer()
|
var idCommsBuffer = idCommsBytes.toBuffer()
|
||||||
let idCommsBufferPtr = addr idCommsBuffer
|
let idCommsBufferPtr = addr idCommsBuffer
|
||||||
# add the member to the tree
|
# add the member to the tree
|
||||||
@ -414,7 +414,7 @@ proc getMerkleRoot*(rlnInstance: ptr RLN): MerkleNodeResult =
|
|||||||
root {.noinit.}: Buffer = Buffer()
|
root {.noinit.}: Buffer = Buffer()
|
||||||
rootPtr = addr(root)
|
rootPtr = addr(root)
|
||||||
getRootSuccessful = getRoot(rlnInstance, rootPtr)
|
getRootSuccessful = getRoot(rlnInstance, rootPtr)
|
||||||
if not getRootSuccessful:
|
if not getRootSuccessful:
|
||||||
return err("could not get the root")
|
return err("could not get the root")
|
||||||
if not root.len == 32:
|
if not root.len == 32:
|
||||||
return err("wrong output size")
|
return err("wrong output size")
|
||||||
@ -423,17 +423,17 @@ proc getMerkleRoot*(rlnInstance: ptr RLN): MerkleNodeResult =
|
|||||||
return ok(rootValue)
|
return ok(rootValue)
|
||||||
|
|
||||||
proc updateValidRootQueue*(wakuRlnRelay: WakuRLNRelay, root: MerkleNode): void =
|
proc updateValidRootQueue*(wakuRlnRelay: WakuRLNRelay, root: MerkleNode): void =
|
||||||
## updates the valid Merkle root queue with the latest root and pops the oldest one when the capacity of `AcceptableRootWindowSize` is reached
|
## updates the valid Merkle root queue with the latest root and pops the oldest one when the capacity of `AcceptableRootWindowSize` is reached
|
||||||
let overflowCount = wakuRlnRelay.validMerkleRoots.len() - AcceptableRootWindowSize
|
let overflowCount = wakuRlnRelay.validMerkleRoots.len() - AcceptableRootWindowSize
|
||||||
if overflowCount >= 0:
|
if overflowCount >= 0:
|
||||||
# Delete the oldest `overflowCount` elements in the deque (index 0..`overflowCount`)
|
# Delete the oldest `overflowCount` elements in the deque (index 0..`overflowCount`)
|
||||||
for i in 0..overflowCount:
|
for i in 0..overflowCount:
|
||||||
wakuRlnRelay.validMerkleRoots.popFirst()
|
wakuRlnRelay.validMerkleRoots.popFirst()
|
||||||
# Push the next root into the queue
|
# Push the next root into the queue
|
||||||
wakuRlnRelay.validMerkleRoots.addLast(root)
|
wakuRlnRelay.validMerkleRoots.addLast(root)
|
||||||
|
|
||||||
proc insertMembers*(wakuRlnRelay: WakuRLNRelay,
|
proc insertMembers*(wakuRlnRelay: WakuRLNRelay,
|
||||||
index: MembershipIndex,
|
index: MembershipIndex,
|
||||||
idComms: seq[IDCommitment]): RlnRelayResult[void] =
|
idComms: seq[IDCommitment]): RlnRelayResult[void] =
|
||||||
## inserts a sequence of id commitments into the local merkle tree, and adds the changed root to the
|
## inserts a sequence of id commitments into the local merkle tree, and adds the changed root to the
|
||||||
## queue of valid roots
|
## queue of valid roots
|
||||||
@ -528,7 +528,7 @@ proc createMembershipList*(n: int): RlnRelayResult[(
|
|||||||
output.add(keyTuple)
|
output.add(keyTuple)
|
||||||
|
|
||||||
idCommitments.add(keypair.idCommitment)
|
idCommitments.add(keypair.idCommitment)
|
||||||
|
|
||||||
# Insert members into tree
|
# Insert members into tree
|
||||||
let membersAdded = rln.insertMembers(0, idCommitments)
|
let membersAdded = rln.insertMembers(0, idCommitments)
|
||||||
if not membersAdded:
|
if not membersAdded:
|
||||||
@ -591,8 +591,8 @@ proc hasDuplicate*(rlnPeer: WakuRLNRelay, msg: WakuMessage): RlnRelayResult[bool
|
|||||||
|
|
||||||
# extract the proof metadata of the supplied `msg`
|
# extract the proof metadata of the supplied `msg`
|
||||||
let proofMD = ProofMetadata(
|
let proofMD = ProofMetadata(
|
||||||
nullifier: proof.nullifier,
|
nullifier: proof.nullifier,
|
||||||
shareX: proof.shareX,
|
shareX: proof.shareX,
|
||||||
shareY: proof.shareY
|
shareY: proof.shareY
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -632,8 +632,8 @@ proc updateLog*(rlnPeer: WakuRLNRelay, msg: WakuMessage): RlnRelayResult[bool] =
|
|||||||
|
|
||||||
# extract the proof metadata of the supplied `msg`
|
# extract the proof metadata of the supplied `msg`
|
||||||
let proofMD = ProofMetadata(
|
let proofMD = ProofMetadata(
|
||||||
nullifier: proof.nullifier,
|
nullifier: proof.nullifier,
|
||||||
shareX: proof.shareX,
|
shareX: proof.shareX,
|
||||||
shareY: proof.shareY
|
shareY: proof.shareY
|
||||||
)
|
)
|
||||||
debug "proof metadata", proofMD = proofMD
|
debug "proof metadata", proofMD = proofMD
|
||||||
@ -684,7 +684,7 @@ proc absDiff*(e1, e2: Epoch): uint64 =
|
|||||||
let
|
let
|
||||||
epoch1 = fromEpoch(e1)
|
epoch1 = fromEpoch(e1)
|
||||||
epoch2 = fromEpoch(e2)
|
epoch2 = fromEpoch(e2)
|
||||||
|
|
||||||
# Manually perform an `abs` calculation
|
# Manually perform an `abs` calculation
|
||||||
if epoch1 > epoch2:
|
if epoch1 > epoch2:
|
||||||
return epoch1 - epoch2
|
return epoch1 - epoch2
|
||||||
@ -838,7 +838,7 @@ proc generateGroupUpdateHandler(rlnPeer: WakuRLNRelay): GroupUpdateHandler =
|
|||||||
return ok()
|
return ok()
|
||||||
return handler
|
return handler
|
||||||
|
|
||||||
proc parse*(event: type MemberRegistered,
|
proc parse*(event: type MemberRegistered,
|
||||||
log: JsonNode): RlnRelayResult[MembershipTuple] =
|
log: JsonNode): RlnRelayResult[MembershipTuple] =
|
||||||
## parses the `data` parameter of the `MemberRegistered` event `log`
|
## parses the `data` parameter of the `MemberRegistered` event `log`
|
||||||
## returns an error if it cannot parse the `data` parameter
|
## returns an error if it cannot parse the `data` parameter
|
||||||
@ -856,7 +856,7 @@ proc parse*(event: type MemberRegistered,
|
|||||||
offset += decode(data, offset, pubkey)
|
offset += decode(data, offset, pubkey)
|
||||||
# Parse the index
|
# Parse the index
|
||||||
offset += decode(data, offset, index)
|
offset += decode(data, offset, index)
|
||||||
return ok((index: index.toMembershipIndex(),
|
return ok((index: index.toMembershipIndex(),
|
||||||
idComm: pubkey.toIDCommitment()))
|
idComm: pubkey.toIDCommitment()))
|
||||||
except:
|
except:
|
||||||
return err("failed to parse the data field of the MemberRegistered event")
|
return err("failed to parse the data field of the MemberRegistered event")
|
||||||
@ -900,16 +900,16 @@ proc subscribeToGroupEvents*(ethClientUri: string,
|
|||||||
ethAccountAddress: Option[Address] = none(Address),
|
ethAccountAddress: Option[Address] = none(Address),
|
||||||
contractAddress: Address,
|
contractAddress: Address,
|
||||||
blockNumber: string = "0x0",
|
blockNumber: string = "0x0",
|
||||||
handler: GroupUpdateHandler) {.async, gcsafe.} =
|
handler: GroupUpdateHandler) {.async, gcsafe.} =
|
||||||
## connects to the eth client whose URI is supplied as `ethClientUri`
|
## connects to the eth client whose URI is supplied as `ethClientUri`
|
||||||
## subscribes to the `MemberRegistered` event emitted from the `MembershipContract` which is available on the supplied `contractAddress`
|
## subscribes to the `MemberRegistered` event emitted from the `MembershipContract` which is available on the supplied `contractAddress`
|
||||||
## it collects all the events starting from the given `blockNumber`
|
## it collects all the events starting from the given `blockNumber`
|
||||||
## for every received block, it calls the `handler`
|
## for every received block, it calls the `handler`
|
||||||
let web3 = await newWeb3(ethClientUri)
|
let web3 = await newWeb3(ethClientUri)
|
||||||
let contract = web3.contractSender(MembershipContract, contractAddress)
|
let contract = web3.contractSender(MembershipContract, contractAddress)
|
||||||
|
|
||||||
let blockTableRes = await getHistoricalEvents(ethClientUri,
|
let blockTableRes = await getHistoricalEvents(ethClientUri,
|
||||||
contractAddress,
|
contractAddress,
|
||||||
fromBlock=blockNumber)
|
fromBlock=blockNumber)
|
||||||
if blockTableRes.isErr():
|
if blockTableRes.isErr():
|
||||||
error "failed to retrieve historical events", error=blockTableRes.error
|
error "failed to retrieve historical events", error=blockTableRes.error
|
||||||
@ -926,7 +926,7 @@ proc subscribeToGroupEvents*(ethClientUri: string,
|
|||||||
discard blockTable
|
discard blockTable
|
||||||
|
|
||||||
var latestBlock: BlockNumber
|
var latestBlock: BlockNumber
|
||||||
let handleLog = proc(blockHeader: BlockHeader) {.async, gcsafe.} =
|
let handleLog = proc(blockHeader: BlockHeader) {.async, gcsafe.} =
|
||||||
try:
|
try:
|
||||||
let membershipRegistrationLogs = await contract.getJsonLogs(MemberRegistered,
|
let membershipRegistrationLogs = await contract.getJsonLogs(MemberRegistered,
|
||||||
blockHash = some(blockheader.hash))
|
blockHash = some(blockheader.hash))
|
||||||
@ -970,17 +970,17 @@ proc handleGroupUpdates*(rlnPeer: WakuRLNRelay) {.async, gcsafe.} =
|
|||||||
ethAccountAddress = rlnPeer.ethAccountAddress,
|
ethAccountAddress = rlnPeer.ethAccountAddress,
|
||||||
contractAddress = rlnPeer.membershipContractAddress,
|
contractAddress = rlnPeer.membershipContractAddress,
|
||||||
handler = handler)
|
handler = handler)
|
||||||
|
|
||||||
proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: PubsubTopic, contentTopic: ContentTopic, spamHandler: Option[SpamHandler] = none(SpamHandler)) =
|
proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: PubsubTopic, contentTopic: ContentTopic, spamHandler: Option[SpamHandler] = none(SpamHandler)) =
|
||||||
## this procedure is a thin wrapper for the pubsub addValidator method
|
## this procedure is a thin wrapper for the pubsub addValidator method
|
||||||
## it sets a validator for the waku messages published on the supplied pubsubTopic and contentTopic
|
## it sets a validator for the waku messages published on the supplied pubsubTopic and contentTopic
|
||||||
## if contentTopic is empty, then validation takes place for All the messages published on the given pubsubTopic
|
## if contentTopic is empty, then validation takes place for All the messages published on the given pubsubTopic
|
||||||
## the message validation logic is according to https://rfc.vac.dev/spec/17/
|
## the message validation logic is according to https://rfc.vac.dev/spec/17/
|
||||||
proc validator(topic: string, message: messages.Message): Future[pubsub.ValidationResult] {.async.} =
|
proc validator(topic: string, message: messages.Message): Future[pubsub.ValidationResult] {.async.} =
|
||||||
trace "rln-relay topic validator is called"
|
trace "rln-relay topic validator is called"
|
||||||
let decodeRes = WakuMessage.decode(message.data)
|
let decodeRes = WakuMessage.decode(message.data)
|
||||||
if decodeRes.isOk():
|
if decodeRes.isOk():
|
||||||
let
|
let
|
||||||
wakumessage = decodeRes.value
|
wakumessage = decodeRes.value
|
||||||
payload = string.fromBytes(wakumessage.payload)
|
payload = string.fromBytes(wakumessage.payload)
|
||||||
|
|
||||||
@ -997,7 +997,7 @@ proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: PubsubTopic, contentTopi
|
|||||||
let msgProof = decodeRes.get()
|
let msgProof = decodeRes.get()
|
||||||
|
|
||||||
# validate the message
|
# validate the message
|
||||||
let
|
let
|
||||||
validationRes = node.wakuRlnRelay.validateMessage(wakumessage)
|
validationRes = node.wakuRlnRelay.validateMessage(wakumessage)
|
||||||
proof = toHex(msgProof.proof)
|
proof = toHex(msgProof.proof)
|
||||||
epoch = fromEpoch(msgProof.epoch)
|
epoch = fromEpoch(msgProof.epoch)
|
||||||
@ -1021,7 +1021,7 @@ proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: PubsubTopic, contentTopi
|
|||||||
let handler = spamHandler.get()
|
let handler = spamHandler.get()
|
||||||
handler(wakumessage)
|
handler(wakumessage)
|
||||||
return pubsub.ValidationResult.Reject
|
return pubsub.ValidationResult.Reject
|
||||||
# set a validator for the supplied pubsubTopic
|
# set a validator for the supplied pubsubTopic
|
||||||
let pb = PubSub(node.wakuRelay)
|
let pb = PubSub(node.wakuRelay)
|
||||||
pb.addValidator(pubsubTopic, validator)
|
pb.addValidator(pubsubTopic, validator)
|
||||||
|
|
||||||
@ -1058,7 +1058,7 @@ proc mountRlnRelayStatic*(node: WakuNode,
|
|||||||
# create the WakuRLNRelay
|
# create the WakuRLNRelay
|
||||||
let rlnPeer = WakuRLNRelay(membershipKeyPair: memKeyPair,
|
let rlnPeer = WakuRLNRelay(membershipKeyPair: memKeyPair,
|
||||||
membershipIndex: memIndex,
|
membershipIndex: memIndex,
|
||||||
rlnInstance: rln,
|
rlnInstance: rln,
|
||||||
pubsubTopic: pubsubTopic,
|
pubsubTopic: pubsubTopic,
|
||||||
contentTopic: contentTopic)
|
contentTopic: contentTopic)
|
||||||
|
|
||||||
@ -1074,7 +1074,7 @@ proc mountRlnRelayStatic*(node: WakuNode,
|
|||||||
debug "rln relay topic validator is mounted successfully", pubsubTopic=pubsubTopic, contentTopic=contentTopic
|
debug "rln relay topic validator is mounted successfully", pubsubTopic=pubsubTopic, contentTopic=contentTopic
|
||||||
|
|
||||||
node.wakuRlnRelay = rlnPeer
|
node.wakuRlnRelay = rlnPeer
|
||||||
return ok()
|
return ok()
|
||||||
|
|
||||||
proc mountRlnRelayDynamic*(node: WakuNode,
|
proc mountRlnRelayDynamic*(node: WakuNode,
|
||||||
ethClientAddr: string = "",
|
ethClientAddr: string = "",
|
||||||
@ -1105,7 +1105,7 @@ proc mountRlnRelayDynamic*(node: WakuNode,
|
|||||||
let rln = rlnInstance.get()
|
let rln = rlnInstance.get()
|
||||||
|
|
||||||
# prepare rln membership key pair
|
# prepare rln membership key pair
|
||||||
var
|
var
|
||||||
keyPair: MembershipKeyPair
|
keyPair: MembershipKeyPair
|
||||||
rlnIndex: MembershipIndex
|
rlnIndex: MembershipIndex
|
||||||
if memKeyPair.isNone: # no rln credentials provided
|
if memKeyPair.isNone: # no rln credentials provided
|
||||||
@ -1118,11 +1118,11 @@ proc mountRlnRelayDynamic*(node: WakuNode,
|
|||||||
keyPair = keyPairRes.value()
|
keyPair = keyPairRes.value()
|
||||||
# register the rln-relay peer to the membership contract
|
# register the rln-relay peer to the membership contract
|
||||||
waku_rln_registration_duration_seconds.nanosecondTime:
|
waku_rln_registration_duration_seconds.nanosecondTime:
|
||||||
let regIndexRes = await register(idComm = keyPair.idCommitment,
|
let regIndexRes = await register(idComm = keyPair.idCommitment,
|
||||||
ethAccountAddress = ethAccountAddress,
|
ethAccountAddress = ethAccountAddress,
|
||||||
ethAccountPrivKey = ethAccountPrivKeyOpt.get(),
|
ethAccountPrivKey = ethAccountPrivKeyOpt.get(),
|
||||||
ethClientAddress = ethClientAddr,
|
ethClientAddress = ethClientAddr,
|
||||||
membershipContractAddress = memContractAddr,
|
membershipContractAddress = memContractAddr,
|
||||||
registrationHandler = registrationHandler)
|
registrationHandler = registrationHandler)
|
||||||
# check whether registration is done
|
# check whether registration is done
|
||||||
if regIndexRes.isErr():
|
if regIndexRes.isErr():
|
||||||
@ -1159,8 +1159,8 @@ proc mountRlnRelayDynamic*(node: WakuNode,
|
|||||||
node.wakuRlnRelay = rlnPeer
|
node.wakuRlnRelay = rlnPeer
|
||||||
return ok()
|
return ok()
|
||||||
|
|
||||||
proc writeRlnCredentials*(path: string,
|
proc writeRlnCredentials*(path: string,
|
||||||
credentials: RlnMembershipCredentials,
|
credentials: RlnMembershipCredentials,
|
||||||
password: string): RlnRelayResult[void] =
|
password: string): RlnRelayResult[void] =
|
||||||
# Returns RlnRelayResult[void], which indicates the success of the call
|
# Returns RlnRelayResult[void], which indicates the success of the call
|
||||||
info "Storing RLN credentials"
|
info "Storing RLN credentials"
|
||||||
@ -1173,10 +1173,10 @@ proc writeRlnCredentials*(path: string,
|
|||||||
return err("Error while saving keyfile for RLN credentials")
|
return err("Error while saving keyfile for RLN credentials")
|
||||||
return ok()
|
return ok()
|
||||||
|
|
||||||
# Attempts decryptions of all keyfiles with the provided password.
|
# Attempts decryptions of all keyfiles with the provided password.
|
||||||
# If one or more credentials are successfully decrypted, the max(min(index,number_decrypted),0)-th is returned.
|
# If one or more credentials are successfully decrypted, the max(min(index,number_decrypted),0)-th is returned.
|
||||||
proc readRlnCredentials*(path: string,
|
proc readRlnCredentials*(path: string,
|
||||||
password: string,
|
password: string,
|
||||||
index: int = 0): RlnRelayResult[Option[RlnMembershipCredentials]] =
|
index: int = 0): RlnRelayResult[Option[RlnMembershipCredentials]] =
|
||||||
# Returns RlnRelayResult[Option[RlnMembershipCredentials]], which indicates the success of the call
|
# Returns RlnRelayResult[Option[RlnMembershipCredentials]], which indicates the success of the call
|
||||||
info "Reading RLN credentials"
|
info "Reading RLN credentials"
|
||||||
@ -1187,7 +1187,7 @@ proc readRlnCredentials*(path: string,
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
var decodedKeyfiles = loadKeyFiles(path, password)
|
var decodedKeyfiles = loadKeyFiles(path, password)
|
||||||
|
|
||||||
if decodedKeyfiles.isOk():
|
if decodedKeyfiles.isOk():
|
||||||
var decodedRlnCredentials = decodedKeyfiles.get()
|
var decodedRlnCredentials = decodedKeyfiles.get()
|
||||||
debug "Successfully decrypted keyfiles for the provided password", numberKeyfilesDecrypted=decodedRlnCredentials.len
|
debug "Successfully decrypted keyfiles for the provided password", numberKeyfilesDecrypted=decodedRlnCredentials.len
|
||||||
@ -1195,7 +1195,7 @@ proc readRlnCredentials*(path: string,
|
|||||||
let credentialIndex = max(min(index, decodedRlnCredentials.len - 1), 0)
|
let credentialIndex = max(min(index, decodedRlnCredentials.len - 1), 0)
|
||||||
debug "Picking credential with (adjusted) index", inputIndex=index, adjustedIndex=credentialIndex
|
debug "Picking credential with (adjusted) index", inputIndex=index, adjustedIndex=credentialIndex
|
||||||
let jsonObject = parseJson(string.fromBytes(decodedRlnCredentials[credentialIndex].get()))
|
let jsonObject = parseJson(string.fromBytes(decodedRlnCredentials[credentialIndex].get()))
|
||||||
let deserializedRlnCredentials = to(jsonObject, RlnMembershipCredentials)
|
let deserializedRlnCredentials = to(jsonObject, RlnMembershipCredentials)
|
||||||
debug "Deserialized RLN credentials", rlnCredentials=deserializedRlnCredentials
|
debug "Deserialized RLN credentials", rlnCredentials=deserializedRlnCredentials
|
||||||
return ok(some(deserializedRlnCredentials))
|
return ok(some(deserializedRlnCredentials))
|
||||||
else:
|
else:
|
||||||
@ -1222,11 +1222,11 @@ proc mount(node: WakuNode,
|
|||||||
return err("failed to mount WakuRLNRelay")
|
return err("failed to mount WakuRLNRelay")
|
||||||
else:
|
else:
|
||||||
# mount rlnrelay in off-chain mode with a static group of users
|
# mount rlnrelay in off-chain mode with a static group of users
|
||||||
let mountRes = node.mountRlnRelayStatic(group = groupOpt.get(),
|
let mountRes = node.mountRlnRelayStatic(group = groupOpt.get(),
|
||||||
memKeyPair = memKeyPairOpt.get(),
|
memKeyPair = memKeyPairOpt.get(),
|
||||||
memIndex= memIndexOpt.get(),
|
memIndex= memIndexOpt.get(),
|
||||||
pubsubTopic = conf.rlnRelayPubsubTopic,
|
pubsubTopic = conf.rlnRelayPubsubTopic,
|
||||||
contentTopic = conf.rlnRelayContentTopic,
|
contentTopic = conf.rlnRelayContentTopic,
|
||||||
spamHandler = spamHandler)
|
spamHandler = spamHandler)
|
||||||
|
|
||||||
if mountRes.isErr():
|
if mountRes.isErr():
|
||||||
@ -1237,14 +1237,14 @@ proc mount(node: WakuNode,
|
|||||||
|
|
||||||
# check the correct construction of the tree by comparing the calculated root against the expected root
|
# check the correct construction of the tree by comparing the calculated root against the expected root
|
||||||
# no error should happen as it is already captured in the unit tests
|
# no error should happen as it is already captured in the unit tests
|
||||||
# TODO have added this check to account for unseen corner cases, will remove it later
|
# TODO have added this check to account for unseen corner cases, will remove it later
|
||||||
let
|
let
|
||||||
rootRes = node.wakuRlnRelay.rlnInstance.getMerkleRoot()
|
rootRes = node.wakuRlnRelay.rlnInstance.getMerkleRoot()
|
||||||
expectedRoot = StaticGroupMerkleRoot
|
expectedRoot = StaticGroupMerkleRoot
|
||||||
|
|
||||||
if rootRes.isErr():
|
if rootRes.isErr():
|
||||||
return err(rootRes.error())
|
return err(rootRes.error())
|
||||||
|
|
||||||
let root = rootRes.value()
|
let root = rootRes.value()
|
||||||
|
|
||||||
if root.inHex() != expectedRoot:
|
if root.inHex() != expectedRoot:
|
||||||
@ -1254,10 +1254,10 @@ proc mount(node: WakuNode,
|
|||||||
return ok()
|
return ok()
|
||||||
else: # mount the rln relay protocol in the on-chain/dynamic mode
|
else: # mount the rln relay protocol in the on-chain/dynamic mode
|
||||||
debug "setting up waku-rln-relay in on-chain mode... "
|
debug "setting up waku-rln-relay in on-chain mode... "
|
||||||
|
|
||||||
debug "on-chain setup parameters", contractAddress=conf.rlnRelayEthContractAddress
|
debug "on-chain setup parameters", contractAddress=conf.rlnRelayEthContractAddress
|
||||||
# read related inputs to run rln-relay in on-chain mode and do type conversion when needed
|
# read related inputs to run rln-relay in on-chain mode and do type conversion when needed
|
||||||
let
|
let
|
||||||
ethClientAddr = conf.rlnRelayEthClientAddress
|
ethClientAddr = conf.rlnRelayEthClientAddress
|
||||||
|
|
||||||
var ethMemContractAddress: web3.Address
|
var ethMemContractAddress: web3.Address
|
||||||
@ -1272,7 +1272,7 @@ proc mount(node: WakuNode,
|
|||||||
|
|
||||||
if conf.rlnRelayEthAccountPrivateKey != "":
|
if conf.rlnRelayEthAccountPrivateKey != "":
|
||||||
ethAccountPrivKeyOpt = some(keys.PrivateKey(SkSecretKey.fromHex(conf.rlnRelayEthAccountPrivateKey).value))
|
ethAccountPrivKeyOpt = some(keys.PrivateKey(SkSecretKey.fromHex(conf.rlnRelayEthAccountPrivateKey).value))
|
||||||
|
|
||||||
if conf.rlnRelayEthAccountAddress != "":
|
if conf.rlnRelayEthAccountAddress != "":
|
||||||
var ethAccountAddress: web3.Address
|
var ethAccountAddress: web3.Address
|
||||||
try:
|
try:
|
||||||
@ -1280,59 +1280,59 @@ proc mount(node: WakuNode,
|
|||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
return err("invalid eth account address: " & err.msg)
|
return err("invalid eth account address: " & err.msg)
|
||||||
ethAccountAddressOpt = some(ethAccountAddress)
|
ethAccountAddressOpt = some(ethAccountAddress)
|
||||||
|
|
||||||
# if the rlnRelayCredPath config option is non-empty, then rln-relay credentials should be persisted
|
# if the rlnRelayCredPath config option is non-empty, then rln-relay credentials should be persisted
|
||||||
# if the path does not contain any credential file, then a new set is generated and pesisted in the same path
|
# if the path does not contain any credential file, then a new set is generated and pesisted in the same path
|
||||||
# if there is a credential file, then no new credentials are generated, instead the content of the file is read and used to mount rln-relay
|
# if there is a credential file, then no new credentials are generated, instead the content of the file is read and used to mount rln-relay
|
||||||
if conf.rlnRelayCredPath != "":
|
if conf.rlnRelayCredPath != "":
|
||||||
|
|
||||||
let rlnRelayCredPath = joinPath(conf.rlnRelayCredPath, RlnCredentialsFilename)
|
let rlnRelayCredPath = joinPath(conf.rlnRelayCredPath, RlnCredentialsFilename)
|
||||||
debug "rln-relay credential path", rlnRelayCredPath
|
debug "rln-relay credential path", rlnRelayCredPath
|
||||||
|
|
||||||
# check if there is an rln-relay credential file in the supplied path
|
# check if there is an rln-relay credential file in the supplied path
|
||||||
if fileExists(rlnRelayCredPath):
|
if fileExists(rlnRelayCredPath):
|
||||||
|
|
||||||
info "A RLN credential file exists in provided path", path=rlnRelayCredPath
|
info "A RLN credential file exists in provided path", path=rlnRelayCredPath
|
||||||
|
|
||||||
# retrieve rln-relay credential
|
# retrieve rln-relay credential
|
||||||
let readCredentialsRes = readRlnCredentials(rlnRelayCredPath, conf.rlnRelayCredentialsPassword)
|
let readCredentialsRes = readRlnCredentials(rlnRelayCredPath, conf.rlnRelayCredentialsPassword)
|
||||||
|
|
||||||
if readCredentialsRes.isErr():
|
if readCredentialsRes.isErr():
|
||||||
return err("RLN credentials cannot be read: " & readCredentialsRes.error())
|
return err("RLN credentials cannot be read: " & readCredentialsRes.error())
|
||||||
|
|
||||||
credentials = readCredentialsRes.get()
|
credentials = readCredentialsRes.get()
|
||||||
|
|
||||||
else: # there is no credential file available in the supplied path
|
else: # there is no credential file available in the supplied path
|
||||||
# mount the rln-relay protocol leaving rln-relay credentials arguments unassigned
|
# mount the rln-relay protocol leaving rln-relay credentials arguments unassigned
|
||||||
# this infroms mountRlnRelayDynamic proc that new credentials should be generated and registered to the membership contract
|
# this infroms mountRlnRelayDynamic proc that new credentials should be generated and registered to the membership contract
|
||||||
info "no rln credential is provided"
|
info "no rln credential is provided"
|
||||||
|
|
||||||
if credentials.isSome():
|
if credentials.isSome():
|
||||||
# mount rln-relay in on-chain mode, with credentials that were read or generated
|
# mount rln-relay in on-chain mode, with credentials that were read or generated
|
||||||
res = await node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress,
|
res = await node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress,
|
||||||
ethClientAddr = ethClientAddr,
|
ethClientAddr = ethClientAddr,
|
||||||
ethAccountAddress = ethAccountAddressOpt,
|
ethAccountAddress = ethAccountAddressOpt,
|
||||||
ethAccountPrivKeyOpt = ethAccountPrivKeyOpt,
|
ethAccountPrivKeyOpt = ethAccountPrivKeyOpt,
|
||||||
pubsubTopic = conf.rlnRelayPubsubTopic,
|
pubsubTopic = conf.rlnRelayPubsubTopic,
|
||||||
contentTopic = conf.rlnRelayContentTopic,
|
contentTopic = conf.rlnRelayContentTopic,
|
||||||
spamHandler = spamHandler,
|
spamHandler = spamHandler,
|
||||||
registrationHandler = registrationHandler,
|
registrationHandler = registrationHandler,
|
||||||
memKeyPair = some(credentials.get().membershipKeyPair),
|
memKeyPair = some(credentials.get().membershipKeyPair),
|
||||||
memIndex = some(credentials.get().rlnIndex))
|
memIndex = some(credentials.get().rlnIndex))
|
||||||
else:
|
else:
|
||||||
# mount rln-relay in on-chain mode, with the provided private key
|
# mount rln-relay in on-chain mode, with the provided private key
|
||||||
res = await node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress,
|
res = await node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress,
|
||||||
ethClientAddr = ethClientAddr,
|
ethClientAddr = ethClientAddr,
|
||||||
ethAccountAddress = ethAccountAddressOpt,
|
ethAccountAddress = ethAccountAddressOpt,
|
||||||
ethAccountPrivKeyOpt = ethAccountPrivKeyOpt,
|
ethAccountPrivKeyOpt = ethAccountPrivKeyOpt,
|
||||||
pubsubTopic = conf.rlnRelayPubsubTopic,
|
pubsubTopic = conf.rlnRelayPubsubTopic,
|
||||||
contentTopic = conf.rlnRelayContentTopic,
|
contentTopic = conf.rlnRelayContentTopic,
|
||||||
spamHandler = spamHandler,
|
spamHandler = spamHandler,
|
||||||
registrationHandler = registrationHandler)
|
registrationHandler = registrationHandler)
|
||||||
|
|
||||||
# TODO should be replaced with key-store with proper encryption
|
# TODO should be replaced with key-store with proper encryption
|
||||||
# persist rln credential
|
# persist rln credential
|
||||||
credentials = some(RlnMembershipCredentials(rlnIndex: node.wakuRlnRelay.membershipIndex,
|
credentials = some(RlnMembershipCredentials(rlnIndex: node.wakuRlnRelay.membershipIndex,
|
||||||
membershipKeyPair: node.wakuRlnRelay.membershipKeyPair))
|
membershipKeyPair: node.wakuRlnRelay.membershipKeyPair))
|
||||||
if writeRlnCredentials(rlnRelayCredPath, credentials.get(), conf.rlnRelayCredentialsPassword).isErr():
|
if writeRlnCredentials(rlnRelayCredPath, credentials.get(), conf.rlnRelayCredentialsPassword).isErr():
|
||||||
return err("error in storing rln credentials")
|
return err("error in storing rln credentials")
|
||||||
@ -1344,7 +1344,7 @@ proc mount(node: WakuNode,
|
|||||||
res = await node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr,
|
res = await node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr,
|
||||||
ethAccountAddress = ethAccountAddressOpt, ethAccountPrivKeyOpt = ethAccountPrivKeyOpt, pubsubTopic = conf.rlnRelayPubsubTopic,
|
ethAccountAddress = ethAccountAddressOpt, ethAccountPrivKeyOpt = ethAccountPrivKeyOpt, pubsubTopic = conf.rlnRelayPubsubTopic,
|
||||||
contentTopic = conf.rlnRelayContentTopic, spamHandler = spamHandler, registrationHandler = registrationHandler)
|
contentTopic = conf.rlnRelayContentTopic, spamHandler = spamHandler, registrationHandler = registrationHandler)
|
||||||
|
|
||||||
if res.isErr():
|
if res.isErr():
|
||||||
return err("dynamic rln-relay could not be mounted: " & res.error())
|
return err("dynamic rln-relay could not be mounted: " & res.error())
|
||||||
return ok()
|
return ok()
|
||||||
@ -1357,7 +1357,7 @@ proc mountRlnRelay*(node: WakuNode,
|
|||||||
## Mounts the rln-relay protocol on the node.
|
## Mounts the rln-relay protocol on the node.
|
||||||
## The rln-relay protocol can be mounted in two modes: on-chain and off-chain.
|
## The rln-relay protocol can be mounted in two modes: on-chain and off-chain.
|
||||||
## Returns an error if the rln-relay protocol could not be mounted.
|
## Returns an error if the rln-relay protocol could not be mounted.
|
||||||
waku_rln_relay_mounting_duration_seconds.nanosecondTime:
|
waku_rln_relay_mounting_duration_seconds.nanosecondTime:
|
||||||
let res = await mount(
|
let res = await mount(
|
||||||
node,
|
node,
|
||||||
conf,
|
conf,
|
||||||
|
|||||||
@ -52,7 +52,7 @@ proc initProtocolHandler(ws: WakuStore) =
|
|||||||
|
|
||||||
let decodeRes = HistoryRPC.decode(buf)
|
let decodeRes = HistoryRPC.decode(buf)
|
||||||
if decodeRes.isErr():
|
if decodeRes.isErr():
|
||||||
error "failed to decode rpc", peerId=conn.peerId
|
error "failed to decode rpc", peerId= $conn.peerId
|
||||||
waku_store_errors.inc(labelValues = [decodeRpcFailure])
|
waku_store_errors.inc(labelValues = [decodeRpcFailure])
|
||||||
# TODO: Return (BAD_REQUEST, cause: "decode rpc failed")
|
# TODO: Return (BAD_REQUEST, cause: "decode rpc failed")
|
||||||
return
|
return
|
||||||
@ -61,7 +61,7 @@ proc initProtocolHandler(ws: WakuStore) =
|
|||||||
let reqRpc = decodeRes.value
|
let reqRpc = decodeRes.value
|
||||||
|
|
||||||
if reqRpc.query.isNone():
|
if reqRpc.query.isNone():
|
||||||
error "empty query rpc", peerId=conn.peerId, requestId=reqRpc.requestId
|
error "empty query rpc", peerId= $conn.peerId, requestId=reqRpc.requestId
|
||||||
waku_store_errors.inc(labelValues = [emptyRpcQueryFailure])
|
waku_store_errors.inc(labelValues = [emptyRpcQueryFailure])
|
||||||
# TODO: Return (BAD_REQUEST, cause: "empty query")
|
# TODO: Return (BAD_REQUEST, cause: "empty query")
|
||||||
return
|
return
|
||||||
@ -76,7 +76,7 @@ proc initProtocolHandler(ws: WakuStore) =
|
|||||||
let responseRes = ws.queryHandler(request)
|
let responseRes = ws.queryHandler(request)
|
||||||
|
|
||||||
if responseRes.isErr():
|
if responseRes.isErr():
|
||||||
error "history query failed", peerId=conn.peerId, requestId=requestId, error=responseRes.error
|
error "history query failed", peerId= $conn.peerId, requestId=requestId, error=responseRes.error
|
||||||
|
|
||||||
let response = responseRes.toRPC()
|
let response = responseRes.toRPC()
|
||||||
let rpc = HistoryRPC(requestId: requestId, response: some(response))
|
let rpc = HistoryRPC(requestId: requestId, response: some(response))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user