Skip to content

feat: track state-change block and canceler on IndexingAgreement#7

Closed
MoonBoi9001 wants to merge 3 commits into
mb9/track-on-chain-rca-offersfrom
mb9/track-state-change-block-and-canceler
Closed

feat: track state-change block and canceler on IndexingAgreement#7
MoonBoi9001 wants to merge 3 commits into
mb9/track-on-chain-rca-offersfrom
mb9/track-state-change-block-and-canceler

Conversation

@MoonBoi9001
Copy link
Copy Markdown
Member

Motivation

The IndexingAgreement entity currently captures the full business state of an agreement -- payer, indexer, pricing, timestamps of major transitions -- but two gaps make it awkward to consume as a source of truth for state reconciliation.

First, there is no block-indexed marker of the most recent state change. The existing lastUpdatedAt timestamp is only written in handleAgreementUpdated, so polling lastUpdatedAt_gt would miss accepts, cancels, and collections. Consumers that want a delta-style "what moved since block N" have to either iterate every entity on every poll or fall back to reading the event-log entities (which cuts against the aggregated-entity direction of PR #5).

Second, when an agreement is canceled the entity records state = CanceledByServiceProvider | CanceledByPayer but loses the actual signer address. Most cancels come directly from the payer or the indexer so the enum is sufficient, but in production an operator can sign on behalf of either party and the enum collapses that to just the party category. Dipper's chain_listener compares the canceler address to its own signer address to decide whether a cancel was self-initiated or not -- without the address on the entity, that check has to fall back to the event-log entity.

Summary

  • Adds lastStateChangeBlock: BigInt! to IndexingAgreement. Every handler that transitions state stamps it with event.block.number: handleAgreementAccepted / Canceled / Updated / RCACollected on the RecurringCollector data source, and handleIndexingAgreementAccepted / Canceled / Updated on the SubgraphService data source. createOrLoadIndexingAgreement initialises it to zero.
  • Adds canceledBy: Bytes! to IndexingAgreement, initialised to Bytes.empty() and written in a new handleIndexingAgreementCanceled handler that reads canceledOnBehalfOf from the SubgraphService event. The RecurringCollector handler continues to set the state enum; neither handler overwrites the other's field.
  • Binds IndexingAgreementCanceled on the SubgraphService data source in subgraph.template.yaml.
  • Matchstick tests: a new handleIndexingAgreementCanceled test that verifies canceledBy captures a distinct operator address (not inferred from payer/indexer) and that lastStateChangeBlock is stamped. Existing accept and update tests gain lastStateChangeBlock assertions.

Both new fields are additive and backwards-compatible: existing consumers that don't read them see no change, and new consumers that filter on lastStateChangeBlock_gt or read canceledBy get the delta-friendly shape they need.

Generated with Claude Code

@MoonBoi9001 MoonBoi9001 force-pushed the mb9/track-state-change-block-and-canceler branch from 704daf4 to b4c94d8 Compare April 23, 2026 09:27
@MoonBoi9001 MoonBoi9001 changed the base branch from main to mb9/track-on-chain-rca-offers April 23, 2026 09:27
@MoonBoi9001 MoonBoi9001 force-pushed the mb9/track-state-change-block-and-canceler branch from b4c94d8 to 60ec575 Compare April 23, 2026 09:32
MoonBoi9001 added a commit that referenced this pull request Apr 23, 2026
Drop the branches: [main] filter so stacked PRs whose base is another
branch in the same repo (e.g. PR #7 stacked on this one) still get
build-and-test runs. Keep the push trigger narrow to main so CI does
not fire on every force-push across feature branches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MoonBoi9001 MoonBoi9001 force-pushed the mb9/track-state-change-block-and-canceler branch 2 times, most recently from 9bafd57 to 8360209 Compare April 24, 2026 05:30
MoonBoi9001 added a commit that referenced this pull request May 7, 2026
Drop the branches: [main] filter so stacked PRs whose base is another
branch in the same repo (e.g. PR #7 stacked on this one) still get
build-and-test runs. Keep the push trigger narrow to main so CI does
not fire on every force-push across feature branches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MoonBoi9001 MoonBoi9001 force-pushed the mb9/track-on-chain-rca-offers branch from c18a47d to ec72172 Compare May 7, 2026 03:32
@MoonBoi9001 MoonBoi9001 force-pushed the mb9/track-state-change-block-and-canceler branch from 8360209 to a9024b6 Compare May 7, 2026 03:34
MoonBoi9001 and others added 3 commits May 11, 2026 16:08
Add `lastStateChangeBlock` so consumers can poll for agreements
that moved since a given block, and `canceledBy` (taken from the
SubgraphService event's canceledOnBehalfOf) so operator-initiated
cancels capture the real signer, not just the enum.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The audit dropped redundant on-chain timestamps from the Agreement
events and added OfferCancelled, but the subgraph still subscribed
to pre-audit signatures so every handler stayed silent. Update ABI,
yaml, and mappings; subscribe to OfferCancelled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
OfferStored fires for both OFFER_TYPE_NEW and OFFER_TYPE_UPDATE, but
the handler treated the second event as a no-op and dropped the
update. Refresh both fields on every event; keep createdAt pinned
to the first OFFER_TYPE_NEW so consumers can still see the initial.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MoonBoi9001 MoonBoi9001 force-pushed the mb9/track-state-change-block-and-canceler branch from 3000a93 to fdd2084 Compare May 11, 2026 08:09
@MoonBoi9001 MoonBoi9001 deleted the branch mb9/track-on-chain-rca-offers May 11, 2026 08:09
MoonBoi9001 added a commit that referenced this pull request May 11, 2026
Drop the branches: [main] filter so stacked PRs whose base is another
branch in the same repo (e.g. PR #7 stacked on this one) still get
build-and-test runs. Keep the push trigger narrow to main so CI does
not fire on every force-push across feature branches.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant