2021-06-08 18:56:32 +00:00
|
|
|
|
2021-03-23 08:04:51 +00:00
|
|
|
{.used.}
|
|
|
|
|
2021-01-07 20:34:24 +00:00
|
|
|
import
|
2023-06-19 08:16:05 +00:00
|
|
|
std/[options, os, sequtils, times, tempfiles],
|
2023-02-13 10:43:49 +00:00
|
|
|
stew/byteutils,
|
2022-11-04 09:52:08 +00:00
|
|
|
stew/shims/net as stewNet,
|
2023-02-13 10:43:49 +00:00
|
|
|
testutils/unittests,
|
|
|
|
chronos,
|
|
|
|
chronicles,
|
2022-11-04 09:52:08 +00:00
|
|
|
stint,
|
|
|
|
libp2p/crypto/crypto
|
2022-10-21 13:01:39 +00:00
|
|
|
import
|
2023-08-09 17:11:50 +00:00
|
|
|
../../../waku/waku_core,
|
|
|
|
../../../waku/waku_rln_relay,
|
|
|
|
../../../waku/waku_rln_relay/rln,
|
|
|
|
../../../waku/waku_rln_relay/protocol_metrics,
|
|
|
|
../../../waku/waku_keystore,
|
2023-03-02 10:07:37 +00:00
|
|
|
../testlib/common
|
2021-02-17 21:54:49 +00:00
|
|
|
|
2023-06-19 08:16:05 +00:00
|
|
|
proc createRLNInstanceWrapper(): RLNResult =
|
|
|
|
return createRlnInstance(tree_path = genTempPath("rln_tree", "waku_rln_relay"))
|
|
|
|
|
2021-02-17 21:54:49 +00:00
|
|
|
suite "Waku rln relay":
|
|
|
|
|
2022-11-09 18:45:04 +00:00
|
|
|
test "key_gen Nim Wrappers":
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2022-11-09 18:45:04 +00:00
|
|
|
merkleDepth: csize_t = 20
|
2021-02-17 21:54:49 +00:00
|
|
|
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-09 18:45:04 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
# keysBufferPtr will hold the generated identity credential i.e., id trapdoor, nullifier, secret hash and commitment
|
2022-11-09 18:45:04 +00:00
|
|
|
var
|
|
|
|
keysBuffer: Buffer
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2022-11-09 18:45:04 +00:00
|
|
|
keysBufferPtr = addr(keysBuffer)
|
|
|
|
done = key_gen(rlnInstance.get(), keysBufferPtr)
|
2022-12-07 17:17:08 +00:00
|
|
|
require:
|
2022-11-09 18:45:04 +00:00
|
|
|
# check whether the keys are generated successfully
|
2022-12-07 17:17:08 +00:00
|
|
|
done
|
2022-11-09 18:45:04 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let generatedKeys = cast[ptr array[4*32, byte]](keysBufferPtr.`ptr`)[]
|
2022-12-07 17:17:08 +00:00
|
|
|
check:
|
2022-12-14 11:28:09 +00:00
|
|
|
# the id trapdoor, nullifier, secert hash and commitment together are 4*32 bytes
|
|
|
|
generatedKeys.len == 4*32
|
2022-12-07 17:17:08 +00:00
|
|
|
debug "generated keys: ", generatedKeys
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2022-11-04 03:00:42 +00:00
|
|
|
test "membership Key Generation":
|
2021-03-24 17:26:56 +00:00
|
|
|
# create an RLN instance
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
2021-03-24 17:26:56 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let idCredentialsRes = membershipKeyGen(rlnInstance.get())
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredentialsRes.isOk()
|
2022-11-04 03:00:42 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let idCredential = idCredentialsRes.get()
|
2022-12-07 17:17:08 +00:00
|
|
|
let empty = default(array[32, byte])
|
2021-02-18 22:59:10 +00:00
|
|
|
check:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredential.idTrapdoor.len == 32
|
|
|
|
idCredential.idNullifier.len == 32
|
|
|
|
idCredential.idSecretHash.len == 32
|
|
|
|
idCredential.idCommitment.len == 32
|
|
|
|
idCredential.idTrapdoor != empty
|
|
|
|
idCredential.idNullifier != empty
|
|
|
|
idCredential.idSecretHash != empty
|
|
|
|
idCredential.idCommitment != empty
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
debug "the generated identity credential: ", idCredential
|
2021-06-08 18:56:32 +00:00
|
|
|
|
2022-11-04 03:00:42 +00:00
|
|
|
test "getRoot Nim binding":
|
2021-03-24 17:26:56 +00:00
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
2021-03-24 17:26:56 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2022-05-10 21:09:18 +00:00
|
|
|
root1 {.noinit.}: Buffer = Buffer()
|
2022-12-07 17:17:08 +00:00
|
|
|
rootPtr1 = unsafeAddr(root1)
|
2022-11-04 03:00:42 +00:00
|
|
|
getRootSuccessful1 = getRoot(rlnInstance.get(), rootPtr1)
|
2022-12-07 17:17:08 +00:00
|
|
|
require:
|
2022-11-04 03:00:42 +00:00
|
|
|
getRootSuccessful1
|
2021-10-26 21:42:24 +00:00
|
|
|
root1.len == 32
|
2021-03-24 17:26:56 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2022-05-10 21:09:18 +00:00
|
|
|
root2 {.noinit.}: Buffer = Buffer()
|
2022-12-07 17:17:08 +00:00
|
|
|
rootPtr2 = unsafeAddr(root2)
|
2022-11-04 03:00:42 +00:00
|
|
|
getRootSuccessful2 = getRoot(rlnInstance.get(), rootPtr2)
|
2022-12-07 17:17:08 +00:00
|
|
|
require:
|
2022-11-04 03:00:42 +00:00
|
|
|
getRootSuccessful2
|
2021-10-26 21:42:24 +00:00
|
|
|
root2.len == 32
|
2021-03-24 17:26:56 +00:00
|
|
|
|
2022-12-07 17:17:08 +00:00
|
|
|
let rootValue1 = cast[ptr array[32, byte]] (root1.`ptr`)
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex1 = rootValue1[].inHex
|
2021-03-24 17:26:56 +00:00
|
|
|
|
2022-12-07 17:17:08 +00:00
|
|
|
let rootValue2 = cast[ptr array[32, byte]] (root2.`ptr`)
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex2 = rootValue2[].inHex
|
2021-03-24 17:26:56 +00:00
|
|
|
|
2021-08-26 23:14:51 +00:00
|
|
|
# the two roots must be identical
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
|
|
|
rootHex1 == rootHex2
|
2021-08-26 23:14:51 +00:00
|
|
|
test "getMerkleRoot utils":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
2021-08-26 23:14:51 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root
|
2022-12-07 17:17:08 +00:00
|
|
|
let root1 = getMerkleRoot(rln)
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
root1.isOk()
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex1 = root1.value().inHex
|
2021-08-26 23:14:51 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root
|
2022-12-07 17:17:08 +00:00
|
|
|
let root2 = getMerkleRoot(rln)
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
root2.isOk()
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex2 = root2.value().inHex
|
2021-08-26 23:14:51 +00:00
|
|
|
|
2021-03-24 17:26:56 +00:00
|
|
|
# the two roots must be identical
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
|
|
|
rootHex1 == rootHex2
|
2021-03-24 17:26:56 +00:00
|
|
|
|
|
|
|
test "update_next_member Nim Wrapper":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
2022-12-14 11:28:09 +00:00
|
|
|
# generate an identity credential
|
|
|
|
let idCredentialRes = membershipKeyGen(rln)
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredentialRes.isOk()
|
2023-02-13 10:43:49 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let idCredential = idCredentialRes.get()
|
|
|
|
let pkBuffer = toBuffer(idCredential.idCommitment)
|
2022-12-07 17:17:08 +00:00
|
|
|
let pkBufferPtr = unsafeAddr(pkBuffer)
|
2021-03-24 17:26:56 +00:00
|
|
|
|
|
|
|
# add the member to the tree
|
2022-11-04 03:00:42 +00:00
|
|
|
let memberAdded = updateNextMember(rln, pkBufferPtr)
|
2021-03-24 17:26:56 +00:00
|
|
|
check:
|
2022-11-04 03:00:42 +00:00
|
|
|
memberAdded
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2023-06-12 10:00:07 +00:00
|
|
|
test "getMember Nim wrapper":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2023-06-12 10:00:07 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
|
|
|
# generate an identity credential
|
|
|
|
let idCredentialRes = membershipKeyGen(rln)
|
|
|
|
require:
|
|
|
|
idCredentialRes.isOk()
|
|
|
|
|
|
|
|
let idCredential = idCredentialRes.get()
|
|
|
|
let pkBuffer = toBuffer(idCredential.idCommitment)
|
|
|
|
let pkBufferPtr = unsafeAddr(pkBuffer)
|
|
|
|
|
|
|
|
let
|
|
|
|
root1 {.noinit.}: Buffer = Buffer()
|
|
|
|
rootPtr1 = unsafeAddr(root1)
|
|
|
|
getRootSuccessful1 = getRoot(rlnInstance.get(), rootPtr1)
|
|
|
|
|
|
|
|
# add the member to the tree
|
|
|
|
let memberAdded = updateNextMember(rln, pkBufferPtr)
|
|
|
|
require:
|
|
|
|
memberAdded
|
|
|
|
|
|
|
|
let leafRes = getMember(rln, 0)
|
|
|
|
require:
|
|
|
|
leafRes.isOk()
|
|
|
|
let leaf = leafRes.get()
|
|
|
|
let leafHex = leaf.inHex()
|
|
|
|
check:
|
|
|
|
leafHex == idCredential.idCommitment.inHex()
|
|
|
|
|
2021-03-24 17:26:56 +00:00
|
|
|
test "delete_member Nim wrapper":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
2023-05-05 10:18:06 +00:00
|
|
|
# generate an identity credential
|
|
|
|
let rln = rlnInstance.get()
|
|
|
|
let idCredentialRes = rln.membershipKeyGen()
|
|
|
|
require:
|
|
|
|
idCredentialRes.isOk()
|
|
|
|
rln.insertMember(idCredentialRes.get().idCommitment)
|
2021-03-24 17:26:56 +00:00
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
# delete the first member
|
2022-11-04 03:00:42 +00:00
|
|
|
let deletedMemberIndex = MembershipIndex(0)
|
2023-05-05 10:18:06 +00:00
|
|
|
let deletionSuccess = rln.deleteMember(deletedMemberIndex)
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
2022-11-04 03:00:42 +00:00
|
|
|
deletionSuccess
|
2021-06-08 18:56:32 +00:00
|
|
|
|
2022-11-10 16:58:31 +00:00
|
|
|
test "insertMembers rln utils":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-10 16:58:31 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
2022-12-14 11:28:09 +00:00
|
|
|
# generate an identity credential
|
|
|
|
let idCredentialRes = rln.membershipKeyGen()
|
2022-11-10 16:58:31 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredentialRes.isOk()
|
2022-11-10 16:58:31 +00:00
|
|
|
check:
|
2022-12-14 11:28:09 +00:00
|
|
|
rln.insertMembers(0, @[idCredentialRes.get().idCommitment])
|
2022-11-10 16:58:31 +00:00
|
|
|
|
2021-08-26 23:14:51 +00:00
|
|
|
test "insertMember rln utils":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
2022-12-14 11:28:09 +00:00
|
|
|
# generate an identity credential
|
|
|
|
let idCredentialRes = rln.membershipKeyGen()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredentialRes.isOk()
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
2022-12-14 11:28:09 +00:00
|
|
|
rln.insertMember(idCredentialRes.get().idCommitment)
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2021-08-26 23:14:51 +00:00
|
|
|
test "removeMember rln utils":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
2023-05-05 10:18:06 +00:00
|
|
|
|
|
|
|
let idCredentialRes = rln.membershipKeyGen()
|
|
|
|
require:
|
|
|
|
idCredentialRes.isOk()
|
|
|
|
rln.insertMember(idCredentialRes.get().idCommitment)
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
2021-09-24 17:32:45 +00:00
|
|
|
rln.removeMember(MembershipIndex(0))
|
2021-08-26 23:14:51 +00:00
|
|
|
|
2023-06-16 06:03:41 +00:00
|
|
|
test "setMetadata rln utils":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2023-06-16 06:03:41 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
|
|
|
check:
|
2023-08-23 12:53:30 +00:00
|
|
|
rln.setMetadata(RlnMetadata(lastProcessedBlock: 128,
|
|
|
|
chainId: 1155511,
|
|
|
|
contractAddress: "0x9c09146844c1326c2dbc41c451766c7138f88155")).isOk()
|
2023-06-16 06:03:41 +00:00
|
|
|
|
|
|
|
test "getMetadata rln utils":
|
|
|
|
# create an RLN instance which also includes an empty Merkle tree
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2023-06-16 06:03:41 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
2023-08-21 06:55:34 +00:00
|
|
|
|
2023-06-16 06:03:41 +00:00
|
|
|
require:
|
2023-08-23 12:53:30 +00:00
|
|
|
rln.setMetadata(RlnMetadata(lastProcessedBlock: 128,
|
|
|
|
chainId: 1155511,
|
|
|
|
contractAddress: "0x9c09146844c1326c2dbc41c451766c7138f88155")).isOk()
|
2023-06-16 06:03:41 +00:00
|
|
|
|
|
|
|
let metadataRes = rln.getMetadata()
|
|
|
|
|
|
|
|
require:
|
|
|
|
metadataRes.isOk()
|
|
|
|
|
|
|
|
let metadata = metadataRes.get()
|
|
|
|
|
|
|
|
check:
|
|
|
|
metadata.lastProcessedBlock == 128
|
2023-08-23 12:53:30 +00:00
|
|
|
metadata.chainId == 1155511
|
|
|
|
metadata.contractAddress == "0x9c09146844c1326c2dbc41c451766c7138f88155"
|
2023-06-16 06:03:41 +00:00
|
|
|
|
2021-03-24 17:26:56 +00:00
|
|
|
test "Merkle tree consistency check between deletion and insertion":
|
|
|
|
# create an RLN instance
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
|
|
|
|
let rln = rlnInstance.get()
|
2021-03-24 17:26:56 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2022-05-10 21:09:18 +00:00
|
|
|
root1 {.noinit.}: Buffer = Buffer()
|
2022-12-07 17:17:08 +00:00
|
|
|
rootPtr1 = unsafeAddr(root1)
|
2022-11-04 03:00:42 +00:00
|
|
|
getRootSuccessful1 = getRoot(rln, rootPtr1)
|
|
|
|
require:
|
|
|
|
getRootSuccessful1
|
2021-10-26 21:42:24 +00:00
|
|
|
root1.len == 32
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
# generate an identity credential
|
|
|
|
let idCredentialRes = membershipKeyGen(rln)
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredentialRes.isOk()
|
2023-02-13 10:43:49 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let idCredential = idCredentialRes.get()
|
|
|
|
let pkBuffer = toBuffer(idCredential.idCommitment)
|
2022-12-07 17:17:08 +00:00
|
|
|
let pkBufferPtr = unsafeAddr(pkBuffer)
|
2021-03-24 17:26:56 +00:00
|
|
|
|
|
|
|
# add the member to the tree
|
2022-11-04 03:00:42 +00:00
|
|
|
let memberAdded = updateNextMember(rln, pkBufferPtr)
|
|
|
|
require:
|
|
|
|
memberAdded
|
2021-03-24 17:26:56 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root after insertion
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2022-05-10 21:09:18 +00:00
|
|
|
root2 {.noinit.}: Buffer = Buffer()
|
2022-12-07 17:17:08 +00:00
|
|
|
rootPtr2 = unsafeAddr(root2)
|
2022-11-04 03:00:42 +00:00
|
|
|
getRootSuccessful = getRoot(rln, rootPtr2)
|
|
|
|
require:
|
|
|
|
getRootSuccessful
|
2021-10-26 21:42:24 +00:00
|
|
|
root2.len == 32
|
2021-03-24 17:26:56 +00:00
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
# delete the first member
|
2022-11-04 03:00:42 +00:00
|
|
|
let deletedMemberIndex = MembershipIndex(0)
|
|
|
|
let deletionSuccess = deleteMember(rln, deletedMemberIndex)
|
|
|
|
require:
|
|
|
|
deletionSuccess
|
2021-03-24 17:26:56 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root after the deletion
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2022-05-10 21:09:18 +00:00
|
|
|
root3 {.noinit.}: Buffer = Buffer()
|
2022-12-07 17:17:08 +00:00
|
|
|
rootPtr3 = unsafeAddr(root3)
|
2022-11-04 03:00:42 +00:00
|
|
|
getRootSuccessful3 = getRoot(rln, rootPtr3)
|
|
|
|
require:
|
|
|
|
getRootSuccessful3
|
2021-10-26 21:42:24 +00:00
|
|
|
root3.len == 32
|
2021-03-24 17:26:56 +00:00
|
|
|
|
2022-11-04 03:00:42 +00:00
|
|
|
let rootValue1 = cast[ptr array[32, byte]] (root1.`ptr`)
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex1 = rootValue1[].inHex
|
2021-03-24 17:26:56 +00:00
|
|
|
debug "The initial root", rootHex1
|
|
|
|
|
2022-11-04 03:00:42 +00:00
|
|
|
let rootValue2 = cast[ptr array[32, byte]] (root2.`ptr`)
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex2 = rootValue2[].inHex
|
2021-03-24 17:26:56 +00:00
|
|
|
debug "The root after insertion", rootHex2
|
|
|
|
|
2022-11-04 03:00:42 +00:00
|
|
|
let rootValue3 = cast[ptr array[32, byte]] (root3.`ptr`)
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex3 = rootValue3[].inHex
|
2021-03-24 17:26:56 +00:00
|
|
|
debug "The root after deletion", rootHex3
|
|
|
|
|
|
|
|
# the root must change after the insertion
|
2023-02-13 10:43:49 +00:00
|
|
|
check:
|
2022-11-04 03:00:42 +00:00
|
|
|
not(rootHex1 == rootHex2)
|
2021-03-24 17:26:56 +00:00
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
## The initial root of the tree (empty tree) must be identical to
|
2021-03-24 17:26:56 +00:00
|
|
|
## the root of the tree after one insertion followed by a deletion
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
|
|
|
rootHex1 == rootHex3
|
2022-11-04 03:00:42 +00:00
|
|
|
|
2021-08-26 23:14:51 +00:00
|
|
|
test "Merkle tree consistency check between deletion and insertion using rln utils":
|
|
|
|
# create an RLN instance
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
|
|
|
|
let rln = rlnInstance.get()
|
2021-08-26 23:14:51 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root
|
2022-11-04 03:00:42 +00:00
|
|
|
let root1 = rln.getMerkleRoot()
|
|
|
|
require:
|
|
|
|
root1.isOk()
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex1 = root1.value().inHex()
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
# generate an identity credential
|
|
|
|
let idCredentialRes = rln.membershipKeyGen()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredentialRes.isOk()
|
|
|
|
let memberInserted = rln.insertMembers(0, @[idCredentialRes.get().idCommitment])
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
memberInserted
|
2021-08-26 23:14:51 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root after insertion
|
2022-11-04 03:00:42 +00:00
|
|
|
let root2 = rln.getMerkleRoot()
|
|
|
|
require:
|
|
|
|
root2.isOk()
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex2 = root2.value().inHex()
|
2021-08-26 23:14:51 +00:00
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
|
|
|
|
# delete the first member
|
2022-11-04 03:00:42 +00:00
|
|
|
let deletedMemberIndex = MembershipIndex(0)
|
|
|
|
let deletionSuccess = rln.removeMember(deletedMemberIndex)
|
|
|
|
require:
|
|
|
|
deletionSuccess
|
2021-08-26 23:14:51 +00:00
|
|
|
|
|
|
|
# read the Merkle Tree root after the deletion
|
2022-11-04 03:00:42 +00:00
|
|
|
let root3 = rln.getMerkleRoot()
|
|
|
|
require:
|
|
|
|
root3.isOk()
|
2022-10-12 08:38:48 +00:00
|
|
|
let rootHex3 = root3.value().inHex()
|
2021-08-26 23:14:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
debug "The initial root", rootHex1
|
|
|
|
debug "The root after insertion", rootHex2
|
|
|
|
debug "The root after deletion", rootHex3
|
|
|
|
|
|
|
|
# the root must change after the insertion
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
|
|
|
not(rootHex1 == rootHex2)
|
2021-08-26 23:14:51 +00:00
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
## The initial root of the tree (empty tree) must be identical to
|
2021-08-26 23:14:51 +00:00
|
|
|
## the root of the tree after one insertion followed by a deletion
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
|
|
|
rootHex1 == rootHex3
|
2021-08-26 23:14:51 +00:00
|
|
|
|
2021-04-01 00:39:27 +00:00
|
|
|
test "hash Nim Wrappers":
|
|
|
|
# create an RLN instance
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2021-04-01 00:39:27 +00:00
|
|
|
# prepare the input
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2021-10-26 21:42:24 +00:00
|
|
|
msg = "Hello".toBytes()
|
2023-03-01 11:59:13 +00:00
|
|
|
hashInput = encodeLengthPrefix(msg)
|
2022-05-10 21:09:18 +00:00
|
|
|
hashInputBuffer = toBuffer(hashInput)
|
2021-04-01 00:39:27 +00:00
|
|
|
|
|
|
|
# prepare other inputs to the hash function
|
2022-12-07 17:17:08 +00:00
|
|
|
let outputBuffer = default(Buffer)
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2023-02-22 14:17:12 +00:00
|
|
|
let hashSuccess = sha256(unsafeAddr hashInputBuffer,
|
|
|
|
unsafeAddr outputBuffer)
|
2022-12-07 17:17:08 +00:00
|
|
|
require:
|
2022-05-10 21:09:18 +00:00
|
|
|
hashSuccess
|
|
|
|
let outputArr = cast[ptr array[32, byte]](outputBuffer.`ptr`)[]
|
2023-02-13 10:43:49 +00:00
|
|
|
|
2022-11-09 18:45:04 +00:00
|
|
|
check:
|
|
|
|
"1e32b3ab545c07c8b4a7ab1ca4f46bc31e4fdc29ac3b240ef1d54b4017a26e4c" ==
|
|
|
|
outputArr.inHex()
|
2021-04-01 00:39:27 +00:00
|
|
|
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
2022-05-10 21:09:18 +00:00
|
|
|
hashOutput = cast[ptr array[32, byte]] (outputBuffer.`ptr`)[]
|
2021-04-01 00:39:27 +00:00
|
|
|
hashOutputHex = hashOutput.toHex()
|
|
|
|
|
|
|
|
debug "hash output", hashOutputHex
|
|
|
|
|
2023-03-13 14:39:33 +00:00
|
|
|
test "sha256 hash utils":
|
2021-10-20 00:37:29 +00:00
|
|
|
# create an RLN instance
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2021-10-20 00:37:29 +00:00
|
|
|
# prepare the input
|
2021-10-26 21:42:24 +00:00
|
|
|
let msg = "Hello".toBytes()
|
2021-04-01 00:39:27 +00:00
|
|
|
|
2023-03-13 14:39:33 +00:00
|
|
|
let hashRes = sha256(msg)
|
2022-08-05 20:58:19 +00:00
|
|
|
|
2022-11-09 18:45:04 +00:00
|
|
|
check:
|
2023-03-13 14:39:33 +00:00
|
|
|
hashRes.isOk()
|
2022-11-09 18:45:04 +00:00
|
|
|
"1e32b3ab545c07c8b4a7ab1ca4f46bc31e4fdc29ac3b240ef1d54b4017a26e4c" ==
|
2023-03-13 14:39:33 +00:00
|
|
|
hashRes.get().inHex()
|
|
|
|
|
|
|
|
test "poseidon hash utils":
|
|
|
|
# create an RLN instance
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2023-03-13 14:39:33 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
|
|
|
|
|
|
|
# prepare the input
|
|
|
|
let msg = @["126f4c026cd731979365f79bd345a46d673c5a3f6f588bdc718e6356d02b6fdc".toBytes(),
|
|
|
|
"1f0e5db2b69d599166ab16219a97b82b662085c93220382b39f9f911d3b943b1".toBytes()]
|
|
|
|
|
|
|
|
let hashRes = poseidon(msg)
|
|
|
|
|
|
|
|
# Value taken from zerokit
|
|
|
|
check:
|
|
|
|
hashRes.isOk()
|
|
|
|
"28a15a991fe3d2a014485c7fa905074bfb55c0909112f865ded2be0a26a932c3" ==
|
|
|
|
hashRes.get().inHex()
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2021-09-17 17:31:25 +00:00
|
|
|
test "create a list of membership keys and construct a Merkle tree based on the list":
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2023-02-28 13:38:30 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
let
|
2021-09-17 17:31:25 +00:00
|
|
|
groupSize = 100
|
2023-02-28 13:38:30 +00:00
|
|
|
memListRes = rln.createMembershipList(groupSize)
|
2022-11-04 03:00:42 +00:00
|
|
|
|
|
|
|
require:
|
|
|
|
memListRes.isOk()
|
|
|
|
|
|
|
|
let (list, root) = memListRes.get()
|
2021-09-17 17:31:25 +00:00
|
|
|
|
|
|
|
debug "created membership key list", list
|
|
|
|
debug "the Merkle tree root", root
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2021-09-17 17:31:25 +00:00
|
|
|
check:
|
2022-05-10 21:09:18 +00:00
|
|
|
list.len == groupSize # check the number of keys
|
2022-09-30 12:43:42 +00:00
|
|
|
root.len == HashHexSize # check the size of the calculated tree root
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2023-02-28 13:38:30 +00:00
|
|
|
test "check correctness of toIdentityCredentials":
|
2022-09-30 12:43:42 +00:00
|
|
|
let groupKeys = StaticGroupKeys
|
2021-09-17 17:31:25 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
# create a set of IdentityCredentials objects from groupKeys
|
|
|
|
let groupIdCredentialsRes = groupKeys.toIdentityCredentials()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
groupIdCredentialsRes.isOk()
|
2023-02-13 10:43:49 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let groupIdCredentials = groupIdCredentialsRes.get()
|
2021-09-17 17:31:25 +00:00
|
|
|
# extract the id commitments
|
2022-12-14 11:28:09 +00:00
|
|
|
let groupIDCommitments = groupIdCredentials.mapIt(it.idCommitment)
|
2021-09-17 17:31:25 +00:00
|
|
|
# calculate the Merkle tree root out of the extracted id commitments
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2023-02-28 13:38:30 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
let rln = rlnInstance.get()
|
|
|
|
|
|
|
|
# create a Merkle tree
|
|
|
|
let membersAdded = rln.insertMembers(0, groupIDCommitments)
|
|
|
|
require:
|
|
|
|
membersAdded
|
|
|
|
let rootRes = rln.getMerkleRoot()
|
2022-11-04 03:00:42 +00:00
|
|
|
|
|
|
|
require:
|
|
|
|
rootRes.isOk()
|
|
|
|
|
2023-02-28 13:38:30 +00:00
|
|
|
let root = rootRes.get().inHex()
|
2021-09-17 17:31:25 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
debug "groupIdCredentials", groupIdCredentials
|
2021-09-17 17:31:25 +00:00
|
|
|
debug "groupIDCommitments", groupIDCommitments
|
|
|
|
debug "root", root
|
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
2022-12-14 11:28:09 +00:00
|
|
|
# check that the correct number of identity credentials is created
|
|
|
|
groupIdCredentials.len == StaticGroupSize
|
2021-09-17 17:31:25 +00:00
|
|
|
# compare the calculated root against the correct root
|
2022-09-30 12:43:42 +00:00
|
|
|
root == StaticGroupMerkleRoot
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2022-11-09 18:45:04 +00:00
|
|
|
test "RateLimitProof Protobuf encode/init test":
|
|
|
|
var
|
|
|
|
proof: ZKSNARK
|
|
|
|
merkleRoot: MerkleNode
|
|
|
|
epoch: Epoch
|
|
|
|
shareX: MerkleNode
|
|
|
|
shareY: MerkleNode
|
|
|
|
nullifier: Nullifier
|
|
|
|
rlnIdentifier: RlnIdentifier
|
|
|
|
|
|
|
|
# populate fields with dummy values
|
|
|
|
for x in proof.mitems: x = 1
|
|
|
|
for x in merkleRoot.mitems: x = 2
|
|
|
|
for x in epoch.mitems: x = 3
|
|
|
|
for x in shareX.mitems: x = 4
|
|
|
|
for x in shareY.mitems: x = 5
|
|
|
|
for x in nullifier.mitems: x = 6
|
|
|
|
for x in rlnIdentifier.mitems: x = 7
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2022-11-09 18:45:04 +00:00
|
|
|
let
|
|
|
|
rateLimitProof = RateLimitProof(proof: proof,
|
|
|
|
merkleRoot: merkleRoot,
|
|
|
|
epoch: epoch,
|
|
|
|
shareX: shareX,
|
|
|
|
shareY: shareY,
|
|
|
|
nullifier: nullifier,
|
|
|
|
rlnIdentifier: rlnIdentifier)
|
|
|
|
protobuf = rateLimitProof.encode()
|
|
|
|
decodednsp = RateLimitProof.init(protobuf.buffer)
|
2021-10-20 00:37:29 +00:00
|
|
|
|
2022-12-07 17:17:08 +00:00
|
|
|
require:
|
|
|
|
decodednsp.isOk()
|
2022-11-09 18:45:04 +00:00
|
|
|
check:
|
|
|
|
decodednsp.value == rateLimitProof
|
2021-10-20 00:37:29 +00:00
|
|
|
|
2021-11-23 22:48:40 +00:00
|
|
|
test "toEpoch and fromEpoch consistency check":
|
|
|
|
# check edge cases
|
2022-05-10 21:09:18 +00:00
|
|
|
let
|
|
|
|
epoch = uint64.high # rln epoch
|
|
|
|
epochBytes = epoch.toEpoch()
|
|
|
|
decodedEpoch = epochBytes.fromEpoch()
|
|
|
|
check:
|
|
|
|
epoch == decodedEpoch
|
|
|
|
debug "encoded and decode time", epoch = epoch, epochBytes = epochBytes,
|
|
|
|
decodedEpoch = decodedEpoch
|
|
|
|
|
2022-11-01 00:25:39 +00:00
|
|
|
test "Epoch comparison, epoch1 > epoch2":
|
2021-11-23 22:48:40 +00:00
|
|
|
# check edge cases
|
2022-05-10 21:09:18 +00:00
|
|
|
let
|
2021-11-23 22:48:40 +00:00
|
|
|
time1 = uint64.high
|
|
|
|
time2 = uint64.high - 1
|
|
|
|
epoch1 = time1.toEpoch()
|
|
|
|
epoch2 = time2.toEpoch()
|
2022-05-10 21:09:18 +00:00
|
|
|
check:
|
2022-11-01 00:25:39 +00:00
|
|
|
absDiff(epoch1, epoch2) == uint64(1)
|
|
|
|
absDiff(epoch2, epoch1) == uint64(1)
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2021-11-23 22:48:40 +00:00
|
|
|
test "updateLog and hasDuplicate tests":
|
2022-05-10 21:09:18 +00:00
|
|
|
let
|
2021-11-23 22:48:40 +00:00
|
|
|
wakurlnrelay = WakuRLNRelay()
|
|
|
|
epoch = getCurrentEpoch()
|
|
|
|
|
2022-12-07 17:17:08 +00:00
|
|
|
# create some dummy nullifiers and secret shares
|
2021-11-23 22:48:40 +00:00
|
|
|
var nullifier1: Nullifier
|
|
|
|
for index, x in nullifier1.mpairs: nullifier1[index] = 1
|
|
|
|
var shareX1: MerkleNode
|
|
|
|
for index, x in shareX1.mpairs: shareX1[index] = 1
|
|
|
|
let shareY1 = shareX1
|
|
|
|
|
|
|
|
var nullifier2: Nullifier
|
|
|
|
for index, x in nullifier2.mpairs: nullifier2[index] = 2
|
|
|
|
var shareX2: MerkleNode
|
|
|
|
for index, x in shareX2.mpairs: shareX2[index] = 2
|
|
|
|
let shareY2 = shareX2
|
|
|
|
|
|
|
|
let nullifier3 = nullifier1
|
|
|
|
var shareX3: MerkleNode
|
|
|
|
for index, x in shareX3.mpairs: shareX3[index] = 3
|
|
|
|
let shareY3 = shareX3
|
|
|
|
|
2022-11-22 17:29:43 +00:00
|
|
|
proc encodeAndGetBuf(proof: RateLimitProof): seq[byte] =
|
|
|
|
return proof.encode().buffer
|
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
let
|
2023-03-13 14:39:33 +00:00
|
|
|
proof1 = RateLimitProof(epoch: epoch,
|
|
|
|
nullifier: nullifier1,
|
|
|
|
shareX: shareX1,
|
|
|
|
shareY: shareY1)
|
|
|
|
wm1 = WakuMessage(proof: proof1.encodeAndGetBuf())
|
|
|
|
proof2 = RateLimitProof(epoch: epoch,
|
|
|
|
nullifier: nullifier2,
|
|
|
|
shareX: shareX2,
|
|
|
|
shareY: shareY2)
|
|
|
|
wm2 = WakuMessage(proof: proof2.encodeAndGetBuf())
|
|
|
|
proof3 = RateLimitProof(epoch: epoch,
|
|
|
|
nullifier: nullifier3,
|
|
|
|
shareX: shareX3,
|
|
|
|
shareY: shareY3)
|
|
|
|
wm3 = WakuMessage(proof: proof3.encodeAndGetBuf())
|
2021-11-23 22:48:40 +00:00
|
|
|
|
|
|
|
# check whether hasDuplicate correctly finds records with the same nullifiers but different secret shares
|
2023-03-13 14:39:33 +00:00
|
|
|
# no duplicate for proof1 should be found, since the log is empty
|
|
|
|
let result1 = wakurlnrelay.hasDuplicate(proof1.extractMetadata().tryGet())
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
result1.isOk()
|
2021-11-23 22:48:40 +00:00
|
|
|
# no duplicate is found
|
|
|
|
result1.value == false
|
|
|
|
# add it to the log
|
2023-03-13 14:39:33 +00:00
|
|
|
discard wakurlnrelay.updateLog(proof1.extractMetadata().tryGet())
|
2021-11-23 22:48:40 +00:00
|
|
|
|
2023-03-13 14:39:33 +00:00
|
|
|
# # no duplicate for proof2 should be found, its nullifier differs from proof1
|
|
|
|
let result2 = wakurlnrelay.hasDuplicate(proof2.extractMetadata().tryGet())
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
result2.isOk()
|
2021-11-23 22:48:40 +00:00
|
|
|
# no duplicate is found
|
|
|
|
result2.value == false
|
|
|
|
# add it to the log
|
2023-03-13 14:39:33 +00:00
|
|
|
discard wakurlnrelay.updateLog(proof2.extractMetadata().tryGet())
|
2021-11-23 22:48:40 +00:00
|
|
|
|
2023-03-13 14:39:33 +00:00
|
|
|
# proof3 has the same nullifier as proof1 but different secret shares, it should be detected as duplicate
|
|
|
|
let result3 = wakurlnrelay.hasDuplicate(proof3.extractMetadata().tryGet())
|
2022-12-07 17:17:08 +00:00
|
|
|
require:
|
2022-11-04 03:00:42 +00:00
|
|
|
result3.isOk()
|
2022-12-07 17:17:08 +00:00
|
|
|
check:
|
2021-11-23 22:48:40 +00:00
|
|
|
# it is a duplicate
|
|
|
|
result3.value == true
|
|
|
|
|
2023-02-28 13:38:30 +00:00
|
|
|
asyncTest "validateMessage test":
|
2021-11-23 22:48:40 +00:00
|
|
|
let index = MembershipIndex(5)
|
|
|
|
|
2023-02-28 13:38:30 +00:00
|
|
|
let rlnConf = WakuRlnConfig(rlnRelayDynamic: false,
|
2023-07-07 11:58:37 +00:00
|
|
|
rlnRelayCredIndex: index.uint,
|
|
|
|
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_2"))
|
2023-02-28 13:38:30 +00:00
|
|
|
let wakuRlnRelayRes = await WakuRlnRelay.new(rlnConf)
|
2022-09-27 04:40:04 +00:00
|
|
|
require:
|
2023-02-28 13:38:30 +00:00
|
|
|
wakuRlnRelayRes.isOk()
|
|
|
|
let wakuRlnRelay = wakuRlnRelayRes.get()
|
2022-09-27 04:40:04 +00:00
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
# get the current epoch time
|
2021-11-23 22:48:40 +00:00
|
|
|
let time = epochTime()
|
|
|
|
|
|
|
|
# create some messages from the same peer and append rln proof to them, except wm4
|
2022-05-10 21:09:18 +00:00
|
|
|
var
|
2021-11-23 22:48:40 +00:00
|
|
|
wm1 = WakuMessage(payload: "Valid message".toBytes())
|
|
|
|
# another message in the same epoch as wm1, it will break the messaging rate limit
|
|
|
|
wm2 = WakuMessage(payload: "Spam".toBytes())
|
2022-05-10 21:09:18 +00:00
|
|
|
# wm3 points to the next epoch
|
2021-11-23 22:48:40 +00:00
|
|
|
wm3 = WakuMessage(payload: "Valid message".toBytes())
|
2022-05-10 21:09:18 +00:00
|
|
|
wm4 = WakuMessage(payload: "Invalid message".toBytes())
|
|
|
|
|
2022-12-07 17:17:08 +00:00
|
|
|
let
|
|
|
|
proofAdded1 = wakuRlnRelay.appendRLNProof(wm1, time)
|
|
|
|
proofAdded2 = wakuRlnRelay.appendRLNProof(wm2, time)
|
|
|
|
proofAdded3 = wakuRlnRelay.appendRLNProof(wm3, time+EpochUnitSeconds)
|
|
|
|
|
|
|
|
# ensure proofs are added
|
|
|
|
require:
|
2021-11-23 22:48:40 +00:00
|
|
|
proofAdded1
|
|
|
|
proofAdded2
|
|
|
|
proofAdded3
|
|
|
|
|
|
|
|
# validate messages
|
|
|
|
# validateMessage proc checks the validity of the message fields and adds it to the log (if valid)
|
|
|
|
let
|
2022-01-28 21:57:17 +00:00
|
|
|
msgValidate1 = wakuRlnRelay.validateMessage(wm1, some(time))
|
2021-11-23 22:48:40 +00:00
|
|
|
# wm2 is published within the same Epoch as wm1 and should be found as spam
|
2022-01-28 21:57:17 +00:00
|
|
|
msgValidate2 = wakuRlnRelay.validateMessage(wm2, some(time))
|
2022-05-10 21:09:18 +00:00
|
|
|
# a valid message should be validated successfully
|
2022-01-28 21:57:17 +00:00
|
|
|
msgValidate3 = wakuRlnRelay.validateMessage(wm3, some(time))
|
2021-11-23 22:48:40 +00:00
|
|
|
# wm4 has no rln proof and should not be validated
|
2022-01-28 21:57:17 +00:00
|
|
|
msgValidate4 = wakuRlnRelay.validateMessage(wm4, some(time))
|
2021-11-23 22:48:40 +00:00
|
|
|
|
2022-05-10 21:09:18 +00:00
|
|
|
|
2021-11-23 22:48:40 +00:00
|
|
|
check:
|
|
|
|
msgValidate1 == MessageValidationResult.Valid
|
2022-05-10 21:09:18 +00:00
|
|
|
msgValidate2 == MessageValidationResult.Spam
|
2021-11-23 22:48:40 +00:00
|
|
|
msgValidate3 == MessageValidationResult.Valid
|
|
|
|
msgValidate4 == MessageValidationResult.Invalid
|
2023-08-21 06:55:34 +00:00
|
|
|
|
2023-07-07 11:58:37 +00:00
|
|
|
asyncTest "should validate invalid proofs if bandwidth is available":
|
|
|
|
let index = MembershipIndex(5)
|
|
|
|
|
|
|
|
let rlnConf = WakuRlnConfig(rlnRelayDynamic: false,
|
|
|
|
rlnRelayCredIndex: index.uint,
|
|
|
|
rlnRelayBandwidthThreshold: 4,
|
|
|
|
rlnRelayTreePath: genTempPath("rln_tree", "waku_rln_relay_3"))
|
|
|
|
let wakuRlnRelayRes = await WakuRlnRelay.new(rlnConf)
|
|
|
|
require:
|
|
|
|
wakuRlnRelayRes.isOk()
|
|
|
|
let wakuRlnRelay = wakuRlnRelayRes.get()
|
|
|
|
|
|
|
|
# get the current epoch time
|
|
|
|
let time = epochTime()
|
|
|
|
|
|
|
|
# create some messages from the same peer and append rln proof to them, except wm4
|
|
|
|
var
|
|
|
|
# this one will pass through the bandwidth threshold
|
|
|
|
wm1 = WakuMessage(payload: "Spam".toBytes())
|
|
|
|
# this message, will be over the bandwidth threshold, hence has to be verified
|
|
|
|
wm2 = WakuMessage(payload: "Valid message".toBytes())
|
|
|
|
# this message will be over the bandwidth threshold, hence has to be verified, will be false (since no proof)
|
|
|
|
wm3 = WakuMessage(payload: "Invalid message".toBytes())
|
|
|
|
wm4 = WakuMessage(payload: "Spam message".toBytes())
|
2023-08-21 06:55:34 +00:00
|
|
|
|
2023-07-07 11:58:37 +00:00
|
|
|
let
|
|
|
|
proofAdded1 = wakuRlnRelay.appendRLNProof(wm1, time)
|
|
|
|
proofAdded2 = wakuRlnRelay.appendRLNProof(wm2, time+EpochUnitSeconds)
|
|
|
|
proofAdded3 = wakuRlnRelay.appendRLNProof(wm4, time)
|
|
|
|
|
|
|
|
# ensure proofs are added
|
|
|
|
require:
|
|
|
|
proofAdded1
|
|
|
|
proofAdded2
|
|
|
|
proofAdded3
|
|
|
|
|
|
|
|
# validate messages
|
|
|
|
# validateMessage proc checks the validity of the message fields and adds it to the log (if valid)
|
|
|
|
let
|
|
|
|
# this should be no verification, Valid
|
|
|
|
msgValidate1 = wakuRlnRelay.validateMessage(wm1, some(time))
|
|
|
|
# this should be verification, Valid
|
|
|
|
msgValidate2 = wakuRlnRelay.validateMessage(wm2, some(time))
|
|
|
|
# this should be verification, Invalid
|
|
|
|
msgValidate3 = wakuRlnRelay.validateMessage(wm3, some(time))
|
|
|
|
# this should be verification, Spam
|
|
|
|
msgValidate4 = wakuRlnRelay.validateMessage(wm4, some(time))
|
|
|
|
|
|
|
|
check:
|
|
|
|
msgValidate1 == MessageValidationResult.Valid
|
|
|
|
msgValidate2 == MessageValidationResult.Valid
|
|
|
|
msgValidate3 == MessageValidationResult.Invalid
|
|
|
|
msgValidate4 == MessageValidationResult.Spam
|
2023-08-21 06:55:34 +00:00
|
|
|
|
2022-08-05 20:58:19 +00:00
|
|
|
|
2022-05-30 19:14:07 +00:00
|
|
|
test "toIDCommitment and toUInt256":
|
|
|
|
# create an instance of rln
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
|
|
|
|
|
|
|
let rln = rlnInstance.get()
|
2023-02-13 10:43:49 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
# create an idendity credential
|
|
|
|
let idCredentialRes = rln.membershipKeyGen()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredentialRes.isOk()
|
2022-11-04 03:00:42 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let idCredential = idCredentialRes.get()
|
2022-05-30 19:14:07 +00:00
|
|
|
|
|
|
|
# convert the idCommitment to UInt256
|
2022-12-14 11:28:09 +00:00
|
|
|
let idCUInt = idCredential.idCommitment.toUInt256()
|
2022-05-30 19:14:07 +00:00
|
|
|
# convert the UInt256 back to ICommitment
|
|
|
|
let idCommitment = toIDCommitment(idCUInt)
|
2021-11-23 22:48:40 +00:00
|
|
|
|
2022-05-30 19:14:07 +00:00
|
|
|
# check that the conversion has not distorted the original value
|
|
|
|
check:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredential.idCommitment == idCommitment
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2022-10-28 09:13:05 +00:00
|
|
|
test "Read/Write RLN credentials":
|
2022-08-05 10:48:01 +00:00
|
|
|
# create an RLN instance
|
2023-06-19 08:16:05 +00:00
|
|
|
let rlnInstance = createRLNInstanceWrapper()
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
|
|
|
rlnInstance.isOk()
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let idCredentialRes = membershipKeyGen(rlnInstance.get())
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredentialRes.isOk()
|
2022-11-04 03:00:42 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
let idCredential = idCredentialRes.get()
|
2022-12-07 17:17:08 +00:00
|
|
|
let empty = default(array[32, byte])
|
|
|
|
require:
|
2022-12-14 11:28:09 +00:00
|
|
|
idCredential.idTrapdoor.len == 32
|
|
|
|
idCredential.idNullifier.len == 32
|
|
|
|
idCredential.idSecretHash.len == 32
|
|
|
|
idCredential.idCommitment.len == 32
|
|
|
|
idCredential.idTrapdoor != empty
|
|
|
|
idCredential.idNullifier != empty
|
|
|
|
idCredential.idSecretHash != empty
|
|
|
|
idCredential.idCommitment != empty
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2022-12-14 11:28:09 +00:00
|
|
|
debug "the generated identity credential: ", idCredential
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2023-02-08 15:26:23 +00:00
|
|
|
let index = MembershipIndex(1)
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2023-02-08 15:26:23 +00:00
|
|
|
let rlnMembershipContract = MembershipContract(chainId: "5", address: "0x0123456789012345678901234567890123456789")
|
|
|
|
let rlnMembershipGroup = MembershipGroup(membershipContract: rlnMembershipContract, treeIndex: index)
|
|
|
|
let rlnMembershipCredentials = MembershipCredentials(identityCredential: idCredential, membershipGroups: @[rlnMembershipGroup])
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2022-10-28 09:13:05 +00:00
|
|
|
let password = "%m0um0ucoW%"
|
|
|
|
|
|
|
|
let filepath = "./testRLNCredentials.txt"
|
|
|
|
defer: removeFile(filepath)
|
2022-08-05 10:48:01 +00:00
|
|
|
|
|
|
|
# Write RLN credentials
|
2022-11-04 03:00:42 +00:00
|
|
|
require:
|
2023-02-08 15:26:23 +00:00
|
|
|
addMembershipCredentials(path = filepath,
|
|
|
|
credentials = @[rlnMembershipCredentials],
|
|
|
|
password = password,
|
|
|
|
appInfo = RLNAppInfo).isOk()
|
2023-02-13 10:43:49 +00:00
|
|
|
|
2023-02-08 15:26:23 +00:00
|
|
|
let readCredentialsResult = getMembershipCredentials(path = filepath,
|
|
|
|
password = password,
|
|
|
|
filterMembershipContracts = @[rlnMembershipContract],
|
|
|
|
appInfo = RLNAppInfo)
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2022-12-07 17:17:08 +00:00
|
|
|
require:
|
2022-10-28 09:13:05 +00:00
|
|
|
readCredentialsResult.isOk()
|
|
|
|
|
2023-02-08 15:26:23 +00:00
|
|
|
# getMembershipCredentials returns all credentials in keystore as sequence matching the filter
|
|
|
|
let allMatchingCredentials = readCredentialsResult.get()
|
2023-02-13 10:43:49 +00:00
|
|
|
# if any is found, we return the first credential, otherwise credentials is none
|
2023-02-08 15:26:23 +00:00
|
|
|
var credentials = none(MembershipCredentials)
|
|
|
|
if allMatchingCredentials.len() > 0:
|
|
|
|
credentials = some(allMatchingCredentials[0])
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2022-12-07 17:17:08 +00:00
|
|
|
require:
|
2022-10-28 09:13:05 +00:00
|
|
|
credentials.isSome()
|
2022-12-07 17:17:08 +00:00
|
|
|
check:
|
2022-12-14 11:28:09 +00:00
|
|
|
credentials.get().identityCredential == idCredential
|
2023-02-08 15:26:23 +00:00
|
|
|
credentials.get().membershipGroups == @[rlnMembershipGroup]
|
2022-10-28 09:13:05 +00:00
|
|
|
|
2022-09-30 12:43:42 +00:00
|
|
|
test "histogram static bucket generation":
|
|
|
|
let buckets = generateBucketsForHistogram(10)
|
2022-08-05 10:48:01 +00:00
|
|
|
|
2022-09-30 12:43:42 +00:00
|
|
|
check:
|
|
|
|
buckets.len == 5
|
|
|
|
buckets == [2.0, 4.0, 6.0, 8.0, 10.0]
|