fix: verify only paid quotes in SingleNode payment model#1
Closed
jacderida wants to merge 1 commit into
Closed
Conversation
The SingleNode payment model pays only the median-priced quote (3x) and sends Amount::ZERO for the other 4. evmlib's pay_for_quotes() filters out zero-amount payments, so only 1 quote has an on-chain record. The verifier was using verify_data_payment() which fails if ANY result is isValid=false — causing every upload to fail because the 4 unpaid quotes have no on-chain record. Fix: call the contract's verifyPayment() directly and require that at least one result is valid (the paid quote), rather than requiring all results to be valid. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jacderida
added a commit
that referenced
this pull request
Jun 8, 2026
… delta PR WithAutonomi#122 made pricing and the freshness gate read the same record source, but uploads on a fresh, rapidly-filling testnet (STG-01, 0.11.6-rc.2) still failed ~100%. The residual cause is the freshness gate itself. The gate compared the price-derived quoted record count against the node's current count with a fixed `max(5, 5%)` tolerance, symmetrically (abs_diff). Two problems on an actively-replicating network: 1. Tolerance too tight for normal in-flight churn. Between a node quoting and verifying a payment (the client collects 7 quotes/chunk, pays on-chain via Arbitrum, then PUTs — several seconds) the node's record count drifts by a handful of records via replication. Sampled STG-01 rejects had a median delta of 8 — just over the floor of 5. At low/moderate fill the pricing curve is nearly flat, so that drift is a negligible price change, yet it was rejected. 2. Symmetric abs_diff rejected over-payments. ~36% of rejects had current < quoted: the node had FEWER records than when it quoted (prune/churn), so the client paid for a fuller, pricier node — an over-payment — and the node rejected it anyway. Rejecting money a node is owed is nonsensical. Because an upload needs every chunk stored, even a ~40% per-chunk reject rate drives upload success to ~0 (0.6^9 for a 9-chunk file; worse for large files). So per-chunk rejection has to approach zero, not merely shrink. Fix: make the gate price-based and one-directional. Compute the price the node would charge now for its current fullness and reject only if the quote paid less than that by more than QUOTE_PRICE_STALENESS_PCT_TOLERANCE (25%). - Over-payment (paid >= current price) is always accepted (fixes #2). - Comparing prices self-scales with the quadratic curve: benign churn on the flat part of the curve is ignored, while genuine staleness at high fill — where the curve is steep — is still caught (fixes #1). Replaces the two record-delta tolerance constants with a single price percentage. Reworks the freshness tests: a 10-record drift now passes (it was "stale by 10" before), over-payment passes (regression test for #2), and a quote underpricing by >25% is still rejected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Amount::ZEROfor the other 4evmlib::pay_for_quotes()filters out zero-amount payments, so only 1 quote has an on-chain recordverify_data_payment()which fails if ANY result isisValid=false, causing every upload to fail because the 4 unpaid quotes have no on-chain recordverifyPayment()directly and require that at least one result is valid (the paid quote), rather than requiring all results to be validTest plan
🤖 Generated with Claude Code