Skip to content

feat(tap-agent): use network subgraph for Horizon RAV redemption tracking#922

Merged
suchapalaver merged 14 commits intomainfrom
feat/network-subgraph-rav-tracking
Feb 3, 2026
Merged

feat(tap-agent): use network subgraph for Horizon RAV redemption tracking#922
suchapalaver merged 14 commits intomainfrom
feat/network-subgraph-rav-tracking

Conversation

@suchapalaver
Copy link
Copy Markdown
Collaborator

@suchapalaver suchapalaver commented Feb 3, 2026

Summary

  • Add allocation-redeemed validation to indexer-service so redeemed receipts are rejected before storage (mirrors tap-agent safety and reduces DB bloat).
  • Use network subgraph (Horizon/V2) for redemption checks and escrow account data; keep v1 escrow subgraph usage for legacy receipts.
  • Align allocation ID encoding to 20-byte address for Horizon network subgraph queries and improve test coverage/error paths.
  • Make watcher shutdown behavior consistent (graceful exit instead of panic).

Signed off by Joseph Livesey joseph@semiotic.ai

@suchapalaver suchapalaver marked this pull request as ready for review February 3, 2026 03:21
@coveralls
Copy link
Copy Markdown

coveralls commented Feb 3, 2026

Pull Request Test Coverage Report for Build 21645455959

Details

  • 351 of 410 (85.61%) changed or added relevant lines in 9 files are covered.
  • 4 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.6%) to 69.456%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/service/src/service/router.rs 6 7 85.71%
crates/service/src/service.rs 0 2 0.0%
crates/tap-agent/src/agent/sender_allocation.rs 19 21 90.48%
crates/watcher/src/lib.rs 2 4 50.0%
crates/service/src/tap/checks/allocation_redeemed.rs 132 137 96.35%
crates/tap-agent/src/tap/context/checks/allocation_id.rs 159 168 94.64%
crates/tap-agent/src/agent/sender_account.rs 27 65 41.54%
Files with Coverage Reduction New Missed Lines %
crates/tap-agent/src/agent/sender_account.rs 1 85.72%
crates/watcher/src/lib.rs 3 85.71%
Totals Coverage Status
Change from base Build 21634667492: 0.6%
Covered Lines: 11024
Relevant Lines: 15872

💛 - Coveralls

@suchapalaver suchapalaver marked this pull request as draft February 3, 2026 12:19
Copy link
Copy Markdown
Collaborator

@neithanmo neithanmo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auditors pointed out some checks that were done in tap-agent and not in service, indicating that it could potentially cause database bloat. lets add that allocation-redeemed check in the service too

.filter_map(|allocation_id| {
// Normalize to 20-byte allocation address for comparison.
if let Ok(collection_id) =
CollectionId::from_str(&allocation_id)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this parses hex → CollectionId → AllocationIdCore → back to hex??

neithanmo
neithanmo previously approved these changes Feb 3, 2026
…king

Query paymentsEscrowTransactions from the network subgraph to detect
redeemed Horizon RAVs, replacing the LatestRavs query approach. This
enables more reliable detection of allocation redemptions by checking
for actual redeem transactions rather than comparing RAV values.

Also adds allocation redemption checking for the AllocationId check
to prevent accepting receipts for already-redeemed Horizon allocations.
The horizon branch has been merged, so use main instead.
…ubgraph

The network subgraph stores allocationId as a 20-byte address, not as
a 32-byte CollectionId. Use `as_address()` when encoding the allocation
ID for the GraphQL query.

Also remove redundant normalization logic in the response handling since
the subgraph already returns 20-byte addresses.
Use the defined constant instead of Duration::default() for consistency
with other test configuration values.
When the watcher source receiver is dropped, log a debug message and
break out of the loop cleanly rather than panicking. This allows for
graceful shutdown when the source watcher is dropped.
…20-byte address only

The network subgraph consistently stores allocationId as the 20-byte address
derived from the collection_id (rightmost 20 bytes), so remove the redundant
32-byte format from the query.
Log the allocation IDs being queried when checking for redeemed RAVs via
the network subgraph. This aids debugging production issues with RAV
finalization tracking.
@suchapalaver suchapalaver force-pushed the feat/network-subgraph-rav-tracking branch from 530e2f3 to c3bada7 Compare February 3, 2026 19:18
Add AllocationRedeemedCheck to validate that allocations haven't already
been redeemed before accepting receipts. For v1 receipts, queries the
escrow subgraph for existing redemption transactions. For v2 receipts,
queries the network subgraph for PaymentsEscrowTransactions.

This prevents accepting receipts for allocations that have already been
finalized, which would result in unrecoverable funds.
Add escrow and network subgraph configuration to the router integration
test. This ensures the new allocation redeemed check introduced in the
TAP receipt validation path is exercised during testing.
@suchapalaver suchapalaver force-pushed the feat/network-subgraph-rav-tracking branch from 128ae16 to 2b881a2 Compare February 3, 2026 19:43
@suchapalaver suchapalaver marked this pull request as ready for review February 3, 2026 20:01
@suchapalaver
Copy link
Copy Markdown
Collaborator Author

Thanks for all your feedback @neithanmo 🫡

@suchapalaver suchapalaver merged commit 1aafc9b into main Feb 3, 2026
12 checks passed
@suchapalaver suchapalaver deleted the feat/network-subgraph-rav-tracking branch February 3, 2026 20:33
@github-actions github-actions bot mentioned this pull request Feb 3, 2026
This was referenced Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants