From 29643098149dac3db17c480576b532f2629010ad Mon Sep 17 00:00:00 2001 From: staheri14 Date: Mon, 22 Feb 2021 18:04:54 +0000 Subject: [PATCH] deploy: 50e900a21bf57b219fcecefdf80108026a3f6fe0 --- .update.timestamp | 2 +- Makefile | 2 +- tests/v2/test_waku_rln_relay.nim | 30 ++++++++- .../protocol/waku_protocol.nim.generated.nim | 64 +++++++++---------- waku/v2/node/wakunode2.nim | 46 ++++++++++--- .../waku_rln_relay/waku_rln_relay_utils.nim | 18 ++++-- 6 files changed, 111 insertions(+), 51 deletions(-) diff --git a/.update.timestamp b/.update.timestamp index 4f84ff66c..786f64178 100644 --- a/.update.timestamp +++ b/.update.timestamp @@ -1 +1 @@ -1613763858 \ No newline at end of file +1614015602 \ No newline at end of file diff --git a/Makefile b/Makefile index 1011bc365..8f4038af0 100644 --- a/Makefile +++ b/Makefile @@ -120,7 +120,7 @@ installganache: rlnlib: #cargo clean --manifest-path rln/Cargo.toml #TODO may need to clean the rln directory before cloning the rln repo - git clone --branch full-node https://github.com/kilic/rln; git --git-dir=rln/.git reset --hard a80f5d0; cargo build --manifest-path rln/Cargo.toml; + rm -rf rln; git clone --branch full-node https://github.com/kilic/rln; git --git-dir=rln/.git reset --hard a80f5d0; cargo build --manifest-path rln/Cargo.toml; test2: | build deps installganache echo -e $(BUILD_MSG) "build/$@" && \ diff --git a/tests/v2/test_waku_rln_relay.nim b/tests/v2/test_waku_rln_relay.nim index 72a9edf59..992d2cfb9 100644 --- a/tests/v2/test_waku_rln_relay.nim +++ b/tests/v2/test_waku_rln_relay.nim @@ -1,8 +1,10 @@ import chronos, chronicles, options, stint, unittest, web3, - stew/byteutils, + stew/byteutils, stew/shims/net as stewNet, + libp2p/crypto/crypto, ../../waku/v2/protocol/waku_rln_relay/[rln, waku_rln_relay_utils], + ../../waku/v2/node/wakunode2, ../test_helpers, test_utils @@ -10,6 +12,7 @@ import # the address of Ethereum client (ganache-cli for now) +# TODO this address in hardcoded in the code, we may need to take it as input from the user const EthClient = "ws://localhost:8540/" # poseidonHasherCode holds the bytecode of Poseidon hasher solidity smart contract: @@ -181,8 +184,8 @@ procSuite "Waku rln relay": check: membershipKeyPair.isSome - # initialize the RLNRelayPeer - var rlnPeer = RLNRelayPeer(membershipKeyPair: membershipKeyPair.get(), + # initialize the WakuRLNRelay + var rlnPeer = WakuRLNRelay(membershipKeyPair: membershipKeyPair.get(), ethClientAddress: EthClient, ethAccountAddress: ethAccountAddress, membershipContractAddress: contractAddress) @@ -191,6 +194,27 @@ procSuite "Waku rln relay": let is_successful = await rlnPeer.register() check: is_successful + asyncTest "mounting waku rln relay": + let + nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[] + node = WakuNode.init(nodeKey, ValidIpAddress.init("0.0.0.0"), + Port(60000)) + await node.start() + + # deploy the contract + let membershipContractAddress = await uploadContract(EthClient) + + # prepare rln-relay inputs + let + web3 = await newWeb3(EthClient) + accounts = await web3.provider.eth_accounts() + # choose one of the existing account for the rln-relay peer + ethAccountAddress = accounts[9] + await web3.close() + + # start rln-relay + await node.mountRlnRelay(ethClientAddress = some(EthClient), ethAccountAddress = some(ethAccountAddress), membershipContractAddress = some(membershipContractAddress)) + suite "Waku rln relay": test "Keygen Nim Wrappers": var diff --git a/waku/v1/protocol/waku_protocol.nim.generated.nim b/waku/v1/protocol/waku_protocol.nim.generated.nim index 3a75661d8..d77f6d56e 100644 --- a/waku/v1/protocol/waku_protocol.nim.generated.nim +++ b/waku/v1/protocol/waku_protocol.nim.generated.nim @@ -188,10 +188,10 @@ proc statusRawSender(peerOrResponder: Peer; options: StatusOptions; template status*(peer: Peer; options: StatusOptions; timeout: Duration = milliseconds(10000'i64)): Future[statusObj] = - let peer_175950056 = peer - let sendingFuture`gensym175950057 = statusRawSender(peer, options) - handshakeImpl(peer_175950056, sendingFuture`gensym175950057, - nextMsg(peer_175950056, statusObj), timeout) + let peer_183870056 = peer + let sendingFuture`gensym183870057 = statusRawSender(peer, options) + handshakeImpl(peer_183870056, sendingFuture`gensym183870057, + nextMsg(peer_183870056, statusObj), timeout) proc messages*(peerOrResponder: Peer; envelopes: openarray[Envelope]): Future[void] {. gcsafe.} = @@ -272,9 +272,9 @@ proc p2pSyncResponse*(peerOrResponder: ResponderWithId[p2pSyncResponseObj]): Fut let msgBytes = finish(writer) return sendMsg(peer, msgBytes) -template send*(r`gensym175950072: ResponderWithId[p2pSyncResponseObj]; - args`gensym175950073: varargs[untyped]): auto = - p2pSyncResponse(r`gensym175950072, args`gensym175950073) +template send*(r`gensym183870072: ResponderWithId[p2pSyncResponseObj]; + args`gensym183870073: varargs[untyped]): auto = + p2pSyncResponse(r`gensym183870072, args`gensym183870073) proc p2pSyncRequest*(peerOrResponder: Peer; timeout: Duration = milliseconds(10000'i64)): Future[ @@ -458,71 +458,71 @@ proc p2pRequestCompleteUserHandler(peer: Peer; requestId: Hash; discard -proc statusThunk(peer: Peer; _`gensym175950033: int; data`gensym175950034: Rlp) {. +proc statusThunk(peer: Peer; _`gensym183870033: int; data`gensym183870034: Rlp) {. async, gcsafe.} = - var rlp = data`gensym175950034 + var rlp = data`gensym183870034 var msg {.noinit.}: statusObj msg.options = checkedRlpRead(peer, rlp, StatusOptions) -proc messagesThunk(peer: Peer; _`gensym175950058: int; data`gensym175950059: Rlp) {. +proc messagesThunk(peer: Peer; _`gensym183870058: int; data`gensym183870059: Rlp) {. async, gcsafe.} = - var rlp = data`gensym175950059 + var rlp = data`gensym183870059 var msg {.noinit.}: messagesObj msg.envelopes = checkedRlpRead(peer, rlp, openarray[Envelope]) await(messagesUserHandler(peer, msg.envelopes)) -proc statusOptionsThunk(peer: Peer; _`gensym175950060: int; data`gensym175950061: Rlp) {. +proc statusOptionsThunk(peer: Peer; _`gensym183870060: int; data`gensym183870061: Rlp) {. async, gcsafe.} = - var rlp = data`gensym175950061 + var rlp = data`gensym183870061 var msg {.noinit.}: statusOptionsObj msg.options = checkedRlpRead(peer, rlp, StatusOptions) await(statusOptionsUserHandler(peer, msg.options)) -proc p2pRequestThunk(peer: Peer; _`gensym175950062: int; data`gensym175950063: Rlp) {. +proc p2pRequestThunk(peer: Peer; _`gensym183870062: int; data`gensym183870063: Rlp) {. async, gcsafe.} = - var rlp = data`gensym175950063 + var rlp = data`gensym183870063 var msg {.noinit.}: p2pRequestObj msg.envelope = checkedRlpRead(peer, rlp, Envelope) await(p2pRequestUserHandler(peer, msg.envelope)) -proc p2pMessageThunk(peer: Peer; _`gensym175950064: int; data`gensym175950065: Rlp) {. +proc p2pMessageThunk(peer: Peer; _`gensym183870064: int; data`gensym183870065: Rlp) {. async, gcsafe.} = - var rlp = data`gensym175950065 + var rlp = data`gensym183870065 var msg {.noinit.}: p2pMessageObj msg.envelopes = checkedRlpRead(peer, rlp, openarray[Envelope]) await(p2pMessageUserHandler(peer, msg.envelopes)) -proc batchAcknowledgedThunk(peer: Peer; _`gensym175950066: int; - data`gensym175950067: Rlp) {.async, gcsafe.} = - var rlp = data`gensym175950067 +proc batchAcknowledgedThunk(peer: Peer; _`gensym183870066: int; + data`gensym183870067: Rlp) {.async, gcsafe.} = + var rlp = data`gensym183870067 var msg {.noinit.}: batchAcknowledgedObj await(batchAcknowledgedUserHandler(peer)) -proc messageResponseThunk(peer: Peer; _`gensym175950068: int; - data`gensym175950069: Rlp) {.async, gcsafe.} = - var rlp = data`gensym175950069 +proc messageResponseThunk(peer: Peer; _`gensym183870068: int; + data`gensym183870069: Rlp) {.async, gcsafe.} = + var rlp = data`gensym183870069 var msg {.noinit.}: messageResponseObj await(messageResponseUserHandler(peer)) -proc p2pSyncResponseThunk(peer: Peer; _`gensym175950070: int; - data`gensym175950071: Rlp) {.async, gcsafe.} = - var rlp = data`gensym175950071 +proc p2pSyncResponseThunk(peer: Peer; _`gensym183870070: int; + data`gensym183870071: Rlp) {.async, gcsafe.} = + var rlp = data`gensym183870071 var msg {.noinit.}: p2pSyncResponseObj let reqId = read(rlp, int) await(p2pSyncResponseUserHandler(peer, reqId)) resolveResponseFuture(peer, perPeerMsgId(peer, p2pSyncResponseObj), addr(msg), reqId) -proc p2pSyncRequestThunk(peer: Peer; _`gensym175950074: int; - data`gensym175950075: Rlp) {.async, gcsafe.} = - var rlp = data`gensym175950075 +proc p2pSyncRequestThunk(peer: Peer; _`gensym183870074: int; + data`gensym183870075: Rlp) {.async, gcsafe.} = + var rlp = data`gensym183870075 var msg {.noinit.}: p2pSyncRequestObj let reqId = read(rlp, int) await(p2pSyncRequestUserHandler(peer, reqId)) -proc p2pRequestCompleteThunk(peer: Peer; _`gensym175950076: int; - data`gensym175950077: Rlp) {.async, gcsafe.} = - var rlp = data`gensym175950077 +proc p2pRequestCompleteThunk(peer: Peer; _`gensym183870076: int; + data`gensym183870077: Rlp) {.async, gcsafe.} = + var rlp = data`gensym183870077 var msg {.noinit.}: p2pRequestCompleteObj tryEnterList(rlp) msg.requestId = checkedRlpRead(peer, rlp, Hash) diff --git a/waku/v2/node/wakunode2.nim b/waku/v2/node/wakunode2.nim index 53a7cb3e8..e045b8b10 100644 --- a/waku/v2/node/wakunode2.nim +++ b/waku/v2/node/wakunode2.nim @@ -3,6 +3,7 @@ import chronos, chronicles, metrics, stew/shims/net as stewNet, # TODO: Why do we need eth keys? eth/keys, + web3, libp2p/multiaddress, libp2p/crypto/crypto, libp2p/protocols/protocol, @@ -13,6 +14,7 @@ import ../protocol/waku_store/waku_store, ../protocol/waku_swap/waku_swap, ../protocol/waku_filter/waku_filter, + ../protocol/waku_rln_relay/waku_rln_relay_utils, ../utils/peers, ./message_store/message_store, ../utils/requests, @@ -51,6 +53,7 @@ type wakuStore*: WakuStore wakuFilter*: WakuFilter wakuSwap*: WakuSwap + wakuRlnRelay*: WakuRLNRelay peerInfo*: PeerInfo libp2pTransportLoops*: seq[Future[void]] # TODO Revist messages field indexing as well as if this should be Message or WakuMessage @@ -310,8 +313,34 @@ proc mountStore*(node: WakuNode, store: MessageStore = nil) = node.switch.mount(node.wakuStore) node.subscriptions.subscribe(WakuStoreCodec, node.wakuStore.subscription()) -proc mountRelay*(node: WakuNode, topics: seq[string] = newSeq[string](), rlnRelayEnabled: bool = false) {.gcsafe.} = - # TODO add the RLN registration +proc mountRlnRelay*(node: WakuNode, ethClientAddress: Option[string] = none(string), ethAccountAddress: Option[Address] = none(Address), membershipContractAddress: Option[Address] = none(Address)) {.async.} = + # check whether inputs are provided + doAssert(ethClientAddress.isSome()) + doAssert(ethAccountAddress.isSome()) + doAssert(membershipContractAddress.isSome()) + + # generate the membership keys + let membershipKeyPair = membershipKeyGen() + # check whether keys are generated + doAssert(membershipKeyPair.isSome()) + debug "the membership key for the rln relay is generated" + + # initialize the WakuRLNRelay + var rlnPeer = WakuRLNRelay(membershipKeyPair: membershipKeyPair.get(), + ethClientAddress: ethClientAddress.get(), + ethAccountAddress: ethAccountAddress.get(), + membershipContractAddress: membershipContractAddress.get()) + + # register the rln-relay peer to the membership contract + let is_successful = await rlnPeer.register() + # check whether registration is done + doAssert(is_successful) + debug "peer is successfully registered into the membership contract" + + node.wakuRlnRelay = rlnPeer + + +proc mountRelay*(node: WakuNode, topics: seq[string] = newSeq[string](), rlnRelayEnabled = false) {.gcsafe.} = let wakuRelay = WakuRelay.init( switch = node.switch, # Use default @@ -320,13 +349,6 @@ proc mountRelay*(node: WakuNode, topics: seq[string] = newSeq[string](), rlnRela sign = false, verifySignature = false ) - # TODO if rln-relay enabled, then perform registration - if rlnRelayEnabled: - debug "Using WakuRLNRelay" - else: - debug "WakuRLNRelay is disabled" - - node.wakuRelay = wakuRelay node.switch.mount(wakuRelay) @@ -347,6 +369,12 @@ proc mountRelay*(node: WakuNode, topics: seq[string] = newSeq[string](), rlnRela node.subscribe(topic, handler) + if rlnRelayEnabled: + # TODO pass rln relay inputs to this proc, right now it uses default values that are set in the mountRlnRelay proc + info "WakuRLNRelay is enabled" + waitFor mountRlnRelay(node) + info "WakuRLNRelay is mounted successfully" + ## Helpers proc dialPeer*(n: WakuNode, address: string) {.async.} = info "dialPeer", address = address diff --git a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim index 0e3d00485..7cac4bc2d 100644 --- a/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim +++ b/waku/v2/protocol/waku_rln_relay/waku_rln_relay_utils.nim @@ -1,7 +1,7 @@ import - chronicles, options, chronos, stint, - stew/byteutils, + chronicles, options, chronos, stint, web3, + stew/byteutils, eth/keys, rln @@ -9,16 +9,22 @@ type MembershipKeyPair* = object secretKey*: array[32, byte] publicKey*: array[32, byte] -type RLNRelayPeer* = object +type WakuRLNRelay* = object membershipKeyPair*: MembershipKeyPair ethClientAddress*: string ethAccountAddress*: Address + # this field is required for signing transactions + # TODO may need to erase this ethAccountPrivateKey when is not used + # TODO may need to make ethAccountPrivateKey mandatory + ethAccountPrivateKey*: Option[PrivateKey] membershipContractAddress*: Address # inputs of the membership contract constructor const MembershipFee* = 5.u256 Depth* = 32.u256 + # TODO the EthClient should be an input to the rln-relay + EthClient* = "ws://localhost:8540/" # membership contract interface contract(MembershipContract): @@ -79,14 +85,16 @@ proc membershipKeyGen*(): Option[MembershipKeyPair] = return some(keypair) -proc register*(rlnPeer: RLNRelayPeer): Future[bool] {.async.} = +proc register*(rlnPeer: WakuRLNRelay): Future[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 web3 = await newWeb3(rlnPeer.ethClientAddress) web3.defaultAccount = rlnPeer.ethAccountAddress + # 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 = rlnPeer.ethAccountPrivateKey var sender = web3.contractSender(MembershipContract, rlnPeer.membershipContractAddress) # creates a Sender object with a web3 field and contract address of type Address let pk = cast[UInt256](rlnPeer.membershipKeyPair.publicKey) - # TODO sign the transaction discard await sender.register(pk).send(MembershipFee) # TODO check the receipt and then return true/false await web3.close()