Skip to content

Commit

Permalink
Persisting rln credentials (#1037)
Browse files Browse the repository at this point in the history
* Persisting Credentials implemented by writing json of keypair and rlnindex to files

* Removing testing files and ignores

* Update waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim

Co-authored-by: Daniel Kaiser <[email protected]>

* Update waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim

Co-authored-by: Daniel Kaiser <[email protected]>

* Comments

* Comments

* Security warning in comments

* Redundant echos. Omitting unused variables.

* Update waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim

Co-authored-by: Hanno Cornelius <[email protected]>

* Limit line lengths using line breaks and indents

* Membership file paths declared as const

* Const fix

* Rln Credentials Merged.
Reading credentials from file abstracted away.

* Spaces

* Spaces

* Dangling constants removed. Comments position.

* Import sequence.

* Path as argument to readPersistentKeys.
Spaces in comments

* readPersistentKeys test

* Debug and info

* Index check in test

* Update tests/v2/test_waku_rln_relay.nim

Co-authored-by: G. <[email protected]>

* Abstracted writeRlnCredentials.
Fix var name in test.

* Usage of writeRlnCredentials in test

* Dnsclient?

* Test reverted to direct call to writeFile.
Abstrated writePersistentRlnCredentials usage causing error,
with readPersistentRlnCredentials

* Indentation

* Revert "Dnsclient?"

This reverts commit 3f4dba1.

* Reverting abstraction of writing..
..persiting credential

Co-authored-by: Daniel Kaiser <[email protected]>
Co-authored-by: Keshav Gupta <[email protected]>
Co-authored-by: Hanno Cornelius <[email protected]>
Co-authored-by: G. <[email protected]>
  • Loading branch information
5 people authored Aug 5, 2022
1 parent eebaffd commit 115982f
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 8 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ node_modules/
/.update.timestamp

# Ignore Jetbrains IDE files
.idea/
.idea/
rlnCredentials.txt
testPath.txt
37 changes: 37 additions & 0 deletions tests/v2/test_waku_rln_relay.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import
testutils/unittests, chronos, chronicles, stint,
stew/byteutils, stew/shims/net as stewNet,
libp2p/crypto/crypto,
json,
../../waku/v2/protocol/waku_rln_relay/[rln, waku_rln_relay_utils,
waku_rln_relay_types],
../../waku/v2/node/wakunode2,
Expand Down Expand Up @@ -720,3 +721,39 @@ suite "Waku rln relay":
# check that the conversion has not distorted the original value
check:
keypair.get().idCommitment == idCommitment

test "Read Persistent RLN credentials":
# create an RLN instance
var rlnInstance = createRLNInstance()
check:
rlnInstance.isOk == true

var key = membershipKeyGen(rlnInstance.value)
var empty: array[32, byte]
check:
key.isSome
key.get().idKey.len == 32
key.get().idCommitment.len == 32
key.get().idKey != empty
key.get().idCommitment != empty

debug "the generated membership key pair: ", key

let
k = key.get()
index = MembershipIndex(1)

var rlnMembershipCredentials = RlnMembershipCredentials(membershipKeyPair: k, rlnIndex: index)

let path = "testPath.txt"

# Write RLN credentials
writeFile(path, pretty(%rlnMembershipCredentials))

var credentials = readPersistentRlnCredentials(path)

check:
credentials.membershipKeyPair == k
credentials.rlnIndex == index


12 changes: 10 additions & 2 deletions waku/v2/protocol/waku_rln_relay/waku_rln_relay_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ type MembershipKeyPair* = object
# more details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership
idCommitment*: IDCommitment

type MembershipIndex* = uint

type RlnMembershipCredentials* = object
membershipKeyPair*: MembershipKeyPair
rlnIndex*: MembershipIndex

type RateLimitProof* = object
## RateLimitProof holds the public inputs to rln circuit as
## defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Public-Inputs
Expand All @@ -56,8 +62,6 @@ type RateLimitProof* = object
## see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Nullifiers
nullifier*: Nullifier

type MembershipIndex* = uint

type ProofMetadata* = object
nullifier*: Nullifier
shareX*: MerkleNode
Expand Down Expand Up @@ -87,6 +91,10 @@ type WakuRLNRelay* = ref object
type MessageValidationResult* {.pure.} = enum
Valid, Invalid, Spam

# RLN membership key and index files path
const
RLN_CREDENTIALS_FILEPATH* = "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
Expand Down
43 changes: 38 additions & 5 deletions waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import
std/sequtils, tables, times,
std/streams,
std/os,
chronicles, options, chronos, stint,
confutils,
web3, json,
Expand Down Expand Up @@ -741,7 +743,6 @@ proc mountRlnRelayStatic*(node: WakuNode,
node.wakuRlnRelay = rlnPeer



proc mountRlnRelayDynamic*(node: WakuNode,
ethClientAddr: string = "",
ethAccAddr: web3.Address,
Expand Down Expand Up @@ -788,9 +789,19 @@ proc mountRlnRelayDynamic*(node: WakuNode,
else: # if no eth private key is available, skip registration
debug "running waku-rln-relay in relay-only mode"
else:
debug "Peer is already registered to the membership contract"
keyPair = memKeyPair.get()
rlnIndex = memIndex.get()

var
rlnMembershipCredentials = RlnMembershipCredentials(membershipKeyPair: keyPair, rlnIndex: rlnIndex)

# Since the files are stored as a raw text file, it is highly susceptible to theft.
# The files needs some encryption to resolve this.

# Write RLN credentials
writeFile(RLN_CREDENTIALS_FILEPATH, pretty(%rlnMembershipCredentials))

# create the WakuRLNRelay
var rlnPeer = WakuRLNRelay(membershipKeyPair: keyPair,
membershipIndex: rlnIndex,
Expand Down Expand Up @@ -821,8 +832,21 @@ proc mountRlnRelayDynamic*(node: WakuNode,

node.wakuRlnRelay = rlnPeer

proc readPersistentRlnCredentials*(path: string) : RlnMembershipCredentials {.raises: [Defect, OSError, IOError, Exception].} =
info "Rln credentials exist in file"
# With regards to printing the keys, it is purely for debugging purposes so that the user becomes explicitly aware of the current keys in use when nwaku is started.
# Note that this is only until the RLN contract being used is the one deployed on Goerli testnet.
# These prints need to omitted once RLN contract is deployed on Ethereum mainnet and using valuable funds for staking.

let entireRlnCredentialsFile = readFile(path)

let jsonObject = parseJson(entireRlnCredentialsFile)
let deserializedRlnCredentials = to(jsonObject, RlnMembershipCredentials)

debug "Deserialized Rln credentials", rlnCredentials=deserializedRlnCredentials
result = deserializedRlnCredentials

proc mountRlnRelay*(node: WakuNode, conf: WakuNodeConf|Chat2Conf, spamHandler: Option[SpamHandler] = none(SpamHandler)) {.raises: [Defect, ValueError, IOError, CatchableError].} =
proc mountRlnRelay*(node: WakuNode, conf: WakuNodeConf|Chat2Conf, spamHandler: Option[SpamHandler] = none(SpamHandler)) {.raises: [Defect, ValueError, IOError, CatchableError, Exception].} =
if not conf.rlnRelayDynamic:
info " setting up waku-rln-relay in on-chain mode... "
# set up rln relay inputs
Expand Down Expand Up @@ -866,9 +890,18 @@ proc mountRlnRelay*(node: WakuNode, conf: WakuNodeConf|Chat2Conf, spamHandler: O
let keyPair = @[(rlnRelayId, rlnRelayIdCommitmentKey)]
let memKeyPair = keyPair.toMembershipKeyPairs()[0]
# mount the rln relay protocol in the on-chain/dynamic mode
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr, memKeyPair = some(memKeyPair), memIndex = some(rlnRelayIndex), ethAccAddr = ethAccountAddr, ethAccountPrivKeyOpt = ethAccountPrivKeyOpt, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic, spamHandler = spamHandler)
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr,
memKeyPair = some(memKeyPair), memIndex = some(rlnRelayIndex), ethAccAddr = ethAccountAddr,
ethAccountPrivKeyOpt = ethAccountPrivKeyOpt, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic, spamHandler = spamHandler)
elif fileExists(RLN_CREDENTIALS_FILEPATH):
var credentials = readPersistentRlnCredentials(RLN_CREDENTIALS_FILEPATH)
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr,
memKeyPair = some(credentials.membershipKeyPair), memIndex = some(credentials.rlnIndex), ethAccAddr = ethAccountAddr,
ethAccountPrivKeyOpt = ethAccountPrivKeyOpt, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic, spamHandler = spamHandler)
else:
# no rln credential is provided
# mount the rln relay protocol in the on-chain/dynamic mode
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr, ethAccAddr = ethAccountAddr, ethAccountPrivKeyOpt = ethAccountPrivKeyOpt, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic, spamHandler = spamHandler)

info "no rln credential is provided"
waitFor node.mountRlnRelayDynamic(memContractAddr = ethMemContractAddress, ethClientAddr = ethClientAddr,
ethAccAddr = ethAccountAddr, ethAccountPrivKeyOpt = ethAccountPrivKeyOpt, pubsubTopic = conf.rlnRelayPubsubTopic,
contentTopic = conf.rlnRelayContentTopic, spamHandler = spamHandler)

0 comments on commit 115982f

Please sign in to comment.