From acb6f598c3320eab43112d9dd9c5b7734fac6e7d Mon Sep 17 00:00:00 2001 From: staheri14 Date: Sat, 5 Feb 2022 00:25:12 +0000 Subject: [PATCH] deploy: 5a77d6e2a641616d62c778da2d8937ecb25644d7 --- CHANGELOG.md | 19 ++++++ examples/v2/chat2.nim | 61 +++++++++++++++++-- examples/v2/config_chat2.nim | 32 +++++++--- tests/v2/test_waku_rln_relay.nim | 17 +++++- tests/v2/test_wakunode.nim | 57 +++++++++-------- .../vendor/libbacktrace-upstream/libtool | 2 +- waku/v2/node/config.nim | 10 ++- waku/v2/node/wakunode2.nim | 36 ++++++----- .../waku_rln_relay/waku_rln_relay_types.nim | 3 + .../waku_rln_relay/waku_rln_relay_utils.nim | 8 ++- 10 files changed, 187 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c97cda9..27437ad3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## Next Release +Release highlights: + +- + +The full list of changes is below. + +### Features + +- The `waku-rln-relay` now supports spam-protection for a specific combination of `pubsubTopic` and `contentTopic` (available under the `rln` compiler flag). +- The `waku-rln-relay` protocol in integrated into `chat2` (available under the`rln` compiler flag) + +### Changes + +- ... +### Fixes + +- ... + ## 2021-01-19 v0.7 Release highlights: diff --git a/examples/v2/chat2.nim b/examples/v2/chat2.nim index f1de1361b..3fc843877 100644 --- a/examples/v2/chat2.nim +++ b/examples/v2/chat2.nim @@ -27,6 +27,13 @@ import ../../waku/v2/node/[wakunode2, waku_payload], ../../waku/common/utils/nat, ./config_chat2 +when defined(rln): + import + libp2p/protocols/pubsub/rpc/messages, + libp2p/protocols/pubsub/pubsub, + web3, + ../../waku/v2/protocol/waku_rln_relay/[rln, waku_rln_relay_utils] + const Help = """ Commands: /[?|help|connect|nick|exit] help: Prints this help @@ -191,7 +198,8 @@ proc readNick(transp: StreamTransport): Future[string] {.async.} = proc publish(c: Chat, line: string) = # First create a Chat2Message protobuf with this line of text - let chat2pb = Chat2Message(timestamp: getTime().toUnix(), + let time = getTime().toUnix() + let chat2pb = Chat2Message(timestamp: time, nick: c.nick, payload: line.toBytes()).encode() @@ -206,8 +214,17 @@ proc publish(c: Chat, line: string) = version = 1'u32 encodedPayload = payload.encode(version, c.node.rng[]) if encodedPayload.isOk(): - let message = WakuMessage(payload: encodedPayload.get(), + var message = WakuMessage(payload: encodedPayload.get(), contentTopic: c.contentTopic, version: version) + when defined(rln): + if not isNil(c.node.wakuRlnRelay): + # for future version when we support more than one rln protected content topic, + # we should check the message content topic as well + let success = c.node.wakuRlnRelay.appendRLNProof(message, float64(time)) + if not success: + debug "could not append rate limit proof to the message", success=success + else: + debug "rate limit proof is appended to the message", success=success if not c.node.wakuLightPush.isNil(): # Attempt lightpush asyncSpawn c.node.lightpush(DefaultTopic, message, handler) @@ -217,8 +234,18 @@ proc publish(c: Chat, line: string) = warn "Payload encoding failed", error = encodedPayload.error else: # No payload encoding/encryption from Waku - let message = WakuMessage(payload: chat2pb.buffer, + var message = WakuMessage(payload: chat2pb.buffer, contentTopic: c.contentTopic, version: 0) + when defined(rln): + if not isNil(c.node.wakuRlnRelay): + # for future version when we support more than one rln protected content topic, + # we should check the message content topic as well + let success = c.node.wakuRlnRelay.appendRLNProof(message, float64(time)) + if not success: + debug "could not append rate limit proof to the message", success=success + else: + debug "rate limit proof is appended to the message", success=success + if not c.node.wakuLightPush.isNil(): # Attempt lightpush asyncSpawn c.node.lightpush(DefaultTopic, message, handler) @@ -326,7 +353,6 @@ proc processInput(rfd: AsyncFD, rng: ref BrHmacDrbgContext) {.async.} = wsBindPort = Port(uint16(conf.websocketPort) + conf.portsShift), wsEnabled = conf.websocketSupport, wssEnabled = conf.websocketSecureSupport) - await node.start() node.mountRelay(conf.topics.split(" "), @@ -465,6 +491,33 @@ proc processInput(rfd: AsyncFD, rng: ref BrHmacDrbgContext) {.async.} = let topic = cast[Topic](DefaultTopic) node.subscribe(topic, handler) + when defined(rln): + if conf.rlnRelay: + info "WakuRLNRelay is enabled" + + # set up rln relay inputs + let (groupOpt, memKeyPairOpt, memIndexOpt) = rlnRelaySetUp(conf.rlnRelayMemIndex) + if memIndexOpt.isNone: + error "failed to mount WakuRLNRelay" + else: + # mount rlnrelay in offline mode (for now) + waitFor node.mountRlnRelay(groupOpt = groupOpt, memKeyPairOpt = memKeyPairOpt, memIndexOpt= memIndexOpt, onchainMode = false, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic) + + trace "membership id key", idkey=memKeyPairOpt.get().idKey.toHex + trace "membership id commitment key", idCommitmentkey=memKeyPairOpt.get().idCommitment.toHex + + # 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 + # TODO have added this check to account for unseen corner cases, will remove it later + let + root = node.wakuRlnRelay.rlnInstance.getMerkleRoot.value.toHex() + expectedRoot = STATIC_GROUP_MERKLE_ROOT + if root != expectedRoot: + error "root mismatch: something went wrong not in Merkle tree construction" + trace "the calculated root", root + trace "WakuRLNRelay is mounted successfully", pubsubtopic=conf.rlnRelayPubsubTopic, contentTopic=conf.rlnRelayContentTopic + + await chat.readWriteLoop() if conf.keepAlive: diff --git a/examples/v2/config_chat2.nim b/examples/v2/config_chat2.nim index 7519afcfc..75fb33183 100644 --- a/examples/v2/config_chat2.nim +++ b/examples/v2/config_chat2.nim @@ -5,8 +5,9 @@ import libp2p/crypto/crypto, libp2p/crypto/secp, nimcrypto/utils, - eth/keys - + eth/keys, + ../../waku/v2/protocol/waku_rln_relay/waku_rln_relay_types, + ../../waku/v2/protocol/waku_message type Fleet* = enum none @@ -75,11 +76,6 @@ type defaultValue: true name: "relay" }: bool - rlnRelay* {. - desc: "Enable spam protection through rln-relay: true|false", - defaultValue: false - name: "rln-relay" }: bool - staticnodes* {. desc: "Peer multiaddr to directly connect with. Argument may be repeated." name: "staticnode" }: seq[string] @@ -231,6 +227,28 @@ type defaultValue: false name: "websocket-secure-support" }: bool + ## rln-relay configuration + + rlnRelay* {. + desc: "Enable spam protection through rln-relay: true|false", + defaultValue: false + name: "rln-relay" }: bool + + rlnRelayMemIndex* {. + desc: "(experimental) the index of node in the rln-relay group: a value between 0-99 inclusive", + defaultValue: MembershipIndex(0) + name: "rln-relay-membership-index" }: MembershipIndex + + rlnRelayContentTopic* {. + desc: "the pubsub topic for which rln-relay gets enabled", + defaultValue: "waku/2/rln-relay/proto" + name: "rln-relay-content-topic" }: ContentTopic + + rlnRelayPubsubTopic* {. + desc: "the pubsub topic for which rln-relay gets enabled", + defaultValue: "/waku/2/default-waku/proto" + name: "rln-relay-pubsub-topic" }: string + # NOTE: Keys are different in nim-libp2p proc parseCmdArg*(T: type crypto.PrivateKey, p: TaintedString): T = try: diff --git a/tests/v2/test_waku_rln_relay.nim b/tests/v2/test_waku_rln_relay.nim index 2b8655fa7..a26fe70a6 100644 --- a/tests/v2/test_waku_rln_relay.nim +++ b/tests/v2/test_waku_rln_relay.nim @@ -12,6 +12,7 @@ import ./test_utils const RLNRELAY_PUBSUB_TOPIC = "waku/2/rlnrelay/proto" +const RLNRELAY_CONTENT_TOPIC = "waku/2/rlnrelay/proto" # POSEIDON_HASHER_CODE holds the bytecode of Poseidon hasher solidity smart contract: # https://github.com/kilic/rlnapp/blob/master/packages/contracts/contracts/crypto/PoseidonHasher.sol @@ -250,7 +251,14 @@ procSuite "Waku rln relay": # start rln-relay node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC]) - await node.mountRlnRelay(ethClientAddrOpt = some(ETH_CLIENT), ethAccAddrOpt = some(ethAccountAddress), memContractAddOpt = some(membershipContractAddress), groupOpt = some(group), memKeyPairOpt = some(keypair.get()), memIndexOpt = some(index), pubsubTopic = RLNRELAY_PUBSUB_TOPIC) + await node.mountRlnRelay(ethClientAddrOpt = some(EthClient), + ethAccAddrOpt = some(ethAccountAddress), + memContractAddOpt = some(membershipContractAddress), + groupOpt = some(group), + memKeyPairOpt = some(keypair.get()), + memIndexOpt = some(index), + pubsubTopic = RLNRELAY_PUBSUB_TOPIC, + contentTopic = RLNRELAY_CONTENT_TOPIC) let calculatedRoot = node.wakuRlnRelay.rlnInstance.getMerkleRoot().value().toHex debug "calculated root ", calculatedRoot @@ -286,7 +294,12 @@ procSuite "Waku rln relay": # -------- mount rln-relay in the off-chain mode node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC]) - await node.mountRlnRelay(groupOpt = some(groupIDCommitments), memKeyPairOpt = some(groupKeyPairs[index]), memIndexOpt = some(index), onchainMode = false, pubsubTopic = RLNRELAY_PUBSUB_TOPIC) + await node.mountRlnRelay(groupOpt = some(groupIDCommitments), + memKeyPairOpt = some(groupKeyPairs[index]), + memIndexOpt = some(index), + onchainMode = false, + pubsubTopic = RLNRELAY_PUBSUB_TOPIC, + contentTopic = RLNRELAY_CONTENT_TOPIC) # get the root of Merkle tree which is constructed inside the mountRlnRelay proc let calculatedRoot = node.wakuRlnRelay.rlnInstance.getMerkleRoot().value().toHex diff --git a/tests/v2/test_wakunode.nim b/tests/v2/test_wakunode.nim index f9ed67d06..2ed780e20 100644 --- a/tests/v2/test_wakunode.nim +++ b/tests/v2/test_wakunode.nim @@ -2,6 +2,7 @@ import testutils/unittests, + std/sequtils, chronicles, chronos, stew/shims/net as stewNet, stew/byteutils, std/os, libp2p/crypto/crypto, libp2p/crypto/secp, @@ -617,7 +618,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt1, memIndexOpt= memIndexOpt1, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node1.start() # node 2 @@ -628,7 +630,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt2, memIndexOpt= memIndexOpt2, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node2.start() # node 3 @@ -639,7 +642,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt3, memIndexOpt= memIndexOpt3, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node3.start() # connect them together @@ -663,19 +667,11 @@ procSuite "WakuNode": let payload = "Hello".toBytes() # prepare the epoch - let epoch = getCurrentEpoch() + let epoch = getCurrentEpoch() - # prepare the proof - let rateLimitProofRes = node1.wakuRlnRelay.rlnInstance.proofGen(data = payload, - memKeys = node1.wakuRlnRelay.membershipKeyPair, - memIndex = node1.wakuRlnRelay.membershipIndex, - epoch = epoch) - doAssert(rateLimitProofRes.isOk()) - let rateLimitProof = rateLimitProofRes.value - - let message = WakuMessage(payload: @payload, - contentTopic: contentTopic, - proof: rateLimitProof) + var message = WakuMessage(payload: @payload, + contentTopic: contentTopic) + doAssert(node1.wakuRlnRelay.appendRLNProof(message, epochTime())) ## node1 publishes a message with a rate limit proof, the message is then relayed to node2 which in turn @@ -715,7 +711,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt1, memIndexOpt= memIndexOpt1, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node1.start() # node 2 @@ -726,7 +723,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt2, memIndexOpt= memIndexOpt2, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node2.start() # node 3 @@ -737,7 +735,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt3, memIndexOpt= memIndexOpt3, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node3.start() # connect them together @@ -765,7 +764,10 @@ procSuite "WakuNode": let epoch = getCurrentEpoch() # prepare the proof - let rateLimitProofRes = node1.wakuRlnRelay.rlnInstance.proofGen(data = payload, + let + contentTopicBytes = contentTopic.toBytes + input = concat(payload, contentTopicBytes) + rateLimitProofRes = node1.wakuRlnRelay.rlnInstance.proofGen(data = input, memKeys = node1.wakuRlnRelay.membershipKeyPair, memIndex = MembershipIndex(4), epoch = epoch) @@ -817,7 +819,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt1, memIndexOpt= memIndexOpt1, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node1.start() # node 2 @@ -828,7 +831,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt2, memIndexOpt= memIndexOpt2, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node2.start() # node 3 @@ -839,7 +843,8 @@ procSuite "WakuNode": memKeyPairOpt = memKeyPairOpt3, memIndexOpt= memIndexOpt3, onchainMode = false, - pubsubTopic = rlnRelayPubSubTopic) + pubsubTopic = rlnRelayPubSubTopic, + contentTopic = contentTopic) await node3.start() # connect the nodes together node1 <-> node2 <-> node3 @@ -850,15 +855,15 @@ procSuite "WakuNode": let time = epochTime() # create some messages with rate limit proofs var - wm1 = WakuMessage(payload: "message 1".toBytes()) + wm1 = WakuMessage(payload: "message 1".toBytes(), contentTopic: contentTopic) proofAdded1 = node3.wakuRlnRelay.appendRLNProof(wm1, time) # another message in the same epoch as wm1, it will break the messaging rate limit - wm2 = WakuMessage(payload: "message2".toBytes()) + wm2 = WakuMessage(payload: "message2".toBytes(), contentTopic: contentTopic) proofAdded2 = node3.wakuRlnRelay.appendRLNProof(wm2, time) # wm3 points to the next epoch - wm3 = WakuMessage(payload: "message 3".toBytes()) + wm3 = WakuMessage(payload: "message 3".toBytes(), contentTopic: contentTopic) proofAdded3 = node3.wakuRlnRelay.appendRLNProof(wm3, time+EPOCH_UNIT_SECONDS) - wm4 = WakuMessage(payload: "message4".toBytes()) + wm4 = WakuMessage(payload: "message4".toBytes(), contentTopic: contentTopic) # check proofs are added correctly check: diff --git a/vendor/nim-libbacktrace/vendor/libbacktrace-upstream/libtool b/vendor/nim-libbacktrace/vendor/libbacktrace-upstream/libtool index 1d68b6b2e..ea6e4c81f 100755 --- a/vendor/nim-libbacktrace/vendor/libbacktrace-upstream/libtool +++ b/vendor/nim-libbacktrace/vendor/libbacktrace-upstream/libtool @@ -2,7 +2,7 @@ # libtool - Provide generalized library-building support services. # Generated automatically by config.status (libbacktrace) version-unused -# Libtool was configured on host fv-az129-248: +# Libtool was configured on host fv-az190-627: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, diff --git a/waku/v2/node/config.nim b/waku/v2/node/config.nim index 2bd283e16..cd6a239bd 100644 --- a/waku/v2/node/config.nim +++ b/waku/v2/node/config.nim @@ -6,7 +6,8 @@ import libp2p/crypto/secp, nimcrypto/utils, eth/keys, - ../protocol/waku_rln_relay/[waku_rln_relay_types] + ../protocol/waku_rln_relay/waku_rln_relay_types, + ../protocol/waku_message type WakuNodeConf* = object @@ -83,8 +84,13 @@ type rlnRelayPubsubTopic* {. desc: "the pubsub topic for which rln-relay gets enabled", - defaultValue: "waku/2/rlnrelay/proto" + defaultValue: "/waku/2/default-waku/proto" name: "rln-relay-pubsub-topic" }: string + + rlnRelayContentTopic* {. + desc: "the pubsub topic for which rln-relay gets enabled", + defaultValue: "/toy-chat/2/huilong/proto" + name: "rln-relay-content-topic" }: ContentTopic staticnodes* {. desc: "Peer multiaddr to directly connect with. Argument may be repeated." diff --git a/waku/v2/node/wakunode2.nim b/waku/v2/node/wakunode2.nim index 67dd16630..6b18cb155 100644 --- a/waku/v2/node/wakunode2.nim +++ b/waku/v2/node/wakunode2.nim @@ -468,26 +468,30 @@ proc mountStore*(node: WakuNode, store: MessageStore = nil, persistMessages: boo node.switch.mount(node.wakuStore, protocolMatcher(WakuStoreCodec)) when defined(rln): - proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: string) = + proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: string, contentTopic: ContentTopic) = ## this procedure is a thin wrapper for the pubsub addValidator method - ## it sets message validator on the given pubsubTopic, the validator will check that - ## all the messages published in the pubsubTopic have a valid zero-knowledge proof + ## 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 + ## the message validation logic is according to https://rfc.vac.dev/spec/17/ proc validator(topic: string, message: messages.Message): Future[pubsub.ValidationResult] {.async.} = let msg = WakuMessage.init(message.data) if msg.isOk(): - let - wakumessage = msg.value() - # validate the message - validationRes = node.wakuRlnRelay.validateMessage(wakumessage) + let wakumessage = msg.value() + # check the contentTopic + if (wakumessage.contentTopic != "") and (contentTopic != "") and (wakumessage.contentTopic != contentTopic): + trace "content topic did not match:", contentTopic=wakumessage.contentTopic, payload=string.fromBytes(wakumessage.payload) + return pubsub.ValidationResult.Accept + # validate the message + let validationRes = node.wakuRlnRelay.validateMessage(wakumessage) case validationRes: of Valid: - info "message validity is verified, relaying:", wakumessage=wakumessage + trace "message validity is verified, relaying:", wakumessage=wakumessage, payload=string.fromBytes(wakumessage.payload) return pubsub.ValidationResult.Accept of Invalid: - info "message validity could not be verified, discarding:", wakumessage=wakumessage + trace "message validity could not be verified, discarding:", wakumessage=wakumessage, payload=string.fromBytes(wakumessage.payload) return pubsub.ValidationResult.Reject of Spam: - info "A spam message is found! yay! discarding:", wakumessage=wakumessage + trace "A spam message is found! yay! discarding:", wakumessage=wakumessage, payload=string.fromBytes(wakumessage.payload) return pubsub.ValidationResult.Reject # set a validator for the supplied pubsubTopic let pb = PubSub(node.wakuRelay) @@ -501,7 +505,8 @@ when defined(rln): memKeyPairOpt: Option[MembershipKeyPair] = none(MembershipKeyPair), memIndexOpt: Option[MembershipIndex] = none(MembershipIndex), onchainMode: bool = true, - pubsubTopic: string) {.async.} = + pubsubTopic: string, + contentTopic: ContentTopic) {.async.} = # TODO return a bool value to indicate the success of the call # check whether inputs are provided @@ -581,7 +586,8 @@ when defined(rln): ethClientAddress: ethClientAddr, ethAccountAddress: ethAccAddr, rlnInstance: rln, - pubsubTopic: pubsubTopic) + pubsubTopic: pubsubTopic, + contentTopic: contentTopic) if onchainMode: # register the rln-relay peer to the membership contract @@ -593,7 +599,7 @@ when defined(rln): # adds a topic validator for the supplied pubsub topic at the relay protocol # messages published on this pubsub topic will be relayed upon a successful validation, otherwise they will be dropped # the topic validator checks for the correct non-spamming proof of the message - addRLNRelayValidator(node, pubsubTopic) + addRLNRelayValidator(node, pubsubTopic, contentTopic) debug "rln relay topic validator is mounted successfully", pubsubTopic=pubsubTopic node.wakuRlnRelay = rlnPeer @@ -1071,7 +1077,7 @@ when isMainModule: error "failed to mount WakuRLNRelay" else: # mount rlnrelay in offline mode (for now) - waitFor node.mountRlnRelay(groupOpt = groupOpt, memKeyPairOpt = memKeyPairOpt, memIndexOpt= memIndexOpt, onchainMode = false, pubsubTopic = conf.rlnRelayPubsubTopic) + waitFor node.mountRlnRelay(groupOpt = groupOpt, memKeyPairOpt = memKeyPairOpt, memIndexOpt= memIndexOpt, onchainMode = false, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic) info "membership id key", idkey=memKeyPairOpt.get().idKey.toHex info "membership id commitment key", idCommitmentkey=memKeyPairOpt.get().idCommitment.toHex @@ -1085,7 +1091,7 @@ when isMainModule: if root != expectedRoot: error "root mismatch: something went wrong not in Merkle tree construction" debug "the calculated root", root - info "WakuRLNRelay is mounted successfully", pubsubtopic=conf.rlnRelayPubsubTopic + info "WakuRLNRelay is mounted successfully", pubsubtopic=conf.rlnRelayPubsubTopic, contentTopic=conf.rlnRelayContentTopic if conf.swap: mountSwap(node) diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim index 9d38d4155..131577b6b 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim @@ -77,6 +77,9 @@ type WakuRLNRelay* = ref object ethAccountPrivateKey*: Option[PrivateKey] rlnInstance*: RLN[Bn256] pubsubTopic*: string # the pubsub topic for which rln relay is mounted + # contentTopic should be of type waku_message.ContentTopic, however, due to recursive module dependency, the underlying type of ContentTopic is used instead + # TODO a long-term solution is to place types with recursive dependency inside one file + contentTopic*: string # the log of nullifiers and Shamir shares of the past messages grouped per epoch nullifierLog*: Table[Epoch, seq[ProofMetadata]] diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim index 031623be1..59c232ebd 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim @@ -454,16 +454,22 @@ proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage, timeOption: Optio if abs(gap) >= MAX_EPOCH_GAP: # message's epoch is too old or too ahead # accept messages whose epoch is within +-MAX_EPOCH_GAP from the current epoch + debug "invalid message: epoch gap exceeds a threshold",gap=gap return MessageValidationResult.Invalid # verify the proof - if not rlnPeer.rlnInstance.proofVerify(msg.payload, msg.proof): + let + contentTopicBytes = msg.contentTopic.toBytes + input = concat(msg.payload, contentTopicBytes) + if not rlnPeer.rlnInstance.proofVerify(input, msg.proof): # invalid proof + debug "invalid message: invalid proof" return MessageValidationResult.Invalid # check if double messaging has happened let hasDup = rlnPeer.hasDuplicate(msg) if hasDup.isOk and hasDup.value == true: + debug "invalid message: message is a spam" return MessageValidationResult.Spam # insert the message to the log