fix(rln-relay): feature guard

This commit is contained in:
rymnc 2022-11-11 16:28:24 +05:30
parent 07833ce313
commit 9344f41a34
No known key found for this signature in database
GPG Key ID: C740033EE3F41EBD
5 changed files with 1610 additions and 1602 deletions

View File

@ -86,6 +86,7 @@ type
wakuFilter*: WakuFilter
wakuFilterClient*: WakuFilterClient
wakuSwap*: WakuSwap
when defined(rln):
wakuRlnRelay*: WakuRLNRelay
wakuLightPush*: WakuLightPush
wakuLightpushClient*: WakuLightPushClient

View File

@ -40,6 +40,7 @@ type WakuMessage* = object
# the proof field indicates that the message is not a spam
# this field will be used in the rln-relay protocol
# XXX Experimental, this is part of https://rfc.vac.dev/spec/17/ spec and not yet part of WakuMessage spec
when defined(rln):
proof*: RateLimitProof
# The ephemeral field indicates if the message should
# be stored. bools and uints are
@ -56,6 +57,7 @@ proc encode*(message: WakuMessage): ProtoBuffer =
buf.write3(2, message.contentTopic)
buf.write3(3, message.version)
buf.write3(10, zint64(message.timestamp))
when defined(rln):
buf.write3(21, message.proof.encode())
buf.write3(31, uint64(message.ephemeral))
buf.finish3()
@ -75,6 +77,7 @@ proc decode*(T: type WakuMessage, buffer: seq[byte]): ProtoResult[T] =
msg.timestamp = Timestamp(timestamp)
# XXX Experimental, this is part of https://rfc.vac.dev/spec/17/ spec
when defined(rln):
var proofBytes: seq[byte]
discard ?pb.getField(21, proofBytes)
msg.proof = ?RateLimitProof.init(proofBytes)

View File

