mirror of https://github.com/waku-org/nwaku.git
chore(rln-relay-v2): wakunode testing + improvements (#2501)
* chore(rln-relay-v2): additional testing * fix: bump librln to v0.4.2 for v2 * fix: catch possible error from the copyFrom * ci: rename step title for rln-version
This commit is contained in:
parent
097cb36279
commit
059cb97518
|
@ -55,11 +55,12 @@ jobs:
|
|||
if: ${{ needs.changes.outputs.v2 == 'true' || needs.changes.outputs.common == 'true' }}
|
||||
strategy:
|
||||
matrix:
|
||||
rln_version : [1, 2]
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60
|
||||
|
||||
name: build-${{ matrix.os }}
|
||||
name: build-${{ matrix.os }}-rln-v${{ matrix.rln_version }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
@ -78,18 +79,19 @@ jobs:
|
|||
key: ${{ runner.os }}-vendor-modules-${{ steps.submodules.outputs.hash }}
|
||||
|
||||
- name: Build binaries
|
||||
run: make V=1 QUICK_AND_DIRTY_COMPILER=1 all tools
|
||||
run: make RLN_V${{matrix.rln_version}}=true V=1 QUICK_AND_DIRTY_COMPILER=1 all tools
|
||||
|
||||
test:
|
||||
needs: changes
|
||||
if: ${{ needs.changes.outputs.v2 == 'true' || needs.changes.outputs.common == 'true' }}
|
||||
strategy:
|
||||
matrix:
|
||||
rln_version : [1, 2]
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60
|
||||
|
||||
name: test-${{ matrix.os }}
|
||||
name: test-${{ matrix.os }}-rln-v${{ matrix.rln_version }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
@ -118,7 +120,7 @@ jobs:
|
|||
sudo docker run --rm -d -e POSTGRES_PASSWORD=test123 -p 5432:5432 postgres:15.4-alpine3.18
|
||||
fi
|
||||
|
||||
make V=1 LOG_LEVEL=DEBUG QUICK_AND_DIRTY_COMPILER=1 POSTGRES=1 test testwakunode2
|
||||
make RLN_V${{matrix.rln_version}}=true V=1 LOG_LEVEL=DEBUG QUICK_AND_DIRTY_COMPILER=1 POSTGRES=1 test testwakunode2
|
||||
|
||||
build-docker-image:
|
||||
needs: changes
|
||||
|
|
|
@ -20,11 +20,12 @@ jobs:
|
|||
build-docker-image:
|
||||
strategy:
|
||||
matrix:
|
||||
rln_v2: [true, false]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60
|
||||
|
||||
name: docker-build-${{ matrix.os }}
|
||||
name: docker-build-${{ matrix.os }}-rln-v2-${{ matrix.rln_v2 }}
|
||||
outputs:
|
||||
image: ${{ steps.build.outputs.image }}
|
||||
steps:
|
||||
|
@ -48,12 +49,12 @@ jobs:
|
|||
id: build
|
||||
run: |
|
||||
|
||||
make -j${NPROC} V=1 QUICK_AND_DIRTY_COMPILER=1 NIMFLAGS="-d:disableMarchNative -d:postgres" wakunode2
|
||||
make RLN_V2=${{matrix.rln_v2}} -j${NPROC} V=1 QUICK_AND_DIRTY_COMPILER=1 NIMFLAGS="-d:disableMarchNative -d:postgres" wakunode2
|
||||
|
||||
SHORT_REF=$(git rev-parse --short HEAD)
|
||||
|
||||
TAG=$([ "${PR_NUMBER}" == "" ] && echo "${SHORT_REF}" || echo "${PR_NUMBER}")
|
||||
IMAGE=quay.io/wakuorg/nwaku-pr:${TAG}
|
||||
IMAGE=quay.io/wakuorg/nwaku-pr:${TAG}-rln-v2-${{matrix.rln_v2}}
|
||||
|
||||
echo "image=${IMAGE}" >> $GITHUB_OUTPUT
|
||||
echo "commit_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
||||
|
|
2
Makefile
2
Makefile
|
@ -135,7 +135,7 @@ clean: | clean-libbacktrace
|
|||
|
||||
LIBRLN_BUILDDIR := $(CURDIR)/vendor/zerokit
|
||||
ifeq ($(RLN_V2),true)
|
||||
LIBRLN_VERSION := v0.4.1
|
||||
LIBRLN_VERSION := v0.4.2
|
||||
else
|
||||
LIBRLN_VERSION := v0.3.6
|
||||
endif
|
||||
|
|
|
@ -80,9 +80,4 @@ import
|
|||
./wakunode_rest/test_rest_admin,
|
||||
./wakunode_rest/test_rest_cors
|
||||
|
||||
import
|
||||
./waku_rln_relay/test_waku_rln_relay,
|
||||
./waku_rln_relay/test_wakunode_rln_relay,
|
||||
./waku_rln_relay/test_rln_group_manager_onchain,
|
||||
./waku_rln_relay/test_rln_group_manager_static,
|
||||
./wakunode_rest/test_rest_health
|
||||
import ./waku_rln_relay/test_all
|
||||
|
|
|
@ -1,6 +1,30 @@
|
|||
import std/tempfiles
|
||||
|
||||
import ../../../waku/waku_rln_relay/[rln, protocol_types]
|
||||
import
|
||||
../../../waku/waku_rln_relay,
|
||||
../../../waku/waku_rln_relay/[rln, protocol_types]
|
||||
|
||||
proc createRLNInstanceWrapper*(): RLNResult =
|
||||
return createRlnInstance(tree_path = genTempPath("rln_tree", "waku_rln_relay"))
|
||||
|
||||
|
||||
proc unsafeAppendRLNProof*(rlnPeer: WakuRLNRelay,
|
||||
msg: var WakuMessage,
|
||||
senderEpochTime: float64): RlnRelayResult[void] =
|
||||
## this proc derived from appendRLNProof, does not perform nonce check to
|
||||
## facilitate bad message id generation for testing
|
||||
|
||||
let input = msg.toRLNSignal()
|
||||
let epoch = rlnPeer.calcEpoch(senderEpochTime)
|
||||
|
||||
when defined(rln_v2):
|
||||
# we do not fetch a nonce from the nonce manager,
|
||||
# instead we use 0 as the nonce
|
||||
let proof = rlnPeer.groupManager.generateProof(input, epoch, 0).valueOr:
|
||||
return err("could not generate rln-v2 proof: " & $error)
|
||||
else:
|
||||
let proof = rlnPeer.groupManager.generateProof(input, epoch).valueOr:
|
||||
return err("could not generate rln proof: " & $error)
|
||||
|
||||
msg.proof = proof.encode().buffer
|
||||
return ok()
|
|
@ -73,7 +73,7 @@ suite "RLN Relay v2: serde":
|
|||
userMessageLimit = rateCommitment.userMessageLimit,
|
||||
messageId = 0,
|
||||
index = 0,
|
||||
epoch = rln.calcEpoch(epochTime()))
|
||||
epoch = uint64(epochTime()/1.float64).toEpoch())
|
||||
|
||||
assert proofRes.isOk, $proofRes.error
|
||||
|
||||
|
|
|
@ -6,3 +6,6 @@ import
|
|||
./test_waku_rln_relay,
|
||||
./test_wakunode_rln_relay,
|
||||
./test_rln_nonce_manager
|
||||
|
||||
when defined(rln_v2):
|
||||
import ./rln_v2/test_rln_relay_v2_serde
|
||||
|
|
|
@ -18,34 +18,31 @@ suite "Nonce manager":
|
|||
|
||||
test "should generate a new nonce":
|
||||
let nm = NonceManager.init(nonceLimit = 100.uint)
|
||||
let nonceRes = nm.get()
|
||||
|
||||
assert nonceRes.isOk(), $nonceRes.error
|
||||
let nonce = nm.getNonce().valueOr:
|
||||
raiseAssert $error
|
||||
|
||||
check:
|
||||
nonceRes.get() == 0.uint
|
||||
nonce == 0.uint
|
||||
nm.nextNonce == 1.uint
|
||||
|
||||
test "should fail to generate a new nonce if limit is reached":
|
||||
let nm = NonceManager.init(nonceLimit = 1.uint)
|
||||
let nonceRes = nm.get()
|
||||
let nonceRes2 = nm.get()
|
||||
|
||||
assert nonceRes.isOk(), $nonceRes.error
|
||||
assert nonceRes2.isErr(), "Expected error, got: " & $nonceRes2.value
|
||||
let nonce = nm.getNonce().valueOr:
|
||||
raiseAssert $error
|
||||
let failedNonceRes = nm.getNonce()
|
||||
|
||||
check:
|
||||
nonceRes2.error.kind == NonceManagerErrorKind.NonceLimitReached
|
||||
failedNonceRes.isErr()
|
||||
failedNonceRes.error.kind == NonceManagerErrorKind.NonceLimitReached
|
||||
|
||||
test "should generate a new nonce if epoch is crossed":
|
||||
let nm = NonceManager.init(nonceLimit = 1.uint, epoch = float(0.000001))
|
||||
let nonceRes = nm.get()
|
||||
let nonce = nm.getNonce().valueOr:
|
||||
raiseAssert $error
|
||||
sleep(1)
|
||||
let nonceRes2 = nm.get()
|
||||
|
||||
assert nonceRes.isOk(), $nonceRes.error
|
||||
assert nonceRes2.isOk(), $nonceRes2.error
|
||||
let nonce2 = nm.getNonce().valueOr:
|
||||
raiseAssert $error
|
||||
|
||||
check:
|
||||
nonceRes.value == 0.uint
|
||||
nonceRes2.value == 0.uint
|
||||
nonce == 0.uint
|
||||
nonce2 == 0.uint
|
|
@ -518,18 +518,23 @@ suite "Waku rln relay":
|
|||
let rln = rlnInstance.get()
|
||||
|
||||
# create a Merkle tree
|
||||
when defined(rln_v2):
|
||||
let rateCommitments = groupIDCommitments.mapIt(RateCommitment(idCommitment: it,
|
||||
userMessageLimit: 20))
|
||||
let leaves = rateCommitments.toLeaves().valueOr:
|
||||
raiseAssert $error
|
||||
let membersAdded = rln.insertMembers(0, leaves)
|
||||
else:
|
||||
let membersAdded = rln.insertMembers(0, groupIDCommitments)
|
||||
require:
|
||||
membersAdded
|
||||
let rootRes = rln.getMerkleRoot()
|
||||
|
||||
require:
|
||||
rootRes.isOk()
|
||||
assert membersAdded, "members should be added"
|
||||
let rawRoot = rln.getMerkleRoot().valueOr:
|
||||
raiseAssert $error
|
||||
|
||||
let root = rootRes.get().inHex()
|
||||
let root = rawRoot.inHex()
|
||||
|
||||
debug "groupIdCredentials", groupIdCredentials
|
||||
debug "groupIDCommitments", groupIDCommitments
|
||||
debug "groupIDCommitments", groupIDCommitments = groupIDCommitments.mapIt(it.inHex())
|
||||
debug "root", root
|
||||
|
||||
check:
|
||||
|
@ -597,8 +602,8 @@ suite "Waku rln relay":
|
|||
|
||||
test "updateLog and hasDuplicate tests":
|
||||
let
|
||||
wakurlnrelay = WakuRLNRelay()
|
||||
epoch = wakurlnrelay.getCurrentEpoch()
|
||||
wakuRlnRelay = WakuRLNRelay()
|
||||
epoch = wakuRlnRelay.getCurrentEpoch()
|
||||
|
||||
# create some dummy nullifiers and secret shares
|
||||
var nullifier1: Nullifier
|
||||
|
@ -640,37 +645,44 @@ suite "Waku rln relay":
|
|||
|
||||
# check whether hasDuplicate correctly finds records with the same nullifiers but different secret shares
|
||||
# no duplicate for proof1 should be found, since the log is empty
|
||||
let result1 = wakurlnrelay.hasDuplicate(epoch, proof1.extractMetadata().tryGet())
|
||||
assert result1.isOk(), $result1.error
|
||||
assert result1.value == false, "no duplicate should be found"
|
||||
let proofMetadata1 = proof1.extractMetadata().tryGet()
|
||||
let isDuplicate1 = wakuRlnRelay.hasDuplicate(epoch, proofMetadata1).valueOr:
|
||||
raiseAssert $error
|
||||
assert isDuplicate1 == false, "no duplicate should be found"
|
||||
# add it to the log
|
||||
discard wakurlnrelay.updateLog(epoch, proof1.extractMetadata().tryGet())
|
||||
discard wakuRlnRelay.updateLog(epoch, proofMetadata1)
|
||||
|
||||
# no duplicate for proof2 should be found, its nullifier differs from proof1
|
||||
let result2 = wakurlnrelay.hasDuplicate(epoch, proof2.extractMetadata().tryGet())
|
||||
assert result2.isOk(), $result2.error
|
||||
let proofMetadata2 = proof2.extractMetadata().tryGet()
|
||||
let isDuplicate2 = wakuRlnRelay.hasDuplicate(epoch, proofMetadata2).valueOr:
|
||||
raiseAssert $error
|
||||
# no duplicate is found
|
||||
assert result2.value == false, "no duplicate should be found"
|
||||
assert isDuplicate2 == false, "no duplicate should be found"
|
||||
# add it to the log
|
||||
discard wakurlnrelay.updateLog(epoch, proof2.extractMetadata().tryGet())
|
||||
discard wakuRlnRelay.updateLog(epoch, proofMetadata2)
|
||||
|
||||
# proof3 has the same nullifier as proof1 but different secret shares, it should be detected as duplicate
|
||||
let result3 = wakurlnrelay.hasDuplicate(epoch, proof3.extractMetadata().tryGet())
|
||||
assert result3.isOk(), $result3.error
|
||||
let isDuplicate3 = wakuRlnRelay.hasDuplicate(epoch, proof3.extractMetadata().tryGet()).valueOr:
|
||||
raiseAssert $error
|
||||
# it is a duplicate
|
||||
assert result3.value, "duplicate should be found"
|
||||
assert isDuplicate3, "duplicate should be found"
|
||||
|
||||
asyncTest "validateMessageAndUpdateLog test":
|
||||
let index = MembershipIndex(5)
|
||||
|
||||
let rlnConf = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(index),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_2"))
|
||||
else:
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(index),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_2"))
|
||||
let wakuRlnRelayRes = await WakuRlnRelay.new(rlnConf)
|
||||
require:
|
||||
wakuRlnRelayRes.isOk()
|
||||
let wakuRlnRelay = wakuRlnRelayRes.get()
|
||||
let wakuRlnRelay = (await WakuRlnRelay.new(wakuRlnConfig)).valueOr:
|
||||
raiseAssert $error
|
||||
|
||||
# get the current epoch time
|
||||
let time = epochTime()
|
||||
|
@ -684,16 +696,12 @@ suite "Waku rln relay":
|
|||
wm3 = WakuMessage(payload: "Valid message".toBytes())
|
||||
wm4 = WakuMessage(payload: "Invalid message".toBytes())
|
||||
|
||||
let
|
||||
proofAdded1 = wakuRlnRelay.appendRLNProof(wm1, time)
|
||||
proofAdded2 = wakuRlnRelay.appendRLNProof(wm2, time)
|
||||
proofAdded3 = wakuRlnRelay.appendRLNProof(wm3, time+float64(wakuRlnRelay.rlnEpochSizeSec))
|
||||
|
||||
# ensure proofs are added
|
||||
require:
|
||||
proofAdded1.isOk()
|
||||
proofAdded2.isOk()
|
||||
proofAdded3.isOk()
|
||||
wakuRlnRelay.unsafeAppendRLNProof(wm1, time).isOkOr:
|
||||
raiseAssert $error
|
||||
wakuRlnRelay.unsafeAppendRLNProof(wm2, time).isOkOr:
|
||||
raiseAssert $error
|
||||
wakuRlnRelay.unsafeAppendRLNProof(wm3, time+float64(wakuRlnRelay.rlnEpochSizeSec)).isOkOr:
|
||||
raiseAssert $error
|
||||
|
||||
# validate messages
|
||||
# validateMessage proc checks the validity of the message fields and adds it to the log (if valid)
|
||||
|
@ -717,13 +725,28 @@ suite "Waku rln relay":
|
|||
let index1 = MembershipIndex(5)
|
||||
let index2 = MembershipIndex(6)
|
||||
|
||||
when defined(rln_v2):
|
||||
let rlnConf1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(index1),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_3"))
|
||||
else:
|
||||
let rlnConf1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(index1),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_3"))
|
||||
|
||||
let wakuRlnRelay1 = (await WakuRlnRelay.new(rlnConf1)).valueOr:
|
||||
raiseAssert "failed to create waku rln relay: " & $error
|
||||
|
||||
when defined(rln_v2):
|
||||
let rlnConf2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(index2),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_4"))
|
||||
else:
|
||||
let rlnConf2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(index2),
|
||||
rlnEpochSizeSec: 1,
|
||||
|
@ -740,13 +763,10 @@ suite "Waku rln relay":
|
|||
wm2 = WakuMessage(payload: "Valid message from sender 2".toBytes())
|
||||
|
||||
|
||||
let
|
||||
proofAdded1 = wakuRlnRelay1.appendRLNProof(wm1, time)
|
||||
proofAdded2 = wakuRlnRelay2.appendRLNProof(wm2, time)
|
||||
|
||||
# ensure proofs are added
|
||||
assert proofAdded1.isOk(), "failed to append rln proof: " & $proofAdded1.error
|
||||
assert proofAdded2.isOk(), "failed to append rln proof: " & $proofAdded2.error
|
||||
wakuRlnRelay1.appendRLNProof(wm1, time).isOkOr:
|
||||
raiseAssert $error
|
||||
wakuRlnRelay2.appendRLNProof(wm2, time).isOkOr:
|
||||
raiseAssert $error
|
||||
|
||||
# validate messages
|
||||
# validateMessage proc checks the validity of the message fields and adds it to the log (if valid)
|
||||
|
|
|
@ -14,11 +14,13 @@ import
|
|||
../../../waku/waku_node,
|
||||
../../../waku/waku_rln_relay,
|
||||
../testlib/wakucore,
|
||||
../testlib/wakunode
|
||||
../testlib/wakunode,
|
||||
./rln/waku_rln_relay_utils
|
||||
|
||||
from std/times import epochTime
|
||||
|
||||
procSuite "WakuNode - RLN relay":
|
||||
# NOTE: we set the rlnRelayUserMessageLimit to 1 to make the tests easier to reason about
|
||||
asyncTest "testing rln-relay with valid proof":
|
||||
|
||||
let
|
||||
|
@ -39,33 +41,54 @@ procSuite "WakuNode - RLN relay":
|
|||
await node1.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node1.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"))
|
||||
else:
|
||||
let wakuRlnConfig1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode"))
|
||||
await node1.mountRlnRelay(wakuRlnConfig1)
|
||||
|
||||
await node1.start()
|
||||
|
||||
# node 2
|
||||
await node2.mountRelay(@[DefaultPubsubTopic])
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node2.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(2.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_2"))
|
||||
else:
|
||||
let wakuRlnConfig2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(2.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_2"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_2"))
|
||||
await node2.mountRlnRelay(wakuRlnConfig2)
|
||||
|
||||
await node2.start()
|
||||
|
||||
# node 3
|
||||
await node3.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
await node3.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig3 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(3.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_3"))
|
||||
else:
|
||||
let wakuRlnConfig3 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(3.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_3"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_3"))
|
||||
await node3.mountRlnRelay(wakuRlnConfig3)
|
||||
|
||||
await node3.start()
|
||||
|
||||
|
@ -88,7 +111,7 @@ procSuite "WakuNode - RLN relay":
|
|||
|
||||
# prepare the epoch
|
||||
var message = WakuMessage(payload: @payload, contentTopic: contentTopic)
|
||||
doAssert(node1.wakuRlnRelay.appendRLNProof(message, epochTime()).isOk())
|
||||
doAssert(node1.wakuRlnRelay.unsafeAppendRLNProof(message, epochTime()).isOk())
|
||||
|
||||
|
||||
## node1 publishes a message with a rate limit proof, the message is then relayed to node2 which in turn
|
||||
|
@ -123,10 +146,18 @@ procSuite "WakuNode - RLN relay":
|
|||
|
||||
# mount rlnrelay in off-chain mode
|
||||
for index, node in nodes:
|
||||
await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(index.uint + 1),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_" & $(index+1)))
|
||||
else:
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(index.uint + 1),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_" & $(index+1))))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_" & $(index+1)))
|
||||
await node.mountRlnRelay(wakuRlnConfig)
|
||||
|
||||
# start them
|
||||
await allFutures(nodes.mapIt(it.start()))
|
||||
|
@ -159,12 +190,14 @@ procSuite "WakuNode - RLN relay":
|
|||
|
||||
for i in 0..<3:
|
||||
var message = WakuMessage(payload: ("Payload_" & $i).toBytes(), contentTopic: contentTopics[0])
|
||||
doAssert(nodes[0].wakuRlnRelay.appendRLNProof(message, epochTime).isOk())
|
||||
nodes[0].wakuRlnRelay.unsafeAppendRLNProof(message, epochTime).isOkOr:
|
||||
raiseAssert $error
|
||||
messages1.add(message)
|
||||
|
||||
for i in 0..<3:
|
||||
var message = WakuMessage(payload: ("Payload_" & $i).toBytes(), contentTopic: contentTopics[1])
|
||||
doAssert(nodes[1].wakuRlnRelay.appendRLNProof(message, epochTime).isOk())
|
||||
nodes[1].wakuRlnRelay.unsafeAppendRLNProof(message, epochTime).isOkOr:
|
||||
raiseAssert $error
|
||||
messages2.add(message)
|
||||
|
||||
# publish 3 messages from node[0] (last 2 are spam, window is 10 secs)
|
||||
|
@ -202,34 +235,54 @@ procSuite "WakuNode - RLN relay":
|
|||
await node1.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node1.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_4"))
|
||||
else:
|
||||
let wakuRlnConfig1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_4"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_4"))
|
||||
await node1.mountRlnRelay(wakuRlnConfig1)
|
||||
|
||||
await node1.start()
|
||||
|
||||
# node 2
|
||||
await node2.mountRelay(@[DefaultPubsubTopic])
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node2.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(2.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_5"))
|
||||
else:
|
||||
let wakuRlnConfig2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(2.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_5"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_5"))
|
||||
await node2.mountRlnRelay(wakuRlnConfig2)
|
||||
|
||||
await node2.start()
|
||||
|
||||
# node 3
|
||||
await node3.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
await node3.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig3 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(3.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_6"))
|
||||
else:
|
||||
let wakuRlnConfig3 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(3.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_6"),
|
||||
))
|
||||
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_6"))
|
||||
await node3.mountRlnRelay(wakuRlnConfig3)
|
||||
await node3.start()
|
||||
|
||||
# connect them together
|
||||
|
@ -261,14 +314,13 @@ procSuite "WakuNode - RLN relay":
|
|||
|
||||
when defined(rln_v2):
|
||||
let nonceManager = node1.wakuRlnRelay.nonceManager
|
||||
let rateLimitProofRes = node1.wakuRlnRelay.groupManager.generateProof(input,
|
||||
let rateLimitProofRes = node1.wakuRlnRelay.groupManager.generateProof(concat(input, extraBytes),
|
||||
epoch,
|
||||
MessageId(0))
|
||||
else:
|
||||
let rateLimitProofRes = node1.wakuRlnRelay.groupManager.generateProof(concat(input, extraBytes), # we add extra bytes to invalidate proof verification against original payload
|
||||
epoch)
|
||||
require:
|
||||
rateLimitProofRes.isOk()
|
||||
assert rateLimitProofRes.isOk(), $rateLimitProofRes.error # check the proof is generated correctly outside when block to avoid duplication
|
||||
let rateLimitProof = rateLimitProofRes.get().encode().buffer
|
||||
|
||||
let message = WakuMessage(payload: @payload,
|
||||
|
@ -311,11 +363,18 @@ procSuite "WakuNode - RLN relay":
|
|||
await node1.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node1.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_7"))
|
||||
else:
|
||||
let wakuRlnConfig1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_7"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_7"))
|
||||
await node1.mountRlnRelay(wakuRlnConfig1)
|
||||
|
||||
await node1.start()
|
||||
|
||||
|
@ -323,23 +382,36 @@ procSuite "WakuNode - RLN relay":
|
|||
await node2.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node2.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(2.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_8"))
|
||||
else:
|
||||
let wakuRlnConfig2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(2.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_8"),
|
||||
))
|
||||
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_8"))
|
||||
await node2.mountRlnRelay(wakuRlnConfig2)
|
||||
await node2.start()
|
||||
|
||||
# node 3
|
||||
await node3.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node3.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig3 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(3.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_9"))
|
||||
else:
|
||||
let wakuRlnConfig3 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(3.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_9"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_9"))
|
||||
await node3.mountRlnRelay(wakuRlnConfig3)
|
||||
|
||||
await node3.start()
|
||||
|
||||
|
@ -352,20 +424,18 @@ procSuite "WakuNode - RLN relay":
|
|||
# create some messages with rate limit proofs
|
||||
var
|
||||
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: "message 2".toBytes(), contentTopic: contentTopic)
|
||||
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+float64(node3.wakuRlnRelay.rlnEpochSizeSec))
|
||||
wm4 = WakuMessage(payload: "message 4".toBytes(), contentTopic: contentTopic)
|
||||
|
||||
# check proofs are added correctly
|
||||
check:
|
||||
proofAdded1.isOk()
|
||||
proofAdded2.isOk()
|
||||
proofAdded3.isOk()
|
||||
node3.wakuRlnRelay.unsafeAppendRLNProof(wm1, time).isOkOr:
|
||||
raiseAssert $error
|
||||
node3.wakuRlnRelay.unsafeAppendRLNProof(wm2, time).isOkOr:
|
||||
raiseAssert $error
|
||||
node3.wakuRlnRelay.unsafeAppendRLNProof(wm3, time+float64(node3.wakuRlnRelay.rlnEpochSizeSec)).isOkOr:
|
||||
raiseAssert $error
|
||||
|
||||
# relay handler for node3
|
||||
var completionFut1 = newFuture[bool]()
|
||||
|
@ -434,11 +504,18 @@ procSuite "WakuNode - RLN relay":
|
|||
await node1.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node1.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_10"))
|
||||
else:
|
||||
let wakuRlnConfig1 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_10"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_10"))
|
||||
await node1.mountRlnRelay(wakuRlnConfig1)
|
||||
|
||||
await node1.start()
|
||||
|
||||
|
@ -446,11 +523,18 @@ procSuite "WakuNode - RLN relay":
|
|||
await node2.mountRelay(@[DefaultPubsubTopic])
|
||||
|
||||
# mount rlnrelay in off-chain mode
|
||||
await node2.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(2.uint),
|
||||
rlnRelayUserMessageLimit: 1,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_11"))
|
||||
else:
|
||||
let wakuRlnConfig2 = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(2.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_11"),
|
||||
))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_11"))
|
||||
await node2.mountRlnRelay(wakuRlnConfig2)
|
||||
|
||||
await node2.start()
|
||||
|
||||
|
@ -461,19 +545,17 @@ procSuite "WakuNode - RLN relay":
|
|||
# create some messages with rate limit proofs
|
||||
var
|
||||
wm1 = WakuMessage(payload: "message 1".toBytes(), contentTopic: contentTopic)
|
||||
proofAdded1 = node1.wakuRlnRelay.appendRLNProof(wm1, time)
|
||||
# another message in the same epoch as wm1, it will break the messaging rate limit
|
||||
wm2 = WakuMessage(payload: "message 2".toBytes(), contentTopic: contentTopic)
|
||||
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 + float64(node1.wakuRlnRelay.rlnEpochSizeSec * 2))
|
||||
|
||||
# check proofs are added correctly
|
||||
check:
|
||||
proofAdded1.isOk()
|
||||
proofAdded2.isOk()
|
||||
proofAdded3.isOk()
|
||||
node1.wakuRlnRelay.unsafeAppendRLNProof(wm1, time).isOkOr:
|
||||
raiseAssert $error
|
||||
node1.wakuRlnRelay.unsafeAppendRLNProof(wm2, time).isOkOr:
|
||||
raiseAssert $error
|
||||
node1.wakuRlnRelay.unsafeAppendRLNProof(wm3, time + float64(node1.wakuRlnRelay.rlnEpochSizeSec * 2)).isOkOr:
|
||||
raiseAssert $error
|
||||
|
||||
# relay handler for node2
|
||||
var completionFut1 = newFuture[bool]()
|
||||
|
|
|
@ -208,10 +208,18 @@ suite "Waku v2 Rest API - Relay":
|
|||
let node = testWakuNode()
|
||||
await node.start()
|
||||
await node.mountRelay()
|
||||
await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 20,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
else:
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1")))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
await node.mountRlnRelay(wakuRlnConfig)
|
||||
|
||||
# RPC server setup
|
||||
var restPort = Port(0)
|
||||
|
@ -411,10 +419,18 @@ suite "Waku v2 Rest API - Relay":
|
|||
let node = testWakuNode()
|
||||
await node.start()
|
||||
await node.mountRelay()
|
||||
await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 20,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
else:
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1")))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
await node.mountRlnRelay(wakuRlnConfig)
|
||||
|
||||
# RPC server setup
|
||||
var restPort = Port(0)
|
||||
|
@ -456,10 +472,18 @@ suite "Waku v2 Rest API - Relay":
|
|||
let node = testWakuNode()
|
||||
await node.start()
|
||||
await node.mountRelay()
|
||||
await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 20,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
else:
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1")))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
await node.mountRlnRelay(wakuRlnConfig)
|
||||
|
||||
# RPC server setup
|
||||
var restPort = Port(0)
|
||||
|
@ -496,10 +520,18 @@ suite "Waku v2 Rest API - Relay":
|
|||
let node = testWakuNode()
|
||||
await node.start()
|
||||
await node.mountRelay()
|
||||
await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 20,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
else:
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1")))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
await node.mountRlnRelay(wakuRlnConfig)
|
||||
|
||||
# RPC server setup
|
||||
var restPort = Port(0)
|
||||
|
@ -541,10 +573,18 @@ suite "Waku v2 Rest API - Relay":
|
|||
let node = testWakuNode()
|
||||
await node.start()
|
||||
await node.mountRelay()
|
||||
await node.mountRlnRelay(WakuRlnConfig(rlnRelayDynamic: false,
|
||||
when defined(rln_v2):
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnRelayUserMessageLimit: 20,
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
else:
|
||||
let wakuRlnConfig = WakuRlnConfig(rlnRelayDynamic: false,
|
||||
rlnRelayCredIndex: some(1.uint),
|
||||
rlnEpochSizeSec: 1,
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1")))
|
||||
rlnRelayTreePath: genTempPath("rln_tree", "wakunode_1"))
|
||||
await node.mountRlnRelay(wakuRlnConfig)
|
||||
|
||||
# RPC server setup
|
||||
var restPort = Port(0)
|
||||
|
|
|
@ -132,7 +132,7 @@ proc installRelayApiHandlers*(router: var RestRouter, node: WakuNode, cache: Mes
|
|||
# append the proof to the message
|
||||
node.wakuRlnRelay.appendRLNProof(message,
|
||||
float64(getTime().toUnix())).isOkOr:
|
||||
return RestApiResponse.internalServerError("Failed to publish: error appending RLN proof to message")
|
||||
return RestApiResponse.internalServerError("Failed to publish: error appending RLN proof to message: " & $error)
|
||||
|
||||
(await node.wakuRelay.validateMessage(pubsubTopic, message)).isOkOr:
|
||||
return RestApiResponse.badRequest("Failed to publish: " & error)
|
||||
|
@ -220,7 +220,7 @@ proc installRelayApiHandlers*(router: var RestRouter, node: WakuNode, cache: Mes
|
|||
if not node.wakuRlnRelay.isNil():
|
||||
node.wakuRlnRelay.appendRLNProof(message, float64(getTime().toUnix())).isOkOr:
|
||||
return RestApiResponse.internalServerError(
|
||||
"Failed to publish: error appending RLN proof to message")
|
||||
"Failed to publish: error appending RLN proof to message: " & $error)
|
||||
|
||||
(await node.wakuRelay.validateMessage(pubsubTopic, message)).isOkOr:
|
||||
return RestApiResponse.badRequest("Failed to publish: " & error)
|
||||
|
|
|
@ -58,7 +58,7 @@ const
|
|||
# rln-v2: rate commitments are used for the Merkle tree construction, defaulting the UserMessageLimit to 20
|
||||
# the root is created locally, using createMembershipList proc from waku_rln_relay_utils module, and the result is hardcoded in here
|
||||
when defined(rln_v2):
|
||||
const StaticGroupMerkleRoot* = "0a15ba7c5753ee78e8126603113028a343c1a01ffcb389565c76626be158e964"
|
||||
const StaticGroupMerkleRoot* = "2c149e48886b5ba3da2edf8db8d7a364ae7a25618489c04cf0c0380f7cdd4d6f"
|
||||
else:
|
||||
const StaticGroupMerkleRoot* = "1e534adab58f7d300aaeecae57a25e0a0b18c368a09f720280da92b288950901"
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ proc serialize*(memIndices: seq[MembershipIndex]): seq[byte] =
|
|||
proc toEpoch*(t: uint64): Epoch =
|
||||
## converts `t` to `Epoch` in little-endian order
|
||||
let bytes = toBytes(t, Endianness.littleEndian)
|
||||
debug "bytes", bytes = bytes
|
||||
trace "epoch bytes", bytes = bytes
|
||||
var epoch: Epoch
|
||||
discard epoch.copyFrom(bytes)
|
||||
return epoch
|
||||
|
|
|
@ -43,9 +43,9 @@ proc `$`*(ne: NonceManagerError): string =
|
|||
of NonceLimitReached:
|
||||
return "NonceLimitReached: " & ne.error
|
||||
|
||||
proc init*(T: type NonceManager, nonceLimit: Nonce): T =
|
||||
proc init*(T: type NonceManager, nonceLimit: Nonce, epoch = 1.float64): T =
|
||||
return NonceManager(
|
||||
epoch: 0,
|
||||
epoch: epoch,
|
||||
nextNonce: 0,
|
||||
lastNonceTime: 0,
|
||||
nonceLimit: nonceLimit
|
||||
|
@ -62,6 +62,6 @@ proc getNonce*(n: NonceManager): NonceManagerResult[Nonce] =
|
|||
|
||||
if retNonce >= n.nonceLimit:
|
||||
return err(NonceManagerError(kind: NonceLimitReached,
|
||||
error: "Nonce limit reached. Please wait for the next epoch"))
|
||||
error: "Nonce limit reached. Please wait for the next epoch. requested nonce: " & $retNonce & " & nonceLimit: " & $n.nonceLimit))
|
||||
|
||||
return ok(retNonce)
|
||||
|
|
|
@ -163,7 +163,11 @@ proc poseidon*(data: seq[seq[byte]]): RlnRelayResult[array[32, byte]] =
|
|||
when defined(rln_v2):
|
||||
proc toLeaf*(rateCommitment: RateCommitment): RlnRelayResult[seq[byte]] =
|
||||
let idCommitment = rateCommitment.idCommitment
|
||||
let userMessageLimit = cast[array[32, byte]](rateCommitment.userMessageLimit)
|
||||
var userMessageLimit: array[32, byte]
|
||||
try:
|
||||
discard userMessageLimit.copyFrom(toBytes(rateCommitment.userMessageLimit, Endianness.littleEndian))
|
||||
except CatchableError:
|
||||
return err("could not convert the user message limit to bytes: " & getCurrentExceptionMsg())
|
||||
let leaf = poseidon(@[@idCommitment, @userMessageLimit]).valueOr:
|
||||
return err("could not convert the rate commitment to a leaf")
|
||||
var retLeaf = newSeq[byte](leaf.len)
|
||||
|
@ -179,26 +183,15 @@ when defined(rln_v2):
|
|||
leaves.add(leaf)
|
||||
return ok(leaves)
|
||||
|
||||
# TODO: collocate this proc with the definition of the RateLimitProof
|
||||
# and the ProofMetadata types
|
||||
proc extractMetadata*(proof: RateLimitProof): RlnRelayResult[ProofMetadata] =
|
||||
return ok(ProofMetadata(
|
||||
nullifier: proof.nullifier,
|
||||
shareX: proof.shareX,
|
||||
shareY: proof.shareY,
|
||||
externalNullifier: proof.externalNullifier
|
||||
))
|
||||
else:
|
||||
proc extractMetadata*(proof: RateLimitProof): RlnRelayResult[ProofMetadata] =
|
||||
let externalNullifierRes = poseidon(@[@(proof.epoch),
|
||||
@(proof.rlnIdentifier)])
|
||||
if externalNullifierRes.isErr():
|
||||
let externalNullifier = poseidon(@[@(proof.epoch),
|
||||
@(proof.rlnIdentifier)]).valueOr:
|
||||
return err("could not construct the external nullifier")
|
||||
return ok(ProofMetadata(
|
||||
nullifier: proof.nullifier,
|
||||
shareX: proof.shareX,
|
||||
shareY: proof.shareY,
|
||||
externalNullifier: externalNullifierRes.get()
|
||||
externalNullifier: externalNullifier
|
||||
))
|
||||
|
||||
when defined(rln_v2):
|
||||
|
@ -266,6 +259,8 @@ when defined(rln_v2):
|
|||
let output = RateLimitProof(proof: zkproof,
|
||||
merkleRoot: proofRoot,
|
||||
externalNullifier: externalNullifier,
|
||||
epoch: epoch,
|
||||
rlnIdentifier: rlnIdentifier,
|
||||
shareX: shareX,
|
||||
shareY: shareY,
|
||||
nullifier: nullifier)
|
||||
|
@ -339,8 +334,15 @@ proc proofVerify*(rlnInstance: ptr RLN,
|
|||
validRoots: seq[MerkleNode] = @[]): RlnRelayResult[bool] =
|
||||
## verifies the proof, returns an error if the proof verification fails
|
||||
## returns true if the proof is valid
|
||||
var normalizedProof = proof
|
||||
when defined(rln_v2):
|
||||
# when we do this, we ensure that we compute the proof for the derived value
|
||||
# of the externalNullifier. The proof verification will fail if a malicious peer
|
||||
# attaches invalid epoch+rlnidentifier pair
|
||||
normalizedProof.externalNullifier = poseidon(@[@(proof.epoch), @(proof.rlnIdentifier)]).valueOr:
|
||||
return err("could not construct the external nullifier")
|
||||
var
|
||||
proofBytes = serialize(proof, data)
|
||||
proofBytes = serialize(normalizedProof, data)
|
||||
proofBuffer = proofBytes.toBuffer()
|
||||
validProof: bool
|
||||
rootsBytes = serialize(validRoots)
|
||||
|
|
|
@ -408,7 +408,7 @@ proc mount(conf: WakuRlnConfig,
|
|||
|
||||
when defined(rln_v2):
|
||||
return WakuRLNRelay(groupManager: groupManager,
|
||||
nonceManager: NonceManager.init(conf.rlnRelayUserMessageLimit),
|
||||
nonceManager: NonceManager.init(conf.rlnRelayUserMessageLimit, conf.rlnEpochSizeSec.float),
|
||||
rlnEpochSizeSec: conf.rlnEpochSizeSec,
|
||||
rlnMaxEpochGap: uint64(MaxClockGapSeconds/float64(conf.rlnEpochSizeSec)),
|
||||
onFatalErrorAction: conf.onFatalErrorAction)
|
||||
|
|
Loading…
Reference in New Issue