feat(chat): gate first publish on proof root stability in valid_roots

Replaces the blind 30s post-RLN-ready sleep in sendBytes with a
poll-based wait: capture our cachedProof's merkle root, then wait
until it has been present in our own rootTracker for ≥2 poll cycles
(cap 180s, warn-and-publish on cap). Adaptive to the underlying
chain's block cadence — solves the testnet RLN root-drift race
where a 30-42s sleep wasn't enough for mix-node verifiers to poll
the post-registration root, so proofs failed with
"Spam protection proof verification failed" at mix entry.

Non-OnchainLEZ group managers retain the 30s fallback.

Bumps vendor/nwaku to pick up the OnchainLEZGroupManager.proofRoot +
getPollInterval accessors this gate uses.

Also drops the deprecated logos-cpp-sdk override on the nix-fetched
LOGOSCORE: overriding the SDK breaks liblogos 7df6195's source
(stale requestObject/onEvent shape). Plugins via logos-module-builder
ship the newer SDK and are ABI-compatible with the native build.
This commit is contained in:
Arseniy Klempner 2026-05-20 11:54:57 -06:00
parent 95c5c51c77
commit 0257fdf443
No known key found for this signature in database
GPG Key ID: 51653F18863BD24B
3 changed files with 44 additions and 4 deletions

View File

@ -286,7 +286,11 @@ echo " Gifter allowlist: $GIFTER_ALLOWLIST"
# ---------- Phase 3: Prerequisites ----------
echo "[3/6] Verifying prerequisites..."
LOGOSCORE="${LOGOSCORE:-$(nix build github:logos-co/logos-liblogos/7df6195 --override-input logos-cpp-sdk github:logos-co/logos-cpp-sdk/1468180b2567f4c59346bb94f74951e76341f5c5 --no-link --print-out-paths)/bin/logoscore}"
# Use liblogos's native SDK pin — overriding to 1468180b breaks liblogos
# 7df6195's source (uses old requestObject/onEvent shapes). Plugins built
# via logos-module-builder use SDK 8bdbd13 transitively; smoke load shows
# they're ABI-compatible with the native build.
LOGOSCORE="${LOGOSCORE:-$(nix build github:logos-co/logos-liblogos/7df6195 --no-link --print-out-paths)/bin/logoscore}"
RLN_MODULE="$LEZ_RLN_DIR/logos-rln-module/result-rln/lib"
WALLET_MODULE="$LEZ_RLN_DIR/logos-rln-module/result-wallet/lib"

View File

@ -151,8 +151,44 @@ proc sendBytes*(client: WakuClient, contentTopic: string,
await sleepAsync(2.seconds)
attempts += 1
if client.node.wakuMix.mixRlnSpamProtection.isReady():
info "RLN spam protection ready, waiting 30s for root convergence across mix nodes"
await sleepAsync(30.seconds)
let gm = client.node.wakuMix.mixRlnSpamProtection.groupManager
if gm of OnchainLEZGroupManager:
# Wait until our proof's merkle root has settled in our own
# validRoots window for 2 full poll cycles. By then any other mix
# node polling the same LEZ source should have it too, so the
# verifier's validateRoot will succeed. Avoids a blind sleep that
# is too short on slow chains (e.g. testnet ~60s blocks) and
# wastefully long on fast ones.
let lezGm = OnchainLEZGroupManager(gm)
let pollMs = lezGm.getPollInterval().milliseconds
let stableMs = max(pollMs * 2, 5000)
let probeMs = max(pollMs div 4, 1000)
let deadlineMs = 180_000
info "Waiting for proof root to stabilize in valid_roots",
pollMs = pollMs, stableMs = stableMs
var lastRoot = lezGm.proofRoot()
var stableSince = Moment.now()
let deadline = Moment.now() + chronos.milliseconds(deadlineMs)
var settled = false
while Moment.now() < deadline:
await sleepAsync(chronos.milliseconds(probeMs))
let cur = lezGm.proofRoot()
if cur != lastRoot:
lastRoot = cur
stableSince = Moment.now()
continue
if cur.isSome and lezGm.rootTracker.containsRoot(cur.get()):
if Moment.now() - stableSince >= chronos.milliseconds(stableMs):
settled = true
break
if settled:
info "Proof root stable in valid_roots, proceeding to publish"
else:
warn "Proof root did not stabilize within deadline, publishing anyway",
deadlineMs = deadlineMs
else:
info "RLN spam protection ready (non-LEZ), waiting 30s for root convergence"
await sleepAsync(30.seconds)
else:
warn "RLN spam protection not ready after timeout, sending anyway"

2
vendor/nwaku vendored

@ -1 +1 @@
Subproject commit 7764bbde1869f532da7b90c71bd31a7eaccb1f89
Subproject commit 81c700ad80197069b4fdb9d43fb8886c1fca54a6