mirror of
https://github.com/waku-org/nwaku.git
synced 2025-01-14 17:04:53 +00:00
deploy: 6c8ab0ab0f76fe765d95ef2f7bfb88d691a18bf7
This commit is contained in:
parent
d1f7da16c7
commit
3300ada856
@ -511,12 +511,12 @@ proc processInput(rfd: AsyncFD, rng: ref BrHmacDrbgContext) {.async.} =
|
|||||||
showChatPrompt(chat)
|
showChatPrompt(chat)
|
||||||
|
|
||||||
# set up rln relay inputs
|
# set up rln relay inputs
|
||||||
let (groupOpt, memKeyPairOpt, memIndexOpt) = rlnRelaySetUp(conf.rlnRelayMemIndex)
|
let (groupOpt, memKeyPairOpt, memIndexOpt) = rlnRelayStaticSetUp(conf.rlnRelayMemIndex)
|
||||||
if memIndexOpt.isNone:
|
if memIndexOpt.isNone:
|
||||||
error "failed to mount WakuRLNRelay"
|
error "failed to mount WakuRLNRelay"
|
||||||
else:
|
else:
|
||||||
# mount rlnrelay in offline mode (for now)
|
# mount rlnrelay in offline mode (for now)
|
||||||
waitFor node.mountRlnRelay(groupOpt = groupOpt, memKeyPairOpt = memKeyPairOpt, memIndexOpt= memIndexOpt, onchainMode = false, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic, spamHandler = some(spamHandler))
|
node.mountRlnRelayStatic(group = groupOpt.get(), memKeyPair = memKeyPairOpt.get(), memIndex = memIndexOpt.get(), pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic, spamHandler = some(spamHandler))
|
||||||
|
|
||||||
debug "membership id key", idkey=memKeyPairOpt.get().idKey.toHex
|
debug "membership id key", idkey=memKeyPairOpt.get().idKey.toHex
|
||||||
debug "membership id commitment key", idCommitmentkey=memKeyPairOpt.get().idCommitment.toHex
|
debug "membership id commitment key", idCommitmentkey=memKeyPairOpt.get().idCommitment.toHex
|
||||||
|
@ -45,10 +45,9 @@ procSuite "Waku rln relay":
|
|||||||
|
|
||||||
# -------- mount rln-relay in the off-chain mode
|
# -------- mount rln-relay in the off-chain mode
|
||||||
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
||||||
await node.mountRlnRelay(groupOpt = some(groupIDCommitments),
|
node.mountRlnRelayStatic(group = groupIDCommitments,
|
||||||
memKeyPairOpt = some(groupKeyPairs[index]),
|
memKeyPair = groupKeyPairs[index],
|
||||||
memIndexOpt = some(index),
|
memIndex = index,
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = RLNRELAY_PUBSUB_TOPIC,
|
pubsubTopic = RLNRELAY_PUBSUB_TOPIC,
|
||||||
contentTopic = RLNRELAY_CONTENT_TOPIC)
|
contentTopic = RLNRELAY_CONTENT_TOPIC)
|
||||||
|
|
||||||
|
@ -155,7 +155,6 @@ procSuite "Waku-rln-relay":
|
|||||||
rlnInstance.isOk == true
|
rlnInstance.isOk == true
|
||||||
var rln = rlnInstance.value
|
var rln = rlnInstance.value
|
||||||
|
|
||||||
# create rln membership key pair
|
|
||||||
let keyPair = rln.membershipKeyGen()
|
let keyPair = rln.membershipKeyGen()
|
||||||
check:
|
check:
|
||||||
keyPair.isSome
|
keyPair.isSome
|
||||||
@ -273,7 +272,8 @@ procSuite "Waku-rln-relay":
|
|||||||
check:
|
check:
|
||||||
is_successful
|
is_successful
|
||||||
|
|
||||||
asyncTest "mounting waku rln-relay":
|
|
||||||
|
asyncTest "mounting waku rln-relay: check correct Merkle tree construction in the static/off-chain group management":
|
||||||
# preparation ------------------------------
|
# preparation ------------------------------
|
||||||
let
|
let
|
||||||
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
|
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
|
||||||
@ -281,17 +281,6 @@ procSuite "Waku-rln-relay":
|
|||||||
Port(60000))
|
Port(60000))
|
||||||
await node.start()
|
await node.start()
|
||||||
|
|
||||||
# deploy the contract
|
|
||||||
let membershipContractAddress = await uploadRLNContract(ETH_CLIENT)
|
|
||||||
|
|
||||||
# prepare rln-relay inputs
|
|
||||||
let
|
|
||||||
web3 = await newWeb3(ETH_CLIENT)
|
|
||||||
accounts = await web3.provider.eth_accounts()
|
|
||||||
# choose one of the existing account for the rln-relay peer
|
|
||||||
ethAccountAddress = accounts[0]
|
|
||||||
await web3.close()
|
|
||||||
|
|
||||||
# create current peer's pk
|
# create current peer's pk
|
||||||
var rlnInstance = createRLNInstance()
|
var rlnInstance = createRLNInstance()
|
||||||
check:
|
check:
|
||||||
@ -321,18 +310,16 @@ procSuite "Waku-rln-relay":
|
|||||||
member_is_added = rln.insertMember(memberKeypair.get().idCommitment)
|
member_is_added = rln.insertMember(memberKeypair.get().idCommitment)
|
||||||
doAssert(member_is_added)
|
doAssert(member_is_added)
|
||||||
debug "member key", key = memberKeypair.get().idCommitment.toHex
|
debug "member key", key = memberKeypair.get().idCommitment.toHex
|
||||||
|
|
||||||
let expectedRoot = rln.getMerkleRoot().value().toHex
|
let expectedRoot = rln.getMerkleRoot().value().toHex
|
||||||
debug "expected root ", expectedRoot
|
debug "expected root ", expectedRoot
|
||||||
|
|
||||||
# test ------------------------------
|
# test ------------------------------
|
||||||
# start rln-relay
|
# start rln-relay
|
||||||
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
||||||
await node.mountRlnRelay(ethClientAddrOpt = some(EthClient),
|
node.mountRlnRelayStatic(group = group,
|
||||||
ethAccAddrOpt = some(ethAccountAddress),
|
memKeyPair = keypair.get(),
|
||||||
memContractAddOpt = some(membershipContractAddress),
|
memIndex = index,
|
||||||
groupOpt = some(group),
|
|
||||||
memKeyPairOpt = some(keypair.get()),
|
|
||||||
memIndexOpt = some(index),
|
|
||||||
pubsubTopic = RLNRELAY_PUBSUB_TOPIC,
|
pubsubTopic = RLNRELAY_PUBSUB_TOPIC,
|
||||||
contentTopic = RLNRELAY_CONTENT_TOPIC)
|
contentTopic = RLNRELAY_CONTENT_TOPIC)
|
||||||
let calculatedRoot = node.wakuRlnRelay.rlnInstance.getMerkleRoot().value().toHex
|
let calculatedRoot = node.wakuRlnRelay.rlnInstance.getMerkleRoot().value().toHex
|
||||||
@ -342,3 +329,144 @@ procSuite "Waku-rln-relay":
|
|||||||
expectedRoot == calculatedRoot
|
expectedRoot == calculatedRoot
|
||||||
|
|
||||||
await node.stop()
|
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[])[]
|
||||||
|
node = WakuNode.new(nodeKey, ValidIpAddress.init("0.0.0.0"), Port(60000))
|
||||||
|
await node.start()
|
||||||
|
|
||||||
|
# deploy the contract
|
||||||
|
let contractAddress = await uploadRLNContract(ETH_CLIENT)
|
||||||
|
|
||||||
|
# prepare rln-relay inputs
|
||||||
|
let
|
||||||
|
web3 = await newWeb3(ETH_CLIENT)
|
||||||
|
accounts = await web3.provider.eth_accounts()
|
||||||
|
# choose one of the existing accounts for the rln-relay peer
|
||||||
|
ethAccountAddress = accounts[0]
|
||||||
|
web3.defaultAccount = accounts[0]
|
||||||
|
|
||||||
|
# create an rln instance
|
||||||
|
var rlnInstance = createRLNInstance()
|
||||||
|
check:
|
||||||
|
rlnInstance.isOk == true
|
||||||
|
var rln = rlnInstance.value
|
||||||
|
|
||||||
|
# create two rln key pairs
|
||||||
|
let
|
||||||
|
keyPair1 = rln.membershipKeyGen()
|
||||||
|
keyPair2 = rln.membershipKeyGen()
|
||||||
|
check:
|
||||||
|
keyPair1.isSome
|
||||||
|
keyPair2.isSome
|
||||||
|
let
|
||||||
|
pk1 = keyPair1.get().idCommitment.toUInt256()
|
||||||
|
pk2 = keyPair2.get().idCommitment.toUInt256()
|
||||||
|
debug "member key1", key = keyPair1.get().idCommitment.toHex
|
||||||
|
debug "member key2", key = keyPair2.get().idCommitment.toHex
|
||||||
|
|
||||||
|
# add the rln keys to the Merkle tree
|
||||||
|
let
|
||||||
|
member_is_added1 = rln.insertMember(keyPair1.get().idCommitment)
|
||||||
|
member_is_added2 = rln.insertMember(keyPair2.get().idCommitment)
|
||||||
|
doAssert(member_is_added1)
|
||||||
|
doAssert(member_is_added2)
|
||||||
|
|
||||||
|
# get the Merkle root
|
||||||
|
let expectedRoot = rln.getMerkleRoot().value().toHex
|
||||||
|
|
||||||
|
# prepare a contract sender to interact with it
|
||||||
|
var contractObj = web3.contractSender(MembershipContract,
|
||||||
|
contractAddress) # creates a Sender object with a web3 field and contract address of type Address
|
||||||
|
|
||||||
|
# register the members to the contract
|
||||||
|
let tx1Hash = await contractObj.register(pk1).send(value = MEMBERSHIP_FEE)
|
||||||
|
debug "a member is registered", tx1 = tx1Hash
|
||||||
|
|
||||||
|
# register another member to the contract
|
||||||
|
let tx2Hash = await contractObj.register(pk2).send(value = MEMBERSHIP_FEE)
|
||||||
|
debug "a member is registered", tx2 = tx2Hash
|
||||||
|
|
||||||
|
# test ------------------------------
|
||||||
|
# start rln-relay
|
||||||
|
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
||||||
|
await node.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
||||||
|
ethAccAddr = ethAccountAddress,
|
||||||
|
memContractAddr = contractAddress,
|
||||||
|
memKeyPair = keyPair1,
|
||||||
|
memIndex = some(MembershipIndex(0)),
|
||||||
|
pubsubTopic = RLNRELAY_PUBSUB_TOPIC,
|
||||||
|
contentTopic = RLNRELAY_CONTENT_TOPIC)
|
||||||
|
|
||||||
|
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
|
||||||
|
let calculatedRoot = node.wakuRlnRelay.rlnInstance.getMerkleRoot().value().toHex
|
||||||
|
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
|
||||||
|
let contractAddress = await uploadRLNContract(ETH_CLIENT)
|
||||||
|
|
||||||
|
# prepare rln-relay inputs
|
||||||
|
let
|
||||||
|
web3 = await newWeb3(ETH_CLIENT)
|
||||||
|
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[])[]
|
||||||
|
node = WakuNode.new(nodeKey, ValidIpAddress.init("0.0.0.0"), Port(60000))
|
||||||
|
await node.start()
|
||||||
|
|
||||||
|
let
|
||||||
|
nodeKey2 = crypto.PrivateKey.random(Secp256k1, rng[])[]
|
||||||
|
node2 = WakuNode.new(nodeKey2, ValidIpAddress.init("0.0.0.0"), Port(60001))
|
||||||
|
await node2.start()
|
||||||
|
|
||||||
|
# start rln-relay on the first node, leave rln-relay credentials empty
|
||||||
|
node.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
||||||
|
await node.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
||||||
|
ethAccAddr = ethAccountAddress1,
|
||||||
|
memContractAddr = contractAddress,
|
||||||
|
memKeyPair = none(MembershipKeyPair),
|
||||||
|
memIndex = none(MembershipIndex),
|
||||||
|
pubsubTopic = RLNRELAY_PUBSUB_TOPIC,
|
||||||
|
contentTopic = RLNRELAY_CONTENT_TOPIC)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# start rln-relay on the second node, leave rln-relay credentials empty
|
||||||
|
node2.mountRelay(@[RLNRELAY_PUBSUB_TOPIC])
|
||||||
|
await node2.mountRlnRelayDynamic(ethClientAddr = EthClient,
|
||||||
|
ethAccAddr = ethAccountAddress2,
|
||||||
|
memContractAddr = contractAddress,
|
||||||
|
memKeyPair = none(MembershipKeyPair),
|
||||||
|
memIndex = none(MembershipIndex),
|
||||||
|
pubsubTopic = RLNRELAY_PUBSUB_TOPIC,
|
||||||
|
contentTopic = RLNRELAY_CONTENT_TOPIC)
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
await node2.stop()
|
@ -725,36 +725,33 @@ procSuite "WakuNode":
|
|||||||
# set up three nodes
|
# set up three nodes
|
||||||
# node1
|
# node1
|
||||||
node1.mountRelay(@[rlnRelayPubSubTopic])
|
node1.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt1, memKeyPairOpt1, memIndexOpt1) = rlnRelaySetUp(1) # set up rln relay inputs
|
let (groupOpt1, memKeyPairOpt1, memIndexOpt1) = rlnRelayStaticSetUp(1) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node1.mountRlnRelay(groupOpt = groupOpt1,
|
node1.mountRlnRelayStatic(group = groupOpt1.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt1,
|
memKeyPair = memKeyPairOpt1.get(),
|
||||||
memIndexOpt= memIndexOpt1,
|
memIndex = memIndexOpt1.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node1.start()
|
await node1.start()
|
||||||
|
|
||||||
# node 2
|
# node 2
|
||||||
node2.mountRelay(@[rlnRelayPubSubTopic])
|
node2.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt2, memKeyPairOpt2, memIndexOpt2) = rlnRelaySetUp(2) # set up rln relay inputs
|
let (groupOpt2, memKeyPairOpt2, memIndexOpt2) = rlnRelayStaticSetUp(2) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node2.mountRlnRelay(groupOpt = groupOpt2,
|
node2.mountRlnRelayStatic(group = groupOpt2.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt2,
|
memKeyPair = memKeyPairOpt2.get(),
|
||||||
memIndexOpt= memIndexOpt2,
|
memIndex = memIndexOpt2.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node2.start()
|
await node2.start()
|
||||||
|
|
||||||
# node 3
|
# node 3
|
||||||
node3.mountRelay(@[rlnRelayPubSubTopic])
|
node3.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt3, memKeyPairOpt3, memIndexOpt3) = rlnRelaySetUp(3) # set up rln relay inputs
|
let (groupOpt3, memKeyPairOpt3, memIndexOpt3) = rlnRelayStaticSetUp(3) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node3.mountRlnRelay(groupOpt = groupOpt3,
|
node3.mountRlnRelayStatic(group = groupOpt3.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt3,
|
memKeyPair = memKeyPairOpt3.get(),
|
||||||
memIndexOpt= memIndexOpt3,
|
memIndex = memIndexOpt3.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node3.start()
|
await node3.start()
|
||||||
@ -818,36 +815,33 @@ procSuite "WakuNode":
|
|||||||
# set up three nodes
|
# set up three nodes
|
||||||
# node1
|
# node1
|
||||||
node1.mountRelay(@[rlnRelayPubSubTopic])
|
node1.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt1, memKeyPairOpt1, memIndexOpt1) = rlnRelaySetUp(1) # set up rln relay inputs
|
let (groupOpt1, memKeyPairOpt1, memIndexOpt1) = rlnRelayStaticSetUp(1) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node1.mountRlnRelay(groupOpt = groupOpt1,
|
node1.mountRlnRelayStatic(group = groupOpt1.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt1,
|
memKeyPair = memKeyPairOpt1.get(),
|
||||||
memIndexOpt= memIndexOpt1,
|
memIndex = memIndexOpt1.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node1.start()
|
await node1.start()
|
||||||
|
|
||||||
# node 2
|
# node 2
|
||||||
node2.mountRelay(@[rlnRelayPubSubTopic])
|
node2.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt2, memKeyPairOpt2, memIndexOpt2) = rlnRelaySetUp(2) # set up rln relay inputs
|
let (groupOpt2, memKeyPairOpt2, memIndexOpt2) = rlnRelayStaticSetUp(2) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node2.mountRlnRelay(groupOpt = groupOpt2,
|
node2.mountRlnRelayStatic(group = groupOpt2.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt2,
|
memKeyPair = memKeyPairOpt2.get(),
|
||||||
memIndexOpt= memIndexOpt2,
|
memIndex = memIndexOpt2.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node2.start()
|
await node2.start()
|
||||||
|
|
||||||
# node 3
|
# node 3
|
||||||
node3.mountRelay(@[rlnRelayPubSubTopic])
|
node3.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt3, memKeyPairOpt3, memIndexOpt3) = rlnRelaySetUp(3) # set up rln relay inputs
|
let (groupOpt3, memKeyPairOpt3, memIndexOpt3) = rlnRelayStaticSetUp(3) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node3.mountRlnRelay(groupOpt = groupOpt3,
|
node3.mountRlnRelayStatic(group = groupOpt3.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt3,
|
memKeyPair = memKeyPairOpt3.get(),
|
||||||
memIndexOpt= memIndexOpt3,
|
memIndex= memIndexOpt3.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node3.start()
|
await node3.start()
|
||||||
@ -926,36 +920,33 @@ procSuite "WakuNode":
|
|||||||
# set up three nodes
|
# set up three nodes
|
||||||
# node1
|
# node1
|
||||||
node1.mountRelay(@[rlnRelayPubSubTopic])
|
node1.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt1, memKeyPairOpt1, memIndexOpt1) = rlnRelaySetUp(1) # set up rln relay inputs
|
let (groupOpt1, memKeyPairOpt1, memIndexOpt1) = rlnRelayStaticSetUp(1) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node1.mountRlnRelay(groupOpt = groupOpt1,
|
node1.mountRlnRelayStatic(group = groupOpt1.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt1,
|
memKeyPair = memKeyPairOpt1.get(),
|
||||||
memIndexOpt= memIndexOpt1,
|
memIndex = memIndexOpt1.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node1.start()
|
await node1.start()
|
||||||
|
|
||||||
# node 2
|
# node 2
|
||||||
node2.mountRelay(@[rlnRelayPubSubTopic])
|
node2.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt2, memKeyPairOpt2, memIndexOpt2) = rlnRelaySetUp(2) # set up rln relay inputs
|
let (groupOpt2, memKeyPairOpt2, memIndexOpt2) = rlnRelayStaticSetUp(2) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node2.mountRlnRelay(groupOpt = groupOpt2,
|
node2.mountRlnRelayStatic(group = groupOpt2.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt2,
|
memKeyPair = memKeyPairOpt2.get(),
|
||||||
memIndexOpt= memIndexOpt2,
|
memIndex = memIndexOpt2.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node2.start()
|
await node2.start()
|
||||||
|
|
||||||
# node 3
|
# node 3
|
||||||
node3.mountRelay(@[rlnRelayPubSubTopic])
|
node3.mountRelay(@[rlnRelayPubSubTopic])
|
||||||
let (groupOpt3, memKeyPairOpt3, memIndexOpt3) = rlnRelaySetUp(3) # set up rln relay inputs
|
let (groupOpt3, memKeyPairOpt3, memIndexOpt3) = rlnRelayStaticSetUp(3) # set up rln relay inputs
|
||||||
# mount rlnrelay in off-chain mode
|
# mount rlnrelay in off-chain mode
|
||||||
waitFor node3.mountRlnRelay(groupOpt = groupOpt3,
|
node3.mountRlnRelayStatic(group = groupOpt3.get(),
|
||||||
memKeyPairOpt = memKeyPairOpt3,
|
memKeyPair = memKeyPairOpt3.get(),
|
||||||
memIndexOpt= memIndexOpt3,
|
memIndex = memIndexOpt3.get(),
|
||||||
onchainMode = false,
|
|
||||||
pubsubTopic = rlnRelayPubSubTopic,
|
pubsubTopic = rlnRelayPubSubTopic,
|
||||||
contentTopic = contentTopic)
|
contentTopic = contentTopic)
|
||||||
await node3.start()
|
await node3.start()
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# libtool - Provide generalized library-building support services.
|
# libtool - Provide generalized library-building support services.
|
||||||
# Generated automatically by config.status (libbacktrace) version-unused
|
# Generated automatically by config.status (libbacktrace) version-unused
|
||||||
# Libtool was configured on host fv-az447-649:
|
# Libtool was configured on host fv-az241-328:
|
||||||
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
|
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
|
||||||
#
|
#
|
||||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
|
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
|
||||||
|
@ -8,6 +8,7 @@ import
|
|||||||
libp2p/crypto/secp,
|
libp2p/crypto/secp,
|
||||||
nimcrypto/utils,
|
nimcrypto/utils,
|
||||||
eth/keys,
|
eth/keys,
|
||||||
|
web3,
|
||||||
../protocol/waku_rln_relay/waku_rln_relay_types,
|
../protocol/waku_rln_relay/waku_rln_relay_types,
|
||||||
../protocol/waku_message
|
../protocol/waku_message
|
||||||
|
|
||||||
@ -129,6 +130,36 @@ type
|
|||||||
defaultValue: "/toy-chat/2/luzhou/proto"
|
defaultValue: "/toy-chat/2/luzhou/proto"
|
||||||
name: "rln-relay-content-topic" }: ContentTopic
|
name: "rln-relay-content-topic" }: ContentTopic
|
||||||
|
|
||||||
|
rlnRelayDynamic* {.
|
||||||
|
desc: "Enable waku-rln-relay with on-chain dynamic group management: true|false",
|
||||||
|
defaultValue: false
|
||||||
|
name: "rln-relay-dynamic" }: bool
|
||||||
|
|
||||||
|
rlnRelayIdKey* {.
|
||||||
|
desc: "Rln relay identity secret key as a Hex string",
|
||||||
|
defaultValue: ""
|
||||||
|
name: "rln-relay-id" }: string
|
||||||
|
|
||||||
|
rlnRelayIdCommitmentKey* {.
|
||||||
|
desc: "Rln relay identity commitment key as a Hex string",
|
||||||
|
defaultValue: ""
|
||||||
|
name: "rln-relay-id-commitment" }: string
|
||||||
|
|
||||||
|
rlnRelayEthAccount* {.
|
||||||
|
desc: "Ethereum testnet account address",
|
||||||
|
defaultValue: ""
|
||||||
|
name: "eth-account-address" }: string
|
||||||
|
|
||||||
|
rlnRelayEthClientAddress* {.
|
||||||
|
desc: "Ethereum testnet client address e.g., ws://localhost:8540/",
|
||||||
|
defaultValue: "ws://localhost:8540/"
|
||||||
|
name: "eth-client-address" }: string
|
||||||
|
|
||||||
|
rlnRelayEthMemContractAddress* {.
|
||||||
|
desc: "Address of membership contract on an Ethereum testnet",
|
||||||
|
defaultValue: ""
|
||||||
|
name: "eth-mem-contract-address" }: string
|
||||||
|
|
||||||
staticnodes* {.
|
staticnodes* {.
|
||||||
desc: "Peer multiaddr to directly connect with. Argument may be repeated."
|
desc: "Peer multiaddr to directly connect with. Argument may be repeated."
|
||||||
name: "staticnode" }: seq[string]
|
name: "staticnode" }: seq[string]
|
||||||
|
@ -6,6 +6,7 @@ import
|
|||||||
stew/shims/net as stewNet,
|
stew/shims/net as stewNet,
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
eth/keys,
|
eth/keys,
|
||||||
|
nimcrypto,
|
||||||
eth/p2p/discoveryv5/enr,
|
eth/p2p/discoveryv5/enr,
|
||||||
libp2p/crypto/crypto,
|
libp2p/crypto/crypto,
|
||||||
libp2p/protocols/ping,
|
libp2p/protocols/ping,
|
||||||
@ -38,7 +39,7 @@ when defined(rln):
|
|||||||
import
|
import
|
||||||
libp2p/protocols/pubsub/rpc/messages,
|
libp2p/protocols/pubsub/rpc/messages,
|
||||||
libp2p/protocols/pubsub/pubsub,
|
libp2p/protocols/pubsub/pubsub,
|
||||||
web3,
|
web3, web3/ethtypes,
|
||||||
../protocol/waku_rln_relay/[rln, waku_rln_relay_utils]
|
../protocol/waku_rln_relay/[rln, waku_rln_relay_utils]
|
||||||
|
|
||||||
declarePublicCounter waku_node_messages, "number of messages received", ["type"]
|
declarePublicCounter waku_node_messages, "number of messages received", ["type"]
|
||||||
@ -543,20 +544,17 @@ when defined(rln):
|
|||||||
let pb = PubSub(node.wakuRelay)
|
let pb = PubSub(node.wakuRelay)
|
||||||
pb.addValidator(pubsubTopic, validator)
|
pb.addValidator(pubsubTopic, validator)
|
||||||
|
|
||||||
proc mountRlnRelay*(node: WakuNode,
|
proc mountRlnRelayStatic*(node: WakuNode,
|
||||||
ethClientAddrOpt: Option[string] = none(string),
|
group: seq[IDCommitment],
|
||||||
ethAccAddrOpt: Option[web3.Address] = none(web3.Address),
|
memKeyPair: MembershipKeyPair,
|
||||||
memContractAddOpt: Option[web3.Address] = none(web3.Address),
|
memIndex: MembershipIndex,
|
||||||
groupOpt: Option[seq[IDCommitment]] = none(seq[IDCommitment]),
|
|
||||||
memKeyPairOpt: Option[MembershipKeyPair] = none(MembershipKeyPair),
|
|
||||||
memIndexOpt: Option[MembershipIndex] = none(MembershipIndex),
|
|
||||||
onchainMode: bool = true,
|
|
||||||
pubsubTopic: string,
|
pubsubTopic: string,
|
||||||
contentTopic: ContentTopic,
|
contentTopic: ContentTopic,
|
||||||
spamHandler: Option[SpamHandler] = none(SpamHandler)) {.async.} =
|
spamHandler: Option[SpamHandler] = none(SpamHandler)) {.raises: [Defect, IOError].}=
|
||||||
# TODO return a bool value to indicate the success of the call
|
# TODO return a bool value to indicate the success of the call
|
||||||
# check whether inputs are provided
|
|
||||||
|
|
||||||
|
debug "mounting rln-relay in off-chain/static mode"
|
||||||
|
# check whether inputs are provided
|
||||||
# relay protocol is the prerequisite of rln-relay
|
# relay protocol is the prerequisite of rln-relay
|
||||||
if node.wakuRelay.isNil:
|
if node.wakuRelay.isNil:
|
||||||
error "Failed to mount WakuRLNRelay. Relay protocol is not mounted."
|
error "Failed to mount WakuRLNRelay. Relay protocol is not mounted."
|
||||||
@ -565,41 +563,8 @@ when defined(rln):
|
|||||||
if pubsubTopic notin node.wakuRelay.defaultTopics:
|
if pubsubTopic notin node.wakuRelay.defaultTopics:
|
||||||
error "Failed to mount WakuRLNRelay. The relay protocol does not support the configured pubsub topic.", pubsubTopic=pubsubTopic
|
error "Failed to mount WakuRLNRelay. The relay protocol does not support the configured pubsub topic.", pubsubTopic=pubsubTopic
|
||||||
return
|
return
|
||||||
if onchainMode:
|
|
||||||
if memContractAddOpt.isNone():
|
|
||||||
error "failed to mount rln relay: membership contract address is not provided"
|
|
||||||
return
|
|
||||||
if ethClientAddrOpt.isNone():
|
|
||||||
error "failed to mount rln relay: Ethereum client address is not provided"
|
|
||||||
return
|
|
||||||
if ethAccAddrOpt.isNone():
|
|
||||||
error "failed to mount rln relay: Ethereum account address is not provided"
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
if groupOpt.isNone():
|
|
||||||
error "failed to mount rln relay: group information is not provided"
|
|
||||||
return
|
|
||||||
|
|
||||||
if memKeyPairOpt.isNone():
|
debug "rln-relay input validation passed"
|
||||||
error "failed to mount rln relay: membership key of the node is not provided"
|
|
||||||
return
|
|
||||||
if memIndexOpt.isNone():
|
|
||||||
error "failed to mount rln relay: membership index is not provided"
|
|
||||||
return
|
|
||||||
|
|
||||||
var
|
|
||||||
ethClientAddr: string
|
|
||||||
ethAccAddr: web3.Address
|
|
||||||
memContractAdd: web3.Address
|
|
||||||
if onchainMode:
|
|
||||||
ethClientAddr = ethClientAddrOpt.get()
|
|
||||||
ethAccAddr = ethAccAddrOpt.get()
|
|
||||||
memContractAdd = memContractAddOpt.get()
|
|
||||||
|
|
||||||
let
|
|
||||||
group = groupOpt.get()
|
|
||||||
memKeyPair = memKeyPairOpt.get()
|
|
||||||
memIndex = memIndexOpt.get()
|
|
||||||
|
|
||||||
# check the peer's index and the inclusion of user's identity commitment in the group
|
# check the peer's index and the inclusion of user's identity commitment in the group
|
||||||
doAssert((memKeyPair.idCommitment) == group[int(memIndex)])
|
doAssert((memKeyPair.idCommitment) == group[int(memIndex)])
|
||||||
@ -609,40 +574,94 @@ when defined(rln):
|
|||||||
doAssert(rlnInstance.isOk)
|
doAssert(rlnInstance.isOk)
|
||||||
var rln = rlnInstance.value
|
var rln = rlnInstance.value
|
||||||
|
|
||||||
# generate the membership keys if none is provided
|
|
||||||
# in a happy path, this condition never gets through for a static group of users
|
|
||||||
# the node should pass its keys i.e., memKeyPairOpt to the function
|
|
||||||
if not memKeyPairOpt.isSome:
|
|
||||||
let membershipKeyPair = rln.membershipKeyGen()
|
|
||||||
# check whether keys are generated
|
|
||||||
doAssert(membershipKeyPair.isSome())
|
|
||||||
debug "the membership key for the rln relay is generated", idKey=membershipKeyPair.get().idKey.toHex, idCommitment=membershipKeyPair.get().idCommitment.toHex
|
|
||||||
|
|
||||||
|
|
||||||
# add members to the Merkle tree
|
# add members to the Merkle tree
|
||||||
for index in 0..group.len-1:
|
for index in 0..group.len-1:
|
||||||
let member = group[index]
|
let member = group[index]
|
||||||
let member_is_added = rln.insertMember(member)
|
let member_is_added = rln.insertMember(member)
|
||||||
doAssert(member_is_added)
|
doAssert(member_is_added)
|
||||||
|
|
||||||
|
|
||||||
# create the WakuRLNRelay
|
# create the WakuRLNRelay
|
||||||
var rlnPeer = WakuRLNRelay(membershipKeyPair: memKeyPair,
|
var rlnPeer = WakuRLNRelay(membershipKeyPair: memKeyPair,
|
||||||
membershipIndex: memIndex,
|
membershipIndex: memIndex,
|
||||||
membershipContractAddress: memContractAdd,
|
rlnInstance: rln,
|
||||||
|
pubsubTopic: pubsubTopic,
|
||||||
|
contentTopic: contentTopic)
|
||||||
|
|
||||||
|
# adds a topic validator for the supplied pubsub topic at the relay protocol
|
||||||
|
# messages published on this pubsub topic will be relayed upon a successful validation, otherwise they will be dropped
|
||||||
|
# the topic validator checks for the correct non-spamming proof of the message
|
||||||
|
node.addRLNRelayValidator(pubsubTopic, contentTopic, spamHandler)
|
||||||
|
debug "rln relay topic validator is mounted successfully", pubsubTopic=pubsubTopic, contentTopic=contentTopic
|
||||||
|
|
||||||
|
node.wakuRlnRelay = rlnPeer
|
||||||
|
|
||||||
|
|
||||||
|
proc mountRlnRelayDynamic*(node: WakuNode,
|
||||||
|
ethClientAddr: string = "",
|
||||||
|
ethAccAddr: web3.Address,
|
||||||
|
memContractAddr: web3.Address,
|
||||||
|
memKeyPair: Option[MembershipKeyPair] = none(MembershipKeyPair),
|
||||||
|
memIndex: Option[MembershipIndex] = none(MembershipIndex),
|
||||||
|
pubsubTopic: string,
|
||||||
|
contentTopic: ContentTopic,
|
||||||
|
spamHandler: Option[SpamHandler] = none(SpamHandler)) {.async.} =
|
||||||
|
debug "mounting rln-relay in on-chain/dynamic mode"
|
||||||
|
# TODO return a bool value to indicate the success of the call
|
||||||
|
# relay protocol is the prerequisite of rln-relay
|
||||||
|
if node.wakuRelay.isNil:
|
||||||
|
error "Failed to mount WakuRLNRelay. Relay protocol is not mounted."
|
||||||
|
return
|
||||||
|
# check whether the pubsub topic is supported at the relay level
|
||||||
|
if pubsubTopic notin node.wakuRelay.defaultTopics:
|
||||||
|
error "Failed to mount WakuRLNRelay. The relay protocol does not support the configured pubsub topic.", pubsubTopic=pubsubTopic
|
||||||
|
return
|
||||||
|
debug "rln-relay input validation passed"
|
||||||
|
|
||||||
|
# create an RLN instance
|
||||||
|
var rlnInstance = createRLNInstance()
|
||||||
|
doAssert(rlnInstance.isOk)
|
||||||
|
var rln = rlnInstance.value
|
||||||
|
|
||||||
|
# prepare rln membership key pair
|
||||||
|
var
|
||||||
|
keyPair: MembershipKeyPair
|
||||||
|
rlnIndex: MembershipIndex
|
||||||
|
if memKeyPair.isNone: # if non provided, create one and register to the contract
|
||||||
|
trace "no rln-relay key is provided, generating one"
|
||||||
|
let keyPairOpt = rln.membershipKeyGen()
|
||||||
|
doAssert(keyPairOpt.isSome)
|
||||||
|
keyPair = keyPairOpt.get()
|
||||||
|
# register the rln-relay peer to the membership contract
|
||||||
|
let regIndexRes = await register(idComm = keyPair.idCommitment, ethAccountAddress = ethAccAddr, ethClientAddress = ethClientAddr, membershipContractAddress = memContractAddr)
|
||||||
|
# check whether registration is done
|
||||||
|
doAssert(regIndexRes.isOk())
|
||||||
|
rlnIndex = regIndexRes.value
|
||||||
|
debug "peer is successfully registered into the membership contract", rlnIndex=rlnIndex, idComm=keyPair.idCommitment.toHex(), idKey=keyPair.idKey.toHex()
|
||||||
|
else:
|
||||||
|
keyPair = memKeyPair.get()
|
||||||
|
rlnIndex = memIndex.get()
|
||||||
|
|
||||||
|
# create the WakuRLNRelay
|
||||||
|
var rlnPeer = WakuRLNRelay(membershipKeyPair: keyPair,
|
||||||
|
membershipIndex: rlnIndex,
|
||||||
|
membershipContractAddress: memContractAddr,
|
||||||
ethClientAddress: ethClientAddr,
|
ethClientAddress: ethClientAddr,
|
||||||
ethAccountAddress: ethAccAddr,
|
ethAccountAddress: ethAccAddr,
|
||||||
rlnInstance: rln,
|
rlnInstance: rln,
|
||||||
pubsubTopic: pubsubTopic,
|
pubsubTopic: pubsubTopic,
|
||||||
contentTopic: contentTopic)
|
contentTopic: contentTopic)
|
||||||
|
|
||||||
if onchainMode:
|
|
||||||
# register the rln-relay peer to the membership contract
|
|
||||||
let isSuccessful = await rlnPeer.register()
|
|
||||||
# check whether registration is done
|
|
||||||
doAssert(isSuccessful)
|
|
||||||
debug "peer is successfully registered into the membership contract"
|
|
||||||
|
|
||||||
|
proc handler(pubkey: Uint256, index: Uint256) =
|
||||||
|
debug "a new key is added", pubkey=pubkey
|
||||||
|
# assuming all the members arrive in order
|
||||||
|
let pk = pubkey.toIDCommitment()
|
||||||
|
let isSuccessful = rlnPeer.rlnInstance.insertMember(pk)
|
||||||
|
debug "received pk", pk=pk.toHex, index =index
|
||||||
|
doAssert(isSuccessful)
|
||||||
|
|
||||||
|
asyncSpawn rlnPeer.handleGroupUpdates(handler)
|
||||||
|
debug "dynamic group management is started"
|
||||||
# adds a topic validator for the supplied pubsub topic at the relay protocol
|
# adds a topic validator for the supplied pubsub topic at the relay protocol
|
||||||
# messages published on this pubsub topic will be relayed upon a successful validation, otherwise they will be dropped
|
# messages published on this pubsub topic will be relayed upon a successful validation, otherwise they will be dropped
|
||||||
# the topic validator checks for the correct non-spamming proof of the message
|
# the topic validator checks for the correct non-spamming proof of the message
|
||||||
@ -1207,15 +1226,15 @@ when isMainModule:
|
|||||||
|
|
||||||
when defined(rln):
|
when defined(rln):
|
||||||
if conf.rlnRelay:
|
if conf.rlnRelay:
|
||||||
info "WakuRLNRelay is enabled"
|
if not conf.rlnRelayDynamic:
|
||||||
|
info " setting up waku-rln-relay in on-chain mode... "
|
||||||
# set up rln relay inputs
|
# set up rln relay inputs
|
||||||
let (groupOpt, memKeyPairOpt, memIndexOpt) = rlnRelaySetUp(conf.rlnRelayMemIndex)
|
let (groupOpt, memKeyPairOpt, memIndexOpt) = rlnRelayStaticSetUp(conf.rlnRelayMemIndex)
|
||||||
if memIndexOpt.isNone:
|
if memIndexOpt.isNone:
|
||||||
error "failed to mount WakuRLNRelay"
|
error "failed to mount WakuRLNRelay"
|
||||||
else:
|
else:
|
||||||
# mount rlnrelay in offline mode (for now)
|
# mount rlnrelay in off-chain mode with a static group of users
|
||||||
waitFor node.mountRlnRelay(groupOpt = groupOpt, memKeyPairOpt = memKeyPairOpt, memIndexOpt= memIndexOpt, onchainMode = false, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic)
|
node.mountRlnRelayStatic(group = groupOpt.get(), memKeyPair = memKeyPairOpt.get(), memIndex= memIndexOpt.get(), pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic)
|
||||||
|
|
||||||
info "membership id key", idkey=memKeyPairOpt.get().idKey.toHex
|
info "membership id key", idkey=memKeyPairOpt.get().idKey.toHex
|
||||||
info "membership id commitment key", idCommitmentkey=memKeyPairOpt.get().idCommitment.toHex
|
info "membership id commitment key", idCommitmentkey=memKeyPairOpt.get().idCommitment.toHex
|
||||||
@ -1230,6 +1249,28 @@ when isMainModule:
|
|||||||
error "root mismatch: something went wrong not in Merkle tree construction"
|
error "root mismatch: something went wrong not in Merkle tree construction"
|
||||||
debug "the calculated root", root
|
debug "the calculated root", root
|
||||||
info "WakuRLNRelay is mounted successfully", pubsubtopic=conf.rlnRelayPubsubTopic, contentTopic=conf.rlnRelayContentTopic
|
info "WakuRLNRelay is mounted successfully", pubsubtopic=conf.rlnRelayPubsubTopic, contentTopic=conf.rlnRelayContentTopic
|
||||||
|
else:
|
||||||
|
info " setting up waku-rln-relay in on-chain mode... "
|
||||||
|
|
||||||
|
# read related inputs to run rln-relay in on-chain mode and do type conversion when needed
|
||||||
|
let
|
||||||
|
ethAccountAddr = web3.fromHex(web3.Address, conf.rlnRelayEthAccount)
|
||||||
|
ethClientAddr = conf.rlnRelayEthClientAddress
|
||||||
|
ethMemContractAddress = web3.fromHex(web3.Address, conf.rlnRelayEthMemContractAddress)
|
||||||
|
rlnRelayId = conf.rlnRelayIdKey
|
||||||
|
rlnRelayIdCommitmentKey = conf.rlnRelayIdCommitmentKey
|
||||||
|
rlnRelayIndex = conf.rlnRelayMemIndex
|
||||||
|
# check if the peer has provided its rln credentials
|
||||||
|
if rlnRelayIdCommitmentKey != "" and rlnRelayId != "":
|
||||||
|
# type conversation from hex strings to MembershipKeyPair
|
||||||
|
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, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic)
|
||||||
|
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, pubsubTopic = conf.rlnRelayPubsubTopic, contentTopic = conf.rlnRelayContentTopic)
|
||||||
|
|
||||||
if conf.swap:
|
if conf.swap:
|
||||||
mountSwap(node)
|
mountSwap(node)
|
||||||
|
@ -74,7 +74,7 @@ type WakuRLNRelay* = ref object
|
|||||||
# this field is required for signing transactions
|
# this field is required for signing transactions
|
||||||
# TODO may need to erase this ethAccountPrivateKey when is not used
|
# TODO may need to erase this ethAccountPrivateKey when is not used
|
||||||
# TODO may need to make ethAccountPrivateKey mandatory
|
# TODO may need to make ethAccountPrivateKey mandatory
|
||||||
ethAccountPrivateKey*: Option[PrivateKey]
|
ethAccountPrivateKey*: PrivateKey
|
||||||
rlnInstance*: RLN[Bn256]
|
rlnInstance*: RLN[Bn256]
|
||||||
pubsubTopic*: string # the pubsub topic for which rln relay is mounted
|
pubsubTopic*: string # the pubsub topic for which rln relay is mounted
|
||||||
# contentTopic should be of type waku_message.ContentTopic, however, due to recursive module dependency, the underlying type of ContentTopic is used instead
|
# contentTopic should be of type waku_message.ContentTopic, however, due to recursive module dependency, the underlying type of ContentTopic is used instead
|
||||||
|
@ -4,6 +4,7 @@ import
|
|||||||
std/sequtils, tables, times,
|
std/sequtils, tables, times,
|
||||||
chronicles, options, chronos, stint,
|
chronicles, options, chronos, stint,
|
||||||
web3, json,
|
web3, json,
|
||||||
|
eth/keys,
|
||||||
stew/results,
|
stew/results,
|
||||||
stew/[byteutils, arrayops, endians2],
|
stew/[byteutils, arrayops, endians2],
|
||||||
rln,
|
rln,
|
||||||
@ -65,6 +66,7 @@ proc createRLNInstance*(d: int = MERKLE_TREE_DEPTH): RLNResult
|
|||||||
return err("error in parameters generation")
|
return err("error in parameters generation")
|
||||||
return ok(rlnInstance)
|
return ok(rlnInstance)
|
||||||
|
|
||||||
|
|
||||||
proc membershipKeyGen*(ctxPtr: RLN[Bn256]): Option[MembershipKeyPair] =
|
proc membershipKeyGen*(ctxPtr: RLN[Bn256]): Option[MembershipKeyPair] =
|
||||||
## generates a MembershipKeyPair that can be used for the registration into the rln membership contract
|
## generates a MembershipKeyPair that can be used for the registration into the rln membership contract
|
||||||
|
|
||||||
@ -99,28 +101,65 @@ proc membershipKeyGen*(ctxPtr: RLN[Bn256]): Option[MembershipKeyPair] =
|
|||||||
return some(keypair)
|
return some(keypair)
|
||||||
|
|
||||||
proc toUInt256*(idCommitment: IDCommitment): UInt256 =
|
proc toUInt256*(idCommitment: IDCommitment): UInt256 =
|
||||||
let pk = cast[UInt256](idCommitment)
|
let pk = UInt256.fromBytesBE(idCommitment)
|
||||||
return pk
|
return pk
|
||||||
|
|
||||||
proc toIDCommitment*(idCommitment: UInt256): IDCommitment =
|
proc toIDCommitment*(idCommitmentUint: UInt256): IDCommitment =
|
||||||
let pk = cast[IDCommitment](idCommitment)
|
let pk = IDCommitment(idCommitmentUint.toBytesBE())
|
||||||
return pk
|
return pk
|
||||||
|
|
||||||
|
proc toMembershipIndex(v: UInt256): MembershipIndex =
|
||||||
|
let result: MembershipIndex = cast[MembershipIndex](v)
|
||||||
|
return result
|
||||||
|
|
||||||
|
proc register*(idComm: IDCommitment, ethAccountAddress: Address, ethClientAddress: string, membershipContractAddress: Address): Future[Result[MembershipIndex, string]] {.async.} =
|
||||||
|
# TODO may need to also get eth Account Private Key as PrivateKey
|
||||||
|
## registers the idComm into the membership contract whose address is in rlnPeer.membershipContractAddress
|
||||||
|
let web3 = await newWeb3(ethClientAddress)
|
||||||
|
web3.defaultAccount = ethAccountAddress
|
||||||
|
|
||||||
|
# when the private key is set in a web3 instance, the send proc (sender.register(pk).send(MEMBERSHIP_FEE))
|
||||||
|
# does the signing using the provided key
|
||||||
|
# web3.privateKey = some(ethAccountPrivateKey)
|
||||||
|
var sender = web3.contractSender(MembershipContract, membershipContractAddress) # creates a Sender object with a web3 field and contract address of type Address
|
||||||
|
|
||||||
|
debug "registering an id commitment", idComm=idComm
|
||||||
|
let
|
||||||
|
pk = idComm.toUInt256()
|
||||||
|
txHash = await sender.register(pk).send(MEMBERSHIP_FEE)
|
||||||
|
tsReceipt = await web3.getMinedTransactionReceipt(txHash)
|
||||||
|
|
||||||
|
# the receipt topic holds the hash of signature of the raised events
|
||||||
|
let firstTopic = tsReceipt.logs[0].topics[0]
|
||||||
|
# the hash of the signature of MemberRegistered(uint256,uint256) event is equal to the following hex value
|
||||||
|
if firstTopic[0..65] != "0x5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d2":
|
||||||
|
return err("invalid event signature hash")
|
||||||
|
|
||||||
|
# the arguments of the raised event i.e., MemberRegistered are encoded inside the data field
|
||||||
|
# data = pk encoded as 256 bits || index encoded as 256 bits
|
||||||
|
let arguments = tsReceipt.logs[0].data
|
||||||
|
debug "tx log data", arguments=arguments
|
||||||
|
let
|
||||||
|
argumentsBytes = arguments.hexToSeqByte()
|
||||||
|
eventIdCommUint = UInt256.fromBytesBE(argumentsBytes[0..31])
|
||||||
|
eventIndex = UInt256.fromBytesBE(argumentsBytes[32..^1])
|
||||||
|
eventIdComm = eventIdCommUint.toIDCommitment()
|
||||||
|
debug "the identity commitment key extracted from tx log", eventIdComm=eventIdComm
|
||||||
|
debug "the index of registered identity commitment key", eventIndex=eventIndex
|
||||||
|
|
||||||
|
if eventIdComm != idComm:
|
||||||
|
return err("invalid id commitment key")
|
||||||
|
|
||||||
|
|
||||||
|
await web3.close()
|
||||||
|
return ok(toMembershipIndex(eventIndex))
|
||||||
|
|
||||||
proc register*(rlnPeer: WakuRLNRelay): Future[bool] {.async.} =
|
proc register*(rlnPeer: WakuRLNRelay): Future[bool] {.async.} =
|
||||||
## registers the public key of the rlnPeer which is rlnPeer.membershipKeyPair.publicKey
|
## registers the public key of the rlnPeer which is rlnPeer.membershipKeyPair.publicKey
|
||||||
## into the membership contract whose address is in rlnPeer.membershipContractAddress
|
## into the membership contract whose address is in rlnPeer.membershipContractAddress
|
||||||
let web3 = await newWeb3(rlnPeer.ethClientAddress)
|
let pk = rlnPeer.membershipKeyPair.idCommitment
|
||||||
web3.defaultAccount = rlnPeer.ethAccountAddress
|
discard await register(idComm = pk, ethAccountAddress = rlnPeer.ethAccountAddress, ethClientAddress = rlnPeer.ethClientAddress, membershipContractAddress = rlnPeer.membershipContractAddress )
|
||||||
# when the private key is set in a web3 instance, the send proc (sender.register(pk).send(MEMBERSHIP_FEE))
|
|
||||||
# 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 = rlnPeer.membershipKeyPair.idCommitment.toUInt256()
|
|
||||||
discard await sender.register(pk).send(MEMBERSHIP_FEE)
|
|
||||||
debug "pk", pk = pk
|
|
||||||
# TODO check the receipt and then return true/false
|
|
||||||
await web3.close()
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
proc appendLength*(input: openArray[byte]): seq[byte] =
|
proc appendLength*(input: openArray[byte]): seq[byte] =
|
||||||
@ -343,7 +382,7 @@ proc createMembershipList*(n: int): (seq[(string, string)], string) {.raises: [
|
|||||||
let root = rln.getMerkleRoot().value.toHex
|
let root = rln.getMerkleRoot().value.toHex
|
||||||
return (output, root)
|
return (output, root)
|
||||||
|
|
||||||
proc rlnRelaySetUp*(rlnRelayMemIndex: MembershipIndex): (Option[seq[
|
proc rlnRelayStaticSetUp*(rlnRelayMemIndex: MembershipIndex): (Option[seq[
|
||||||
IDCommitment]], Option[MembershipKeyPair], Option[
|
IDCommitment]], Option[MembershipKeyPair], Option[
|
||||||
MembershipIndex]) {.raises: [Defect, ValueError].} =
|
MembershipIndex]) {.raises: [Defect, ValueError].} =
|
||||||
let
|
let
|
||||||
@ -579,6 +618,7 @@ proc subscribeToGroupEvents(ethClientUri: string, contractAddress: Address, bloc
|
|||||||
debug "onRegister", pubkey = pubkey, index = index
|
debug "onRegister", pubkey = pubkey, index = index
|
||||||
handler(pubkey, index)
|
handler(pubkey, index)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
# chronos still raises exceptions which inherit directly from Exception
|
||||||
doAssert false, err.msg
|
doAssert false, err.msg
|
||||||
do (err: CatchableError):
|
do (err: CatchableError):
|
||||||
echo "Error from subscription: ", err.msg
|
echo "Error from subscription: ", err.msg
|
||||||
|
Loading…
x
Reference in New Issue
Block a user