mirror of https://github.com/waku-org/nwaku.git
fix(rln-relay): feature guard
This commit is contained in:
parent
07833ce313
commit
9344f41a34
|
@ -86,6 +86,7 @@ type
|
|||
wakuFilter*: WakuFilter
|
||||
wakuFilterClient*: WakuFilterClient
|
||||
wakuSwap*: WakuSwap
|
||||
when defined(rln):
|
||||
wakuRlnRelay*: WakuRLNRelay
|
||||
wakuLightPush*: WakuLightPush
|
||||
wakuLightpushClient*: WakuLightPushClient
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue