mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-02-21 22:33:08 +00:00
chore(rlnv2): contract interface changes (#2770)
* chore(rlnv2): contract interface changes * fix: tests * fix: remove stuint[32]
This commit is contained in:
parent
ed23c04090
commit
2db7f2a385
@ -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
|
||||
|
||||
|
||||
@ -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
@ -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"
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user