Skip to content

relay: gate mismatched-nonce PoW rejection behind StrictPow - #10

Merged
naliyi merged 2 commits into
mainfrom
fix-relay-pow-strict-gate
Sep 3, 2026
Merged

relay: gate mismatched-nonce PoW rejection behind StrictPow#10
naliyi merged 2 commits into
mainfrom
fix-relay-pow-strict-gate

Conversation

@naliyi

@naliyi naliyi commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Session.processEvent called Event.Verify() with no options, so any event carrying a nonce tag whose declared difficulty didn't match the event ID's actual leading-zero-bit count was hard-rejected unconditionally — no relay config could disable it.
  • This is distinct from (and runs before) the existing MinPowDifficulty/StrictPow floor check, which is opt-in and was already correctly gated.
  • Fix: skip the base mismatch check the same way, via nip01.WithoutPowCheck(), unless Limitation.StrictPow is on — consistent with the existing floor check and with this repo's own tests' stated intent ("min: 0 == accept all" by default).

Downstream symptom this fixes: ncli apply stream/sync forwarding an event whose nonce tag overclaims its difficulty to any nmilat-backed relay got it silently dropped at the relay (invalid: pow check failed: ...), regardless of strictPow/--strict-pow on the ncli side — because that setting only ever controlled ncli's own read-side verification, never the destination relay's independent ingest decision.

Test plan

  • relay/pow_test.go: added TestProcessEvent_MismatchedNonceToleratedByDefault and TestProcessEvent_MismatchedNonceRejectedWhenStrict, covering the previously-untested "nonce tag overclaims its difficulty" case (existing tests only used honestly-mined events).
  • Verified the new tests fail against the pre-fix code with the exact reported error message, and pass after the fix.
  • go test ./... passes with no regressions.
  • gofmt -l clean on changed files.

processEvent's Verify() call ran with no options, so any event carrying a
nonce tag whose declared difficulty didn't match the event ID's actual
leading-zero-bit count was hard-rejected unconditionally -- there was no
relay config to disable it. This is distinct from (and ran before) the
existing MinPowDifficulty/StrictPow floor check, which is opt-in and
correctly gated already.

Skip the base check the same way: pass nip01.WithoutPowCheck() unless
Limitation.StrictPow is on, matching this repo's own tests' stated intent
("min: 0 == accept all" by default) and the documented behavior consumers
like ncli's apply --strict-pow already assume the relay side follows.

Adds regression coverage in relay/pow_test.go for both the tolerant default
and the StrictPow=true rejection.
@naliyi
naliyi marked this pull request as ready for review September 3, 2026 11:51
@naliyi
naliyi merged commit 006b8cb into main Sep 3, 2026
3 checks passed
naliyi added a commit that referenced this pull request Sep 3, 2026
changelog: add (#9)/(#10) PR backrefs, trim relay PoW entry
@naliyi
naliyi deleted the fix-relay-pow-strict-gate branch September 3, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant