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)