mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-01-17 05:13:09 +00:00
feat: upgrade validate Root
This commit is contained in:
parent
ff3f84c34a
commit
cf80eb4bec
@ -21,66 +21,82 @@ type OnchainSyncGroupManager* = ref object of GroupManager
|
|||||||
keystorePath*: Option[string]
|
keystorePath*: Option[string]
|
||||||
keystorePassword*: Option[string]
|
keystorePassword*: Option[string]
|
||||||
registrationHandler*: Option[RegistrationHandler]
|
registrationHandler*: Option[RegistrationHandler]
|
||||||
# Much simpler state tracking
|
validRootBuffer*: Deque[MerkleNode]
|
||||||
contractSynced*: bool
|
|
||||||
|
|
||||||
|
# using the when predicate does not work within the contract macro, hence need to dupe
|
||||||
|
contract(WakuRlnContract):
|
||||||
|
# this serves as an entrypoint into the rln membership set
|
||||||
|
proc register(idCommitment: UInt256, userMessageLimit: EthereumUInt32)
|
||||||
|
# Initializes the implementation contract (only used in unit tests)
|
||||||
|
proc initialize(maxMessageLimit: UInt256)
|
||||||
|
# this event is raised when a new member is registered
|
||||||
|
proc MemberRegistered(rateCommitment: UInt256, index: EthereumUInt32) {.event.}
|
||||||
|
# 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 commitmentIndex(): UInt256 {.view.}
|
||||||
|
# this constant describes the block number this contract was deployed on
|
||||||
|
proc deployedBlockNumber(): UInt256 {.view.}
|
||||||
|
# this constant describes max message limit of rln contract
|
||||||
|
proc MAX_MESSAGE_LIMIT(): UInt256 {.view.}
|
||||||
|
# this function returns the merkleProof for a given index
|
||||||
|
proc merkleProofElements(index: Uint256): seq[Uint256] {.view.}
|
||||||
|
# this function returns the Merkle root
|
||||||
|
proc root(): Uint256 {.view.}
|
||||||
|
|
||||||
|
proc fetchMerkleProof*(g: OnchainSyncGroupManager) {.async.} =
|
||||||
|
let index = stuint(g.membershipIndex.get(), 256)
|
||||||
|
try:
|
||||||
|
let merkleProofInvocation = g.wakuRlnContract.get().merkleProofElements(index)
|
||||||
|
let merkleProof = await merkleProofInvocation.call()
|
||||||
|
# Await the contract call and extract the result
|
||||||
|
return merkleProof
|
||||||
|
except CatchableError:
|
||||||
|
error "Failed to fetch merkle proof: " & getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
proc fetchMerkleRoot*(g: OnchainSyncGroupManager) {.async.} =
|
||||||
|
let merkleRootInvocation = g.wakuRlnContract.get().root()
|
||||||
|
let merkleRoot = await merkleRootInvocation.call()
|
||||||
|
return merkleRoot
|
||||||
|
|
||||||
template initializedGuard(g: OnchainGroupManager): untyped =
|
template initializedGuard(g: OnchainGroupManager): untyped =
|
||||||
if not g.initialized:
|
if not g.initialized:
|
||||||
raise newException(CatchableError, "OnchainGroupManager is not initialized")
|
raise newException(CatchableError, "OnchainGroupManager is not initialized")
|
||||||
|
|
||||||
proc resultifiedInitGuard(g: OnchainGroupManager): GroupManagerResult[void] =
|
|
||||||
try:
|
|
||||||
initializedGuard(g)
|
|
||||||
return ok()
|
|
||||||
except CatchableError:
|
|
||||||
return err("OnchainGroupManager is not initialized")
|
|
||||||
|
|
||||||
template retryWrapper(
|
template retryWrapper(
|
||||||
g: OnchainGroupManager, res: auto, errStr: string, body: untyped
|
g: OnchainSyncGroupManager, res: auto, errStr: string, body: untyped
|
||||||
): auto =
|
): auto =
|
||||||
retryWrapper(res, RetryStrategy.new(), errStr, g.onFatalErrorAction):
|
retryWrapper(res, RetryStrategy.new(), errStr, g.onFatalErrorAction):
|
||||||
body
|
body
|
||||||
|
|
||||||
proc setMetadata*(
|
method validateRoot*(
|
||||||
g: OnchainGroupManager, lastProcessedBlock = none(BlockNumber)
|
g: OnchainSyncGroupManager, root: MerkleNode
|
||||||
): GroupManagerResult[void] =
|
): bool {.base, gcsafe, raises: [].} =
|
||||||
let normalizedBlock =
|
if g.validRootBuffer.find(root) >= 0:
|
||||||
if lastProcessedBlock.isSome():
|
return true
|
||||||
lastProcessedBlock.get()
|
return false
|
||||||
else:
|
|
||||||
g.latestProcessedBlock
|
proc slideRootQueue*(g: OnchainSyncGroupManager): untyped =
|
||||||
try:
|
let rootRes = g.fetchMerkleRoot()
|
||||||
let metadataSetRes = g.rlnInstance.setMetadata(
|
if rootRes.isErr():
|
||||||
RlnMetadata(
|
raise newException(ValueError, "failed to get merkle root")
|
||||||
lastProcessedBlock: normalizedBlock.uint64,
|
let rootAfterUpdate = rootRes.get()
|
||||||
chainId: g.chainId,
|
|
||||||
contractAddress: g.ethContractAddress,
|
let overflowCount = g.validRootBuffer.len - AcceptableRootWindowSize + 1
|
||||||
validRoots: g.validRoots.toSeq(),
|
if overflowCount > 0:
|
||||||
)
|
for i in 0 ..< overflowCount:
|
||||||
)
|
g.validRootBuffer.popFirst()
|
||||||
if metadataSetRes.isErr():
|
|
||||||
return err("failed to persist rln metadata: " & metadataSetRes.error)
|
g.validRootBuffer.addLast(rootAfterUpdate)
|
||||||
except CatchableError:
|
|
||||||
return err("failed to persist rln metadata: " & getCurrentExceptionMsg())
|
|
||||||
return ok()
|
|
||||||
|
|
||||||
method atomicBatch*(
|
method atomicBatch*(
|
||||||
g: OnchainGroupManager,
|
g: OnchainSyncGroupManager,
|
||||||
start: MembershipIndex,
|
start: MembershipIndex,
|
||||||
rateCommitments = newSeq[RawRateCommitment](),
|
rateCommitments = newSeq[RawRateCommitment](),
|
||||||
toRemoveIndices = newSeq[MembershipIndex](),
|
toRemoveIndices = newSeq[MembershipIndex](),
|
||||||
): Future[void] {.async: (raises: [Exception]), base.} =
|
): Future[void] {.async: (raises: [Exception]), base.} =
|
||||||
initializedGuard(g)
|
initializedGuard(g)
|
||||||
|
|
||||||
waku_rln_membership_insertion_duration_seconds.nanosecondTime:
|
|
||||||
let operationSuccess =
|
|
||||||
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
|
|
||||||
waku_rln_number_registered_memberships.set(int64(g.rlnInstance.leavesSet()))
|
|
||||||
|
|
||||||
if g.registerCb.isSome():
|
if g.registerCb.isSome():
|
||||||
var membersSeq = newSeq[Membership]()
|
var membersSeq = newSeq[Membership]()
|
||||||
for i in 0 ..< rateCommitments.len:
|
for i in 0 ..< rateCommitments.len:
|
||||||
@ -91,10 +107,10 @@ method atomicBatch*(
|
|||||||
membersSeq.add(member)
|
membersSeq.add(member)
|
||||||
await g.registerCb.get()(membersSeq)
|
await g.registerCb.get()(membersSeq)
|
||||||
|
|
||||||
g.validRootBuffer = g.slideRootQueue()
|
g.slideRootQueue()
|
||||||
|
|
||||||
method register*(
|
method register*(
|
||||||
g: OnchainGroupManager, rateCommitment: RateCommitment
|
g: OnchainSyncGroupManager, rateCommitment: RateCommitment
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
initializedGuard(g)
|
initializedGuard(g)
|
||||||
|
|
||||||
@ -105,7 +121,7 @@ method register*(
|
|||||||
raise newException(ValueError, getCurrentExceptionMsg())
|
raise newException(ValueError, getCurrentExceptionMsg())
|
||||||
|
|
||||||
method registerBatch*(
|
method registerBatch*(
|
||||||
g: OnchainGroupManager, rateCommitments: seq[RawRateCommitment]
|
g: OnchainSyncGroupManager, rateCommitments: seq[RawRateCommitment]
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
initializedGuard(g)
|
initializedGuard(g)
|
||||||
|
|
||||||
@ -113,7 +129,7 @@ method registerBatch*(
|
|||||||
g.latestIndex += MembershipIndex(rateCommitments.len)
|
g.latestIndex += MembershipIndex(rateCommitments.len)
|
||||||
|
|
||||||
method register*(
|
method register*(
|
||||||
g: OnchainGroupManager,
|
g: OnchainSyncGroupManager,
|
||||||
identityCredential: IdentityCredential,
|
identityCredential: IdentityCredential,
|
||||||
userMessageLimit: UserMessageLimit,
|
userMessageLimit: UserMessageLimit,
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
@ -166,34 +182,18 @@ method register*(
|
|||||||
g.userMessageLimit = some(userMessageLimit)
|
g.userMessageLimit = some(userMessageLimit)
|
||||||
g.membershipIndex = some(membershipIndex.toMembershipIndex())
|
g.membershipIndex = some(membershipIndex.toMembershipIndex())
|
||||||
|
|
||||||
# don't handle member insertion into the tree here, it will be handled by the event listener
|
|
||||||
return
|
return
|
||||||
|
|
||||||
method withdraw*(
|
method withdraw*(
|
||||||
g: OnchainGroupManager, idCommitment: IDCommitment
|
g: OnchainSyncGroupManager, idCommitment: IDCommitment
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
initializedGuard(g) # TODO: after slashing is enabled on the contract
|
initializedGuard(g) # TODO: after slashing is enabled on the contract
|
||||||
|
|
||||||
method withdrawBatch*(
|
method withdrawBatch*(
|
||||||
g: OnchainGroupManager, idCommitments: seq[IDCommitment]
|
g: OnchainSyncGroupManager, idCommitments: seq[IDCommitment]
|
||||||
): Future[void] {.async: (raises: [Exception]).} =
|
): Future[void] {.async: (raises: [Exception]).} =
|
||||||
initializedGuard(g)
|
initializedGuard(g)
|
||||||
|
|
||||||
proc fetchMerkleProof*(g: OnchainSyncGroupManager) {.async.} =
|
|
||||||
let index = stuint(g.membershipIndex.get(), 256)
|
|
||||||
try:
|
|
||||||
let merkleProofInvocation = g.wakuRlnContract.get().merkleProofElements(index)
|
|
||||||
let merkleProof = await merkleProofInvocation.call()
|
|
||||||
# Await the contract call and extract the result
|
|
||||||
return merkleProof
|
|
||||||
except CatchableError:
|
|
||||||
error "Failed to fetch merkle proof: " & getCurrentExceptionMsg()
|
|
||||||
|
|
||||||
proc fetchMerkleRoot*(g: OnchainSyncGroupManager) {.async.} =
|
|
||||||
let merkleRootInvocation = g.wakuRlnContract.get().root()
|
|
||||||
let merkleRoot = await merkleRootInvocation.call()
|
|
||||||
return merkleRoot
|
|
||||||
|
|
||||||
method generateProof*(
|
method generateProof*(
|
||||||
g: OnchainSyncGroupManager,
|
g: OnchainSyncGroupManager,
|
||||||
data: seq[byte],
|
data: seq[byte],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user