chore(rlnv2): contract interface changes (#2770)

* chore(rlnv2): contract interface changes

* fix: tests

* fix: remove stuint[32]
This commit is contained in:
Aaryamann Challani 2024-06-06 00:58:21 +05:30 committed by GitHub
parent ed23c04090
commit 2db7f2a385
7 changed files with 129 additions and 158 deletions

View File

@ -32,10 +32,10 @@ proc generateCredentials(rlnInstance: ptr RLN): IdentityCredential =
proc getRateCommitment(
idCredential: IdentityCredential, userMessageLimit: UserMessageLimit
): RateCommitment =
): RlnRelayResult[RawRateCommitment] =
return RateCommitment(
idCommitment: idCredential.idCommitment, userMessageLimit: userMessageLimit
)
).toLeaf()
proc generateCredentials(rlnInstance: ptr RLN, n: int): seq[IdentityCredential] =
var credentials: seq[IdentityCredential]
@ -60,24 +60,38 @@ proc uploadRLNContract*(ethClientAddress: string): Future[Address] {.async.} =
let balance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
debug "Initial account balance: ", balance
# deploy registry contract with its constructor inputs
let receipt = await web3.deployContract(RegistryContractCode)
let contractAddress = receipt.contractAddress.get()
# deploy poseidon hasher bytecode
let poseidonT3Receipt = await web3.deployContract(PoseidonT3)
let poseidonT3Address = poseidonT3Receipt.contractAddress.get()
let poseidonAddressStripped = strip0xPrefix($poseidonT3Address)
debug "Address of the deployed registry contract: ", contractAddress
# deploy lazy imt bytecode
let lazyImtReceipt = await web3.deployContract(LazyIMT.replace("__$PoseidonT3$__", poseidonAddressStripped))
let lazyImtAddress = lazyImtReceipt.contractAddress.get()
let lazyImtAddressStripped = strip0xPrefix($lazyImtAddress)
let registryContract = web3.contractSender(WakuRlnRegistry, contractAddress)
let initReceipt = await registryContract.initialize().send()
let newStorageReceipt = await registryContract.newStorage(20.u256).send()
# deploy waku rlnv2 contract
let wakuRlnContractReceipt = await web3.deployContract(WakuRlnV2Contract.replace("__$PoseidonT3$__", poseidonAddressStripped).replace("__$LazyIMT$__", lazyImtAddressStripped))
let wakuRlnContractAddress = wakuRlnContractReceipt.contractAddress.get()
let wakuRlnAddressStripped = strip0xPrefix($wakuRlnContractAddress)
debug "Address of the deployed rlnv2 contract: ", wakuRlnContractAddress
# need to send concat: impl & init_bytes
let contractInput = encode(wakuRlnContractAddress).data & Erc1967ProxyContractInput
debug "contractInput", contractInput
let proxyReceipt = await web3.deployContract(Erc1967Proxy, contractInput = contractInput)
debug "proxy receipt", proxyReceipt
let proxyAddress = proxyReceipt.contractAddress.get()
debug "Receipt of the newStorage transaction: ", newStorageReceipt
let newBalance = await web3.provider.eth_getBalance(web3.defaultAccount, "latest")
debug "Account balance after the contract deployment: ", newBalance
await web3.close()
debug "disconnected from ", ethClientAddress
return contractAddress
return proxyAddress
proc createEthAccount(): Future[(keys.PrivateKey, Address)] {.async.} =
let web3 = await newWeb3(EthClient)
@ -161,7 +175,7 @@ proc stopAnvil(runAnvil: Process) {.used.} =
proc setup(): Future[OnchainGroupManager] {.async.} =
let rlnInstanceRes =
createRlnInstance(tree_path = genTempPath("rln_tree", "group_manager_onchain"))
require:
check:
rlnInstanceRes.isOk()
let rlnInstance = rlnInstanceRes.get()
@ -197,8 +211,7 @@ suite "Onchain group manager":
check:
manager.ethRpc.isSome()
manager.rlnContract.isSome()
manager.membershipFee.isSome()
manager.wakuRlnContract.isSome()
manager.initialized
manager.rlnContractDeployedBlockNumber > 0
@ -261,6 +274,8 @@ suite "Onchain group manager":
asyncTest "startGroupSync: should sync to the state of the group":
let manager = await setup()
let credentials = generateCredentials(manager.rlnInstance)
let rateCommitment = getRateCommitment(credentials, UserMessageLimit(1)).valueOr:
raiseAssert $error
(await manager.init()).isOkOr:
raiseAssert $error
@ -271,15 +286,10 @@ suite "Onchain group manager":
proc generateCallback(fut: Future[void]): OnRegisterCallback =
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
require:
check:
registrations.len == 1
registrations[0].index == 0
require:
registrations[0].rateCommitment ==
getRateCommitment(credentials, UserMessageLimit(1))
require:
registrations[0].index == 0
registrations[0].rateCommitment == rateCommitment
fut.complete()
return callback
@ -323,9 +333,9 @@ suite "Onchain group manager":
): OnRegisterCallback =
var futureIndex = 0
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
let rateCommitment = getRateCommitment(credentials[futureIndex], UserMessageLimit(1))
if registrations.len == 1 and
registrations[0].rateCommitment ==
getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) and
registrations[0].rateCommitment == rateCommitment.get() and
registrations[0].index == MembershipIndex(futureIndex):
futs[futureIndex].complete()
futureIndex += 1
@ -400,18 +410,16 @@ suite "Onchain group manager":
asyncTest "register: callback is called":
let manager = await setup()
let idCommitment = generateCredentials(manager.rlnInstance).idCommitment
let idCredentials = generateCredentials(manager.rlnInstance)
let idCommitment = idCredentials.idCommitment
let fut = newFuture[void]()
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
require:
let rateCommitment = getRateCommitment(idCredentials, UserMessageLimit(1))
check:
registrations.len == 1
require:
registrations[0].rateCommitment ==
RateCommitment(
idCommitment: idCommitment, userMessageLimit: UserMessageLimit(1)
)
registrations[0].rateCommitment == rateCommitment.get()
registrations[0].index == 0
fut.complete()
@ -429,7 +437,7 @@ suite "Onchain group manager":
except Exception, CatchableError:
assert false, "exception raised: " & getCurrentExceptionMsg()
check await fut.withTimeout(5.seconds)
await fut
await manager.stop()
@ -457,7 +465,7 @@ suite "Onchain group manager":
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
if registrations.len == 1 and
registrations[0].rateCommitment ==
getRateCommitment(credentials, UserMessageLimit(1)) and
getRateCommitment(credentials, UserMessageLimit(1)).get() and
registrations[0].index == 0:
manager.idCredentials = some(credentials)
fut.complete()
@ -485,7 +493,7 @@ suite "Onchain group manager":
data = messageBytes, epoch = epoch, messageId = MessageId(1)
)
require:
check:
validProofRes.isOk()
let validProof = validProofRes.get()
@ -517,12 +525,10 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let validProofRes = manager.generateProof(
let validProof = manager.generateProof(
data = messageBytes, epoch = epoch, messageId = MessageId(0)
)
require:
validProofRes.isOk()
let validProof = validProofRes.get()
).valueOr:
raiseAssert $error
# validate the root (should be false)
let validated = manager.validateRoot(validProof.merkleRoot)
@ -542,7 +548,7 @@ suite "Onchain group manager":
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
if registrations.len == 1 and
registrations[0].rateCommitment ==
getRateCommitment(credentials, UserMessageLimit(1)) and
getRateCommitment(credentials, UserMessageLimit(1)).get() and
registrations[0].index == 0:
manager.idCredentials = some(credentials)
fut.complete()
@ -565,20 +571,16 @@ suite "Onchain group manager":
debug "epoch in bytes", epochHex = epoch.inHex()
# generate proof
let validProofRes = manager.generateProof(
let validProof = manager.generateProof(
data = messageBytes, epoch = epoch, messageId = MessageId(0)
)
require:
validProofRes.isOk()
let validProof = validProofRes.get()
).valueOr:
raiseAssert $error
# verify the proof (should be true)
let verifiedRes = manager.verifyProof(messageBytes, validProof)
require:
verifiedRes.isOk()
let verified = manager.verifyProof(messageBytes, validProof).valueOr:
raiseAssert $error
check:
verifiedRes.get()
check: verified
await manager.stop()
asyncTest "verifyProof: should reject invalid proof":
@ -591,7 +593,8 @@ suite "Onchain group manager":
let idCredential = generateCredentials(manager.rlnInstance)
try:
await manager.register(getRateCommitment(idCredential, UserMessageLimit(1)))
await manager.register(RateCommitment(idCommitment: idCredential.idCommitment,
userMessageLimit: UserMessageLimit(1)))
except Exception, CatchableError:
assert false,
"exception raised when calling startGroupSync: " & getCurrentExceptionMsg()
@ -614,7 +617,7 @@ suite "Onchain group manager":
data = messageBytes, epoch = epoch, messageId = MessageId(0)
)
require:
check:
invalidProofRes.isOk()
let invalidProof = invalidProofRes.get()
@ -645,7 +648,7 @@ suite "Onchain group manager":
proc callback(registrations: seq[Membership]): Future[void] {.async.} =
if registrations.len == 1 and
registrations[0].rateCommitment ==
getRateCommitment(credentials[futureIndex], UserMessageLimit(1)) and
getRateCommitment(credentials[futureIndex], UserMessageLimit(1)).get() and
registrations[0].index == MembershipIndex(futureIndex):
futs[futureIndex].complete()
futureIndex += 1
@ -665,7 +668,7 @@ suite "Onchain group manager":
await allFutures(futures)
# At this point, we should have a full root queue, 5 roots, and partial buffer of 1 root
require:
check:
manager.validRoots.len() == credentialCount - 1
manager.validRootBuffer.len() == 1

