Integrate registration into wakunode and Enable signed registration transactions (#385)

* cleans up imported modules

* adds uploadContract proc and consolidates rln-relay test files

* deletes test_rln_relay_wrappers

* deletes wrappers tests

* adds waku_rln_relay_utils

* adds the unit test for the membership key generation

* adds the key generation procedure

* adds unit test of key gen proc

* adds RLNRelayPeer data type

* adds the register proc

* adds the register proc unit test

* minor

* edits registration test

* adds comments to the registration unit test and relocates some constants

* defines constants variables for membership contract inputs and adds todos

* fixes a typo

* enables signed transaction

* adds registration into waku rln relay

* adds a TODO

* adds debug notes

* WIP add registration test

* integrates rln relay inputs into the mountRelay proc

* minor

* adds mountRelay

* renames RlnRelayPeer to WakuRlnRelay

* adds debugging notes

* changes the test title

* adds rln to gitignore

* cleans up tests, fixes a bug

* exposes mountRlnrelay, adds some comments

* fixes a bug

* deletes async pragma from mountRelay

* exposes the wakuRlnRelay field

* adds bash command to delete any existing rln directory before cloning the rln repo

* removes -v verbose flag from rln removal

* replaces await with WaitFor

* embed mountRlnRelay inside mountRelay
This commit is contained in:
Sanaz Taheri Boshrooyeh 2021-02-22 09:40:02 -08:00 committed by GitHub
parent 57a9447972
commit e152ed349f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 18 deletions

View File

@ -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/$@" && \

View File

@ -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

View File

@ -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

View File

@ -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()