Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(rln-relay): integrate waku-org/waku-rln-contract #1884

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,8 @@
url = https://github.com/nitely/nim-unicodedb.git
ignore = untracked
branch = master
[submodule "vendor/waku-rln-contract"]
path = vendor/waku-rln-contract
url = https://github.com/waku-org/waku-rln-contract
ignore = untracked
branch = main
3 changes: 2 additions & 1 deletion tests/all_tests_v2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,5 @@ when defined(rln):
./v2/waku_rln_relay/test_waku_rln_relay,
./v2/waku_rln_relay/test_wakunode_rln_relay,
./v2/waku_rln_relay/test_rln_group_manager_onchain,
./v2/waku_rln_relay/test_rln_group_manager_static
./v2/waku_rln_relay/test_rln_group_manager_static,
./v2/waku_rln_relay/test_rln_contract_interface
30 changes: 30 additions & 0 deletions tests/v2/waku_rln_relay/test_rln_contract_interface.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{.used.}

when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}

import
testutils/unittests,
stew/results
import
../../../waku/v2/waku_rln_relay/contract_interface

suite "Waku Rln Contract Interface":
test "Should fetch the address of a deployed contract":
let addressRes = getContractAddressForChain(Chains.Sepolia, Contracts.PoseidonHasher)
assert addressRes.isOk(), addressRes.error()

let address = addressRes.get()
check:
address != ""

test "Should fetch the bytecode of a deployed contract":
let bytecodeRes = getContractBytecodeForChain(Chains.Sepolia, Contracts.PoseidonHasher)
assert bytecodeRes.isOk(), bytecodeRes.error()

let bytecode = bytecodeRes.get()
check:
bytecode != ""

34 changes: 20 additions & 14 deletions tests/v2/waku_rln_relay/test_rln_group_manager_onchain.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import
import
../../../waku/v2/waku_rln_relay/protocol_types,
../../../waku/v2/waku_rln_relay/constants,
../../../waku/v2/waku_rln_relay/contract,
../../../waku/v2/waku_rln_relay/contract_interface,
../../../waku/v2/waku_rln_relay/rln,
../../../waku/v2/waku_rln_relay/conversion_utils,
../../../waku/v2/waku_rln_relay/group_manager/on_chain/group_manager,
Expand Down Expand Up @@ -53,32 +53,39 @@ proc uploadRLNContract*(ethClientAddress: string): Future[Address] {.async.} =
let balance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
debug "Initial account balance: ", balance

# we will get the deployed bytecode from sepolia
let poseidonHasherCodeRes = getContractBytecodeForChain(Chains.Sepolia,
Contracts.PoseidonHasher)
if poseidonHasherCodeRes.isErr():
raise newException(ValueError, "Failed to get PoseidonHasher bytecode: " & $poseidonHasherCodeRes.error())
let poseidonHasherCode = poseidonHasherCodeRes.get()

# deploy the poseidon hash contract and gets its address
let
hasherReceipt = await web3.deployContract(PoseidonHasherCode)
hasherAddress = hasherReceipt.contractAddress.get
hasherReceipt = await web3.deployContract(poseidonHasherCode)
hasherAddress = hasherReceipt.contractAddress.get()
debug "hasher address: ", hasherAddress


# encode membership contract inputs to 32 bytes zero-padded
let
membershipFeeEncoded = encode(MembershipFee).data
depthEncoded = encode(MerkleTreeDepth.u256).data
hasherAddressEncoded = encode(hasherAddress).data
# this is the contract constructor input
contractInput = membershipFeeEncoded & depthEncoded & hasherAddressEncoded

contractInput = hasherAddressEncoded
wakuRlnCodeRes = getContractBytecodeForChain(Chains.Sepolia, Contracts.WakuRln)

if wakuRlnCodeRes.isErr():
raise newException(ValueError, "Failed to get WakuRln bytecode: " & $wakuRlnCodeRes.error())
let wakuRlnCode = wakuRlnCodeRes.get()

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
let receipt = await web3.deployContract(MembershipContractCode,
contractInput = contractInput)
let contractAddress = receipt.contractAddress.get
debug "Address of the deployed membership contract: ", contractAddress
let receipt = await web3.deployContract(wakuRlnCode,
contractInput = contractInput)
let contractAddress = receipt.contractAddress.get()
warn "Address of the deployed membership contract: ", contractAddress

