perf: stop querying the network subgraph on every TAP receipt#1069
Open
MoonBoi9001 wants to merge 6 commits into
Open
perf: stop querying the network subgraph on every TAP receipt#1069MoonBoi9001 wants to merge 6 commits into
MoonBoi9001 wants to merge 6 commits into
Conversation
The TAP receipt path queried the network subgraph once per receipt to ask whether the allocation's escrow was already redeemed, blocking every paid query on an external round trip. A watcher now keeps a snapshot for the active allocations and the check reads it in memory.
The redeemed check no longer polls the network subgraph at all. indexer-agent already records when a collection's closing RAV is redeemed on-chain; the check now loads those rows and stays current through a trigger with pg_notify, the same pattern the deny-list check uses.
The final flag is only set a finality window after redemption, past the default buffer in which receipts still pass eligibility, so the check never fired. Keying on last and redeemed_at fires at redemption time; rows are scoped per service provider and reconnects trigger reloads.
In the routine lifecycle redemption follows the same recently-closed buffer that gates the eligibility check, so by the time a closing RAV is redeemed, eligibility already rejects the receipt; the check's real role is insurance against out-of-band redemptions, not a routine gate.
Contributor
Coverage Report for CI Build 29090347846Coverage increased (+0.1%) to 71.593%Details
Uncovered Changes
Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
When the notification connection dropped, the watcher reloaded the redeemed set while still disconnected; sqlx only reconnects on the next receive call, so a redemption landing between the reload and the reconnect went unseen. Re-issue LISTEN first, then reload, as at startup.
The watcher used to log and skip a notification it could not parse. The payload comes from this repo's own trigger, so a parse failure means the trigger and the Rust code drifted apart and every later notification would fail too; reload the whole set from the table instead.
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.
This PR makes the allocation-redeemed receipt check read the indexer's own database instead of issuing a live network-subgraph query per receipt. That lookup sat in the hot path of every paid query: an external round trip (billed, for indexers whose network subgraph is gateway-served) spent asking a question whose answer almost never matters in the routine lifecycle. tap-agent only writes the closing RAV when an allocation ages out of the recently-closed buffer, indexer-agent redeems only closing RAVs, and the eligibility check stops accepting receipts at that same buffer expiry, so by the time a redemption exists, receipts for that allocation are already rejected 1 check earlier. The redeemed check is really insurance against out-of-band redemptions and agent-service config skew, and insurance should not cost a network call per receipt.
The replacement keeps exactly that insurance at zero hot-path cost. indexer-agent already records redemptions in
redeemed_at(and reconciles them against the chain in both directions, including clearing on reorg), so the check now holds an in-memory set of redeemed closing RAVs, loaded at startup and updated through a new trigger with pg_notify, the deny-list check's pattern. Rows are scoped to this service provider and keyed by payer, data service, and collection, matching the receipt's own fields.