diff --git a/tests/v2/test_waku_rln_relay.nim b/tests/v2/test_waku_rln_relay.nim index 5867d0888d..f5bde7eb83 100644 --- a/tests/v2/test_waku_rln_relay.nim +++ b/tests/v2/test_waku_rln_relay.nim @@ -1045,9 +1045,9 @@ suite "Waku rln relay": let index = MembershipIndex(1) + let rlnMembershipContract = MembershipContract(chainId: "5", address: "0x0123456789012345678901234567890123456789") let rlnMembershipCredentials = MembershipCredentials(identityCredential: idCredential, - membershipGroups: @[MembershipGroup(chainId: "5", - contract: "0x0123456789012345678901234567890123456789", + membershipGroups: @[MembershipGroup(membershipContract: rlnMembershipContract, treeIndex: index) ]) let password = "%m0um0ucoW%" diff --git a/waku/v2/node/waku_node.nim b/waku/v2/node/waku_node.nim index 841d87854a..a32760f7ea 100644 --- a/waku/v2/node/waku_node.nim +++ b/waku/v2/node/waku_node.nim @@ -285,7 +285,7 @@ proc info*(node: WakuNode): WakuInfo = proc connectToNodes*(node: WakuNode, nodes: seq[RemotePeerInfo] | seq[string], source = "api") {.async.} = ## `source` indicates source of node addrs (static config, api call, discovery, etc) # NOTE This is dialing on WakuRelay protocol specifically - await connectToNodes(node.peerManager, nodes, WakuRelayCodec, source=source) + await peer_manager.connectToNodes(node.peerManager, nodes, WakuRelayCodec, source=source) ## Waku relay diff --git a/waku/v2/protocol/waku_rln_relay/constants.nim b/waku/v2/protocol/waku_rln_relay/constants.nim index 4d0f06754a..01d8f0b6af 100644 --- a/waku/v2/protocol/waku_rln_relay/constants.nim +++ b/waku/v2/protocol/waku_rln_relay/constants.nim @@ -53,4 +53,6 @@ const MaxEpochGap* = uint64(MaxClockGapSeconds/EpochUnitSeconds) const KeystoreApplication* = "nwaku-rln-relay" KeystoreAppIdentifier* = "01234567890abcdef" - KeystoreVersion* = "0.1" \ No newline at end of file + KeystoreVersion* = "0.1" + # NOTE: 256-bytes long credentials are due to the use of BN254 in RLN. Other implementations/curves might have a different byte size + CredentialByteSize* = 256 \ No newline at end of file diff --git a/waku/v2/protocol/waku_rln_relay/conversion_utils.nim b/waku/v2/protocol/waku_rln_relay/conversion_utils.nim index 5fa412c294..b698fbd277 100644 --- a/waku/v2/protocol/waku_rln_relay/conversion_utils.nim +++ b/waku/v2/protocol/waku_rln_relay/conversion_utils.nim @@ -10,9 +10,11 @@ import stew/[arrayops, results, endians2], stint import + ./constants, ./protocol_types import - ../../utils/keyfile + ../../utils/keyfile, + ../../utils/credentials export web3, @@ -27,7 +29,7 @@ proc toUInt256*(idCommitment: IDCommitment): UInt256 = return pk proc toIDCommitment*(idCommitmentUint: UInt256): IDCommitment = - let pk = IDCommitment(idCommitmentUint.toBytesLE()) + let pk = IDCommitment(@(idCommitmentUint.toBytesLE())) return pk proc inHex*(value: array[32, byte]): string = @@ -115,10 +117,10 @@ proc toIdentityCredentials*(groupKeys: seq[(string, string, string, string)]): R for i in 0..groupKeys.len-1: try: let - idTrapdoor = hexToUint[IdentityTrapdoor.len*8](groupKeys[i][0]).toBytesLE() - idNullifier = hexToUint[IdentityNullifier.len*8](groupKeys[i][1]).toBytesLE() - idSecretHash = hexToUint[IdentitySecretHash.len*8](groupKeys[i][2]).toBytesLE() - idCommitment = hexToUint[IDCommitment.len*8](groupKeys[i][3]).toBytesLE() + idTrapdoor = IdentityTrapdoor(@(hexToUint[CredentialByteSize](groupKeys[i][0]).toBytesLE())) + idNullifier = IdentityNullifier(@(hexToUint[CredentialByteSize](groupKeys[i][1]).toBytesLE())) + idSecretHash = IdentitySecretHash(@(hexToUint[CredentialByteSize](groupKeys[i][2]).toBytesLE())) + idCommitment = IDCommitment(@(hexToUint[CredentialByteSize](groupKeys[i][3]).toBytesLE())) groupIdCredentials.add(IdentityCredential(idTrapdoor: idTrapdoor, idNullifier: idNullifier, idSecretHash: idSecretHash, idCommitment: idCommitment)) except ValueError as err: @@ -138,8 +140,8 @@ proc toIdentityCredentials*(groupKeys: seq[(string, string)]): RlnRelayResult[se for i in 0..groupKeys.len-1: try: let - idSecretHash = hexToUint[IdentitySecretHash.len*8](groupKeys[i][0]).toBytesLE() - idCommitment = hexToUint[IDCommitment.len*8](groupKeys[i][1]).toBytesLE() + idSecretHash = IdentitySecretHash(@(hexToUint[CredentialByteSize](groupKeys[i][0]).toBytesLE())) + idCommitment = IDCommitment(@(hexToUint[CredentialByteSize](groupKeys[i][1]).toBytesLE())) groupIdCredentials.add(IdentityCredential(idSecretHash: idSecretHash, idCommitment: idCommitment)) except ValueError as err: diff --git a/waku/v2/protocol/waku_rln_relay/rln/wrappers.nim b/waku/v2/protocol/waku_rln_relay/rln/wrappers.nim index d80837a867..33ce239a19 100644 --- a/waku/v2/protocol/waku_rln_relay/rln/wrappers.nim +++ b/waku/v2/protocol/waku_rln_relay/rln/wrappers.nim @@ -11,6 +11,7 @@ import ../protocol_metrics, ../constants import + ../../../utils/credentials, ../../../utils/time logScope: @@ -47,7 +48,7 @@ proc membershipKeyGen*(ctxPtr: ptr RLN): RlnRelayResult[IdentityCredential] = for (i, x) in idCommitment.mpairs: x = generatedKeys[i+3*32] var - identityCredential = IdentityCredential(idTrapdoor: idTrapdoor, idNullifier: idNullifier, idSecretHash: idSecretHash, idCommitment: idCommitment) + identityCredential = IdentityCredential(idTrapdoor: @idTrapdoor, idNullifier: @idNullifier, idSecretHash: @idSecretHash, idCommitment: @idCommitment) return ok(identityCredential) diff --git a/waku/v2/protocol/waku_rln_relay/utils.nim b/waku/v2/protocol/waku_rln_relay/utils.nim index 4d018b413a..0021912b2d 100644 --- a/waku/v2/protocol/waku_rln_relay/utils.nim +++ b/waku/v2/protocol/waku_rln_relay/utils.nim @@ -4,7 +4,7 @@ else: {.push raises: [].} import - std/[sequtils, tables, times, os, deques], + std/[algorithm, sequtils, tables, times, os, deques], chronicles, options, chronos, stint, confutils, strutils, @@ -51,7 +51,7 @@ type MembershipTuple* = tuple[index: MembershipIndex, idComm: IDCommitment] # membership contract interface -contract(MembershipContract): +contract(MembershipContractInterface): proc register(pubkey: Uint256) # external payable proc MemberRegistered(pubkey: Uint256, index: Uint256) {.event.} # TODO the followings are to be supported @@ -67,10 +67,11 @@ proc inHex*(value: MerkleNode or Nullifier or Epoch or - RlnIdentifier + RlnIdentifier ): string = - var valueHex = UInt256.fromBytesLE(value) - valueHex = valueHex.toHex() + var valueHex = "" #UInt256.fromBytesLE(value) + for b in value.reversed(): + valueHex = valueHex & b.toHex() # We pad leading zeroes while valueHex.len < value.len * 2: valueHex = "0" & valueHex @@ -96,7 +97,7 @@ proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAcco # when the private key is set in a web3 instance, the send proc (sender.register(pk).send(MembershipFee)) # does the signing using the provided key # web3.privateKey = some(ethAccountPrivateKey) - var sender = web3.contractSender(MembershipContract, membershipContractAddress) # creates a Sender object with a web3 field and contract address of type Address + var sender = web3.contractSender(MembershipContractInterface, membershipContractAddress) # creates a Sender object with a web3 field and contract address of type Address debug "registering an id commitment", idComm=idComm.inHex() let pk = idComm.toUInt256() @@ -564,7 +565,7 @@ proc getHistoricalEvents*(ethClientUri: string, ## returns a table that maps block numbers to the list of members registered in that block ## returns an error if it cannot retrieve the historical events let web3 = await newWeb3(ethClientUri) - let contract = web3.contractSender(MembershipContract, contractAddress) + let contract = web3.contractSender(MembershipContractInterface, contractAddress) # Get the historical events, and insert memberships into the tree let historicalEvents = await contract.getJsonLogs(MemberRegistered, fromBlock=some(fromBlock.blockId()), @@ -593,11 +594,11 @@ proc subscribeToGroupEvents*(ethClientUri: string, blockNumber: string = "0x0", handler: GroupUpdateHandler) {.async, gcsafe.} = ## connects to the eth client whose URI is supplied as `ethClientUri` - ## subscribes to the `MemberRegistered` event emitted from the `MembershipContract` which is available on the supplied `contractAddress` + ## subscribes to the `MemberRegistered` event emitted from the `MembershipContractInterface` which is available on the supplied `contractAddress` ## it collects all the events starting from the given `blockNumber` ## for every received block, it calls the `handler` let web3 = await newWeb3(ethClientUri) - let contract = web3.contractSender(MembershipContract, contractAddress) + let contract = web3.contractSender(MembershipContractInterface, contractAddress) let blockTableRes = await getHistoricalEvents(ethClientUri, contractAddress, @@ -731,7 +732,7 @@ proc mountRlnRelayStatic*(wakuRelay: WakuRelay, debug "mounting rln-relay in off-chain/static mode" # check the peer's index and the inclusion of user's identity commitment in the group - if not memIdCredential.idCommitment == group[int(memIndex)]: + if memIdCredential.idCommitment != group[int(memIndex)]: return err("The peer's index is not consistent with the group") # create an RLN instance @@ -988,12 +989,12 @@ proc mount(wakuRelay: WakuRelay, let wakuRlnRelay = rlnRelayRes.get() if persistCredentials: # persist rln credential + let contract = MembershipContract(chainId: "5", # This is Goerli ChainID. TODO: pass chainId to web3 as config option + address: conf.rlnRelayEthContractAddress) + credentials = some(MembershipCredentials(identityCredential: wakuRlnRelay.identityCredential, - membershipGroups: @[MembershipGroup(chainId: "5", # This is Goerli ChainID. TODO: pass chainId to web3 as config option - contract: conf.rlnRelayEthContractAddress, - treeIndex: wakuRlnRelay.membershipIndex) - ] - )) + membershipGroups: @[MembershipGroup(membershipContract: contract, treeIndex: wakuRlnRelay.membershipIndex)] + )) if writeMembershipCredentials(rlnRelayCredPath, credentials.get(), conf.rlnRelayCredentialsPassword).isErr(): return err("error in storing rln credentials") return ok(wakuRlnRelay)