diff --git a/tests/waku_rln_relay/test_waku_rln_relay.nim b/tests/waku_rln_relay/test_waku_rln_relay.nim index 94a2315e19..1bf6495043 100644 --- a/tests/waku_rln_relay/test_waku_rln_relay.nim +++ b/tests/waku_rln_relay/test_waku_rln_relay.nim @@ -7,7 +7,9 @@ import chronos, chronicles, stint, - libp2p/crypto/crypto + libp2p/crypto/crypto, + random + import waku/[ waku_core, @@ -638,3 +640,34 @@ suite "Waku rln relay": var testEpochSizes: seq[uint] = @[1, 5, 10, 30, 60, 600] for i in testEpochSizes: await runTestForEpochSizeSec(i) + + asyncTest "testing rln-relay rate limit testing ": + let index = MembershipIndex(7) + + # Generate a random rate limit between 20 and 600 + randomize() + let randomRateLimit = rand(20 .. 600).uint + + let wakuRlnConfig = getWakuRlnConfig(manager = manager, index = index) + let wakuRlnRelay = (await WakuRlnRelay.new(wakuRlnConfig)).valueOr: + raiseAssert $error + + let manager = cast[OnchainGroupManager](wakuRlnRelay.groupManager) + let idCredentials = generateCredentials(manager.rlnInstance) + + # Register the membership with the random rate limit + try: + waitFor manager.register(idCredentials, UserMessageLimit(randomRateLimit)) + except Exception, CatchableError: + assert false, + "exception raised when calling register: " & getCurrentExceptionMsg() + + # Fetch the rate limit for the registered membership + let rateLimitRes = + await manager.fetchMembershipRateLimit(idCredentials.idCommitment) + if rateLimitRes.isErr(): + raiseAssert "Failed to fetch membership rate limit: " & rateLimitRes.error + + let rateLimit = rateLimitRes.get() + check: + rateLimit == randomRateLimit.u256 # Check against the random rate limit diff --git a/waku/waku_rln_relay/group_manager/on_chain/group_manager.nim b/waku/waku_rln_relay/group_manager/on_chain/group_manager.nim index d1a7a1310a..5ac43ebbea 100644 --- a/waku/waku_rln_relay/group_manager/on_chain/group_manager.nim +++ b/waku/waku_rln_relay/group_manager/on_chain/group_manager.nim @@ -128,6 +128,32 @@ proc fetchMembershipStatus*( error "Failed to fetch membership set membership", error = getCurrentExceptionMsg() return err("Failed to fetch membership set membership: " & getCurrentExceptionMsg()) +proc fetchMembershipRateLimit*( + g: OnchainGroupManager, idCommitment: IDCommitment +): Future[Result[UInt256, string]] {.async.} = + ## Fetch the `rateLimit` of a membership by its idCommitment. + ## Decodes the first 32-byte word returned by `getMembershipInfo`. + try: + let params = idCommitment.reversed() + let resultBytes = await sendEthCallWithParams( + ethRpc = g.ethRpc.get(), + functionSignature = "getMembershipInfo(uint256)", + params = params, + fromAddress = g.ethRpc.get().defaultAccount, + toAddress = fromHex(Address, g.ethContractAddress), + chainId = g.chainId, + ) + if resultBytes.isErr(): + return err(resultBytes.error) + let bytes = resultBytes.get() + if bytes.len < 32: + return err("unexpected ABI response length " & $bytes.len) + let rateLimit = UInt256.fromBytesBE(bytes[0 .. 31]) + return ok(rateLimit) + except CatchableError: + error "Failed to fetch membership rate limit", error = getCurrentExceptionMsg() + return err("Failed to fetch membership rate limit: " & getCurrentExceptionMsg()) + proc fetchMaxMembershipRateLimit*( g: OnchainGroupManager ): Future[Result[UInt256, string]] {.async.} =