Extract broker RLN proof provider into generateRLNProofWithRootRefresh

The broker proof provider's inline logic — generate proof, decode it,
self-validate the root against the acceptable-root window, and on stale
root force-refresh + regenerate — is a reusable primitive on its own.
Lift it into rln/proof.nim next to the existing generateRLNProof so the
provider closure in mount() collapses to a single call, and any future
non-broker caller can share the same flow.

Pure refactor; behavior identical.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
stubbsta 2026-07-08 09:49:56 +02:00
parent a65736b65a
commit e705e4d51d
No known key found for this signature in database
2 changed files with 25 additions and 16 deletions

View File

@ -71,6 +71,27 @@ proc generateRLNProof*(
return err("could not generate rln-v2 proof: " & $error)
return ok(proof.encode().buffer)
proc generateRLNProofWithRootRefresh*(
rln: Rln, input: seq[byte], senderEpochTime: float64
): Future[Result[seq[byte], string]] {.async.} =
## Generates an RLN proof and self-validates its merkle root against the
## acceptable-root window. If the cached path has slid out of that window
## (typical after a long inactivity or on-chain group churn), force-refreshes
## the merkle path and regenerates the proof once. Returns the proof bytes
## the caller can attach to the message.
let proofBytes = (await rln.generateRLNProof(input, senderEpochTime)).valueOr:
return err(error)
let rlnProof = RateLimitProof.init(proofBytes).valueOr:
return err("could not decode proof for root check: " & $error)
if await rln.groupManager.validateRoot(rlnProof.merkleRoot):
return ok(proofBytes)
info "RLN: stale merkle root detected; force-refreshing merkle path"
return
await rln.generateRLNProof(input, senderEpochTime, forceMerkleProofRefresh = true)
proc checkAndGenerateRLNProof*(
rln: Option[Rln],
message: WakuMessage,

View File

@ -233,23 +233,11 @@ proc mount(
proc(
msg: WakuMessage, senderEpochTime: float64
): Future[Result[RequestGenerateRlnProof, string]] {.async.} =
let proofBytes = (await rln.generateRLNProof(msg.toRLNSignal(), senderEpochTime)).valueOr:
return err("Could not create RLN proof: " & error)
let rlnProof = RateLimitProof.init(proofBytes).valueOr:
return err("Could not decode RLN proof for root check: " & $error)
if await rln.groupManager.validateRoot(rlnProof.merkleRoot):
return ok(RequestGenerateRlnProof(proof: proofBytes))
# Cached merkle proof path root has slid out of the valid window; force-refresh and regenerate
info "RLN broker provider: stale merkle root detected; force-refreshing merkle path"
let retryProof = (
await rln.generateRLNProof(
msg.toRLNSignal(), senderEpochTime, forceMerkleProofRefresh = true
)
let proofBytes = (
await rln.generateRLNProofWithRootRefresh(msg.toRLNSignal(), senderEpochTime)
).valueOr:
return err("Could not create RLN proof on retry: " & error)
return ok(RequestGenerateRlnProof(proof: retryProof)),
return err("Could not create RLN proof: " & error)
return ok(RequestGenerateRlnProof(proof: proofBytes)),
).isOkOr:
return err("Proof generator provider cannot be set: " & $error)