fix(payment): widen paid-quote issuer admission to close group + margin#139
Conversation
The paid-quote issuer close-group check compares the client's network-lookup-derived quote set against this node's *local* routing-table view. On a young / large / NAT-heavy network the local routing table does not perfectly reflect the global K-closest, so a peer the client legitimately quoted routinely ranks just outside the bare close-group window. The honest payment is then rejected with "Paid quote issuer ... is not among this node's local 7 closest peers", which aborts the whole upload (one un-storable chunk fails the file) — a failure rate that scales multiplicatively with file size. This is the same local-view divergence the sibling receiver admission check already absorbs via `storage_admission_width` (close_group_size + STORAGE_ADMISSION_MARGIN). Apply the same margin to the issuer check for symmetry, widening its window from `close_group_size` (7) to `storage_admission_width(close_group_size)` (9). No change to the receiver admission check or to any other behaviour. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hermes Agent reviewThanks Chris — I reviewed the diff locally. Verdict: looks reasonable to me; I would wait for the remaining CI test jobs to finish before merging. What I checked
Local check runcargo test -p ant-node paid --lib --no-fail-fastResult: CI observed at review timePassing: builds, clippy, docs, format, security audit, no-logging test. Pending at the time I checked: Minor non-blocking noteThe No blocking code issue found from my review. |
Pin saorsa-core 0.25.0 and ant-protocol 2.1.3 to their now-published crates.io versions (they were released earlier this cycle), collapsing the dual saorsa-core lineage that broke the ant-devnet build. Includes the PR #139 payment-admission fix.
Problem
The paid-quote issuer close-group check in
PaymentVerifier::validate_paid_quote_issuer_close_groupcompares the client's network-lookup-derived quote set against this node's local routing-table view (find_closest_nodes_local_with_self). On a young / large / NAT-heavy network the local routing table does not perfectly reflect the global K-closest, so a peer the client legitimately quoted routinely ranks just outside the bareclose_group_sizewindow. The honest payment is then rejected:Because one un-storable chunk fails the whole file, the upload failure rate scales multiplicatively with file size.
Observed
Seen on a staging testnet (ant-node
0.12.1-rc.1, 900 nodes, ~30% NAT-simulated). Failure rate by file size: ~1000 MB ≈ 100%, ~100 MB ≈ 55%, ~20 MB ≈ 10%; every failed upload reportedN-1/N chunks stored, 1 failed, dominated by the "issuer is not among this node's local 7 closest peers" rejection.Cause
fix(payment): enforce local admission before proof verificationnarrowed the issuer check from the wide K-closest window down to the bare configured close group (close_group_size, 7). That is the same local-view divergence thatfix(replication): widen local storage admission rangeaddressed for the sibling receiver admission check by addingSTORAGE_ADMISSION_MARGIN(→storage_admission_width, 9). The issuer check never received that margin and so over-rejects.Fix
Apply the same margin to the issuer check: widen its window from
close_group_size(7) tostorage_admission_width(close_group_size)(9), mirroring the receiver admission check. Single-file change; no change to the receiver check or any other behaviour.Notes
enforce local admission before proof verification(issuer ∈ local close group) and simply reuses the tolerance margin already established for the receiver path — it does not revert either prior change.🤖 Generated with Claude Code