Context
ComputeAnForValidator (internal/auditing/auditing.go:280-355) computes the per-tranche stochastic audit assignment. For each work report, it:
- Builds context ⟨XU ⌢ Y(Hv) ⌢ H(w) ⌢ n⟩
- VRF-signs context with the validator's Bandersnatch key
- Extracts VRF output
sₙ(w)
- Compares
sn_w[0] · V / (256 · F) < mₙ to decide whether this validator is assigned to audit w in tranche n
F = types.BiasFactor = 2 per GP §17.16 — Burdges/Cevallos 2024 modeling shows this gives one no-show in a tranche an expected F = 2 validators picking it up the next round, the cryptoeconomic recovery invariant for audit.
Currently 0 tests. A wrong-direction comparison, F=1 instead of F=2, division swapped with multiplication, or threshold inverted would all silently break audit recovery and no existing test would catch it.
Suggested test plan
Two layers, low cost together:
-
Threshold logic, mocked VRF output — extract or directly drive the threshold check with synthetic sn_w[0] values around the boundary 256·F·mₙ/V:
- Just below threshold → assigned
- Just above threshold → not assigned
- Exactly at threshold → check the edge consistently
If the threshold check is hard to isolate from the VRF call, a small refactor to extract func isAssignedByThreshold(snWByte0 byte, validatorsCount, biasFactor, noShowCount int) bool would make this unit-testable and is a wider win for readability.
-
(Optional) statistical — fixed seed Bandersnatch VRF, run N=1000 reports through ComputeAnForValidator, assert assigned count is within ±10% of F · mₙ. Slightly flaky in principle but with a fixed seed should be stable. Skip if Bandersnatch fixture plumbing is too heavy for this issue's scope.
Out of scope
- §17.16
eₙ via Refine (PVM cost instrumentation)
SingleNodeAuditingAndPublish end-to-end (separate followup)
References
Context
ComputeAnForValidator(internal/auditing/auditing.go:280-355) computes the per-tranche stochastic audit assignment. For each work report, it:sₙ(w)sn_w[0] · V / (256 · F) < mₙto decide whether this validator is assigned to auditwin tranchenF = types.BiasFactor = 2per GP §17.16 — Burdges/Cevallos 2024 modeling shows this gives one no-show in a tranche an expectedF = 2validators picking it up the next round, the cryptoeconomic recovery invariant for audit.Currently 0 tests. A wrong-direction comparison, F=1 instead of F=2, division swapped with multiplication, or threshold inverted would all silently break audit recovery and no existing test would catch it.
Suggested test plan
Two layers, low cost together:
Threshold logic, mocked VRF output — extract or directly drive the threshold check with synthetic
sn_w[0]values around the boundary256·F·mₙ/V:If the threshold check is hard to isolate from the VRF call, a small refactor to extract
func isAssignedByThreshold(snWByte0 byte, validatorsCount, biasFactor, noShowCount int) boolwould make this unit-testable and is a wider win for readability.(Optional) statistical — fixed seed Bandersnatch VRF, run N=1000 reports through
ComputeAnForValidator, assert assigned count is within ±10% ofF · mₙ. Slightly flaky in principle but with a fixed seed should be stable. Skip if Bandersnatch fixture plumbing is too heavy for this issue's scope.Out of scope
eₙvia Refine (PVM cost instrumentation)SingleNodeAuditingAndPublishend-to-end (separate followup)References