@ -1,41 +1,43 @@
import
stint
# Acceptable roots for merkle root validation of incoming messages
const AcceptableRootWindowSize* = 5
when defined(rln):
# RLN membership key and index files path
const
# Acceptable roots for merkle root validation of incoming messages
const AcceptableRootWindowSize* = 5
# RLN membership key and index files path
const
RlnCredentialsFilename* = "rlnCredentials.txt"
# inputs of the membership contract constructor
# TODO may be able to make these constants private and put them inside the waku_rln_relay_utils
const
# inputs of the membership contract constructor
# TODO may be able to make these constants private and put them inside the waku_rln_relay_utils
const
MembershipFee* = 1000000000000000.u256
# the current implementation of the rln lib supports a circuit for Merkle tree with depth 20
MerkleTreeDepth* = 20
EthClient* = "ws://127.0.0.1:8540"
const
const
# the size of poseidon hash output in bits
HashBitSize* = 256
# the size of poseidon hash output as the number hex digits
HashHexSize* = int(HashBitSize/4)
const
const
# The relative folder where the circuit, proving and verification key for RLN can be found
# Note that resources has to be compiled with respect to the above MerkleTreeDepth
RlnResourceFolder* = "vendor/zerokit/rln/resources/tree_height_" & $MerkleTreeDepth & "/"
# temporary variables to test waku-rln-relay performance in the static group mode
const
# temporary variables to test waku-rln-relay performance in the static group mode
const
StaticGroupSize* = 100
# StaticGroupKeys is a static list of 100 membership keys in the form of (identity key, identity commitment)
# keys are created locally, using createMembershipList proc from waku_rln_relay_utils module, and the results are hardcoded in here
# this list is temporary and is created to test the performance of waku-rln-relay for the static groups
# in the later versions, this static hardcoded group will be replaced with a dynamic one
const
const
StaticGroupKeys* = @[("2c0198101a2828a0ac6c9e58fc131e1bd83326a4f748ef592588eeb8c3112dc1",
"1ca742a54641e2de14c5cb87ad707fd869693f682cedb901e47b8138918aecb3"), (
"095177fd334629dbc29c5fc9e32addecfcb6a42f9673268810fa9f70d1a8191a",

View File

@ -16,11 +16,12 @@ import
type RlnRelayResult*[T] = Result[T, string]
## RLN is a Nim wrapper for the data types used in zerokit RLN
type RLN* {.incompleteStruct.} = object
type RLNResult* = RlnRelayResult[ptr RLN]
when defined(rln):
## RLN is a Nim wrapper for the data types used in zerokit RLN
type RLN* {.incompleteStruct.} = object
type RLNResult* = RlnRelayResult[ptr RLN]
type
type
# identity key as defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
IDKey* = array[32, byte]
# hash of identity key as defined ed in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
@ -31,8 +32,8 @@ type
RlnIdentifier* = array[32, byte]
ZKSNARK* = array[128, byte]
# Custom data types defined for waku rln relay -------------------------
type MembershipKeyPair* = object
# Custom data types defined for waku rln relay -------------------------
type MembershipKeyPair* = object
## user's identity key (a secret key) which is selected randomly
## see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
idKey*: IDKey
@ -41,7 +42,7 @@ type MembershipKeyPair* = object
# more details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
idCommitment*: IDCommitment
type RateLimitProof* = object
type RateLimitProof* = object
## RateLimitProof holds the public inputs to rln circuit as
## defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Public-Inputs
## the `proof` field carries the actual zkSNARK proof
@ -61,18 +62,18 @@ type RateLimitProof* = object
## Application specific RLN Identifier
rlnIdentifier*: RlnIdentifier
type MembershipIndex* = uint
type MembershipIndex* = uint
type RlnMembershipCredentials* = object
type RlnMembershipCredentials* = object
membershipKeyPair*: MembershipKeyPair
rlnIndex*: MembershipIndex
type ProofMetadata* = object
type ProofMetadata* = object
nullifier*: Nullifier
shareX*: MerkleNode
shareY*: MerkleNode
type WakuRLNRelay* = ref object
type WakuRLNRelay* = ref object
membershipKeyPair*: MembershipKeyPair
# membershipIndex denotes the index of a leaf in the Merkle tree
# that contains the pk of the current peer
@ -97,7 +98,7 @@ type WakuRLNRelay* = ref object
lastSeenMembershipIndex*: MembershipIndex # the last seen membership index
lastProcessedBlock*: BlockNumber # the last processed block number
type
type
MessageValidationResult* {.pure.} = enum
Valid,
Invalid,
@ -105,8 +106,8 @@ type
MerkleNodeResult* = RlnRelayResult[MerkleNode]
RateLimitProofResult* = RlnRelayResult[RateLimitProof]
# Protobufs enc and init
proc init*(T: type RateLimitProof, buffer: seq[byte]): ProtoResult[T] =
# Protobufs enc and init
proc init*(T: type RateLimitProof, buffer: seq[byte]): ProtoResult[T] =
var nsp: RateLimitProof
let pb = initProtoBuffer(buffer)
@ -140,7 +141,7 @@ proc init*(T: type RateLimitProof, buffer: seq[byte]): ProtoResult[T] =
return ok(nsp)
proc encode*(nsp: RateLimitProof): ProtoBuffer =
proc encode*(nsp: RateLimitProof): ProtoBuffer =
var output = initProtoBuffer()
output.write3(1, nsp.proof)

View File

@ -63,7 +63,8 @@ proc toBuffer*(x: openArray[byte]): Buffer =
let output = Buffer(`ptr`: cast[ptr uint8](baseAddr), len: uint(temp.len))
return output
proc createRLNInstanceLocal(d: int = MerkleTreeDepth): RLNResult =
when defined(rln):
proc createRLNInstanceLocal(d: int = MerkleTreeDepth): RLNResult =
## generates an instance of RLN
## An RLN instance supports both zkSNARKs logics and Merkle tree data structure and operations
## d indicates the depth of Merkle tree
@ -81,7 +82,7 @@ proc createRLNInstanceLocal(d: int = MerkleTreeDepth): RLNResult =
return err("error in parameters generation")
return ok(rlnInstance)
proc membershipKeyGen*(ctxPtr: ptr RLN): RlnRelayResult[MembershipKeyPair] =
proc membershipKeyGen*(ctxPtr: ptr RLN): RlnRelayResult[MembershipKeyPair] =
## generates a MembershipKeyPair that can be used for the registration into the rln membership contract
## Returns an error if the key generation fails
@ -112,7 +113,7 @@ proc membershipKeyGen*(ctxPtr: ptr RLN): RlnRelayResult[MembershipKeyPair] =
return ok(keypair)
proc createRLNInstance*(d: int = MerkleTreeDepth): RLNResult =
proc createRLNInstance*(d: int = MerkleTreeDepth): RLNResult =
## Wraps the rln instance creation for metrics
## Returns an error if the instance creation fails
var res: RLNResult
@ -120,26 +121,26 @@ proc createRLNInstance*(d: int = MerkleTreeDepth): RLNResult =
res = createRLNInstanceLocal(d)
return res
proc toUInt256*(idCommitment: IDCommitment): UInt256 =
proc toUInt256*(idCommitment: IDCommitment): UInt256 =
let pk = UInt256.fromBytesLE(idCommitment)
return pk
proc toIDCommitment*(idCommitmentUint: UInt256): IDCommitment =
proc toIDCommitment*(idCommitmentUint: UInt256): IDCommitment =
let pk = IDCommitment(idCommitmentUint.toBytesLE())
return pk
proc inHex*(value: IDKey or IDCommitment or MerkleNode or Nullifier or Epoch or RlnIdentifier): string =
proc inHex*(value: IDKey or IDCommitment or MerkleNode or Nullifier or Epoch or RlnIdentifier): string =
var valueHex = (UInt256.fromBytesLE(value)).toHex
# We pad leading zeroes
while valueHex.len < value.len * 2:
valueHex = "0" & valueHex
return valueHex
proc toMembershipIndex(v: UInt256): MembershipIndex =
proc toMembershipIndex(v: UInt256): MembershipIndex =
let membershipIndex: MembershipIndex = cast[MembershipIndex](v)
return membershipIndex
proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAccountPrivKey: keys.PrivateKey, ethClientAddress: string, membershipContractAddress: Address, registrationHandler: Option[RegistrationHandler] = none(RegistrationHandler)): Future[Result[MembershipIndex, string]] {.async.} =
proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAccountPrivKey: keys.PrivateKey, ethClientAddress: string, membershipContractAddress: Address, registrationHandler: Option[RegistrationHandler] = none(RegistrationHandler)): Future[Result[MembershipIndex, string]] {.async.} =
# TODO may need to also get eth Account Private Key as PrivateKey
## registers the idComm into the membership contract whose address is in rlnPeer.membershipContractAddress
@ -201,7 +202,7 @@ proc register*(idComm: IDCommitment, ethAccountAddress: Option[Address], ethAcco
handler(toHex(txHash))
return ok(toMembershipIndex(eventIndex))
proc register*(rlnPeer: WakuRLNRelay, registrationHandler: Option[RegistrationHandler] = none(RegistrationHandler)): Future[RlnRelayResult[bool]] {.async.} =
proc register*(rlnPeer: WakuRLNRelay, registrationHandler: Option[RegistrationHandler] = none(RegistrationHandler)): Future[RlnRelayResult[bool]] {.async.} =
## registers the public key of the rlnPeer which is rlnPeer.membershipKeyPair.publicKey
## into the membership contract whose address is in rlnPeer.membershipContractAddress
let pk = rlnPeer.membershipKeyPair.idCommitment
@ -210,7 +211,7 @@ proc register*(rlnPeer: WakuRLNRelay, registrationHandler: Option[RegistrationHa
return err(regResult.error())
return ok(true)
proc appendLength*(input: openArray[byte]): seq[byte] =
proc appendLength*(input: openArray[byte]): seq[byte] =
## returns length prefixed version of the input
## with the following format [len<8>|input<var>]
## len: 8-byte value that represents the number of bytes in the `input`
@ -222,7 +223,7 @@ proc appendLength*(input: openArray[byte]): seq[byte] =
output = concat(@len, @input)
return output
proc hash*(rlnInstance: ptr RLN, data: openArray[byte]): MerkleNode =
proc hash*(rlnInstance: ptr RLN, data: openArray[byte]): MerkleNode =
## a thin layer on top of the Nim wrapper of the Poseidon hasher
debug "hash input", hashhex = data.toHex()
var lenPrefData = appendLength(data)
@ -237,7 +238,7 @@ proc hash*(rlnInstance: ptr RLN, data: openArray[byte]): MerkleNode =
return output
proc serialize(idKey: IDKey, memIndex: MembershipIndex, epoch: Epoch,
proc serialize(idKey: IDKey, memIndex: MembershipIndex, epoch: Epoch,
msg: openArray[byte]): seq[byte] =
## a private proc to convert RateLimitProof and the data to a byte seq
## this conversion is used in the proofGen proc
@ -248,7 +249,7 @@ proc serialize(idKey: IDKey, memIndex: MembershipIndex, epoch: Epoch,
let output = concat(@idKey, @memIndexBytes, @epoch, lenPrefMsg)
return output
proc proofGen*(rlnInstance: ptr RLN, data: openArray[byte],
proc proofGen*(rlnInstance: ptr RLN, data: openArray[byte],
memKeys: MembershipKeyPair, memIndex: MembershipIndex,
epoch: Epoch): RateLimitProofResult =
@ -308,7 +309,7 @@ proc proofGen*(rlnInstance: ptr RLN, data: openArray[byte],
return ok(output)
proc serialize(proof: RateLimitProof, data: openArray[byte]): seq[byte] =
proc serialize(proof: RateLimitProof, data: openArray[byte]): seq[byte] =
## a private proc to convert RateLimitProof and data to a byte seq
## this conversion is used in the proof verification proc
## [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
@ -324,16 +325,16 @@ proc serialize(proof: RateLimitProof, data: openArray[byte]): seq[byte] =
return proofBytes
# Serializes a sequence of MerkleNodes
proc serialize(roots: seq[MerkleNode]): seq[byte] =
# Serializes a sequence of MerkleNodes
proc serialize(roots: seq[MerkleNode]): seq[byte] =
var rootsBytes: seq[byte] = @[]
for root in roots:
rootsBytes = concat(rootsBytes, @root)
return rootsBytes
# validRoots should contain a sequence of roots in the acceptable windows.
# As default, it is set to an empty sequence of roots. This implies that the validity check for the proof's root is skipped
proc proofVerify*(rlnInstance: ptr RLN,
# validRoots should contain a sequence of roots in the acceptable windows.
# As default, it is set to an empty sequence of roots. This implies that the validity check for the proof's root is skipped
proc proofVerify*(rlnInstance: ptr RLN,
data: openArray[byte],
proof: RateLimitProof,
validRoots: seq[MerkleNode] = @[]): RlnRelayResult[bool] =
@ -359,7 +360,7 @@ proc proofVerify*(rlnInstance: ptr RLN,
else:
return ok(true)
proc insertMember*(rlnInstance: ptr RLN, idComm: IDCommitment): bool =
proc insertMember*(rlnInstance: ptr RLN, idComm: IDCommitment): bool =
## inserts a member to the tree
## returns true if the member is inserted successfully
## returns false if the member could not be inserted
@ -370,7 +371,7 @@ proc insertMember*(rlnInstance: ptr RLN, idComm: IDCommitment): bool =
let memberAdded = update_next_member(rlnInstance, pkBufferPtr)
return memberAdded
proc serializeIdCommitments*(idComms: seq[IDCommitment]): seq[byte] =
proc serializeIdCommitments*(idComms: seq[IDCommitment]): seq[byte] =
## serializes a seq of IDCommitments to a byte seq
## the serialization is based on https://github.com/status-im/nwaku/blob/37bd29fbc37ce5cf636734e7dd410b1ed27b88c8/waku/v2/protocol/waku_rln_relay/rln.nim#L142
## the order of serialization is |id_commitment_len<8>|id_commitment<var>|
@ -385,7 +386,7 @@ proc serializeIdCommitments*(idComms: seq[IDCommitment]): seq[byte] =
return idCommsBytes
proc insertMembers*(rlnInstance: ptr RLN,
proc insertMembers*(rlnInstance: ptr RLN,
index: MembershipIndex,
idComms: seq[IDCommitment]): bool =
## Insert multiple members i.e., identity commitments
@ -402,11 +403,11 @@ proc insertMembers*(rlnInstance: ptr RLN,
let membersAdded = set_leaves_from(rlnInstance, index, idCommsBufferPtr)
return membersAdded
proc removeMember*(rlnInstance: ptr RLN, index: MembershipIndex): bool =
proc removeMember*(rlnInstance: ptr RLN, index: MembershipIndex): bool =
let deletion_success = delete_member(rlnInstance, index)
return deletion_success
proc getMerkleRoot*(rlnInstance: ptr RLN): MerkleNodeResult =
proc getMerkleRoot*(rlnInstance: ptr RLN): MerkleNodeResult =
# read the Merkle Tree root after insertion
var
root {.noinit.}: Buffer = Buffer()
@ -420,7 +421,7 @@ proc getMerkleRoot*(rlnInstance: ptr RLN): MerkleNodeResult =
var rootValue = cast[ptr MerkleNode] (root.`ptr`)[]
return ok(rootValue)
proc updateValidRootQueue*(wakuRlnRelay: WakuRLNRelay, root: MerkleNode): void =
proc updateValidRootQueue*(wakuRlnRelay: WakuRLNRelay, root: MerkleNode): void =
## updates the valid Merkle root queue with the latest root and pops the oldest one when the capacity of `AcceptableRootWindowSize` is reached
let overflowCount = wakuRlnRelay.validMerkleRoots.len() - AcceptableRootWindowSize
if overflowCount >= 0:
@ -430,7 +431,7 @@ proc updateValidRootQueue*(wakuRlnRelay: WakuRLNRelay, root: MerkleNode): void =
# Push the next root into the queue
wakuRlnRelay.validMerkleRoots.addLast(root)
proc insertMembers*(wakuRlnRelay: WakuRLNRelay,
proc insertMembers*(wakuRlnRelay: WakuRLNRelay,
index: MembershipIndex,
idComms: seq[IDCommitment]): RlnRelayResult[void] =
## inserts a sequence of id commitments into the local merkle tree, and adds the changed root to the
@ -445,7 +446,7 @@ proc insertMembers*(wakuRlnRelay: WakuRLNRelay,
wakuRlnRelay.updateValidRootQueue(rootAfterUpdate)
return ok()
proc removeMember*(wakuRlnRelay: WakuRLNRelay, index: MembershipIndex): RlnRelayResult[void] =
proc removeMember*(wakuRlnRelay: WakuRLNRelay, index: MembershipIndex): RlnRelayResult[void] =
## removes a commitment from the local merkle tree at `index`, and adds the changed root to the
## queue of valid roots
## Returns an error if the removal fails
@ -458,11 +459,11 @@ proc removeMember*(wakuRlnRelay: WakuRLNRelay, index: MembershipIndex): RlnRelay
wakuRlnRelay.updateValidRootQueue(rootAfterUpdate)
return ok()
proc validateRoot*(wakuRlnRelay: WakuRLNRelay, root: MerkleNode): bool =
proc validateRoot*(wakuRlnRelay: WakuRLNRelay, root: MerkleNode): bool =
## Validate against the window of roots stored in wakuRlnRelay.validMerkleRoots
return root in wakuRlnRelay.validMerkleRoots
proc toMembershipKeyPairs*(groupKeys: seq[(string, string)]): RlnRelayResult[seq[
proc toMembershipKeyPairs*(groupKeys: seq[(string, string)]): RlnRelayResult[seq[
MembershipKeyPair]] =
## groupKeys is sequence of membership key tuples in the form of (identity key, identity commitment) all in the hexadecimal format
## the toMembershipKeyPairs proc populates a sequence of MembershipKeyPairs using the supplied groupKeys
@ -482,7 +483,7 @@ proc toMembershipKeyPairs*(groupKeys: seq[(string, string)]): RlnRelayResult[seq
return err("could not convert the group key to bytes: " & err.msg)
return ok(groupKeyPairs)
proc calcMerkleRoot*(list: seq[IDCommitment]): RlnRelayResult[string] =
proc calcMerkleRoot*(list: seq[IDCommitment]): RlnRelayResult[string] =
## returns the root of the Merkle tree that is computed from the supplied list
## the root is in hexadecimal format
## Returns an error if the computation fails
@ -499,7 +500,7 @@ proc calcMerkleRoot*(list: seq[IDCommitment]): RlnRelayResult[string] =
let root = rln.getMerkleRoot().value().inHex()
return ok(root)
proc createMembershipList*(n: int): RlnRelayResult[(
proc createMembershipList*(n: int): RlnRelayResult[(
seq[(string, string)], string
)] =
## createMembershipList produces a sequence of membership key pairs in the form of (identity key, id commitment keys) in the hexadecimal format
@ -535,7 +536,7 @@ proc createMembershipList*(n: int): RlnRelayResult[(
let root = rln.getMerkleRoot().value().inHex()
return ok((output, root))
proc rlnRelayStaticSetUp*(rlnRelayMembershipIndex: MembershipIndex): RlnRelayResult[(Option[seq[
proc rlnRelayStaticSetUp*(rlnRelayMembershipIndex: MembershipIndex): RlnRelayResult[(Option[seq[
IDCommitment]], Option[MembershipKeyPair], Option[
MembershipIndex])] =
## rlnRelayStaticSetUp is a proc that is used to initialize the static group keys and the static membership index
@ -575,7 +576,7 @@ proc rlnRelayStaticSetUp*(rlnRelayMembershipIndex: MembershipIndex): RlnRelayRes
return ok((groupOpt, memKeyPairOpt, memIndexOpt))
proc hasDuplicate*(rlnPeer: WakuRLNRelay, msg: WakuMessage): RlnRelayResult[bool] =
proc hasDuplicate*(rlnPeer: WakuRLNRelay, msg: WakuMessage): RlnRelayResult[bool] =
## returns true if there is another message in the `nullifierLog` of the `rlnPeer` with the same
## epoch and nullifier as `msg`'s epoch and nullifier but different Shamir secret shares
## otherwise, returns false
@ -608,7 +609,7 @@ proc hasDuplicate*(rlnPeer: WakuRLNRelay, msg: WakuMessage): RlnRelayResult[bool
except KeyError as e:
return err("the epoch was not found")
proc updateLog*(rlnPeer: WakuRLNRelay, msg: WakuMessage): RlnRelayResult[bool] =
proc updateLog*(rlnPeer: WakuRLNRelay, msg: WakuMessage): RlnRelayResult[bool] =
## extracts the `ProofMetadata` of the supplied messages `msg` and
## saves it in the `nullifierLog` of the `rlnPeer`
## Returns an error if it cannot update the log
@ -632,7 +633,7 @@ proc updateLog*(rlnPeer: WakuRLNRelay, msg: WakuMessage): RlnRelayResult[bool] =
except KeyError as e:
return err("the epoch was not found")
proc toEpoch*(t: uint64): Epoch =
proc toEpoch*(t: uint64): Epoch =
## converts `t` to `Epoch` in little-endian order
let bytes = toBytes(t, Endianness.littleEndian)
debug "bytes", bytes = bytes
@ -640,22 +641,22 @@ proc toEpoch*(t: uint64): Epoch =
discard epoch.copyFrom(bytes)
return epoch
proc fromEpoch*(epoch: Epoch): uint64 =
proc fromEpoch*(epoch: Epoch): uint64 =
## decodes bytes of `epoch` (in little-endian) to uint64
let t = fromBytesLE(uint64, array[32, byte](epoch))
return t
proc calcEpoch*(t: float64): Epoch =
proc calcEpoch*(t: float64): Epoch =
## gets time `t` as `flaot64` with subseconds resolution in the fractional part
## and returns its corresponding rln `Epoch` value
let e = uint64(t/EpochUnitSeconds)
return toEpoch(e)
proc getCurrentEpoch*(): Epoch =
proc getCurrentEpoch*(): Epoch =
## gets the current rln Epoch time
return calcEpoch(epochTime())
proc absDiff*(e1, e2: Epoch): uint64 =
proc absDiff*(e1, e2: Epoch): uint64 =
## returns the absolute difference between the two rln `Epoch`s `e1` and `e2`
## i.e., e1 - e2
@ -670,7 +671,7 @@ proc absDiff*(e1, e2: Epoch): uint64 =
else:
return epoch2 - epoch1
proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage,
proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage,
timeOption: Option[float64] = none(float64)): MessageValidationResult =
## validate the supplied `msg` based on the waku-rln-relay routing protocol i.e.,
## the `msg`'s epoch is within MaxEpochGap of the current epoch
@ -751,7 +752,7 @@ proc validateMessage*(rlnPeer: WakuRLNRelay, msg: WakuMessage,
waku_rln_valid_messages_total.observe(rootIndex.toFloat())
return MessageValidationResult.Valid
proc toRLNSignal*(wakumessage: WakuMessage): seq[byte] =
proc toRLNSignal*(wakumessage: WakuMessage): seq[byte] =
## it is a utility proc that prepares the `data` parameter of the proof generation procedure i.e., `proofGen` that resides in the current module
## it extracts the `contentTopic` and the `payload` of the supplied `wakumessage` and serializes them into a byte sequence
let
@ -759,7 +760,7 @@ proc toRLNSignal*(wakumessage: WakuMessage): seq[byte] =
output = concat(wakumessage.payload, contentTopicBytes)
return output
proc appendRLNProof*(rlnPeer: WakuRLNRelay, msg: var WakuMessage,
proc appendRLNProof*(rlnPeer: WakuRLNRelay, msg: var WakuMessage,
senderEpochTime: float64): bool =
## returns true if it can create and append a `RateLimitProof` to the supplied `msg`
## returns false otherwise
@ -779,7 +780,7 @@ proc appendRLNProof*(rlnPeer: WakuRLNRelay, msg: var WakuMessage,
msg.proof = proof.value
return true
proc addAll*(wakuRlnRelay: WakuRLNRelay, list: seq[IDCommitment]): RlnRelayResult[void] =
proc addAll*(wakuRlnRelay: WakuRLNRelay, list: seq[IDCommitment]): RlnRelayResult[void] =
# add members to the Merkle tree of the `rlnInstance`
## Returns an error if it cannot add any member to the Merkle tree
let membersAdded = wakuRlnRelay.insertMembers(0, list)
@ -787,7 +788,7 @@ proc addAll*(wakuRlnRelay: WakuRLNRelay, list: seq[IDCommitment]): RlnRelayResul
return err("failed to add members to the Merkle tree")
return ok()
proc generateGroupUpdateHandler(rlnPeer: WakuRLNRelay): GroupUpdateHandler =
proc generateGroupUpdateHandler(rlnPeer: WakuRLNRelay): GroupUpdateHandler =
## assuming all the members arrive in order
## TODO: check the index and the pubkey depending on
## the group update operation
@ -813,7 +814,7 @@ proc generateGroupUpdateHandler(rlnPeer: WakuRLNRelay): GroupUpdateHandler =
return ok()
return handler
proc parse*(event: type MemberRegistered,
proc parse*(event: type MemberRegistered,
log: JsonNode): RlnRelayResult[MembershipTuple] =
## parses the `data` parameter of the `MemberRegistered` event `log`
## returns an error if it cannot parse the `data` parameter
@ -836,8 +837,8 @@ proc parse*(event: type MemberRegistered,
except:
return err("failed to parse the data field of the MemberRegistered event")
type BlockTable = OrderedTable[BlockNumber, seq[MembershipTuple]]
proc getHistoricalEvents*(ethClientUri: string,
type BlockTable = OrderedTable[BlockNumber, seq[MembershipTuple]]
proc getHistoricalEvents*(ethClientUri: string,
contractAddress: Address,
fromBlock: string = "0x0",
toBlock: string = "latest"): Future[RlnRelayResult[BlockTable]] {.async, gcsafe.} =
@ -871,7 +872,7 @@ proc getHistoricalEvents*(ethClientUri: string,
blockTable[blockNumber] = @[parsedEvent]
return ok(blockTable)
proc subscribeToGroupEvents*(ethClientUri: string,
proc subscribeToGroupEvents*(ethClientUri: string,
ethAccountAddress: Option[Address] = none(Address),
contractAddress: Address,
blockNumber: string = "0x0",
@ -937,7 +938,7 @@ proc subscribeToGroupEvents*(ethClientUri: string,
web3.onDisconnect = proc() =
debug "connection to ethereum node dropped", lastBlock = latestBlock
proc handleGroupUpdates*(rlnPeer: WakuRLNRelay) {.async, gcsafe.} =
proc handleGroupUpdates*(rlnPeer: WakuRLNRelay) {.async, gcsafe.} =
## generates the groupUpdateHandler which is called when a new member is registered,
## and has the WakuRLNRelay instance as a closure
let handler = generateGroupUpdateHandler(rlnPeer)
@ -946,7 +947,7 @@ proc handleGroupUpdates*(rlnPeer: WakuRLNRelay) {.async, gcsafe.} =
contractAddress = rlnPeer.membershipContractAddress,
handler = handler)
proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: PubsubTopic, contentTopic: ContentTopic, spamHandler: Option[SpamHandler] = none(SpamHandler)) =
proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: PubsubTopic, contentTopic: ContentTopic, spamHandler: Option[SpamHandler] = none(SpamHandler)) =
## this procedure is a thin wrapper for the pubsub addValidator method
## it sets a validator for the waku messages published on the supplied pubsubTopic and contentTopic
## if contentTopic is empty, then validation takes place for All the messages published on the given pubsubTopic
@ -993,7 +994,7 @@ proc addRLNRelayValidator*(node: WakuNode, pubsubTopic: PubsubTopic, contentTopi
let pb = PubSub(node.wakuRelay)
pb.addValidator(pubsubTopic, validator)
proc mountRlnRelayStatic*(node: WakuNode,
proc mountRlnRelayStatic*(node: WakuNode,
group: seq[IDCommitment],
memKeyPair: MembershipKeyPair,
memIndex: MembershipIndex,
@ -1044,7 +1045,7 @@ proc mountRlnRelayStatic*(node: WakuNode,
node.wakuRlnRelay = rlnPeer
return ok()
proc mountRlnRelayDynamic*(node: WakuNode,
proc mountRlnRelayDynamic*(node: WakuNode,
ethClientAddr: string = "",
ethAccountAddress: Option[web3.Address] = none(web3.Address),
ethAccountPrivKeyOpt: Option[keys.PrivateKey],
@ -1127,7 +1128,7 @@ proc mountRlnRelayDynamic*(node: WakuNode,
node.wakuRlnRelay = rlnPeer
return ok()
proc writeRlnCredentials*(path: string,
proc writeRlnCredentials*(path: string,
credentials: RlnMembershipCredentials,
password: string): RlnRelayResult[void] =
# Returns RlnRelayResult[void], which indicates the success of the call
@ -1141,9 +1142,9 @@ proc writeRlnCredentials*(path: string,
return err("Error while saving keyfile for RLN credentials")
return ok()
# Attempts decryptions of all keyfiles with the provided password.
# If one or more credentials are successfully decrypted, the max(min(index,number_decrypted),0)-th is returned.
proc readRlnCredentials*(path: string,
# Attempts decryptions of all keyfiles with the provided password.
# If one or more credentials are successfully decrypted, the max(min(index,number_decrypted),0)-th is returned.
proc readRlnCredentials*(path: string,
password: string,
index: int = 0): RlnRelayResult[Option[RlnMembershipCredentials]] =
# Returns RlnRelayResult[Option[RlnMembershipCredentials]], which indicates the success of the call
@ -1172,7 +1173,7 @@ proc readRlnCredentials*(path: string,
except:
return err("Error while loading keyfile for RLN credentials at " & path)
proc mount(node: WakuNode,
proc mount(node: WakuNode,
conf: WakuRlnConfig,
spamHandler: Option[SpamHandler] = none(SpamHandler),
registrationHandler: Option[RegistrationHandler] = none(RegistrationHandler)
@ -1317,7 +1318,7 @@ proc mount(node: WakuNode,
return err("dynamic rln-relay could not be mounted: " & res.error())
return ok()
proc mountRlnRelay*(node: WakuNode,
proc mountRlnRelay*(node: WakuNode,
conf: WakuRlnConfig,
spamHandler: Option[SpamHandler] = none(SpamHandler),
registrationHandler: Option[RegistrationHandler] = none(RegistrationHandler)