chore(rln-relay-v2): added tests for onchain rln-relay-v2 (#2482)

* chore(rln-relay-v2): added tests for onchain rln-relay-v2

* Update tests/waku_rln_relay/test_rln_group_manager_onchain.nim

Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com>

---------

Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com>
This commit is contained in:
Aaryamann Challani 2024-03-01 14:15:40 +05:30 committed by GitHub
parent 045091a9f2
commit 88ff928213
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 179 additions and 66 deletions

View File

@ -31,6 +31,11 @@ proc generateCredentials(rlnInstance: ptr RLN): IdentityCredential =
let credRes = membershipKeyGen(rlnInstance)
return credRes.get()
when defined(rln_v2):
proc getRateCommitment(idCredential: IdentityCredential, userMessageLimit: UserMessageLimit): RateCommitment =
return RateCommitment(idCommitment: idCredential.idCommitment,
userMessageLimit: userMessageLimit)
proc generateCredentials(rlnInstance: ptr RLN, n: int): seq[IdentityCredential] =
var credentials: seq[IdentityCredential]
for i in 0 ..< n:
@ -84,7 +89,11 @@ proc uploadRLNContract*(ethClientAddress: string): Future[Address] {.async.} =
debug "Address of the deployed registry contract: ", contractAddress
let registryContract = web3.contractSender(WakuRlnRegistry, contractAddress)
let newStorageReceipt = await registryContract.newStorage().send()
when defined(rln_v2):
let initReceipt = await registryContract.initialize().send()
let newStorageReceipt = await registryContract.newStorage(20.u256).send()
else:
let newStorageReceipt = await registryContract.newStorage().send()
debug "Receipt of the newStorage transaction: ", newStorageReceipt
let newBalance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
@ -278,14 +287,24 @@ suite "Onchain group manager":
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
require:
registrations.len == 1
registrations[0].idCommitment == credentials.idCommitment
registrations[0].index == 0
when defined(rln_v2):
require:
registrations[0].rateCommitment == getRateCommitment(credentials, UserMessageLimit(1))
else:
require:
registrations[0].idCommitment == credentials.idCommitment
require:
registrations[0].index == 0
fut.complete()
return callback
try:
manager.onRegister(generateCallback(fut))
await manager.register(credentials)
when defined(rln_v2):
await manager.register(credentials, UserMessageLimit(1))
else:
await manager.register(credentials)
await manager.startGroupSync()
except Exception, CatchableError:
assert false, "exception raised: " & getCurrentExceptionMsg()
@ -319,11 +338,18 @@ suite "Onchain group manager":
proc generateCallback(futs: TestGroupSyncFuts, credentials: seq[IdentityCredential]): OnRegisterCallback =
var futureIndex = 0
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
if registrations.len == 1 and
registrations[0].idCommitment == credentials[futureIndex].idCommitment and
registrations[0].index == MembershipIndex(futureIndex):
futs[futureIndex].complete()
futureIndex += 1
when defined(rln_v2):
if registrations.len == 1 and
registrations[0].rateCommitment == getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) and
registrations[0].index == MembershipIndex(futureIndex):
futs[futureIndex].complete()
futureIndex += 1
else:
if registrations.len == 1 and
registrations[0].idCommitment == credentials[futureIndex].idCommitment and
registrations[0].index == MembershipIndex(futureIndex):
futs[futureIndex].complete()
futureIndex += 1
return callback
try:
@ -331,7 +357,10 @@ suite "Onchain group manager":
await manager.startGroupSync()
for i in 0 ..< credentials.len():
await manager.register(credentials[i])
when defined(rln_v2):
await manager.register(credentials[i], UserMessageLimit(1))
else:
await manager.register(credentials[i])
except Exception, CatchableError:
assert false, "exception raised: " & getCurrentExceptionMsg()
@ -352,7 +381,11 @@ suite "Onchain group manager":
let dummyCommitment = default(IDCommitment)
try:
await manager.register(dummyCommitment)
when defined(rln_v2):
await manager.register(RateCommitment(idCommitment: dummyCommitment,
userMessageLimit: UserMessageLimit(1)))
else:
await manager.register(dummyCommitment)
except CatchableError:
assert true
except Exception:
@ -375,7 +408,11 @@ suite "Onchain group manager":
let merkleRootBefore = merkleRootBeforeRes.get()
try:
await manager.register(idCommitment)
when defined(rln_v2):
await manager.register(RateCommitment(idCommitment: idCommitment,
userMessageLimit: UserMessageLimit(1)))
else:
await manager.register(idCommitment)
except Exception, CatchableError:
assert false, "exception raised when calling register: " & getCurrentExceptionMsg()
@ -396,17 +433,27 @@ suite "Onchain group manager":
let fut = newFuture[void]()
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
when defined(rln_v2):
require:
registrations.len == 1
registrations[0].rateCommitment == RateCommitment(idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1))
else:
require:
registrations[0].idCommitment == idCommitment
require:
registrations.len == 1
registrations[0].idCommitment == idCommitment
registrations[0].index == 0
registrations.len == 1
fut.complete()
manager.onRegister(callback)
await manager.init()
try:
await manager.startGroupSync()
await manager.register(idCommitment)
when defined(rln_v2):
await manager.register(RateCommitment(idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1)))
else:
await manager.register(idCommitment)
except Exception, CatchableError:
assert false, "exception raised: " & getCurrentExceptionMsg()
@ -438,18 +485,27 @@ suite "Onchain group manager":
let fut = newFuture[void]()
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
if registrations.len == 1 and
registrations[0].idCommitment == credentials.idCommitment and
registrations[0].index == 0:
manager.idCredentials = some(credentials)
manager.membershipIndex = some(registrations[0].index)
fut.complete()
when defined(rln_v2):
if registrations.len == 1 and
registrations[0].rateCommitment == getRateCommitment(credentials, UserMessageLimit(1)) and
registrations[0].index == 0:
manager.idCredentials = some(credentials)
fut.complete()
else:
if registrations.len == 1 and
registrations[0].idCommitment == credentials.idCommitment and
registrations[0].index == 0:
manager.idCredentials = some(credentials)
fut.complete()
manager.onRegister(callback)
try:
await manager.startGroupSync()
await manager.register(credentials)
when defined(rln_v2):
await manager.register(credentials, UserMessageLimit(1))
else:
await manager.register(credentials)
except Exception, CatchableError:
assert false, "exception raised: " & getCurrentExceptionMsg()
@ -462,8 +518,14 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch)
when defined(rln_v2):
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch,
messageId = MessageId(1))
else:
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch)
require:
validProofRes.isOk()
let validProof = validProofRes.get()
@ -488,6 +550,8 @@ suite "Onchain group manager":
## Assume the registration occured out of band
manager.idCredentials = some(credentials)
manager.membershipIndex = some(MembershipIndex(0))
when defined(rln_v2):
manager.userMessageLimit = some(UserMessageLimit(1))
let messageBytes = "Hello".toBytes()
@ -496,8 +560,13 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch)
when defined(rln_v2):
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch,
messageId = MessageId(0))
else:
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch)
require:
validProofRes.isOk()
let validProof = validProofRes.get()
@ -517,18 +586,27 @@ suite "Onchain group manager":
let fut = newFuture[void]()
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
if registrations.len == 1 and
registrations[0].idCommitment == credentials.idCommitment and
registrations[0].index == 0:
manager.idCredentials = some(credentials)
manager.membershipIndex = some(registrations[0].index)
fut.complete()
when defined(rln_v2):
if registrations.len == 1 and
registrations[0].rateCommitment == getRateCommitment(credentials, UserMessageLimit(1)) and
registrations[0].index == 0:
manager.idCredentials = some(credentials)
fut.complete()
else:
if registrations.len == 1 and
registrations[0].idCommitment == credentials.idCommitment and
registrations[0].index == 0:
manager.idCredentials = some(credentials)
fut.complete()
manager.onRegister(callback)
try:
await manager.startGroupSync()
await manager.register(credentials)
when defined(rln_v2):
await manager.register(credentials, UserMessageLimit(1))
else:
await manager.register(credentials)
except Exception, CatchableError:
assert false, "exception raised: " & getCurrentExceptionMsg()
await fut
@ -540,8 +618,13 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch)
when defined(rln_v2):
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch,
messageId = MessageId(0))
else:
let validProofRes = manager.generateProof(data = messageBytes,
epoch = epoch)
require:
validProofRes.isOk()
let validProof = validProofRes.get()
@ -566,7 +649,10 @@ suite "Onchain group manager":
let idCredential = generateCredentials(manager.rlnInstance)
try:
await manager.register(idCredential.idCommitment)
when defined(rln_v2):
await manager.register(getRateCommitment(idCredential, UserMessageLimit(1)))
else:
await manager.register(idCredential.idCommitment)
except Exception, CatchableError:
assert false, "exception raised when calling startGroupSync: " & getCurrentExceptionMsg()
@ -575,6 +661,8 @@ suite "Onchain group manager":
## Assume the registration occured out of band
manager.idCredentials = some(idCredential2)
manager.membershipIndex = some(MembershipIndex(0))
when defined(rln_v2):
manager.userMessageLimit = some(UserMessageLimit(1))
let messageBytes = "Hello".toBytes()
@ -583,8 +671,14 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let invalidProofRes = manager.generateProof(data = messageBytes,
epoch = epoch)
when defined(rln_v2):
let invalidProofRes = manager.generateProof(data = messageBytes,
epoch = epoch,
messageId = MessageId(0))
else:
let invalidProofRes = manager.generateProof(data = messageBytes,
epoch = epoch)
require:
invalidProofRes.isOk()
let invalidProof = invalidProofRes.get()
@ -613,18 +707,28 @@ suite "Onchain group manager":
proc generateCallback(futs: TestBackfillFuts, credentials: seq[IdentityCredential]): OnRegisterCallback =
var futureIndex = 0
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
if registrations.len == 1 and
registrations[0].idCommitment == credentials[futureIndex].idCommitment and
registrations[0].index == MembershipIndex(futureIndex):
futs[futureIndex].complete()
futureIndex += 1
when defined(rln_v2):
if registrations.len == 1 and
registrations[0].rateCommitment == getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) and
registrations[0].index == MembershipIndex(futureIndex):
futs[futureIndex].complete()
futureIndex += 1
else:
if registrations.len == 1 and
registrations[0].idCommitment == credentials[futureIndex].idCommitment and
registrations[0].index == MembershipIndex(futureIndex):
futs[futureIndex].complete()
futureIndex += 1
return callback
try:
manager.onRegister(generateCallback(futures, credentials))
await manager.startGroupSync()
for i in 0 ..< credentials.len():
await manager.register(credentials[i])
when defined(rln_v2):
await manager.register(credentials[i], UserMessageLimit(1))
else:
await manager.register(credentials[i])
except Exception, CatchableError:
assert false, "exception raised: " & getCurrentExceptionMsg()

