2022-05-10 21:09:18 +00:00
# contains rln-relay tests that require interaction with Ganache i.e., onchain tests
{. used . }
import
2022-11-08 13:28:11 +00:00
std / [ options , osproc , streams , strutils ] ,
2022-05-10 21:09:18 +00:00
testutils / unittests , chronos , chronicles , stint , web3 , json ,
stew / byteutils , stew / shims / net as stewNet ,
libp2p / crypto / crypto ,
2022-07-01 01:05:38 +00:00
eth / keys ,
2022-06-27 19:35:26 +00:00
.. / .. / waku / v2 / protocol / waku_rln_relay / [ waku_rln_relay_utils ,
2022-09-30 12:43:42 +00:00
waku_rln_relay_constants ,
waku_rln_relay_types ,
rln_relay_contract ] ,
2022-10-18 14:05:53 +00:00
.. / .. / waku / v2 / node / waku_node ,
2022-05-10 21:09:18 +00:00
.. / test_helpers ,
. / test_utils
2022-11-08 13:28:11 +00:00
from posix import kill , SIGINT
2022-09-30 12:43:42 +00:00
const RlnRelayPubsubTopic = " waku/2/rlnrelay/proto "
const RlnRelayContentTopic = " waku/2/rlnrelay/proto "
2022-05-10 21:09:18 +00:00
# contract ABI
contract ( MembershipContract ) :
proc register ( pubkey : Uint256 ) # external payable
proc MemberRegistered ( pubkey : Uint256 , index : Uint256 ) {. event . }
# proc registerBatch(pubkeys: seq[Uint256]) # external payable
# proc withdraw(secret: Uint256, pubkeyIndex: Uint256, receiver: Address)
# proc withdrawBatch( secrets: seq[Uint256], pubkeyIndex: seq[Uint256], receiver: seq[Address])
# a util function used for testing purposes
2022-09-30 12:43:42 +00:00
# it deploys membership contract on Ganache (or any Eth client available on EthClient address)
2022-05-10 21:09:18 +00:00
# must be edited if used for a different contract than membership contract
proc uploadRLNContract * ( ethClientAddress : string ) : Future [ Address ] {. async . } =
let web3 = await newWeb3 ( ethClientAddress )
debug " web3 connected to " , ethClientAddress
# fetch the list of registered accounts
let accounts = await web3 . provider . eth_accounts ( )
web3 . defaultAccount = accounts [ 1 ]
let add = web3 . defaultAccount
debug " contract deployer account address " , add
var balance = await web3 . provider . eth_getBalance ( web3 . defaultAccount , " latest " )
debug " Initial account balance: " , balance
# deploy the poseidon hash contract and gets its address
let
2022-09-30 12:43:42 +00:00
hasherReceipt = await web3 . deployContract ( PoseidonHasherCode )
2022-05-10 21:09:18 +00:00
hasherAddress = hasherReceipt . contractAddress . get
debug " hasher address: " , hasherAddress
# encode membership contract inputs to 32 bytes zero-padded
let
2022-09-30 12:43:42 +00:00
membershipFeeEncoded = encode ( MembershipFee ) . data
depthEncoded = encode ( MerkleTreeDepth . u256 ) . data
2022-05-10 21:09:18 +00:00
hasherAddressEncoded = encode ( hasherAddress ) . data
# this is the contract constructor input
contractInput = membershipFeeEncoded & depthEncoded & hasherAddressEncoded
debug " encoded membership fee: " , membershipFeeEncoded
debug " encoded depth: " , depthEncoded
debug " encoded hasher address: " , hasherAddressEncoded
debug " encoded contract input: " , contractInput
# deploy membership contract with its constructor inputs
2022-09-30 12:43:42 +00:00
let receipt = await web3 . deployContract ( MembershipContractCode ,
2022-05-10 21:09:18 +00:00
contractInput = contractInput )
var contractAddress = receipt . contractAddress . get
debug " Address of the deployed membership contract: " , contractAddress
balance = await web3 . provider . eth_getBalance ( web3 . defaultAccount , " latest " )
debug " Account balance after the contract deployment: " , balance
await web3 . close ( )
debug " disconnected from " , ethClientAddress
return contractAddress
2022-07-01 01:05:38 +00:00
proc createEthAccount ( ) : Future [ ( keys . PrivateKey , Address ) ] {. async . } =
let theRNG = keys . newRng ( )
2022-09-30 12:43:42 +00:00
let web3 = await newWeb3 ( EthClient )
2022-07-01 01:05:38 +00:00
let accounts = await web3 . provider . eth_accounts ( )
let gasPrice = int ( await web3 . provider . eth_gasPrice ( ) )
web3 . defaultAccount = accounts [ 0 ]
let pk = keys . PrivateKey . random ( theRNG [ ] )
let acc = Address ( toCanonicalAddress ( pk . toPublicKey ( ) ) )
var tx : EthSend
tx . source = accounts [ 0 ]
tx . value = some ( ethToWei ( 10 . u256 ) )
tx . to = some ( acc )
tx . gasPrice = some ( gasPrice )
# Send 10 eth to acc
discard await web3 . send ( tx )
var balance = await web3 . provider . eth_getBalance ( acc , " latest " )
assert ( balance = = ethToWei ( 10 . u256 ) )
return ( pk , acc )
2022-11-08 13:28:11 +00:00
# Installs Ganache Daemon
proc installGanache ( ) =
# We install Ganache.
# Packages will be installed to the ./build folder through the --prefix option
let installGanache = startProcess ( " npm " , args = [ " install " , " ganache " , " --prefix " , " ./build " ] , options = { poUsePath } )
let returnCode = installGanache . waitForExit ( )
debug " Ganache install log " , returnCode = returnCode , log = installGanache . outputstream . readAll ( )
# Uninstalls Ganache Daemon
proc uninstallGanache ( ) =
# We uninstall Ganache
# Packages will be uninstalled from the ./build folder through the --prefix option.
# Passed option is
# --save: Package will be removed from your dependencies.
# See npm documentation https://docs.npmjs.com/cli/v6/commands/npm-uninstall for further details
let uninstallGanache = startProcess ( " npm " , args = [ " uninstall " , " ganache " , " --save " , " --prefix " , " ./build " ] , options = { poUsePath } )
let returnCode = uninstallGanache . waitForExit ( )
debug " Ganache uninstall log " , returnCode = returnCode , log = uninstallGanache . outputstream . readAll ( )
# Runs Ganache daemon
proc runGanache ( ) : Process =
# We run directly "node node_modules/ganache/dist/node/cli.js" rather than using "npx ganache", so that the daemon does not spawn in a new child process.
# In this way, we can directly send a SIGINT signal to the corresponding PID to gracefully terminate Ganache without dealing with multiple processes.
# Passed options are
# --port Port to listen on.
# --miner.blockGasLimit Sets the block gas limit in WEI.
# --wallet.defaultBalance The default account balance, specified in ether.
# See ganache documentation https://www.npmjs.com/package/ganache for more details
let runGanache = startProcess ( " node " , args = [ " ./build/node_modules/ganache/dist/node/cli.js " , " --port " , " 8540 " , " --miner.blockGasLimit " , " 300000000000000 " , " --wallet.defaultBalance " , " 10000 " ] , options = { poUsePath } )
let ganachePID = runGanache . processID
# We read stdout from Ganache to see when daemon is ready
var ganacheStartLog : string
var cmdline : string
while true :
if runGanache . outputstream . readLine ( cmdline ) :
ganacheStartLog . add cmdline
if cmdline . contains ( " Listening on 127.0.0.1:8540 " ) :
break
debug " Ganache daemon is running and ready " , pid = ganachePID , startLog = ganacheStartLog
return runGanache
# Stops Ganache daemon
proc stopGanache ( runGanache : Process ) =
let ganachePID = runGanache . processID
# We gracefully terminate Ganache daemon by sending a SIGINT signal to the runGanache PID to trigger RPC server termination and clean-up
let returnCodeSIGINT = kill ( ganachePID . int32 , SIGINT )
debug " Sent SIGINT to Ganache " , ganachePID = ganachePID , returnCode = returnCodeSIGINT
# We wait the daemon to exit
let returnCodeExit = runGanache . waitForExit ( )
debug " Ganache daemon terminated " , returnCode = returnCodeExit
debug " Ganache daemon run log " , log = runGanache . outputstream . readAll ( )
2022-05-10 21:09:18 +00:00
procSuite " Waku-rln-relay " :
2022-11-08 13:28:11 +00:00
################################
## Installing/running Ganache
################################
# We install Ganache
installGanache ( )
# We run Ganache
let runGanache = runGanache ( )
2022-05-10 21:09:18 +00:00
asyncTest " event subscription " :
# preparation ------------------------------
2022-09-30 12:43:42 +00:00
debug " ethereum client address " , EthClient
let contractAddress = await uploadRLNContract ( EthClient )
2022-05-10 21:09:18 +00:00
# connect to the eth client
2022-09-30 12:43:42 +00:00
let web3 = await newWeb3 ( EthClient )
debug " web3 connected to " , EthClient
2022-05-10 21:09:18 +00:00
# fetch the list of registered accounts
let accounts = await web3 . provider . eth_accounts ( )
web3 . defaultAccount = accounts [ 1 ]
debug " contract deployer account address " ,
defaultAccount = web3 . defaultAccount
# prepare a contract sender to interact with it
2022-11-04 03:00:42 +00:00
let contractObj = web3 . contractSender ( MembershipContract ,
2022-05-10 21:09:18 +00:00
contractAddress ) # creates a Sender object with a web3 field and contract address of type Address
# create an RLN instance
2022-11-04 03:00:42 +00:00
let rlnInstance = createRLNInstance ( )
require :
rlnInstance . isOk ( )
2022-05-10 21:09:18 +00:00
# generate the membership keys
2022-11-04 03:00:42 +00:00
let membershipKeyPairRes = membershipKeyGen ( rlnInstance . get ( ) )
require :
membershipKeyPairRes . isOk ( )
let membershipKeyPair = membershipKeyPairRes . get ( )
let pk = membershipKeyPair . idCommitment . toUInt256 ( )
2022-05-10 21:09:18 +00:00
debug " membership commitment key " , pk = pk
# test ------------------------------
var fut = newFuture [ void ] ( )
let s = await contractObj . subscribe ( MemberRegistered , % * { " fromBlock " : " 0x0 " ,
" address " : contractAddress } ) do (
pubkey : Uint256 , index : Uint256 ) {. raises : [ Defect ] , gcsafe . } :
try :
debug " onRegister " , pubkey = pubkey , index = index
check :
pubkey = = pk
fut . complete ( )
except Exception as err :
# chronos still raises exceptions which inherit directly from Exception
doAssert false , err . msg
do ( err : CatchableError ) :
echo " Error from subscription: " , err . msg
# register a member
2022-09-30 12:43:42 +00:00
let tx = await contractObj . register ( pk ) . send ( value = MembershipFee )
2022-05-10 21:09:18 +00:00
debug " a member is registered " , tx = tx
# wait for the event to be received
await fut
2022-05-30 19:14:07 +00:00
# release resources -----------------------
await web3 . close ( )
asyncTest " dynamic group management " :
# preparation ------------------------------
2022-09-30 12:43:42 +00:00
debug " ethereum client address " , EthClient
let contractAddress = await uploadRLNContract ( EthClient )
2022-05-30 19:14:07 +00:00
# connect to the eth client
2022-09-30 12:43:42 +00:00
let web3 = await newWeb3 ( EthClient )
debug " web3 connected to " , EthClient
2022-05-30 19:14:07 +00:00
# fetch the list of registered accounts
let accounts = await web3 . provider . eth_accounts ( )
web3 . defaultAccount = accounts [ 1 ]
debug " contract deployer account address " ,
defaultAccount = web3 . defaultAccount
# prepare a contract sender to interact with it
2022-11-04 03:00:42 +00:00
let contractObj = web3 . contractSender ( MembershipContract ,
2022-05-30 19:14:07 +00:00
contractAddress ) # creates a Sender object with a web3 field and contract address of type Address
# test ------------------------------
# create an RLN instance
2022-11-04 03:00:42 +00:00
let rlnInstance = createRLNInstance ( )
require :
rlnInstance . isOk ( )
let rln = rlnInstance . get ( )
let keyPairRes = rln . membershipKeyGen ( )
require :
keyPairRes . isOk ( )
let keypair = keyPairRes . get ( )
let pk = keyPair . idCommitment . toUInt256 ( )
2022-05-30 19:14:07 +00:00
debug " membership commitment key " , pk = pk
# initialize the WakuRLNRelay
2022-11-04 03:00:42 +00:00
let rlnPeer = WakuRLNRelay ( membershipKeyPair : keyPair ,
2022-05-30 19:14:07 +00:00
membershipIndex : MembershipIndex ( 0 ) ,
2022-09-30 12:43:42 +00:00
ethClientAddress : EthClient ,
2022-10-12 02:18:11 +00:00
ethAccountAddress : some ( accounts [ 0 ] ) ,
2022-05-30 19:14:07 +00:00
membershipContractAddress : contractAddress ,
rlnInstance : rln )
# generate another membership key pair
2022-11-04 03:00:42 +00:00
let keyPair2Res = rln . membershipKeyGen ( )
require :
keyPair2Res . isOk ( )
let keyPair2 = keyPair2Res . get ( )
let pk2 = keyPair2 . idCommitment . toUInt256 ( )
2022-05-30 19:14:07 +00:00
debug " membership commitment key " , pk2 = pk2
var events = [ newFuture [ void ] ( ) , newFuture [ void ] ( ) ]
2022-11-01 02:45:34 +00:00
proc handler ( pubkey : Uint256 , index : Uint256 ) : RlnRelayResult [ void ] =
2022-05-30 19:14:07 +00:00
debug " handler is called " , pubkey = pubkey , index = index
if pubkey = = pk :
events [ 0 ] . complete ( )
if pubkey = = pk2 :
events [ 1 ] . complete ( )
let isSuccessful = rlnPeer . rlnInstance . insertMember ( pubkey . toIDCommitment ( ) )
check :
isSuccessful
2022-11-01 02:45:34 +00:00
return ok ( )
2022-05-30 19:14:07 +00:00
# mount the handler for listening to the contract events
2022-11-01 02:45:34 +00:00
await subscribeToGroupEvents ( ethClientUri = EthClient ,
ethAccountAddress = some ( accounts [ 0 ] ) ,
contractAddress = contractAddress ,
blockNumber = " 0x0 " ,
handler = handler )
2022-05-30 19:14:07 +00:00
# register a member to the contract
2022-09-30 12:43:42 +00:00
let tx = await contractObj . register ( pk ) . send ( value = MembershipFee )
2022-05-30 19:14:07 +00:00
debug " a member is registered " , tx = tx
# register another member to the contract
2022-09-30 12:43:42 +00:00
let tx2 = await contractObj . register ( pk2 ) . send ( value = MembershipFee )
2022-05-30 19:14:07 +00:00
debug " a member is registered " , tx2 = tx2
# wait for all the events to be received by the rlnPeer
await all ( events )
2022-05-10 21:09:18 +00:00
# release resources -----------------------
await web3 . close ( )
asyncTest " insert a key to the membership contract " :
# preparation ------------------------------
2022-09-30 12:43:42 +00:00
debug " ethereum client address " , EthClient
let contractAddress = await uploadRLNContract ( EthClient )
2022-05-10 21:09:18 +00:00
# connect to the eth client
2022-09-30 12:43:42 +00:00
let web3 = await newWeb3 ( EthClient )
debug " web3 connected to " , EthClient
2022-05-10 21:09:18 +00:00
# fetch the list of registered accounts
let accounts = await web3 . provider . eth_accounts ( )
web3 . defaultAccount = accounts [ 1 ]
let add = web3 . defaultAccount
debug " contract deployer account address " , add
# prepare a contract sender to interact with it
2022-11-04 03:00:42 +00:00
let sender = web3 . contractSender ( MembershipContract ,
2022-05-10 21:09:18 +00:00
contractAddress ) # creates a Sender object with a web3 field and contract address of type Address
# send takes the following parameters, c: ContractCallBase, value = 0.u256, gas = 3000000'u64 gasPrice = 0
# should use send proc for the contract functions that update the state of the contract
2022-09-30 12:43:42 +00:00
let tx = await sender . register ( 20 . u256 ) . send ( value = MembershipFee ) # value is the membership fee
2022-05-10 21:09:18 +00:00
debug " The hash of registration tx: " , tx
# var members: array[2, uint256] = [20.u256, 21.u256]
2022-09-30 12:43:42 +00:00
# debug "This is the batch registration result ", await sender.registerBatch(members).send(value = (members.len * MembershipFee)) # value is the membership fee
2022-05-10 21:09:18 +00:00
let balance = await web3 . provider . eth_getBalance ( web3 . defaultAccount , " latest " )
debug " Balance after registration: " , balance
await web3 . close ( )
2022-09-30 12:43:42 +00:00
debug " disconnected from " , EthClient
2022-05-10 21:09:18 +00:00
asyncTest " registration procedure " :
# preparation ------------------------------
# deploy the contract
2022-09-30 12:43:42 +00:00
let contractAddress = await uploadRLNContract ( EthClient )
2022-05-10 21:09:18 +00:00
# prepare rln-relay peer inputs
let
2022-09-30 12:43:42 +00:00
web3 = await newWeb3 ( EthClient )
2022-05-10 21:09:18 +00:00
await web3 . close ( )
# create an RLN instance
2022-11-04 03:00:42 +00:00
let rlnInstance = createRLNInstance ( )
require :
rlnInstance . isOk ( )
2022-05-10 21:09:18 +00:00
# generate the membership keys
2022-11-04 03:00:42 +00:00
let membershipKeyPairRes = membershipKeyGen ( rlnInstance . get ( ) )
require :
membershipKeyPairRes . isOk ( )
let membershipKeyPair = membershipKeyPairRes . get ( )
2022-05-10 21:09:18 +00:00
2022-07-01 01:05:38 +00:00
# create an Ethereum private key and the corresponding account
let ( ethPrivKey , ethacc ) = await createEthAccount ( )
2022-05-10 21:09:18 +00:00
# test ------------------------------
# initialize the WakuRLNRelay
2022-11-04 03:00:42 +00:00
let rlnPeer = WakuRLNRelay ( membershipKeyPair : membershipKeyPair ,
2022-05-10 21:09:18 +00:00
membershipIndex : MembershipIndex ( 0 ) ,
2022-09-30 12:43:42 +00:00
ethClientAddress : EthClient ,
2022-07-28 18:45:29 +00:00
ethAccountPrivateKey : some ( ethPrivKey ) ,
2022-10-12 02:18:11 +00:00
ethAccountAddress : some ( ethacc ) ,
2022-05-10 21:09:18 +00:00
membershipContractAddress : contractAddress )
# register the rln-relay peer to the membership contract
2022-11-04 03:00:42 +00:00
let isSuccessful = await rlnPeer . register ( )
2022-05-10 21:09:18 +00:00
check :
2022-11-04 03:00:42 +00:00
isSuccessful . isOk ( )
2022-05-10 21:09:18 +00:00
2022-06-17 22:00:19 +00:00
asyncTest " mounting waku rln-relay: check correct Merkle tree construction in the static/off-chain group management " :
2022-05-10 21:09:18 +00:00
# preparation ------------------------------
let
nodeKey = crypto . PrivateKey . random ( Secp256k1 , rng [ ] ) [ ]
2022-11-03 13:47:56 +00:00
node = WakuNode . new ( nodeKey , ValidIpAddress . init ( " 0.0.0.0 " ) , Port ( 60110 ) )
2022-05-10 21:09:18 +00:00
await node . start ( )
# create current peer's pk
2022-11-04 03:00:42 +00:00
let rlnInstance = createRLNInstance ( )
require :
rlnInstance . isOk ( )
let rln = rlnInstance . get ( )
2022-05-10 21:09:18 +00:00
# generate a key pair
2022-11-04 03:00:42 +00:00
let keyPairRes = rln . membershipKeyGen ( )
require :
keyPairRes . isOk ( )
2022-05-10 21:09:18 +00:00
2022-11-04 03:00:42 +00:00
let keyPair = keyPairRes . get ( )
2022-05-10 21:09:18 +00:00
# current peer index in the Merkle tree
let index = uint ( 5 )
# Create a group of 10 members
var group = newSeq [ IDCommitment ] ( )
for i in 0 .. 10 :
2022-11-04 03:00:42 +00:00
var memberAdded : bool = false
2022-05-10 21:09:18 +00:00
if ( uint ( i ) = = index ) :
# insert the current peer's pk
2022-11-04 03:00:42 +00:00
group . add ( keyPair . idCommitment )
memberAdded = rln . insertMember ( keyPair . idCommitment )
doAssert ( memberAdded )
debug " member key " , key = keyPair . idCommitment . inHex
2022-05-10 21:09:18 +00:00
else :
2022-11-04 03:00:42 +00:00
let memberKeyPairRes = rln . membershipKeyGen ( )
require :
memberKeyPairRes . isOk ( )
let memberKeyPair = memberKeyPairRes . get ( )
group . add ( memberKeyPair . idCommitment )
let memberAdded = rln . insertMember ( memberKeyPair . idCommitment )
require :
memberAdded
debug " member key " , key = memberKeyPair . idCommitment . inHex
2022-06-17 22:00:19 +00:00
2022-10-12 08:38:48 +00:00
let expectedRoot = rln . getMerkleRoot ( ) . value ( ) . inHex
2022-05-10 21:09:18 +00:00
debug " expected root " , expectedRoot
# test ------------------------------
# start rln-relay
2022-09-30 12:43:42 +00:00
await node . mountRelay ( @ [ RlnRelayPubsubTopic ] )
2022-11-04 03:00:42 +00:00
let mountRes = node . mountRlnRelayStatic ( group = group ,
memKeyPair = keyPair ,
2022-06-17 22:00:19 +00:00
memIndex = index ,
2022-09-30 12:43:42 +00:00
pubsubTopic = RlnRelayPubsubTopic ,
contentTopic = RlnRelayContentTopic )
2022-11-04 03:00:42 +00:00
require :
mountRes . isOk ( )
2022-10-12 08:38:48 +00:00
let calculatedRoot = node . wakuRlnRelay . rlnInstance . getMerkleRoot ( ) . value ( ) . inHex
2022-05-10 21:09:18 +00:00
debug " calculated root " , calculatedRoot
check :
expectedRoot = = calculatedRoot
2022-06-17 22:00:19 +00:00
await node . stop ( )
asyncTest " mounting waku rln-relay: check correct Merkle tree construction in the dynamic/onchain group management " :
# preparation ------------------------------
let
nodeKey = crypto . PrivateKey . random ( Secp256k1 , rng [ ] ) [ ]
2022-11-03 13:47:56 +00:00
node = WakuNode . new ( nodeKey , ValidIpAddress . init ( " 0.0.0.0 " ) , Port ( 60111 ) )
2022-06-17 22:00:19 +00:00
await node . start ( )
# deploy the contract
2022-09-30 12:43:42 +00:00
let contractAddress = await uploadRLNContract ( EthClient )
2022-06-17 22:00:19 +00:00
# prepare rln-relay inputs
let
2022-09-30 12:43:42 +00:00
web3 = await newWeb3 ( EthClient )
2022-06-17 22:00:19 +00:00
accounts = await web3 . provider . eth_accounts ( )
# choose one of the existing accounts for the rln-relay peer
ethAccountAddress = accounts [ 0 ]
web3 . defaultAccount = accounts [ 0 ]
2022-07-01 01:05:38 +00:00
2022-06-17 22:00:19 +00:00
# create an rln instance
2022-11-04 03:00:42 +00:00
let rlnInstance = createRLNInstance ( )
require :
rlnInstance . isOk ( )
let rln = rlnInstance . get ( )
2022-06-17 22:00:19 +00:00
# create two rln key pairs
let
2022-11-04 03:00:42 +00:00
keyPair1Res = rln . membershipKeyGen ( )
keyPair2Res = rln . membershipKeyGen ( )
require :
keyPair1Res . isOk ( )
keyPair2Res . isOk ( )
let
keyPair1 = keyPair1Res . get ( )
keyPair2 = keyPair2Res . get ( )
pk1 = keyPair1 . idCommitment . toUInt256 ( )
pk2 = keyPair2 . idCommitment . toUInt256 ( )
debug " member key1 " , key = keyPair1 . idCommitment . inHex
debug " member key2 " , key = keyPair2 . idCommitment . inHex
2022-06-17 22:00:19 +00:00
# add the rln keys to the Merkle tree
let
2022-11-04 03:00:42 +00:00
memberIsAdded1 = rln . insertMember ( keyPair1 . idCommitment )
memberIsAdded2 = rln . insertMember ( keyPair2 . idCommitment )
require :
memberIsAdded1
memberIsAdded2
2022-06-17 22:00:19 +00:00
# get the Merkle root
2022-10-12 08:38:48 +00:00
let expectedRoot = rln . getMerkleRoot ( ) . value ( ) . inHex
2022-06-17 22:00:19 +00:00
# prepare a contract sender to interact with it
2022-11-04 03:00:42 +00:00
let contractObj = web3 . contractSender ( MembershipContract ,
2022-06-17 22:00:19 +00:00
contractAddress ) # creates a Sender object with a web3 field and contract address of type Address
# register the members to the contract
2022-09-30 12:43:42 +00:00
let tx1Hash = await contractObj . register ( pk1 ) . send ( value = MembershipFee )
2022-06-17 22:00:19 +00:00
debug " a member is registered " , tx1 = tx1Hash
# register another member to the contract
2022-09-30 12:43:42 +00:00
let tx2Hash = await contractObj . register ( pk2 ) . send ( value = MembershipFee )
2022-06-17 22:00:19 +00:00
debug " a member is registered " , tx2 = tx2Hash
2022-07-01 01:05:38 +00:00
# create an Ethereum private key and the corresponding account
let ( ethPrivKey , ethacc ) = await createEthAccount ( )
2022-06-17 22:00:19 +00:00
# test ------------------------------
# start rln-relay
2022-09-30 12:43:42 +00:00
await node . mountRelay ( @ [ RlnRelayPubsubTopic ] )
2022-08-30 17:59:02 +00:00
discard await node . mountRlnRelayDynamic ( ethClientAddr = EthClient ,
2022-10-12 02:18:11 +00:00
ethAccountAddress = some ( ethacc ) ,
2022-07-28 18:45:29 +00:00
ethAccountPrivKeyOpt = some ( ethPrivKey ) ,
2022-06-17 22:00:19 +00:00
memContractAddr = contractAddress ,
2022-11-04 03:00:42 +00:00
memKeyPair = some ( keyPair1 ) ,
2022-06-17 22:00:19 +00:00
memIndex = some ( MembershipIndex ( 0 ) ) ,
2022-09-30 12:43:42 +00:00
pubsubTopic = RlnRelayPubsubTopic ,
contentTopic = RlnRelayContentTopic )
2022-06-17 22:00:19 +00:00
await sleepAsync ( 2000 ) # wait for the event to reach the group handler
# rln pks are inserted into the rln peer's Merkle tree and the resulting root
# is expected to be the same as the calculatedRoot i.e., the one calculated outside of the mountRlnRelayDynamic proc
2022-10-12 08:38:48 +00:00
let calculatedRoot = node . wakuRlnRelay . rlnInstance . getMerkleRoot ( ) . value ( ) . inHex
2022-06-17 22:00:19 +00:00
debug " calculated root " , calculatedRoot = calculatedRoot
debug " expected root " , expectedRoot = expectedRoot
check :
expectedRoot = = calculatedRoot
await web3 . close ( )
await node . stop ( )
asyncTest " mounting waku rln-relay: check correct registration of peers without rln-relay credentials in dynamic/on-chain mode " :
# deploy the contract
2022-09-30 12:43:42 +00:00
let contractAddress = await uploadRLNContract ( EthClient )
2022-06-17 22:00:19 +00:00
# prepare rln-relay inputs
let
2022-09-30 12:43:42 +00:00
web3 = await newWeb3 ( EthClient )
2022-06-17 22:00:19 +00:00
accounts = await web3 . provider . eth_accounts ( )
# choose two of the existing accounts for the rln-relay peers
ethAccountAddress1 = accounts [ 0 ]
ethAccountAddress2 = accounts [ 1 ]
await web3 . close ( )
# prepare two nodes
let
nodeKey = crypto . PrivateKey . random ( Secp256k1 , rng [ ] ) [ ]
2022-11-03 13:47:56 +00:00
node = WakuNode . new ( nodeKey , ValidIpAddress . init ( " 0.0.0.0 " ) , Port ( 60112 ) )
2022-06-17 22:00:19 +00:00
await node . start ( )
let
nodeKey2 = crypto . PrivateKey . random ( Secp256k1 , rng [ ] ) [ ]
2022-11-03 13:47:56 +00:00
node2 = WakuNode . new ( nodeKey2 , ValidIpAddress . init ( " 0.0.0.0 " ) , Port ( 60113 ) )
2022-06-17 22:00:19 +00:00
await node2 . start ( )
2022-07-01 01:05:38 +00:00
# create an Ethereum private key and the corresponding account
let ( ethPrivKey , ethacc ) = await createEthAccount ( )
2022-06-17 22:00:19 +00:00
# start rln-relay on the first node, leave rln-relay credentials empty
2022-09-30 12:43:42 +00:00
await node . mountRelay ( @ [ RlnRelayPubsubTopic ] )
2022-08-30 17:59:02 +00:00
discard await node . mountRlnRelayDynamic ( ethClientAddr = EthClient ,
2022-10-12 02:18:11 +00:00
ethAccountAddress = some ( ethacc ) ,
2022-07-28 18:45:29 +00:00
ethAccountPrivKeyOpt = some ( ethPrivKey ) ,
2022-06-17 22:00:19 +00:00
memContractAddr = contractAddress ,
memKeyPair = none ( MembershipKeyPair ) ,
memIndex = none ( MembershipIndex ) ,
2022-09-30 12:43:42 +00:00
pubsubTopic = RlnRelayPubsubTopic ,
contentTopic = RlnRelayContentTopic )
2022-06-17 22:00:19 +00:00
# start rln-relay on the second node, leave rln-relay credentials empty
2022-09-30 12:43:42 +00:00
await node2 . mountRelay ( @ [ RlnRelayPubsubTopic ] )
2022-08-30 17:59:02 +00:00
discard await node2 . mountRlnRelayDynamic ( ethClientAddr = EthClient ,
2022-10-12 02:18:11 +00:00
ethAccountAddress = some ( ethacc ) ,
2022-07-28 18:45:29 +00:00
ethAccountPrivKeyOpt = some ( ethPrivKey ) ,
2022-06-17 22:00:19 +00:00
memContractAddr = contractAddress ,
memKeyPair = none ( MembershipKeyPair ) ,
memIndex = none ( MembershipIndex ) ,
2022-09-30 12:43:42 +00:00
pubsubTopic = RlnRelayPubsubTopic ,
contentTopic = RlnRelayContentTopic )
2022-06-17 22:00:19 +00:00
# the two nodes should be registered into the contract
# since nodes are spun up sequentially
# the first node has index 0 whereas the second node gets index 1
check :
node . wakuRlnRelay . membershipIndex = = MembershipIndex ( 0 )
node2 . wakuRlnRelay . membershipIndex = = MembershipIndex ( 1 )
await node . stop ( )
2022-07-28 18:45:29 +00:00
await node2 . stop ( )
2022-11-08 13:28:11 +00:00
################################
## Terminating/removing Ganache
################################
# We stop Ganache daemon
stopGanache ( runGanache )
# We uninstall Ganache
uninstallGanache ( )