From 1473301b0987f4fee6b264cd00a6610e35ea47df Mon Sep 17 00:00:00 2001 From: stubbsta Date: Thu, 2 Jul 2026 13:45:49 +0200 Subject: [PATCH] Add tests for lightpush force refresh regenerates proof --- tests/node/test_wakunode_legacy_lightpush.nim | 32 ++++++++++++++++++ tests/node/test_wakunode_lightpush.nim | 33 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/tests/node/test_wakunode_legacy_lightpush.nim b/tests/node/test_wakunode_legacy_lightpush.nim index 9301e9e01..55b42f55f 100644 --- a/tests/node/test_wakunode_legacy_lightpush.nim +++ b/tests/node/test_wakunode_legacy_lightpush.nim @@ -180,6 +180,38 @@ suite "RLN Proofs as a Lightpush Service": assert publishResponse.isErr(), "We expect an error response" check publishResponse.error == protocol_metrics.notPublishedAnyPeer + asyncTest "force refresh regenerates proof and refetches merkle path": + # Exercises the primitive that legacyLightpushPublish leans on after a + # "RLN validation failed" rejection: an already attached proof must NOT + # short-circuit checkAndGenerateRLNProof when forceMerkleProofRefresh=true, + # and the cache must be refetched from chain instead of trusted. + let firstMsg = + (await checkAndGenerateRLNProof(some(server.rln), message)).get() + check firstMsg.proof.len > 0 + + # Corrupt the cache to model a stale/invalid witness — the same state a + # server-side "RLN validation failed" rejection would leave us in. + let manager = cast[OnchainGroupManager](server.rln.groupManager) + let goodCache = manager.merkleProofCache + manager.merkleProofCache = newSeq[byte](goodCache.len) + check manager.merkleProofCache != goodCache + + # Force-regenerate. The existing proof must be discarded, the cache + # refetched from chain, and a fresh proof produced. + let secondMsg = ( + await checkAndGenerateRLNProof( + some(server.rln), firstMsg, forceMerkleProofRefresh = true + ) + ).get() + + check: + secondMsg.proof.len > 0 + # Regenerated, not passed through — nonce manager consumes a new id + # per call, so the two proofs cannot be byte-equal. + secondMsg.proof != firstMsg.proof + # Cache was refetched from chain, overwriting the corruption. + manager.merkleProofCache == goodCache + suite "Waku Legacy Lightpush message delivery": asyncTest "Legacy lightpush message flow succeed": ## Setup diff --git a/tests/node/test_wakunode_lightpush.nim b/tests/node/test_wakunode_lightpush.nim index 6e87ab237..30422e696 100644 --- a/tests/node/test_wakunode_lightpush.nim +++ b/tests/node/test_wakunode_lightpush.nim @@ -177,6 +177,39 @@ suite "RLN Proofs as a Lightpush Service": assert publishResponse.isErr(), "We expect an error response" check publishResponse.error.code == LightPushErrorCode.NO_PEERS_TO_RELAY + asyncTest "force refresh regenerates proof and refetches merkle path": + # Exercises the primitive that lightpushPublish leans on after a 420 + # (INVALID_MESSAGE) or 504 (OUT_OF_RLN_PROOF) rejection: an already + # attached proof must NOT short-circuit checkAndGenerateRLNProof when + # forceMerkleProofRefresh=true, and the cache must be refetched from + # chain instead of trusted. + let firstMsg = + (await checkAndGenerateRLNProof(some(server.rln), message)).get() + check firstMsg.proof.len > 0 + + # Corrupt the cache to model a stale/invalid witness — the same state a + # 420/504 rejection would leave us in. + let manager = cast[OnchainGroupManager](server.rln.groupManager) + let goodCache = manager.merkleProofCache + manager.merkleProofCache = newSeq[byte](goodCache.len) + check manager.merkleProofCache != goodCache + + # Force-regenerate. The existing proof must be discarded, the cache + # refetched from chain, and a fresh proof produced. + let secondMsg = ( + await checkAndGenerateRLNProof( + some(server.rln), firstMsg, forceMerkleProofRefresh = true + ) + ).get() + + check: + secondMsg.proof.len > 0 + # Regenerated, not passed through — nonce manager consumes a new id + # per call, so the two proofs cannot be byte-equal. + secondMsg.proof != firstMsg.proof + # Cache was refetched from chain, overwriting the corruption. + manager.merkleProofCache == goodCache + suite "Waku Lightpush message delivery": asyncTest "lightpush message flow succeed": ## Setup