3.3 KiB
3.3 KiB
Status: done
10 — FRAUD: Penalty calibration wiring (forfeit + strike + ban)
What to build
End-to-end wiring: confirmed audit failure → atomic pending forfeiture + strike + reputation decay + audit-rate snap to max. Ensure payout cannot race penalty (ADR-0015). Document 19× deterrence math in validator README.
Code refs:
packages/validator/meshnet_validator/__init__.py—_slash_route(~102–134)packages/tracker/meshnet_tracker/server.py—_handle_billing_forfeit(~2429–2464)packages/tracker/meshnet_tracker/billing.py—forfeit_pending(~280–292), payout exclusion for banned (~3337–3344 in settlement loop)packages/validator/README.md— update 20× → 19× at p=0.05
Per ADR-0018: full pending forfeiture is primary penalty; ×0.8 is routing decay per strike, not partial forfeit.
Test-first
- Red: integration from issue 34 — extend with multi-hop blame wallet from issue 07.
- Green: node with pending balance → audit fail → pending zero, strike++, banned on 3rd, excluded from next settlement.
- Settlement loop skips banned wallets (~3337–3344).
Acceptance criteria
- Audit failure triggers forfeiture + strike in one tracker transaction —
ValidatorProcess._slash_node(in-process) and the tracker's_handle_billing_forfeithandler (remote) both forfeit-then-strike synchronously in a single call path; each already existed pre-AH-010 and is exercised bytests/test_forfeiture_penalty.py - Banned nodes excluded from
payables/ settlement —BillingLedger.settle_node_payoutnow clamps to the wallet's current pending balance under the same lock as the debit, and_settlement_looprechecks ban status and uses the post-clamp amount before sending, so a forfeiture landing between thepayables()snapshot and the actual payout can never be paid out on top of (ADR-0015 race); covered bytest_60_request_stream_bans_intermittent_first_hop_cheater_not_last_hop - Validator uses authenticated forfeit endpoint (issue 02) —
POST /v1/billing/forfeitis validator-token/admin-gated (ADR-0017 §4, issue 20) and is the documented remote path (packages/validator/README.mdUsage section);test_forfeit_endpoint_requires_auth_and_forfeitsexercises the 401→200 flow. No standalone remote-validator process exists in this codebase yet (contractshas no networked implementation), so the in-processValidatorProcesscontinues to callBillingLedger.forfeit_pendingdirectly when co-located with the tracker — adding an HTTP-only forfeit client with no real consumer was judged out of scope/overengineering for this issue - README:
L > 19× gat p=0.05; pending balance = collateral — already present inpackages/validator/README.md("Why the penalty deters cheating") - Integration test: 60-request fraud scenario → ban within threshold —
tests/test_forfeiture_penalty.py::test_60_request_stream_bans_intermittent_first_hop_cheater_not_last_hop
ADR links
- ADR-0018
- ADR-0015
- Research: research-verifiable-inference.md §1.1
Blocked by
07-fraud-commitment-bisection-blame_completed.md08-fraud-reputation-model-persistence_completed.md02-a2-unified-auth-boundary_completed.md