mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-01-24 00:33:11 +00:00
Update InitializeGuard to not raise exception
This commit is contained in:
parent
b36c3390a9
commit
c4917e4aed
@ -74,10 +74,11 @@ suite "Onchain group manager":
|
||||
raiseAssert "Expected error when keystore file doesn't exist"
|
||||
|
||||
test "trackRootChanges: should guard against uninitialized state":
|
||||
try:
|
||||
discard manager.trackRootChanges()
|
||||
except CatchableError:
|
||||
check getCurrentExceptionMsg().len == 38
|
||||
let initializedResult = waitFor manager.trackRootChanges()
|
||||
|
||||
check:
|
||||
initializedResult.isErr()
|
||||
initializedResult.error == "OnchainGroupManager is not initialized"
|
||||
|
||||
test "trackRootChanges: should sync to the state of the group":
|
||||
let credentials = generateCredentials()
|
||||
@ -87,8 +88,7 @@ suite "Onchain group manager":
|
||||
let merkleRootBefore = waitFor manager.fetchMerkleRoot()
|
||||
|
||||
(waitFor manager.register(credentials, UserMessageLimit(20))).isOkOr:
|
||||
assert false,
|
||||
"error returned when calling register: " & error
|
||||
assert false, "error returned when calling register: " & error
|
||||
|
||||
discard waitFor withTimeout(trackRootChanges(manager), 15.seconds)
|
||||
|
||||
@ -132,7 +132,7 @@ suite "Onchain group manager":
|
||||
|
||||
check:
|
||||
res.isErr()
|
||||
res.error == "Not initialized: OnchainGroupManager is not initialized"
|
||||
res.error == "OnchainGroupManager is not initialized"
|
||||
|
||||
test "register: should register successfully":
|
||||
# TODO :- similar to ```trackRootChanges: should fetch history correctly```
|
||||
@ -143,8 +143,7 @@ suite "Onchain group manager":
|
||||
let merkleRootBefore = waitFor manager.fetchMerkleRoot()
|
||||
|
||||
(waitFor manager.register(idCredentials, UserMessageLimit(20))).isOkOr:
|
||||
assert false,
|
||||
"error returned when calling register: " & error
|
||||
assert false, "error returned when calling register: " & error
|
||||
|
||||
let merkleRootAfter = waitFor manager.fetchMerkleRoot()
|
||||
|
||||
@ -171,13 +170,14 @@ suite "Onchain group manager":
|
||||
|
||||
manager.onRegister(callback)
|
||||
|
||||
(waitFor manager.register(
|
||||
RateCommitment(
|
||||
idCommitment: idCommitment, userMessageLimit: UserMessageLimit(20)
|
||||
(
|
||||
waitFor manager.register(
|
||||
RateCommitment(
|
||||
idCommitment: idCommitment, userMessageLimit: UserMessageLimit(20)
|
||||
)
|
||||
)
|
||||
)).isOkOr:
|
||||
assert false,
|
||||
"error returned when calling register: " & error
|
||||
).isOkOr:
|
||||
assert false, "error returned when calling register: " & error
|
||||
|
||||
waitFor fut
|
||||
|
||||
@ -188,7 +188,7 @@ suite "Onchain group manager":
|
||||
|
||||
check:
|
||||
res.isErr()
|
||||
res.error == "Not initialized: OnchainGroupManager is not initialized"
|
||||
res.error == "OnchainGroupManager is not initialized"
|
||||
|
||||
test "validateRoot: should validate good root":
|
||||
let idCredentials = generateCredentials()
|
||||
@ -289,10 +289,8 @@ suite "Onchain group manager":
|
||||
|
||||
manager.onRegister(callback)
|
||||
|
||||
|
||||
(waitFor manager.register(credentials, UserMessageLimit(20))).isOkOr:
|
||||
assert false,
|
||||
"error returned when calling register: " & error
|
||||
assert false, "error returned when calling register: " & error
|
||||
waitFor fut
|
||||
|
||||
let rootUpdated = waitFor manager.updateRoots()
|
||||
@ -328,8 +326,7 @@ suite "Onchain group manager":
|
||||
let idCredential = generateCredentials()
|
||||
|
||||
(waitFor manager.register(idCredential, UserMessageLimit(20))).isOkOr:
|
||||
assert false,
|
||||
"error returned when calling register: " & error
|
||||
assert false, "error returned when calling register: " & error
|
||||
|
||||
let messageBytes = "Hello".toBytes()
|
||||
|
||||
@ -401,24 +398,18 @@ suite "Onchain group manager":
|
||||
|
||||
manager.ethRpc = none(Web3)
|
||||
|
||||
var isReady = true
|
||||
try:
|
||||
isReady = waitFor manager.isReady()
|
||||
except Exception, CatchableError:
|
||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||
let isReadyResult = waitFor manager.isReady()
|
||||
|
||||
check:
|
||||
isReady == false
|
||||
isReadyResult.isErr()
|
||||
isReadyResult.error == "Ethereum RPC client is not configured"
|
||||
|
||||
test "isReady should return true if ethRpc is ready":
|
||||
(waitFor manager.init()).isOkOr:
|
||||
raiseAssert $error
|
||||
|
||||
var isReady = false
|
||||
try:
|
||||
isReady = waitFor manager.isReady()
|
||||
except Exception, CatchableError:
|
||||
assert false, "exception raised: " & getCurrentExceptionMsg()
|
||||
let isReadyResult = waitFor manager.isReady()
|
||||
|
||||
check:
|
||||
isReady == true
|
||||
isReadyResult.isOk()
|
||||
isReadyResult.value == true
|
||||
|
||||
@ -50,103 +50,85 @@ type
|
||||
proc fetchMerkleProofElements*(
|
||||
g: OnchainGroupManager
|
||||
): Future[Result[seq[byte], string]] {.async.} =
|
||||
try:
|
||||
let membershipIndex = g.membershipIndex.get()
|
||||
let index40 = stuint(membershipIndex, 40)
|
||||
let membershipIndex = g.membershipIndex.get()
|
||||
let index40 = stuint(membershipIndex, 40)
|
||||
|
||||
let methodSig = "getMerkleProof(uint40)"
|
||||
var paddedParam = newSeq[byte](32)
|
||||
let indexBytes = index40.toBytesBE()
|
||||
for i in 0 ..< min(indexBytes.len, paddedParam.len):
|
||||
paddedParam[paddedParam.len - indexBytes.len + i] = indexBytes[i]
|
||||
let methodSig = "getMerkleProof(uint40)"
|
||||
var paddedParam = newSeq[byte](32)
|
||||
let indexBytes = index40.toBytesBE()
|
||||
for i in 0 ..< min(indexBytes.len, paddedParam.len):
|
||||
paddedParam[paddedParam.len - indexBytes.len + i] = indexBytes[i]
|
||||
|
||||
let response = await sendEthCallWithParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = methodSig,
|
||||
params = paddedParam,
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
let response = await sendEthCallWithParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = methodSig,
|
||||
params = paddedParam,
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
|
||||
return response
|
||||
except CatchableError:
|
||||
error "Failed to fetch Merkle proof elements", error = getCurrentExceptionMsg()
|
||||
return err("Failed to fetch merkle proof elements: " & getCurrentExceptionMsg())
|
||||
return response
|
||||
|
||||
proc fetchMerkleRoot*(
|
||||
g: OnchainGroupManager
|
||||
): Future[Result[UInt256, string]] {.async.} =
|
||||
try:
|
||||
let merkleRoot = await sendEthCallWithoutParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = "root()",
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
return merkleRoot
|
||||
except CatchableError:
|
||||
error "Failed to fetch Merkle root", error = getCurrentExceptionMsg()
|
||||
return err("Failed to fetch merkle root: " & getCurrentExceptionMsg())
|
||||
let merkleRoot = await sendEthCallWithoutParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = "root()",
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
return merkleRoot
|
||||
|
||||
proc fetchNextFreeIndex*(
|
||||
g: OnchainGroupManager
|
||||
): Future[Result[UInt256, string]] {.async.} =
|
||||
try:
|
||||
let nextFreeIndex = await sendEthCallWithoutParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = "nextFreeIndex()",
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
return nextFreeIndex
|
||||
except CatchableError:
|
||||
error "Failed to fetch next free index", error = getCurrentExceptionMsg()
|
||||
return err("Failed to fetch next free index: " & getCurrentExceptionMsg())
|
||||
let nextFreeIndex = await sendEthCallWithoutParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = "nextFreeIndex()",
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
return nextFreeIndex
|
||||
|
||||
proc fetchMembershipStatus*(
|
||||
g: OnchainGroupManager, idCommitment: IDCommitment
|
||||
): Future[Result[bool, string]] {.async.} =
|
||||
try:
|
||||
let params = idCommitment.reversed()
|
||||
let responseBytes = (
|
||||
await sendEthCallWithParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = "isInMembershipSet(uint256)",
|
||||
params = params,
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
).valueOr:
|
||||
return err("Failed to check membership: " & error)
|
||||
|
||||
return ok(responseBytes.len == 32 and responseBytes[^1] == 1'u8)
|
||||
except CatchableError:
|
||||
error "Failed to fetch membership set membership", error = getCurrentExceptionMsg()
|
||||
return err("Failed to fetch membership set membership: " & getCurrentExceptionMsg())
|
||||
|
||||
proc fetchMaxMembershipRateLimit*(
|
||||
g: OnchainGroupManager
|
||||
): Future[Result[UInt256, string]] {.async.} =
|
||||
try:
|
||||
let maxMembershipRateLimit = await sendEthCallWithoutParams(
|
||||
let params = idCommitment.reversed()
|
||||
let responseBytes = (
|
||||
await sendEthCallWithParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = "maxMembershipRateLimit()",
|
||||
functionSignature = "isInMembershipSet(uint256)",
|
||||
params = params,
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
return maxMembershipRateLimit
|
||||
except CatchableError:
|
||||
error "Failed to fetch max membership rate limit", error = getCurrentExceptionMsg()
|
||||
return err("Failed to fetch max membership rate limit: " & getCurrentExceptionMsg())
|
||||
).valueOr:
|
||||
return err("Failed to check membership: " & error)
|
||||
|
||||
template initializedGuard(g: OnchainGroupManager): untyped =
|
||||
return ok(responseBytes.len == 32 and responseBytes[^1] == 1'u8)
|
||||
|
||||
proc fetchMaxMembershipRateLimit*(
|
||||
g: OnchainGroupManager
|
||||
): Future[Result[UInt256, string]] {.async.} =
|
||||
let maxMembershipRateLimit = await sendEthCallWithoutParams(
|
||||
ethRpc = g.ethRpc.get(),
|
||||
functionSignature = "maxMembershipRateLimit()",
|
||||
fromAddress = g.ethRpc.get().defaultAccount,
|
||||
toAddress = fromHex(Address, g.ethContractAddress),
|
||||
chainId = g.chainId,
|
||||
)
|
||||
|
||||
return maxMembershipRateLimit
|
||||
|
||||
proc checkInitialized(g: OnchainGroupManager): Result[void, string] =
|
||||
if not g.initialized:
|
||||
raise newException(CatchableError, "OnchainGroupManager is not initialized")
|
||||
return err("OnchainGroupManager is not initialized")
|
||||
return ok()
|
||||
|
||||
proc updateRoots*(g: OnchainGroupManager): Future[bool] {.async.} =
|
||||
let rootRes = (await g.fetchMerkleRoot()).valueOr:
|
||||
@ -167,42 +149,38 @@ proc updateRoots*(g: OnchainGroupManager): Future[bool] {.async.} =
|
||||
return false
|
||||
|
||||
proc trackRootChanges*(g: OnchainGroupManager): Future[Result[void, string]] {.async.} =
|
||||
try:
|
||||
initializedGuard(g)
|
||||
const rpcDelay = 5.seconds
|
||||
checkInitialized(g).isOkOr:
|
||||
return err(error)
|
||||
|
||||
while true:
|
||||
await sleepAsync(rpcDelay)
|
||||
let rootUpdated = await g.updateRoots()
|
||||
const rpcDelay = 5.seconds
|
||||
|
||||
if rootUpdated:
|
||||
## The membership set on-chain has changed (some new members have joined or some members have left)
|
||||
if g.membershipIndex.isSome():
|
||||
## A membership index exists only if the node has registered with RLN.
|
||||
## Non-registered nodes cannot have Merkle proof elements.
|
||||
let proofResult = await g.fetchMerkleProofElements()
|
||||
if proofResult.isErr():
|
||||
error "Failed to fetch Merkle proof", error = proofResult.error
|
||||
else:
|
||||
g.merkleProofCache = proofResult.get()
|
||||
while true:
|
||||
await sleepAsync(rpcDelay)
|
||||
let rootUpdated = await g.updateRoots()
|
||||
|
||||
let nextFreeIndex = (await g.fetchNextFreeIndex()).valueOr:
|
||||
error "Failed to fetch next free index", error = error
|
||||
return err("Failed to fetch next free index: " & error)
|
||||
if rootUpdated:
|
||||
## The membership set on-chain has changed (some new members have joined or some members have left)
|
||||
if g.membershipIndex.isSome():
|
||||
## A membership index exists only if the node has registered with RLN.
|
||||
## Non-registered nodes cannot have Merkle proof elements.
|
||||
let proofResult = await g.fetchMerkleProofElements()
|
||||
if proofResult.isErr():
|
||||
error "Failed to fetch Merkle proof", error = proofResult.error
|
||||
else:
|
||||
g.merkleProofCache = proofResult.get()
|
||||
|
||||
let memberCount = cast[int64](nextFreeIndex)
|
||||
waku_rln_number_registered_memberships.set(float64(memberCount))
|
||||
except CatchableError:
|
||||
error "Fatal error in trackRootChanges", error = getCurrentExceptionMsg()
|
||||
return err("Fatal error in trackRootChanges" & getCurrentExceptionMsg())
|
||||
let nextFreeIndex = (await g.fetchNextFreeIndex()).valueOr:
|
||||
error "Failed to fetch next free index", error = error
|
||||
return err("Failed to fetch next free index: " & error)
|
||||
|
||||
let memberCount = cast[int64](nextFreeIndex)
|
||||
waku_rln_number_registered_memberships.set(float64(memberCount))
|
||||
|
||||
method register*(
|
||||
g: OnchainGroupManager, rateCommitment: RateCommitment
|
||||
): Future[Result[void, string]] {.async.} =
|
||||
try:
|
||||
initializedGuard(g)
|
||||
except CatchableError as e:
|
||||
return err("Not initialized: " & e.msg)
|
||||
checkInitialized(g).isOkOr:
|
||||
return err(error)
|
||||
|
||||
try:
|
||||
let leaf = rateCommitment.toLeaf().get()
|
||||
@ -221,10 +199,8 @@ method register*(
|
||||
identityCredential: IdentityCredential,
|
||||
userMessageLimit: UserMessageLimit,
|
||||
): Future[Result[void, string]] {.async.} =
|
||||
try:
|
||||
initializedGuard(g)
|
||||
except CatchableError as e:
|
||||
return err("Not initialized: " & e.msg)
|
||||
checkInitialized(g).isOkOr:
|
||||
return err(error)
|
||||
|
||||
let ethRpc = g.ethRpc.get()
|
||||
let wakuRlnContract = g.wakuRlnContract.get()
|
||||
@ -335,20 +311,15 @@ method register*(
|
||||
method withdraw*(
|
||||
g: OnchainGroupManager, idCommitment: IDCommitment
|
||||
): Future[Result[void, string]] {.async.} =
|
||||
try:
|
||||
initializedGuard(g)
|
||||
except CatchableError as e:
|
||||
return err("Not initialized: " & e.msg)
|
||||
|
||||
checkInitialized(g).isOkOr:
|
||||
return err(error)
|
||||
return ok()
|
||||
|
||||
method withdrawBatch*(
|
||||
g: OnchainGroupManager, idCommitments: seq[IDCommitment]
|
||||
): Future[Result[void, string]] {.async.} =
|
||||
try:
|
||||
initializedGuard(g)
|
||||
except CatchableError as e:
|
||||
return err("Not initialized: " & e.msg)
|
||||
checkInitialized(g).isOkOr:
|
||||
return err(error)
|
||||
|
||||
return ok()
|
||||
|
||||
@ -382,7 +353,7 @@ method generateProof*(
|
||||
epoch: Epoch,
|
||||
messageId: MessageId,
|
||||
rlnIdentifier = DefaultRlnIdentifier,
|
||||
): GroupManagerResult[RateLimitProof] {.gcsafe, raises: [].} =
|
||||
): GroupManagerResult[RateLimitProof] {.gcsafe.} =
|
||||
## Generates an RLN proof using the cached Merkle proof and custom witness
|
||||
# Ensure identity credentials and membership index are set
|
||||
if g.idCredentials.isNone():
|
||||
@ -480,7 +451,7 @@ method generateProof*(
|
||||
|
||||
method verifyProof*(
|
||||
g: OnchainGroupManager, input: seq[byte], proof: RateLimitProof
|
||||
): GroupManagerResult[bool] {.gcsafe, raises: [].} =
|
||||
): GroupManagerResult[bool] {.gcsafe.} =
|
||||
## -- Verifies an RLN rate-limit proof against the set of valid Merkle roots --
|
||||
|
||||
var normalizedProof = proof
|
||||
@ -656,13 +627,14 @@ method stop*(g: OnchainGroupManager): Future[void] {.async, gcsafe.} =
|
||||
|
||||
g.initialized = false
|
||||
|
||||
method isReady*(g: OnchainGroupManager): Future[bool] {.async.} =
|
||||
initializedGuard(g)
|
||||
method isReady*(g: OnchainGroupManager): Future[Result[bool, string]] {.async.} =
|
||||
checkInitialized(g).isOkOr:
|
||||
return err(error)
|
||||
|
||||
if g.ethRpc.isNone():
|
||||
return false
|
||||
return err("Ethereum RPC client is not configured")
|
||||
|
||||
if g.wakuRlnContract.isNone():
|
||||
return false
|
||||
return err("Waku RLN contract is not configured")
|
||||
|
||||
return true
|
||||
return ok(true)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user