View File

@ -140,7 +140,7 @@ suite "Static group manager":
registrations[0].rateCommitment ==
RateCommitment(
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
)
).toLeaf().get()
callbackCalled = true
fut.complete()
@ -204,7 +204,7 @@ suite "Static group manager":
withdrawals[0].rateCommitment ==
RateCommitment(
idCommitment: idCommitment, userMessageLimit: DefaultUserMessageLimit
)
).toLeaf().get()
callbackCalled = true
fut.complete()

File diff suppressed because one or more lines are too long

View File

@ -15,7 +15,7 @@ export options, chronos, results, protocol_types, protocol_metrics, deques
type Membership* = object
index*: MembershipIndex
rateCommitment*: RateCommitment
rateCommitment*: RawRateCommitment
type OnRegisterCallback* = proc(registrations: seq[Membership]): Future[void] {.gcsafe.}
type OnWithdrawCallback* = proc(withdrawals: seq[Membership]): Future[void] {.gcsafe.}
@ -73,7 +73,7 @@ method register*(
# The user may or may not have the identity secret to these commitments
# It should be used when detecting a batch of new members in the group, and syncing the group state
method registerBatch*(
g: GroupManager, rateCommitments: seq[RateCommitment]
g: GroupManager, rateCommitments: seq[RawRateCommitment]
): Future[void] {.base, async: (raises: [Exception]).} =
raise newException(
CatchableError, "registerBatch proc for " & $g.type & " is not implemented yet"

View File

@ -31,50 +31,34 @@ logScope:
topics = "waku rln_relay onchain_group_manager"
# using the when predicate does not work within the contract macro, hence need to dupe
contract(WakuRlnRegistry):
# this describes the storage slot to use
proc usingStorageIndex(): Uint16 {.pure.}
# this map contains the address of a given storage slot
proc storages(index: Uint16): Address {.pure.}
# this serves as an entrypoint into the rln storage contract
contract(WakuRlnContract):
# this serves as an entrypoint into the rln membership set
proc register(
storageIndex: Uint16, idCommitment: Uint256, userMessageLimit: Uint256
idCommitment: UInt256, userMessageLimit: UInt32
)
# this creates a new storage on the rln registry
proc newStorage(maxMessageLimit: Uint256)
# Initializes the implementation contract (only used in unit tests)
proc initialize()
# membership contract interface
contract(RlnStorage):
proc initialize(maxMessageLimit: UInt256)
# this event is raised when a new member is registered
proc MemberRegistered(
idCommitment: Uint256, userMessageLimit: Uint256, index: Uint256
rateCommitment: UInt256, index: Uint32
) {.event.}
# this constant contains the membership deposit of the contract
proc MEMBERSHIP_DEPOSIT(): Uint256 {.pure.}
# this map denotes existence of a given user
proc memberExists(idCommitment: Uint256): Uint256 {.view.}
# this function denotes existence of a given user
proc memberExists(idCommitment: Uint256): UInt256 {.view.}
# this constant describes the next index of a new member
proc idCommitmentIndex(): Uint256 {.view.}
proc commitmentIndex(): UInt256 {.view.}
# this constant describes the block number this contract was deployed on
proc deployedBlockNumber(): Uint256 {.view.}
proc deployedBlockNumber(): UInt256 {.view.}
type
RegistryContractWithSender = Sender[WakuRlnRegistry]
RlnContractWithSender = Sender[RlnStorage]
WakuRlnContractWithSender = Sender[WakuRlnContract]
OnchainGroupManager* = ref object of GroupManager
ethClientUrl*: string
ethPrivateKey*: Option[string]
ethContractAddress*: string
ethRpc*: Option[Web3]
rlnContract*: Option[RlnContractWithSender]
rlnContractDeployedBlockNumber*: BlockNumber
registryContract*: Option[RegistryContractWithSender]
usingStorageIndex: Option[Uint16]
membershipFee*: Option[Uint256]
wakuRlnContract*: Option[WakuRlnContractWithSender]
latestProcessedBlock*: BlockNumber
registrationTxHash*: Option[TxHash]
chainId*: Option[Quantity]
@ -136,20 +120,14 @@ proc setMetadata*(
method atomicBatch*(
g: OnchainGroupManager,
start: MembershipIndex,
rateCommitments = newSeq[RateCommitment](),
rateCommitments = newSeq[RawRateCommitment](),
toRemoveIndices = newSeq[MembershipIndex](),
): Future[void] {.async: (raises: [Exception]), base.} =
initializedGuard(g)
# convert the rateCommitment struct to a leaf value
let leaves = rateCommitments.toLeaves().valueOr:
raise newException(
ValueError, "failed to convert rateCommitments to leaves: " & $error
)
waku_rln_membership_insertion_duration_seconds.nanosecondTime:
let operationSuccess =
g.rlnInstance.atomicWrite(some(start), leaves, toRemoveIndices)
g.rlnInstance.atomicWrite(some(start), rateCommitments, toRemoveIndices)
if not operationSuccess:
raise newException(CatchableError, "atomic batch operation failed")
# TODO: when slashing is enabled, we need to track slashed members
@ -159,7 +137,7 @@ method atomicBatch*(
var membersSeq = newSeq[Membership]()
for i in 0 ..< rateCommitments.len:
var index = start + MembershipIndex(i)
trace "registering member", rateCommitment = rateCommitments[i], index = index
debug "registering member to callback", rateCommitment = rateCommitments[i], index = index
let member = Membership(rateCommitment: rateCommitments[i], index: index)
membersSeq.add(member)
await g.registerCb.get()(membersSeq)
@ -171,10 +149,15 @@ method register*(
): Future[void] {.async: (raises: [Exception]).} =
initializedGuard(g)
await g.registerBatch(@[rateCommitment])
try:
let leaf = rateCommitment.toLeaf().get()
await g.registerBatch(@[leaf])
except CatchableError:
raise newException(ValueError, getCurrentExceptionMsg())
method registerBatch*(
g: OnchainGroupManager, rateCommitments: seq[RateCommitment]
g: OnchainGroupManager, rateCommitments: seq[RawRateCommitment]
): Future[void] {.async: (raises: [Exception]).} =
initializedGuard(g)
@ -189,23 +172,20 @@ method register*(
initializedGuard(g)
let ethRpc = g.ethRpc.get()
let registryContract = g.registryContract.get()
let membershipFee = g.membershipFee.get()
let wakuRlnContract = g.wakuRlnContract.get()
var gasPrice: int
g.retryWrapper(gasPrice, "Failed to get gas price"):
int(await ethRpc.provider.eth_gasPrice()) * 2
let idCommitment = identityCredential.idCommitment.toUInt256()
let storageIndex = g.usingStorageIndex.get()
debug "registering the member",
idCommitment = idCommitment,
storageIndex = storageIndex,
userMessageLimit = userMessageLimit
var txHash: TxHash
g.retryWrapper(txHash, "Failed to register the member"):
await registryContract
.register(storageIndex, idCommitment, u256(userMessageLimit))
await wakuRlnContract
.register(idCommitment, userMessageLimit.stuint(32))
.send(gasPrice = gasPrice)
# wait for the transaction to be mined
@ -216,23 +196,24 @@ method register*(
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 "ts receipt", tsReceipt
let firstTopic = tsReceipt.logs[0].topics[0]
# the hash of the signature of MemberRegistered(uint256,uint256,uint256) event is equal to the following hex value
# the hash of the signature of MemberRegistered(uint256,uint32) event is equal to the following hex value
if firstTopic !=
cast[FixedBytes[32]](keccak256.digest(
"MemberRegistered(uint256,uint256,uint256)"
"MemberRegistered(uint256,uint32)"
).data):
raise newException(ValueError, "unexpected event signature")
# 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 || userMessageLimit encoded as 256 bits
# data = rateCommitment encoded as 256 bits || index encoded as 32 bits
let arguments = tsReceipt.logs[0].data
debug "tx log data", arguments = arguments
let
argumentsBytes = arguments
# In TX log data, uints are encoded in big endian
membershipIndex = UInt256.fromBytesBE(argumentsBytes[64 ..^ 1])
membershipIndex = UInt256.fromBytesBE(arguments[32 ..^ 1])
debug "parsed membershipIndex", membershipIndex
g.userMessageLimit = some(userMessageLimit)
g.membershipIndex = some(membershipIndex.toMembershipIndex())
@ -257,9 +238,8 @@ proc parseEvent(
): GroupManagerResult[Membership] =
## parses the `data` parameter of the `MemberRegistered` event `log`
## returns an error if it cannot parse the `data` parameter
var idComm: UInt256
var rateCommitment: UInt256
var index: UInt256
var userMessageLimit: UInt256
var data: string
# Remove the 0x prefix
try:
@ -271,18 +251,13 @@ proc parseEvent(
)
var offset = 0
try:
# Parse the idComm
offset += decode(data, offset, idComm)
# Parse the userMessageLimit
offset += decode(data, offset, userMessageLimit)
# Parse the rateCommitment
offset += decode(data, offset, rateCommitment)
# Parse the index
offset += decode(data, offset, index)
return ok(
Membership(
rateCommitment: RateCommitment(
idCommitment: idComm.toIDCommitment(),
userMessageLimit: userMessageLimit.toUserMessageLimit(),
),
rateCommitment: rateCommitment.toRateCommitment(),
index: index.toMembershipIndex(),
)
)
@ -324,11 +299,11 @@ proc getRawEvents(
initializedGuard(g)
let ethRpc = g.ethRpc.get()
let rlnContract = g.rlnContract.get()
let wakuRlnContract = g.wakuRlnContract.get()
var events: JsonNode
g.retryWrapper(events, "Failed to get the events"):
await rlnContract.getJsonLogs(
await wakuRlnContract.getJsonLogs(
MemberRegistered,
fromBlock = some(fromBlock.blockId()),
toBlock = some(toBlock.blockId()),
@ -376,7 +351,7 @@ proc handleEvents(
toRemoveIndices = removalIndices,
)
g.latestIndex = startIndex + MembershipIndex(rateCommitments.len)
trace "new members added to the Merkle tree", commitments = rateCommitments
trace "new members added to the Merkle tree", commitments = rateCommitments.mapIt(it.inHex)
except CatchableError:
error "failed to insert members into the tree", error = getCurrentExceptionMsg()
@ -579,23 +554,11 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.}
ethRpc.defaultAccount =
ethRpc.privateKey.get().toPublicKey().toCanonicalAddress().Address
let registryAddress = web3.fromHex(web3.Address, g.ethContractAddress)
let registryContract = ethRpc.contractSender(WakuRlnRegistry, registryAddress)
# get the current storage index
var usingStorageIndex: Uint16
g.retryWrapper(usingStorageIndex, "Failed to get the storage index"):
await registryContract.usingStorageIndex().call()
g.usingStorageIndex = some(usingStorageIndex)
var rlnContractAddress: Address
g.retryWrapper(rlnContractAddress, "Failed to get the rln contract address"):
await registryContract.storages(usingStorageIndex).call()
let rlnContract = ethRpc.contractSender(RlnStorage, rlnContractAddress)
let contractAddress = web3.fromHex(web3.Address, g.ethContractAddress)
let wakuRlnContract = ethRpc.contractSender(WakuRlnContract, contractAddress)
g.ethRpc = some(ethRpc)
g.rlnContract = some(rlnContract)
g.registryContract = some(registryContract)
g.wakuRlnContract = some(wakuRlnContract)
if g.keystorePath.isSome() and g.keystorePassword.isSome():
if not fileExists(g.keystorePath.get()):
@ -621,7 +584,7 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.}
g.userMessageLimit = some(keystoreCred.userMessageLimit)
# now we check on the contract if the commitment actually has a membership
try:
let membershipExists = await rlnContract
let membershipExists = await wakuRlnContract
.memberExists(keystoreCred.identityCredential.idCommitment.toUInt256())
.call()
if membershipExists == 0:
@ -644,16 +607,10 @@ method init*(g: OnchainGroupManager): Future[GroupManagerResult[void]] {.async.}
g.latestProcessedBlock = metadata.lastProcessedBlock
g.validRoots = metadata.validRoots.toDeque()
# check if the contract exists by calling a static function
var membershipFee: Uint256
g.retryWrapper(membershipFee, "Failed to get the membership deposit"):
await rlnContract.MEMBERSHIP_DEPOSIT().call()
g.membershipFee = some(membershipFee)
var deployedBlockNumber: Uint256
g.retryWrapper(deployedBlockNumber, "Failed to get the deployed block number"):
await rlnContract.deployedBlockNumber().call()
debug "using rln storage", deployedBlockNumber, rlnContractAddress
await wakuRlnContract.deployedBlockNumber().call()
debug "using rln contract", deployedBlockNumber, rlnContractAddress = contractAddress
g.rlnContractDeployedBlockNumber = cast[BlockNumber](deployedBlockNumber)
g.latestProcessedBlock = max(g.latestProcessedBlock, g.rlnContractDeployedBlockNumber)

View File

@ -66,20 +66,17 @@ method register*(
): Future[void] {.async: (raises: [Exception]).} =
initializedGuard(g)
await g.registerBatch(@[rateCommitment])
let leaf = rateCommitment.toLeaf().get()
await g.registerBatch(@[leaf])
method registerBatch*(
g: StaticGroupManager, rateCommitments: seq[RateCommitment]
g: StaticGroupManager, rateCommitments: seq[RawRateCommitment]
): Future[void] {.async: (raises: [Exception]).} =
initializedGuard(g)
let leavesRes = rateCommitments.toLeaves()
if not leavesRes.isOk():
raise newException(ValueError, "Failed to convert rate commitments to leaves")
let leaves = cast[seq[seq[byte]]](leavesRes.get())
let membersInserted = g.rlnInstance.insertMembers(g.latestIndex + 1, leaves)
let membersInserted = g.rlnInstance.insertMembers(g.latestIndex + 1, rateCommitments)
if not membersInserted:
raise newException(ValueError, "Failed to insert members into the merkle tree")
@ -112,7 +109,8 @@ method withdraw*(
let index = MembershipIndex(i)
let rateCommitment = RateCommitment(
idCommitment: idCommitment, userMessageLimit: g.userMessageLimit.get()
)
).toLeaf().valueOr:
raise newException(ValueError, "Failed to parse rateCommitment")
let memberRemoved = g.rlnInstance.removeMember(index)
if not memberRemoved:
raise newException(ValueError, "Failed to remove member from the merkle tree")

View File

@ -3,7 +3,7 @@ when (NimMajor, NimMinor) < (1, 4):
else:
{.push raises: [].}
import std/[options, tables, deques], stew/arrayops, chronos, web3, eth/keys
import std/[options, tables, deques], stew/arrayops, stint, chronos, web3, eth/keys
import ../waku_core, ../waku_keystore, ../common/protobuf
export waku_keystore, waku_core
@ -16,7 +16,7 @@ type RLNResult* = RlnRelayResult[ptr RLN]
type
MerkleNode* = array[32, byte]
# Each node of the Merkle tee is a Poseidon hash which is a 32 byte value
# Each node of the Merkle tree is a Poseidon hash which is a 32 byte value
Nullifier* = array[32, byte]
Epoch* = array[32, byte]
RlnIdentifier* = array[32, byte]
@ -26,6 +26,10 @@ type
RateCommitment* = object
idCommitment*: IDCommitment
userMessageLimit*: UserMessageLimit
RawRateCommitment* = seq[byte]
proc toRateCommitment*(rateCommitmentUint: UInt256): RawRateCommitment =
return RawRateCommitment(@(rateCommitmentUint.toBytesLE()))
# Custom data types defined for waku rln relay -------------------------
type RateLimitProof* = object