Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(rln-relay-v2): wakunode testing + improvements #2501

Merged
merged 5 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/container-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 1 addition & 6 deletions tests/all_tests_waku.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
26 changes: 25 additions & 1 deletion tests/waku_rln_relay/rln/waku_rln_relay_utils.nim
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 1 addition & 1 deletion tests/waku_rln_relay/rln_v2/test_rln_relay_v2_serde.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions tests/waku_rln_relay/test_all.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
31 changes: 14 additions & 17 deletions tests/waku_rln_relay/test_rln_nonce_manager.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
130 changes: 75 additions & 55 deletions tests/waku_rln_relay/test_waku_rln_relay.nim
Original file line number Diff line number Diff line change
Expand Up @@ -518,18 +518,23 @@ suite "Waku rln relay":
let rln = rlnInstance.get()

# create a Merkle tree
let membersAdded = rln.insertMembers(0, groupIDCommitments)
require:
membersAdded
let rootRes = rln.getMerkleRoot()

require:
rootRes.isOk()
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)

assert membersAdded, "members should be added"
let rawRoot = rln.getMerkleRoot().valueOr:
alrevuelta marked this conversation as resolved.
Show resolved Hide resolved
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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
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()
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 wakuRlnRelay = (await WakuRlnRelay.new(wakuRlnConfig)).valueOr:
raiseAssert $error

# get the current epoch time
let time = epochTime()
Expand All @@ -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
alrevuelta marked this conversation as resolved.
Show resolved Hide resolved
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)
Expand All @@ -717,17 +725,32 @@ suite "Waku rln relay":
let index1 = MembershipIndex(5)
let index2 = MembershipIndex(6)

let rlnConf1 = WakuRlnConfig(rlnRelayDynamic: false,
rlnRelayCredIndex: some(index1),
rlnEpochSizeSec: 1,
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_3"))
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

let rlnConf2 = WakuRlnConfig(rlnRelayDynamic: false,
rlnRelayCredIndex: some(index2),
rlnEpochSizeSec: 1,
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_4"))
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,
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_4"))
let wakuRlnRelay2 = (await WakuRlnRelay.new(rlnConf2)).valueOr:
raiseAssert "failed to create waku rln relay: " & $error
# get the current epoch time
Expand All @@ -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)
Expand Down
Loading
Loading