graphprotocol / graphprotocol/dipper

Indexer agent on-chain acceptance and contract deployment

Open
#554 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
0
Forks
1
Avg merge
37m
Merged PRs (30d)
3

Description

Context

Both the Dipper and indexer-rs sides of this feature are now complete. The remaining work is contract deployment and the indexer agent's on-chain acceptance implementation, both of which are outside these two codebases.

This issue tracked the migration from the epoch-based `IndexingAgreementVoucher` to the seconds-based `RecurringCollectionAgreement` (RCA) — the same type the contract consumes — and the end-to-end on-chain acceptance flow.

Architecture

The Dipper signs an RCA with a short deadline (~5 min) and sends it to indexer-rs via gRPC (fire-and-forget, no off-chain ACCEPT/REJECT). The indexer agent picks it up, validates, ensures an allocation, and calls `SubgraphService.acceptIndexingAgreement(allocationId, signedRCA)` on-chain. The Dipper monitors for the `IndexingAgreementAccepted` event and transitions the agreement to `AcceptedOnChain`. If the deadline passes with no on-chain acceptance, the Dipper expires the agreement and reassigns it.

If an indexer rejects the proposal off-chain but accepts on-chain anyway, the chain listener detects this and Dipper cancels the active agreement via `cancelIndexingAgreementByPayer`.

Dipper                 indexer-rs              indexer-agent           SubgraphService contract
  |                        |                        |                         |
  |-- SignedRCA (gRPC) --> |                        |                         |
  |                        |-- store SignedRCA       |                         |
  |                        |                        |-- read pending           |
  |                        |                        |-- validate terms         |
  |                        |                        |-- ensure allocation      |
  |                        |                        |-- acceptIndexingAgreement(allocationId, SignedRCA) -->|
  |                        |                        |                         |-- emit IndexingAgreementAccepted
  |<-- monitor on-chain event ------------------------------------------------|
  |-- mark ACCEPTED_ON_CHAIN                        |                         |

Agreement status flow:

Created -> AcceptedOnChain (on-chain event observed)
Created -> Expired (deadline passed, no on-chain acceptance)
Created -> DeliveryFailed (gRPC error sending to indexer-rs)
AcceptedOnChain -> CanceledByRequester (Dipper cancels adversarial on-chain acceptance)
AcceptedOnChain -> CanceledByIndexer (indexer cancels on-chain)

Phases

  • Phase 1 - Dipper: Status cleanup -- Remove `Accepted` and `Rejected` statuses. `Created` is the only pre-confirmation active status, `AcceptedOnChain` is the confirmed one. Update active agreement queries, unique constraint, replace `at_epoch` with timestamp. (97af12b, PR #553)
  • Phase 2 - Dipper: Switch to seconds-based pricing -- Replace epoch-based internal model (voucher fields, pricing config, DB schema) with seconds-based equivalents matching the contract. (22a648e, PR #555)
  • Phase 3 - Dipper: Sign and send SignedRCA -- Replace voucher signing with RCA signing using the contract's EIP-712 domain. Fire-and-forget gRPC call. ABI-encode `AcceptIndexingAgreementMetadata` into the RCA metadata field. Configurable deadline (~5 min). (22a648e, PR #555)
  • Phase 4 - indexer-rs: Store SignedRCA -- Simplified gRPC endpoint stores the `SignedRCA` blob in `pending_rca_proposals` with idempotent writes. Agent queries this table to pick up pending agreements. (indexer-rs PRs #942, #947, #948)
  • Phase 5 - Indexer agent: On-chain acceptance -- New `AgreementAcceptor` background service (follows TapCollector pattern). Read pending agreements from indexer-rs DB, validate terms, ensure allocation, call `SubgraphService.acceptIndexingAgreement()`. Blocked on Phase 6.
  • Phase 6 - Contract deployment -- The `IndexingAgreement.sol` contract has not been deployed yet. It needs to be deployed to Arbitrum Sepolia for testnet integration first, then to Arbitrum mainnet. Phases 5 and 7 depend on the contract being live.
  • Phase 7 - Protocol subgraph: Create and deploy -- No subgraph currently exists that indexes the `IndexingAgreement.sol` contract events. A new subgraph needs to be written, covering `IndexingAgreementAccepted`, `IndexingAgreementCanceled`, and `IndexingFeesCollectedV1` events emitted by the SubgraphService contract. Once the contract is deployed, the subgraph can be published and indexed. This is a prerequisite for Phase 8.
  • Phase 8 - Dipper: On-chain event monitoring -- Chain listener polls the protocol subgraph for agreement events, transitions `Created → AcceptedOnChain`, expires agreements past deadline, triggers reassignment. Also handles the adversarial case: if an indexer accepted on-chain after rejecting off-chain, Dipper cancels the agreement via `cancelIndexingAgreementByPayer`. (PRs #553, #555, #561)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with Phase 6 and the IndexingAgreement.sol deployment requirement for Arbitrum Sepolia, then review the proposed AgreementAcceptor background service and the pending_rca_proposals flow. Follow the TapCollector pattern and the SubgraphService.acceptIndexingAgreement entry point. Done requires the contract to be deployed and the indexer agent to validate, allocate, and accept pending SignedRCA proposals on-chain.

Written by the indexing model from the issue text.

Assessment

Tech stack
grpc, rust, solidity
Domain
backend, blockchain
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.