Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persisting rln credentials #1037

Merged
merged 33 commits into from
Aug 5, 2022
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
881d593
Persisting Credentials implemented by writing json of keypair and rln…
kgrgpg Jul 20, 2022
b5533d2
Removing testing files and ignores
kgrgpg Jul 20, 2022
942da4e
Update waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim
kgrgpg Jul 20, 2022
f85da55
Update waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim
kgrgpg Jul 20, 2022
68ee74d
Comments
Jul 21, 2022
15f4ee7
Comments
Jul 21, 2022
966eb5b
Security warning in comments
Jul 21, 2022
0e5c725
Redundant echos. Omitting unused variables.
kgrgpg Jul 21, 2022
81bb5c1
Update waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim
kgrgpg Jul 21, 2022
a004b52
Limit line lengths using line breaks and indents
kgrgpg Jul 21, 2022
a90e16a
Membership file paths declared as const
Jul 21, 2022
b375418
Const fix
kgrgpg Jul 21, 2022
6236dd6
Rln Credentials Merged.
kgrgpg Jul 24, 2022
0a2c5ca
Spaces
kgrgpg Jul 24, 2022
7162bfa
Spaces
kgrgpg Jul 24, 2022
8ecd11a
Dangling constants removed. Comments position.
kgrgpg Jul 26, 2022
c600b6c
Import sequence.
kgrgpg Jul 26, 2022
3bbd64b
Path as argument to readPersistentKeys.
kgrgpg Jul 26, 2022
16c1aa4
readPersistentKeys test
kgrgpg Jul 26, 2022
48cfbf5
Debug and info
kgrgpg Jul 26, 2022
51166db
Index check in test
kgrgpg Jul 28, 2022
062632a
Update tests/v2/test_waku_rln_relay.nim
kgrgpg Jul 28, 2022
ed05b6a
Abstracted writeRlnCredentials.
kgrgpg Jul 28, 2022
5081300
Usage of writeRlnCredentials in test
kgrgpg Jul 28, 2022
bdf0296
Merge branch 'master' into Persisting-rln-credentials
kgrgpg Jul 28, 2022
3f4dba1
Dnsclient?
kgrgpg Jul 29, 2022
f10d873
Test reverted to direct call to writeFile.
kgrgpg Jul 29, 2022
0b56889
Merge branch 'master' into Persisting-rln-credentials
kgrgpg Jul 29, 2022
db5fddc
Indentation
kgrgpg Jul 29, 2022
135b72a
Revert "Dnsclient?"
kgrgpg Jul 29, 2022
08ab7a1
Reverting abstraction of writing..
kgrgpg Aug 1, 2022
a9d591f
Merge branch 'master' into Persisting-rln-credentials
kgrgpg Aug 4, 2022
1ad6b4d
Merge branch 'master' into Persisting-rln-credentials
kgrgpg Aug 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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))
s1fr0 marked this conversation as resolved.
Show resolved Hide resolved

var credentials = readPersistentRlnCredentials(path)

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

s1fr0 marked this conversation as resolved.
Show resolved Hide resolved

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"
LNSD marked this conversation as resolved.
Show resolved Hide resolved

# 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer that we do not dump the content of the credentials through the stdout

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refer to #1037 (comment)

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):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, please develop a test to check whether credentials can be correctly created and retrieved when mounting rln-relay.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does 16c1aa4 fulfil ?

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)