From e705e4d51d3a16c2f6217d4827896bff35b09d66 Mon Sep 17 00:00:00 2001 From: stubbsta Date: Wed, 8 Jul 2026 09:49:56 +0200 Subject: [PATCH] Extract broker RLN proof provider into generateRLNProofWithRootRefresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- logos_delivery/waku/rln/proof.nim | 21 +++++++++++++++++++++ logos_delivery/waku/rln/rln.nim | 20 ++++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/logos_delivery/waku/rln/proof.nim b/logos_delivery/waku/rln/proof.nim index 8cf303e38..10a5fff6d 100644 --- a/logos_delivery/waku/rln/proof.nim +++ b/logos_delivery/waku/rln/proof.nim @@ -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, diff --git a/logos_delivery/waku/rln/rln.nim b/logos_delivery/waku/rln/rln.nim index 99f88cccb..fa952822b 100644 --- a/logos_delivery/waku/rln/rln.nim +++ b/logos_delivery/waku/rln/rln.nim @@ -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)