View File

@ -258,8 +258,15 @@ procSuite "WakuNode - RLN relay":
contentTopicBytes = contentTopic.toBytes
input = concat(payload, contentTopicBytes)
extraBytes: seq[byte] = @[byte(1),2,3]
rateLimitProofRes = node1.wakuRlnRelay.groupManager.generateProof(concat(input, extraBytes), # we add extra bytes to invalidate proof verification against original payload
epoch)
when defined(rln_v2):
let nonceManager = node1.wakuRlnRelay.nonceManager
let rateLimitProofRes = node1.wakuRlnRelay.groupManager.generateProof(input,
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()
let rateLimitProof = rateLimitProofRes.get().encode().buffer

View File

@ -40,7 +40,9 @@ when defined(rln_v2):
# this serves as an entrypoint into the rln storage contract
proc register(storageIndex: Uint16, idCommitment: Uint256, userMessageLimit: Uint256)
# this creates a new storage on the rln registry
proc newStorage()
proc newStorage(maxMessageLimit: Uint256)
# Initializes the implementation contract (only used in unit tests)
proc initialize()
# membership contract interface
contract(RlnStorage):
@ -142,10 +144,8 @@ when defined(rln_v2):
initializedGuard(g)
# convert the rateCommitment struct to a leaf value
let leavesRes = rateCommitments.toLeaves()
if leavesRes.isErr():
raise newException(CatchableError, "failed to convert rateCommitments to leaves: " & leavesRes.error)
let leaves = cast[seq[seq[byte]]](leavesRes.get())
let leaves = rateCommitments.toLeaves().valueOr:
raise newException(ValueError, "failed to convert rateCommitments to leaves: " & $error)
waku_rln_membership_insertion_duration_seconds.nanosecondTime:
let operationSuccess = g.rlnInstance.atomicWrite(some(start),
@ -269,11 +269,10 @@ when defined(rln_v2):
let
argumentsBytes = arguments
# In TX log data, uints are encoded in big endian
userMessageLimit = UInt256.fromBytesBE(argumentsBytes[32..64])
membershipIndex = UInt256.fromBytesBE(argumentsBytes[64..^1])
g.userMessageLimit = some(userMessageLimit)
g.membershipIndex = some(membershipIndex.toMembershipIndex())
g.userMessageLimit = some(userMessageLimit.toUserMessageLimit())
# don't handle member insertion into the tree here, it will be handled by the event listener
return
@ -354,11 +353,11 @@ proc parseEvent(event: type MemberRegistered,
try:
# Parse the idComm
offset += decode(data, offset, idComm)
# Parse the index
offset += decode(data, offset, index)
when defined(rln_v2):
# Parse the userMessageLimit
offset += decode(data, offset, userMessageLimit)
# Parse the index
offset += decode(data, offset, index)
when defined(rln_v2):
return ok(Membership(rateCommitment: RateCommitment(idCommitment: idComm.toIDCommitment(),
userMessageLimit: userMessageLimit.toUserMessageLimit()),

View File

@ -52,7 +52,7 @@ proc init*(T: type NonceManager, nonceLimit: Nonce): T =
)
proc get*(n: NonceManager): NonceManagerResult[Nonce] =
proc getNonce*(n: NonceManager): NonceManagerResult[Nonce] =
let now = getTime().toUnixFloat()
var retNonce = n.nextNonce

View File

@ -161,19 +161,22 @@ proc poseidon*(data: seq[seq[byte]]): RlnRelayResult[array[32, byte]] =
return ok(output)
when defined(rln_v2):
func toLeaf*(rateCommitment: RateCommitment): RlnRelayResult[MerkleNode] {.inline.} =
proc toLeaf*(rateCommitment: RateCommitment): RlnRelayResult[seq[byte]] =
let idCommitment = rateCommitment.idCommitment
let userMessageLimit = cast[array[32, byte]](rateCommitment.userMessageLimit)
let leafRes = poseidon(@[@idCommitment, @userMessageLimit])
return leafRes
let leaf = poseidon(@[@idCommitment, @userMessageLimit]).valueOr:
return err("could not convert the rate commitment to a leaf")
var retLeaf = newSeq[byte](leaf.len)
for i in 0..<leaf.len:
retLeaf[i] = leaf[i]
return ok(retLeaf)
func toLeaves*(rateCommitments: seq[RateCommitment]): RlnRelayResult[seq[MerkleNode]] {.inline.} =
var leaves = newSeq[MerkleNode](rateCommitments.len)
proc toLeaves*(rateCommitments: seq[RateCommitment]): RlnRelayResult[seq[seq[byte]]] =
var leaves = newSeq[seq[byte]]()
for rateCommitment in rateCommitments:
let leafRes = toLeaf(rateCommitment)
if leafRes.isErr():
return err("could not convert the rate commitment to a leaf: " & leafRes.error)
leaves.add(leafRes.get())
let leaf = toLeaf(rateCommitment).valueOr:
return err("could not convert the rate commitment to a leaf: " & $error)
leaves.add(leaf)
return ok(leaves)
# TODO: collocate this proc with the definition of the RateLimitProof

View File

@ -86,7 +86,7 @@ type WakuRLNRelay* = ref object of RootObj
groupManager*: GroupManager
onFatalErrorAction*: OnFatalErrorHandler
when defined(rln_v2):
nonceManager: NonceManager
nonceManager*: NonceManager
proc calcEpoch*(rlnPeer: WakuRLNRelay, t: float64): Epoch =
## gets time `t` as `flaot64` with subseconds resolution in the fractional part
@ -306,7 +306,7 @@ proc appendRLNProof*(rlnPeer: WakuRLNRelay,
let epoch = rlnPeer.calcEpoch(senderEpochTime)
when defined(rln_v2):
let nonce = rlnPeer.nonceManager.get().valueOr:
let nonce = rlnPeer.nonceManager.getNonce().valueOr:
return err("could not get new message id to generate an rln proof: " & $error)
let proof = rlnPeer.groupManager.generateProof(input, epoch, nonce).valueOr:
return err("could not generate rln-v2 proof: " & $error)