let newBalance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
debug "Account balance after the contract deployment: ", newBalance
Expand Down Expand Up @@ -160,7 +167,6 @@ proc setup(signer = true): Future[OnchainGroupManager] {.async.} =
let rlnInstanceRes = createRlnInstance(tree_path = genTempPath("rln_tree", "group_manager_onchain"))
require:
rlnInstanceRes.isOk()

let rlnInstance = rlnInstanceRes.get()

let contractAddress = await uploadRLNContract(EthClient)
Expand Down
1 change: 1 addition & 0 deletions vendor/waku-rln-contract
Submodule waku-rln-contract added at 7ebffc
4 changes: 2 additions & 2 deletions waku/v2/waku_rln_relay.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import
./waku_rln_relay/group_manager,
./waku_rln_relay/conversion_utils,
./waku_rln_relay/rln_relay,
./waku_rln_relay/contract
./waku_rln_relay/contract_interface

export
group_manager,
conversion_utils,
rln_relay,
contract
contract_interface
107 changes: 0 additions & 107 deletions waku/v2/waku_rln_relay/contract.nim

This file was deleted.

59 changes: 59 additions & 0 deletions waku/v2/waku_rln_relay/contract_interface.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}

import
os,
std/json

import ./protocol_types

export
json,
protocol_types

# Update these when we have more contracts, chains
type
Contracts* = enum
PoseidonHasher = "PoseidonHasher", WakuRln = "WakuRln"
Chains* = enum
Sepolia = "sepolia"
ArtifactKeys = enum
Address = "address", Bytecode = "bytecode"

proc getContractForChain(chain: Chains, contract: Contracts): RlnRelayResult[JsonNode] =
let path = "vendor/waku-rln-contract/deployments/" & $chain & "/" & $contract & ".json"
# check if file exists
if not fileExists(path):
return err("Contract artifact not found: " & path)
# read file
var data: string
try:
data = path.readFile()
except IOError:
return err("Could not read contract artifact: " & getCurrentExceptionMsg())
# parse json
var jsonNode: JsonNode
try:
jsonNode = parseJson(data)
except IOError, ValueError, Exception:
return err("Could not parse contract artifact: " & getCurrentExceptionMsg())
return ok(jsonNode)

proc getKeyInContractArtifact(chain: Chains, contract: Contracts, key: ArtifactKeys): RlnRelayResult[string] =
let jsonNodeRes = getContractForChain(chain, contract)
if jsonNodeRes.isErr():
return err(jsonNodeRes.error())
var retVal: string
try:
retVal = jsonNodeRes.get()[$key].getStr()
except KeyError:
return err("Could not find key in contract artifact: " & getCurrentExceptionMsg())
return ok(retVal)

proc getContractAddressForChain*(chain: Chains, contract: Contracts): RlnRelayResult[string] =
return getKeyInContractArtifact(chain, contract, ArtifactKeys.Address)

proc getContractBytecodeForChain*(chain: Chains, contract: Contracts): RlnRelayResult[string] =
return getKeyInContractArtifact(chain, contract, ArtifactKeys.Bytecode)
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ logScope:

# membership contract interface
contract(RlnContract):
proc register(idCommitment: Uint256) {.payable.} # external payable
proc register(idCommitment: Uint256) # external payable
proc MemberRegistered(idCommitment: Uint256, index: Uint256) {.event.}
proc MEMBERSHIP_DEPOSIT(): Uint256
# TODO the following are to be supported
Expand Down Expand Up @@ -117,8 +117,7 @@ method register*(g: OnchainGroupManager, identityCredentials: IdentityCredential

var txHash: TxHash
try: # send the registration transaction and check if any error occurs
txHash = await rlnContract.register(idCommitment).send(value = membershipFee,
gasPrice = gasPrice,
txHash = await rlnContract.register(idCommitment).send(gasPrice = gasPrice,
gas = 100000'u64)
except ValueError as e:
error "error while registering the member", msg = e.msg
Expand All @@ -130,6 +129,7 @@ method register*(g: OnchainGroupManager, identityCredentials: IdentityCredential
g.registrationTxHash = some(txHash)
# the receipt topic holds the hash of signature of the raised events
# TODO: make this robust. search within the event list for the event
debug "tx receipt", receipt=tsReceipt
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":
Expand Down