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-10 16:58:31 +00:00
std / [ options , osproc , streams , strutils , sequtils ] ,
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-12-13 09:26:24 +00:00
.. / .. / waku / v2 / protocol / waku_rln_relay ,
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
2022-12-07 17:17:08 +00:00
let balance = await web3 . provider . eth_getBalance ( web3 . defaultAccount , " latest " )
2022-05-10 21:09:18 +00:00
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 )
2022-12-07 17:17:08 +00:00
let contractAddress = receipt . contractAddress . get
2022-05-10 21:09:18 +00:00
debug " Address of the deployed membership contract: " , contractAddress
2022-12-07 17:17:08 +00:00
let newBalance = await web3 . provider . eth_getBalance ( web3 . defaultAccount , " latest " )
debug " Account balance after the contract deployment: " , newBalance
2022-05-10 21:09:18 +00:00
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 ( ) ) )
2022-12-07 17:17:08 +00:00
var tx : EthSend
2022-07-01 01:05:38 +00:00
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 )
2022-12-07 17:17:08 +00:00
let balance = await web3 . provider . eth_getBalance ( acc , " latest " )
2022-07-01 01:05:38 +00:00
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 ) :
2022-12-07 17:17:08 +00:00
ganacheStartLog . add ( cmdline )
2022-11-08 13:28:11 +00:00
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-12-14 11:28:09 +00:00
let identityCredentialRes = membershipKeyGen ( rlnInstance . get ( ) )
2022-11-04 03:00:42 +00:00
require :
2022-12-14 11:28:09 +00:00
identityCredentialRes . isOk ( )
let identityCredential = identityCredentialRes . get ( )
let pk = identityCredential . idCommitment . toUInt256 ( )
2022-05-10 21:09:18 +00:00
debug " membership commitment key " , pk = pk
# test ------------------------------
2022-12-07 17:17:08 +00:00
let fut = newFuture [ void ] ( )
2022-05-10 21:09:18 +00:00
let s = await contractObj . subscribe ( MemberRegistered , % * { " fromBlock " : " 0x0 " ,
" address " : contractAddress } ) do (
2022-12-13 09:26:24 +00:00
idCommitment : Uint256 , index : Uint256 ) {. raises : [ Defect ] , gcsafe . } :
2022-05-10 21:09:18 +00:00
try :
2022-12-13 09:26:24 +00:00
debug " onRegister " , idCommitment = idCommitment , index = index
2022-12-07 17:17:08 +00:00
require :
2022-12-13 09:26:24 +00:00
idCommitment = = pk
2022-05-10 21:09:18 +00:00
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 ( )
2022-12-14 11:28:09 +00:00
let idCredentialRes = rln . membershipKeyGen ( )
2022-11-04 03:00:42 +00:00
require :
2022-12-14 11:28:09 +00:00
idCredentialRes . isOk ( )
let idCredential = idCredentialRes . get ( )
let pk = idCredential . idCommitment . toUInt256 ( )
2022-05-30 19:14:07 +00:00
debug " membership commitment key " , pk = pk
# initialize the WakuRLNRelay
2022-12-14 11:28:09 +00:00
let rlnPeer = WakuRLNRelay ( identityCredential : idCredential ,
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 )
2022-12-14 11:28:09 +00:00
# generate another identity credential
let idCredential2Res = rln . membershipKeyGen ( )
2022-11-04 03:00:42 +00:00
require :
2022-12-14 11:28:09 +00:00
idCredential2Res . isOk ( )
let idCredential2 = idCredential2Res . get ( )
let pk2 = idCredential2 . idCommitment . toUInt256 ( )
2022-05-30 19:14:07 +00:00
debug " membership commitment key " , pk2 = pk2
2022-12-07 17:17:08 +00:00
let events = [ newFuture [ void ] ( ) , newFuture [ void ] ( ) ]
2022-11-10 16:58:31 +00:00
var futIndex = 0
var handler : GroupUpdateHandler
handler = proc ( blockNumber : BlockNumber ,
members : seq [ MembershipTuple ] ) : RlnRelayResult [ void ] =
debug " handler is called " , members = members
events [ futIndex ] . complete ( )
futIndex + = 1
let index = members [ 0 ] . index
2022-12-13 09:26:24 +00:00
let insertRes = rlnPeer . insertMembers ( index , members . mapIt ( it . idComm ) )
2022-05-30 19:14:07 +00:00
check :
2022-12-13 09:26:24 +00:00
insertRes . isOk ( )
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
2022-11-10 16:58:31 +00:00
# wait for the events to be processed
2022-12-13 09:26:24 +00:00
await allFutures ( events )
2022-05-30 19:14:07 +00:00
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
2022-12-07 17:17:08 +00:00
# let 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-12-14 11:28:09 +00:00
let identityCredentialRes = membershipKeyGen ( rlnInstance . get ( ) )
2022-11-04 03:00:42 +00:00
require :
2022-12-14 11:28:09 +00:00
identityCredentialRes . isOk ( )
let identityCredential = identityCredentialRes . 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-12-14 11:28:09 +00:00
let rlnPeer = WakuRLNRelay ( identityCredential : identityCredential ,
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-12-14 11:28:09 +00:00
# generate an identity credential
let idCredentialRes = rln . membershipKeyGen ( )
2022-11-04 03:00:42 +00:00
require :
2022-12-14 11:28:09 +00:00
idCredentialRes . isOk ( )
2022-05-10 21:09:18 +00:00
2022-12-14 11:28:09 +00:00
let idCredential = idCredentialRes . 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 ] ( )
2022-11-10 16:58:31 +00:00
for i in 0 'u .. 10 'u :
2022-11-04 03:00:42 +00:00
var memberAdded : bool = false
2022-11-10 16:58:31 +00:00
if ( i = = index ) :
2022-05-10 21:09:18 +00:00
# insert the current peer's pk
2022-12-14 11:28:09 +00:00
group . add ( idCredential . idCommitment )
memberAdded = rln . insertMembers ( i , @ [ idCredential . idCommitment ] )
2022-11-04 03:00:42 +00:00
doAssert ( memberAdded )
2022-12-14 11:28:09 +00:00
debug " member key " , key = idCredential . idCommitment . inHex
2022-05-10 21:09:18 +00:00
else :
2022-12-14 11:28:09 +00:00
let idCredentialRes = rln . membershipKeyGen ( )
2022-11-04 03:00:42 +00:00
require :
2022-12-14 11:28:09 +00:00
idCredentialRes . isOk ( )
let idCredential = idCredentialRes . get ( )
group . add ( idCredential . idCommitment )
let memberAdded = rln . insertMembers ( i , @ [ idCredential . idCommitment ] )
2022-11-04 03:00:42 +00:00
require :
memberAdded
2022-12-14 11:28:09 +00:00
debug " member key " , key = idCredential . 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-12-13 09:26:24 +00:00
let mountRes = mountRlnRelayStatic ( wakuRelay = node . wakuRelay ,
group = group ,
2022-12-14 11:28:09 +00:00
memIdCredential = idCredential ,
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-12-13 09:26:24 +00:00
let wakuRlnRelay = mountRes . get ( )
let calculatedRoot = 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
2022-12-14 11:28:09 +00:00
# create two identity credentials
2022-06-17 22:00:19 +00:00
let
2022-12-14 11:28:09 +00:00
idCredential1Res = rln . membershipKeyGen ( )
idCredential2Res = rln . membershipKeyGen ( )
2022-11-04 03:00:42 +00:00
require :
2022-12-14 11:28:09 +00:00
idCredential1Res . isOk ( )
idCredential2Res . isOk ( )
2022-11-04 03:00:42 +00:00
let
2022-12-14 11:28:09 +00:00
idCredential1 = idCredential1Res . get ( )
idCredential2 = idCredential2Res . get ( )
pk1 = idCredential1 . idCommitment . toUInt256 ( )
pk2 = idCredential2 . idCommitment . toUInt256 ( )
debug " member key1 " , key = idCredential1 . idCommitment . inHex
debug " member key2 " , key = idCredential2 . idCommitment . inHex
2022-06-17 22:00:19 +00:00
# add the rln keys to the Merkle tree
let
2022-12-14 11:28:09 +00:00
memberIsAdded1 = rln . insertMembers ( 0 , @ [ idCredential1 . idCommitment ] )
memberIsAdded2 = rln . insertMembers ( 1 , @ [ idCredential2 . idCommitment ] )
2022-11-04 03:00:42 +00:00
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-12-13 09:26:24 +00:00
let mountRes = await mountRlnRelayDynamic ( wakuRelay = node . wakuRelay ,
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-12-14 11:28:09 +00:00
memIdCredential = some ( idCredential1 ) ,
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-12-13 09:26:24 +00:00
require :
mountRes . isOk ( )
let wakuRlnRelay = mountRes . get ( )
2022-06-17 22:00:19 +00:00
2022-12-13 09:26:24 +00:00
await sleepAsync ( 2000 . milliseconds ( ) ) # wait for the event to reach the group handler
2022-06-17 22:00:19 +00:00
# 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-12-13 09:26:24 +00:00
let calculatedRoot = 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-12-13 09:26:24 +00:00
let mountRes = await mountRlnRelayDynamic ( wakuRelay = node . wakuRelay ,
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-12-14 11:28:09 +00:00
memIdCredential = none ( IdentityCredential ) ,
2022-06-17 22:00:19 +00:00
memIndex = none ( MembershipIndex ) ,
2022-09-30 12:43:42 +00:00
pubsubTopic = RlnRelayPubsubTopic ,
contentTopic = RlnRelayContentTopic )
2022-06-17 22:00:19 +00:00
2022-12-13 09:26:24 +00:00
require :
mountRes . isOk ( )
let wakuRlnRelay = mountRes . get ( )
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-12-13 09:26:24 +00:00
let mountRes2 = await mountRlnRelayDynamic ( wakuRelay = node2 . wakuRelay ,
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-12-14 11:28:09 +00:00
memIdCredential = none ( IdentityCredential ) ,
2022-06-17 22:00:19 +00:00
memIndex = none ( MembershipIndex ) ,
2022-09-30 12:43:42 +00:00
pubsubTopic = RlnRelayPubsubTopic ,
contentTopic = RlnRelayContentTopic )
2022-06-17 22:00:19 +00:00
2022-12-13 09:26:24 +00:00
require :
mountRes2 . isOk ( )
let wakuRlnRelay2 = mountRes2 . get ( )
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 :
2022-12-13 09:26:24 +00:00
wakuRlnRelay . membershipIndex = = MembershipIndex ( 0 )
wakuRlnRelay2 . membershipIndex = = MembershipIndex ( 1 )
2022-06-17 22:00:19 +00:00
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 ( )