Files
Dobromir Popov 560de08edd Normalize line endings to LF via .gitattributes
Adds a committed .gitattributes so Windows and Linux checkouts converge
on LF for all text files, overriding each developer's local core.autocrlf.
Renormalizes existing blobs (server.py, dashboard.html, etc.) that had
CRLF baked in, clearing the repo-wide phantom "modified" churn.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 16:15:32 +02:00
..

meshnet-validator

Optimistic fraud detection (ADR-0003, penalty amended by ADR-0015): the validator re-runs a random ~5% sample of completed inference requests against a trusted reference node. Audit-capable events are checked by teacher-forcing the claimed token sequence through the reference node and verifying the claimed TOPLOC activation proof. Legacy events without TOPLOC metadata still fall back to text comparison until node-side proof capture lands.

Why the penalty deters cheating

There is no upfront stake. Settlement is periodic (US-033), so a node always has an unpaid pending balance — that balance is the collateral.

At a sampling rate p, a cheater who gains G per fraudulent job and loses L when caught has expected value:

(1 - p) * G - p * L < 0
L > ((1 - p) / p) * G        # p = 0.05  ->  L > 19 x G

With the production settlement period of 24h, the pending balance at any moment approximates a full day's earnings — hundreds to thousands of jobs — which is far above the 19× bar. Each catch also records a strike; three strikes ban the wallet (registration rejected, excluded from routes, unpaid pending never settled), and the probationary period (first N jobs unpaid) makes re-entry with a fresh wallet costly.

TOPLOC audit contract

The validator expects audit-capable events to carry:

  • claimed_token_ids: the final token sequence claimed by the prover.
  • toploc_proof: compact TOPLOC proof data built from prover activations.

On audit the validator calls the reference node's POST /v1/audit/toploc endpoint with the original messages plus claimed_token_ids. The reference node must run a teacher-forced prefill over exactly that token sequence and return the activations for TOPLOC verification. It must not free-generate a second answer for audit.

Canonical audit parameters for the current alpha preset are:

dtype = "bfloat16"
quantization = "bfloat16"
decode_batching_size = 32
topk = 8
skip_prefill = true
encoding = "base64"

verify_activation_proofs_detailed() (meshnet_validator.audit) surfaces the raw TOPLOC divergence — exp_intersections (worst-case across chunks), mant_err_mean, mant_err_median — alongside the pass/fail bool. This is what the calibration corpus below is built from; existing callers that only need the bool keep using verify_activation_proofs().

Do not enable production audit thresholds before issue 21 closes. Production audit thresholds remain gated on the honest-noise calibration corpus in issue 21: the tracker's POST /v1/calibration/toploc/run (admin/validator-only, mirrors POST /v1/benchmark/hop-penalty) dispatches a fixed prompt to every solo-capable registered node, verifies each node's on-demand commitment against a teacher-forced reference replay, and records the divergence into a SQLite corpus (meshnet_tracker.calibration. ToplocCalibrationStore) keyed by node wallet + GPU model + dtype. GET /v1/calibration/toploc/results reports the corpus plus:

  • envelope: p99 honest-noise value per metric with a 20% safety margin — the recommended (not yet wired) tolerance constants.
  • gate_status.ready: whether the corpus covers enough distinct hardware profiles (--toploc-calibration-gate-min-hardware-profiles, default 1). Alpha exception: with the hired-VPS-only launch fleet, ready may legitimately mean "covers every node we currently operate" — this must be revisited (raise the minimum) before a public/volunteer launch broadens the hardware mix, since a new corpus is required whenever the fleet's hardware composition changes.

Two operational notes:

  • Shortening the settlement period shrinks the collateral. Period changes must weigh chain overhead against deterrence.
  • A cheater immediately after a payout has little to forfeit — the strike/ban ladder covers that window.

Usage

ValidatorProcess(
    contracts=contracts,          # registry/validation boundary
    billing=ledger,               # BillingLedger — enables forfeiture
    reference_node_url="http://...",
    sample_rate=0.05,
)

Remote validators can instead call the tracker's privileged POST /v1/billing/forfeit endpoint (non-empty Authorization header).

Reputation-weighted audit rate (ADR-0018 §1, §6-7)

sample_rate is a flat coin flip: every wallet audited at the same rate. Pass audit_sampler=AdaptiveAuditSampler(...) instead to make the audit probability a function of each wallet's tenure and reputation — newcomers and low-reputation wallets sampled at 2030%, veterans in good standing floor at ≥2% — while a running budget balance keeps the fleet-wide realized rate anchored to AuditRateConfig.target_rate (default 5%) regardless of the wallet mix. Passive tripwires (detect_output_tripwire) bump only that one request's odds; they never strike, ban, or affect other wallets' rates.

from meshnet_validator import AdaptiveAuditSampler, detect_output_tripwire

ValidatorProcess(
    contracts=contracts,
    reference_node_url="http://...",
    audit_sampler=AdaptiveAuditSampler(random_seed=42),
)

When audit_sampler is set, sample_rate is ignored — the sampler decides per event, keyed on whichever route wallet has the lowest reputation.