From 3f4f6d7e5be05aef1490ae086fec3a031da78b06 Mon Sep 17 00:00:00 2001 From: Alvaro Revuelta Date: Wed, 28 Feb 2024 17:19:20 +0100 Subject: [PATCH] chore: remove rln epoch hardcoding (#2483) --- apps/benchmarks/benchmarks.nim | 2 +- apps/chat2/chat2.nim | 2 + apps/chat2/config_chat2.nim | 5 +++ apps/networkmonitor/networkmonitor.nim | 3 ++ apps/networkmonitor/networkmonitor_config.nim | 10 +++++ apps/wakunode2/app.nim | 2 + apps/wakunode2/external_config.nim | 9 +++- apps/wakunode2/networks_config.nim | 9 +++- apps/wakunode2/wakunode2.nim | 11 ++++- tests/node/test_wakunode_relay_rln.nim | 13 +++--- .../rln_v2/test_rln_relay_v2_serde.nim | 2 +- tests/waku_rln_relay/test_waku_rln_relay.nim | 5 ++- .../test_wakunode_rln_relay.nim | 18 ++++++-- tests/wakunode_jsonrpc/test_jsonrpc_relay.nim | 2 + tests/wakunode_rest/test_rest_health.nim | 1 + tests/wakunode_rest/test_rest_relay.nim | 5 +++ waku/waku_rln_relay/constants.nim | 4 -- waku/waku_rln_relay/nonce_manager.nim | 4 +- waku/waku_rln_relay/rln_relay.nim | 43 +++++++++++-------- 19 files changed, 107 insertions(+), 43 deletions(-) diff --git a/apps/benchmarks/benchmarks.nim b/apps/benchmarks/benchmarks.nim index 24c011970..c3930aef9 100644 --- a/apps/benchmarks/benchmarks.nim +++ b/apps/benchmarks/benchmarks.nim @@ -30,7 +30,7 @@ proc main(): Future[string] {.async, gcsafe.} = var proofVerTimes: seq[times.Duration] = @[] for i in 0 .. 50: var time = getTime() - let proof = manager.generateProof(data, getCurrentEpoch()).get() + let proof = manager.generateProof(data, default(Epoch)).get() proofGenTimes.add(getTime() - time) time = getTime() diff --git a/apps/chat2/chat2.nim b/apps/chat2/chat2.nim index 98e5842db..c03653650 100644 --- a/apps/chat2/chat2.nim +++ b/apps/chat2/chat2.nim @@ -523,6 +523,7 @@ proc processInput(rfd: AsyncFD, rng: ref HmacDrbgContext) {.async.} = rlnRelayCredPath: conf.rlnRelayCredPath, rlnRelayCredPassword: conf.rlnRelayCredPassword, rlnRelayUserMessageLimit: conf.rlnRelayUserMessageLimit, + rlnEpochSizeSec: conf.rlnEpochSizeSec ) else: let rlnConf = WakuRlnConfig( @@ -532,6 +533,7 @@ proc processInput(rfd: AsyncFD, rng: ref HmacDrbgContext) {.async.} = rlnRelayEthClientAddress: string(conf.rlnRelayethClientAddress), rlnRelayCredPath: conf.rlnRelayCredPath, rlnRelayCredPassword: conf.rlnRelayCredPassword, + rlnEpochSizeSec: conf.rlnEpochSizeSec ) waitFor node.mountRlnRelay(rlnConf, diff --git a/apps/chat2/config_chat2.nim b/apps/chat2/config_chat2.nim index c847ed406..055cd63d3 100644 --- a/apps/chat2/config_chat2.nim +++ b/apps/chat2/config_chat2.nim @@ -272,6 +272,11 @@ type defaultValue: 1, name: "rln-relay-user-message-limit" .}: uint64 + rlnEpochSizeSec* {. + desc: "Epoch size in seconds used to rate limit RLN memberships. Default is 1 second.", + defaultValue: 1 + name: "rln-relay-epoch-sec" .}: uint64 + # NOTE: Keys are different in nim-libp2p proc parseCmdArg*(T: type crypto.PrivateKey, p: string): T = try: diff --git a/apps/networkmonitor/networkmonitor.nim b/apps/networkmonitor/networkmonitor.nim index 7907b2150..ee46338ac 100644 --- a/apps/networkmonitor/networkmonitor.nim +++ b/apps/networkmonitor/networkmonitor.nim @@ -494,6 +494,8 @@ when isMainModule: conf.pubsubTopics = twnClusterConf.pubsubTopics conf.rlnRelayDynamic = twnClusterConf.rlnRelayDynamic conf.rlnRelayEthContractAddress = twnClusterConf.rlnRelayEthContractAddress + conf.rlnEpochSizeSec = twnClusterConf.rlnEpochSizeSec + conf.rlnRelayUserMessageLimit = twnClusterConf.rlnRelayUserMessageLimit if conf.logLevel != LogLevel.NONE: setLogLevel(conf.logLevel) @@ -546,6 +548,7 @@ when isMainModule: rlnRelayCredPath: "", rlnRelayCredPassword: "", rlnRelayTreePath: conf.rlnRelayTreePath, + rlnEpochSizeSec: conf.rlnEpochSizeSec ) try: diff --git a/apps/networkmonitor/networkmonitor_config.nim b/apps/networkmonitor/networkmonitor_config.nim index a1c83ba94..2f0841d34 100644 --- a/apps/networkmonitor/networkmonitor_config.nim +++ b/apps/networkmonitor/networkmonitor_config.nim @@ -75,6 +75,16 @@ type defaultValue: "", name: "rln-relay-eth-contract-address" }: string + rlnEpochSizeSec* {. + desc: "Epoch size in seconds used to rate limit RLN memberships. Default is 1 second.", + defaultValue: 1 + name: "rln-relay-epoch-sec" .}: uint64 + + rlnRelayUserMessageLimit* {. + desc: "Set a user message limit for the rln membership registration. Must be a positive integer. Default is 1.", + defaultValue: 1, + name: "rln-relay-user-message-limit" .}: uint64 + ## Prometheus metrics config metricsServer* {. desc: "Enable the metrics server: true|false" diff --git a/apps/wakunode2/app.nim b/apps/wakunode2/app.nim index 291ea1d1d..b064c2453 100644 --- a/apps/wakunode2/app.nim +++ b/apps/wakunode2/app.nim @@ -477,6 +477,7 @@ proc setupProtocols(node: WakuNode, rlnRelayCredPassword: conf.rlnRelayCredPassword, rlnRelayTreePath: conf.rlnRelayTreePath, rlnRelayUserMessageLimit: conf.rlnRelayUserMessageLimit, + rlnEpochSizeSec: conf.rlnEpochSizeSec, onFatalErrorAction: onFatalErrorAction, ) else: @@ -488,6 +489,7 @@ proc setupProtocols(node: WakuNode, rlnRelayCredPath: conf.rlnRelayCredPath, rlnRelayCredPassword: conf.rlnRelayCredPassword, rlnRelayTreePath: conf.rlnRelayTreePath, + rlnEpochSizeSec: conf.rlnEpochSizeSec, onFatalErrorAction: onFatalErrorAction, ) diff --git a/apps/wakunode2/external_config.nim b/apps/wakunode2/external_config.nim index 72bd64a17..88739de04 100644 --- a/apps/wakunode2/external_config.nim +++ b/apps/wakunode2/external_config.nim @@ -34,7 +34,7 @@ type ProtectedTopic* = object topic*: string key*: secp256k1.SkPublicKey -type ShardIdx = distinct uint16 +type ShardIdx = distinct uint16 type EthRpcUrl = distinct string @@ -83,12 +83,17 @@ type desc: "Private key for broadcasting transactions", defaultValue: "", name: "rln-relay-eth-private-key" }: string - + 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 + rlnEpochSizeSec* {. + desc: "Epoch size in seconds used to rate limit RLN memberships. Default is 1 second.", + defaultValue: 1 + name: "rln-relay-epoch-sec" .}: uint64 + maxMessageSize* {. desc: "Maximum message size. Accepted units: KiB, KB, and B. e.g. 1024KiB; 1500 B; etc." defaultValue: DefaultMaxWakuMessageSizeStr diff --git a/apps/wakunode2/networks_config.nim b/apps/wakunode2/networks_config.nim index c78b0c465..3a7d78aa4 100644 --- a/apps/wakunode2/networks_config.nim +++ b/apps/wakunode2/networks_config.nim @@ -10,13 +10,15 @@ type ClusterConf* = object rlnRelayEthContractAddress*: string rlnRelayDynamic*: bool rlnRelayBandwidthThreshold*: int + rlnEpochSizeSec*: uint64 + rlnRelayUserMessageLimit*: uint64 pubsubTopics*: seq[string] discv5Discovery*: bool discv5BootstrapNodes*: seq[string] -# cluster-id=1 +# cluster-id=1 # Cluster configuration corresponding to The Waku Network. Note that it -# overrides existing cli configuration +# overrides existing cli configuration proc TheWakuNetworkConf*(T: type ClusterConf): ClusterConf = return ClusterConf( maxMessageSize: "150KiB", @@ -25,6 +27,9 @@ proc TheWakuNetworkConf*(T: type ClusterConf): ClusterConf = rlnRelayEthContractAddress: "0xF471d71E9b1455bBF4b85d475afb9BB0954A29c4", rlnRelayDynamic: true, rlnRelayBandwidthThreshold: 0, + rlnEpochSizeSec: 1, + # parameter to be defined with rln_v2 + rlnRelayUserMessageLimit: 1, pubsubTopics: @[ "/waku/2/rs/1/0", "/waku/2/rs/1/1", "/waku/2/rs/1/2", "/waku/2/rs/1/3", diff --git a/apps/wakunode2/wakunode2.nim b/apps/wakunode2/wakunode2.nim index c2d0d3924..e90eada2a 100644 --- a/apps/wakunode2/wakunode2.nim +++ b/apps/wakunode2/wakunode2.nim @@ -33,9 +33,11 @@ proc logConfig(conf: WakuNodeConf) = info "Configuration. Network", cluster = conf.clusterId, - pubsubTopics = conf.pubsubTopics, maxPeers = conf.maxRelayPeers + for shard in conf.pubsubTopics: + info "Configuration. Shards", shard=shard + for i in conf.discv5BootstrapNodes: info "Configuration. Bootstrap nodes", node = i @@ -43,7 +45,10 @@ proc logConfig(conf: WakuNodeConf) = info "Configuration. Validation", mechanism = "onchain rln", contract = conf.rlnRelayEthContractAddress, - maxMessageSize = conf.maxMessageSize + maxMessageSize = conf.maxMessageSize, + rlnEpochSizeSec = conf.rlnEpochSizeSec, + rlnRelayUserMessageLimit = conf.rlnRelayUserMessageLimit, + rlnRelayEthClientAddress = string(conf.rlnRelayEthClientAddress) {.pop.} # @TODO confutils.nim(775, 17) Error: can raise an unlisted exception: ref IOError @@ -100,6 +105,8 @@ when isMainModule: conf.discv5Discovery = twnClusterConf.discv5Discovery conf.discv5BootstrapNodes = conf.discv5BootstrapNodes & twnClusterConf.discv5BootstrapNodes + conf.rlnEpochSizeSec = twnClusterConf.rlnEpochSizeSec + conf.rlnRelayUserMessageLimit = twnClusterConf.rlnRelayUserMessageLimit var wakunode2 = App.init(rng, conf) diff --git a/tests/node/test_wakunode_relay_rln.nim b/tests/node/test_wakunode_relay_rln.nim index 6b8acdee6..ff08da513 100644 --- a/tests/node/test_wakunode_relay_rln.nim +++ b/tests/node/test_wakunode_relay_rln.nim @@ -30,6 +30,7 @@ proc setupRln(node: WakuNode, identifier: uint) {.async.} = rlnRelayDynamic: false, rlnRelayCredIndex: some(identifier), rlnRelayTreePath: genTempPath("rln_tree", "wakunode_" & $identifier), + rlnEpochSizeSec: 1 ) ) @@ -76,7 +77,7 @@ proc sendRlnMessageWithInvalidProof( client.wakuRlnRelay.groupManager.generateProof( concat(payload, extraBytes), # we add extra bytes to invalidate proof verification against original payload - getCurrentEpoch() + client.wakuRlnRelay.getCurrentEpoch() ) rateLimitProof = rateLimitProofRes.get().encode().buffer message = @@ -249,17 +250,17 @@ suite "Waku RlnRelay - End to End": WakuMessage(payload: @payload150kibPlus, contentTopic: contentTopic) doAssert( - client.wakuRlnRelay.appendRLNProof(message1b, epoch + EpochUnitSeconds * 0).isOk() + client.wakuRlnRelay.appendRLNProof(message1b, epoch + client.wakuRlnRelay.rlnEpochSizeSec * 0).isOk() ) doAssert( - client.wakuRlnRelay.appendRLNProof(message1kib, epoch + EpochUnitSeconds * 1).isOk() + client.wakuRlnRelay.appendRLNProof(message1kib, epoch + client.wakuRlnRelay.rlnEpochSizeSec * 1).isOk() ) doAssert( - client.wakuRlnRelay.appendRLNProof(message150kib, epoch + EpochUnitSeconds * 2).isOk() + client.wakuRlnRelay.appendRLNProof(message150kib, epoch + client.wakuRlnRelay.rlnEpochSizeSec * 2).isOk() ) doAssert( client.wakuRlnRelay.appendRLNProof( - message151kibPlus, epoch + EpochUnitSeconds * 3 + message151kibPlus, epoch + client.wakuRlnRelay.rlnEpochSizeSec * 3 ).isOk() ) @@ -324,7 +325,7 @@ suite "Waku RlnRelay - End to End": doAssert( client.wakuRlnRelay.appendRLNProof( - message151kibPlus, epoch + EpochUnitSeconds * 3 + message151kibPlus, epoch + client.wakuRlnRelay.rlnEpochSizeSec * 3 ) ) diff --git a/tests/waku_rln_relay/rln_v2/test_rln_relay_v2_serde.nim b/tests/waku_rln_relay/rln_v2/test_rln_relay_v2_serde.nim index d14054ccc..06bdcb840 100644 --- a/tests/waku_rln_relay/rln_v2/test_rln_relay_v2_serde.nim +++ b/tests/waku_rln_relay/rln_v2/test_rln_relay_v2_serde.nim @@ -73,7 +73,7 @@ suite "RLN Relay v2: serde": userMessageLimit = rateCommitment.userMessageLimit, messageId = 0, index = 0, - epoch = calcEpoch(epochTime())) + epoch = rln.calcEpoch(epochTime())) assert proofRes.isOk, $proofRes.error diff --git a/tests/waku_rln_relay/test_waku_rln_relay.nim b/tests/waku_rln_relay/test_waku_rln_relay.nim index 9e7a1ec73..832d0242e 100644 --- a/tests/waku_rln_relay/test_waku_rln_relay.nim +++ b/tests/waku_rln_relay/test_waku_rln_relay.nim @@ -590,7 +590,7 @@ suite "Waku rln relay": test "updateLog and hasDuplicate tests": let wakurlnrelay = WakuRLNRelay() - epoch = getCurrentEpoch() + epoch = wakurlnrelay.getCurrentEpoch() # create some dummy nullifiers and secret shares var nullifier1: Nullifier @@ -662,6 +662,7 @@ suite "Waku rln relay": let rlnConf = WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(index), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_2")) let wakuRlnRelayRes = await WakuRlnRelay.new(rlnConf) require: @@ -683,7 +684,7 @@ suite "Waku rln relay": let proofAdded1 = wakuRlnRelay.appendRLNProof(wm1, time) proofAdded2 = wakuRlnRelay.appendRLNProof(wm2, time) - proofAdded3 = wakuRlnRelay.appendRLNProof(wm3, time+EpochUnitSeconds) + proofAdded3 = wakuRlnRelay.appendRLNProof(wm3, time+float64(wakuRlnRelay.rlnEpochSizeSec)) # ensure proofs are added require: diff --git a/tests/waku_rln_relay/test_wakunode_rln_relay.nim b/tests/waku_rln_relay/test_wakunode_rln_relay.nim index c57a68b83..719ded6c8 100644 --- a/tests/waku_rln_relay/test_wakunode_rln_relay.nim +++ b/tests/waku_rln_relay/test_wakunode_rln_relay.nim @@ -41,6 +41,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node1.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode"), )) @@ -51,6 +52,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node2.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(2.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_2"), )) @@ -61,6 +63,7 @@ procSuite "WakuNode - RLN relay": await node3.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(3.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_3"), )) @@ -122,6 +125,7 @@ procSuite "WakuNode - RLN relay": for index, node in nodes: await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(index.uint + 1), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_" & $(index+1)))) # start them @@ -200,6 +204,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node1.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_4"), )) @@ -210,6 +215,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node2.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(2.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_5"), )) @@ -220,6 +226,7 @@ procSuite "WakuNode - RLN relay": await node3.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(3.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_6"), )) @@ -244,7 +251,7 @@ procSuite "WakuNode - RLN relay": let payload = "Hello".toBytes() # prepare the epoch - let epoch = getCurrentEpoch() + let epoch = node1.wakuRlnRelay.getCurrentEpoch() # prepare the proof let @@ -299,6 +306,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node1.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_7"), )) @@ -310,6 +318,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node2.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(2.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_8"), )) @@ -321,6 +330,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node3.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(3.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_9"), )) @@ -341,7 +351,7 @@ procSuite "WakuNode - RLN relay": proofAdded2 = node3.wakuRlnRelay.appendRLNProof(wm2, time) # wm3 points to the next epoch wm3 = WakuMessage(payload: "message 3".toBytes(), contentTopic: contentTopic) - proofAdded3 = node3.wakuRlnRelay.appendRLNProof(wm3, time+EpochUnitSeconds) + proofAdded3 = node3.wakuRlnRelay.appendRLNProof(wm3, time+float64(node3.wakuRlnRelay.rlnEpochSizeSec)) wm4 = WakuMessage(payload: "message 4".toBytes(), contentTopic: contentTopic) # check proofs are added correctly @@ -419,6 +429,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node1.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_10"), )) @@ -430,6 +441,7 @@ procSuite "WakuNode - RLN relay": # mount rlnrelay in off-chain mode await node2.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(2.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_11"), )) @@ -448,7 +460,7 @@ procSuite "WakuNode - RLN relay": proofAdded2 = node1.wakuRlnRelay.appendRLNProof(wm2, time) # wm3 points to the next epoch wm3 = WakuMessage(payload: "message 3".toBytes(), contentTopic: contentTopic) - proofAdded3 = node1.wakuRlnRelay.appendRLNProof(wm3, time + EpochUnitSeconds * 2) + proofAdded3 = node1.wakuRlnRelay.appendRLNProof(wm3, time + float64(node1.wakuRlnRelay.rlnEpochSizeSec * 2)) # check proofs are added correctly check: diff --git a/tests/wakunode_jsonrpc/test_jsonrpc_relay.nim b/tests/wakunode_jsonrpc/test_jsonrpc_relay.nim index d62589b47..d5c55dd7d 100644 --- a/tests/wakunode_jsonrpc/test_jsonrpc_relay.nim +++ b/tests/wakunode_jsonrpc/test_jsonrpc_relay.nim @@ -94,10 +94,12 @@ suite "Waku v2 JSON-RPC API - Relay": await srcNode.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))) await dstNode.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(2.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_2"))) await srcNode.connectToNodes(@[dstNode.peerInfo.toRemotePeerInfo()]) diff --git a/tests/wakunode_rest/test_rest_health.nim b/tests/wakunode_rest/test_rest_health.nim index d5d8f29f5..9560384a0 100644 --- a/tests/wakunode_rest/test_rest_health.nim +++ b/tests/wakunode_rest/test_rest_health.nim @@ -62,6 +62,7 @@ suite "Waku v2 REST API - health": # now kick in rln (currently the only check for health) await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode"), )) diff --git a/tests/wakunode_rest/test_rest_relay.nim b/tests/wakunode_rest/test_rest_relay.nim index 5c64faad7..0e0f40424 100644 --- a/tests/wakunode_rest/test_rest_relay.nim +++ b/tests/wakunode_rest/test_rest_relay.nim @@ -210,6 +210,7 @@ suite "Waku v2 Rest API - Relay": await node.mountRelay() await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))) # RPC server setup @@ -412,6 +413,7 @@ suite "Waku v2 Rest API - Relay": await node.mountRelay() await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))) # RPC server setup @@ -456,6 +458,7 @@ suite "Waku v2 Rest API - Relay": await node.mountRelay() await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))) # RPC server setup @@ -495,6 +498,7 @@ suite "Waku v2 Rest API - Relay": await node.mountRelay() await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))) # RPC server setup @@ -539,6 +543,7 @@ suite "Waku v2 Rest API - Relay": await node.mountRelay() await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false, rlnRelayCredIndex: some(1.uint), + rlnEpochSizeSec: 1, rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))) # RPC server setup diff --git a/waku/waku_rln_relay/constants.nim b/waku/waku_rln_relay/constants.nim index 7087ad390..465a56d56 100644 --- a/waku/waku_rln_relay/constants.nim +++ b/waku/waku_rln_relay/constants.nim @@ -59,12 +59,8 @@ const # the root is created locally, using createMembershipList proc from waku_rln_relay_utils module, and the result is hardcoded in here StaticGroupMerkleRoot* = "1e534adab58f7d300aaeecae57a25e0a0b18c368a09f720280da92b288950901" -const EpochUnitSeconds* = float64(1) # the rln-relay epoch length in seconds const MaxClockGapSeconds* = 20.0 # the maximum clock difference between peers in seconds -# maximum allowed gap between the epochs of messages' RateLimitProofs -const MaxEpochGap* = uint64(MaxClockGapSeconds/EpochUnitSeconds) - # RLN Keystore defaults const RLNAppInfo* = AppInfo(application: "waku-rln-relay", appIdentifier: "01234567890abcdef", version: "0.2") diff --git a/waku/waku_rln_relay/nonce_manager.nim b/waku/waku_rln_relay/nonce_manager.nim index 6a0f34b07..fbba55e69 100644 --- a/waku/waku_rln_relay/nonce_manager.nim +++ b/waku/waku_rln_relay/nonce_manager.nim @@ -43,9 +43,9 @@ proc `$`*(ne: NonceManagerError): string = of NonceLimitReached: return "NonceLimitReached: " & ne.error -proc init*(T: type NonceManager, nonceLimit: Nonce, epoch = EpochUnitSeconds): T = +proc init*(T: type NonceManager, nonceLimit: Nonce): T = return NonceManager( - epoch: epoch, + epoch: 0, nextNonce: 0, lastNonceTime: 0, nonceLimit: nonceLimit diff --git a/waku/waku_rln_relay/rln_relay.nim b/waku/waku_rln_relay/rln_relay.nim index b1f885993..42d1644fb 100644 --- a/waku/waku_rln_relay/rln_relay.nim +++ b/waku/waku_rln_relay/rln_relay.nim @@ -43,6 +43,7 @@ type rlnRelayCredPath*: string rlnRelayCredPassword*: string rlnRelayTreePath*: string + rlnEpochSizeSec*: uint64 onFatalErrorAction*: OnFatalErrorHandler when defined(rln_v2): rlnRelayUserMessageLimit*: uint64 @@ -76,21 +77,23 @@ proc createMembershipList*(rln: ptr RLN, n: int): RlnRelayResult[( let root = rln.getMerkleRoot().value().inHex() return ok((output, root)) -proc calcEpoch*(t: float64): Epoch = - ## gets time `t` as `flaot64` with subseconds resolution in the fractional part - ## and returns its corresponding rln `Epoch` value - let e = uint64(t/EpochUnitSeconds) - return toEpoch(e) - type WakuRLNRelay* = ref object of RootObj # the log of nullifiers and Shamir shares of the past messages grouped per epoch nullifierLog*: OrderedTable[Epoch, seq[ProofMetadata]] lastEpoch*: Epoch # the epoch of the last published rln message + rlnEpochSizeSec*: uint64 + rlnMaxEpochGap*: uint64 groupManager*: GroupManager onFatalErrorAction*: OnFatalErrorHandler when defined(rln_v2): nonceManager: NonceManager +proc calcEpoch*(rlnPeer: WakuRLNRelay, t: float64): Epoch = + ## gets time `t` as `flaot64` with subseconds resolution in the fractional part + ## and returns its corresponding rln `Epoch` value + let e = uint64(t/rlnPeer.rlnEpochSizeSec.float64) + return toEpoch(e) + proc stop*(rlnPeer: WakuRLNRelay) {.async: (raises: [Exception]).} = ## stops the rln-relay protocol ## Throws an error if it cannot stop the rln-relay protocol @@ -153,9 +156,9 @@ proc updateLog*(rlnPeer: WakuRLNRelay, except KeyError as e: return err("the external nullifier was not found") # should never happen -proc getCurrentEpoch*(): Epoch = +proc getCurrentEpoch*(rlnPeer: WakuRLNRelay): Epoch = ## gets the current rln Epoch time - return calcEpoch(epochTime()) + return rlnPeer.calcEpoch(epochTime()) proc absDiff*(e1, e2: Epoch): uint64 = ## returns the absolute difference between the two rln `Epoch`s `e1` and `e2` @@ -195,10 +198,10 @@ proc validateMessage*(rlnPeer: WakuRLNRelay, # it corresponds to the validation of rln external nullifier var epoch: Epoch if timeOption.isSome(): - epoch = calcEpoch(timeOption.get()) + epoch = rlnPeer.calcEpoch(timeOption.get()) else: # get current rln epoch - epoch = getCurrentEpoch() + epoch = rlnPeer.getCurrentEpoch() let msgEpoch = proof.epoch @@ -208,7 +211,7 @@ proc validateMessage*(rlnPeer: WakuRLNRelay, trace "epoch info", currentEpoch = fromEpoch(epoch), msgEpoch = fromEpoch(msgEpoch) # validate the epoch - if gap > MaxEpochGap: + if gap > rlnPeer.rlnMaxEpochGap: # message's epoch is too old or too ahead # accept messages whose epoch is within +-MaxEpochGap from the current epoch warn "invalid message: epoch gap exceeds a threshold", gap = gap, @@ -300,7 +303,7 @@ proc appendRLNProof*(rlnPeer: WakuRLNRelay, ## The `epoch` field of `RateLimitProof` is derived from the provided `senderEpochTime` (using `calcEpoch()`) let input = msg.toRLNSignal() - let epoch = calcEpoch(senderEpochTime) + let epoch = rlnPeer.calcEpoch(senderEpochTime) when defined(rln_v2): let nonce = rlnPeer.nonceManager.get().valueOr: @@ -318,11 +321,11 @@ proc clearNullifierLog(rlnPeer: WakuRlnRelay) = # clear the first MaxEpochGap epochs of the nullifer log # if more than MaxEpochGap epochs are in the log # note: the epochs are ordered ascendingly - if rlnPeer.nullifierLog.len().uint < MaxEpochGap: + if rlnPeer.nullifierLog.len().uint < rlnPeer.rlnMaxEpochGap: return - trace "clearing epochs from the nullifier log", count = MaxEpochGap - let epochsToClear = rlnPeer.nullifierLog.keys().toSeq()[0..