livepeer / livepeer/subgraph

Add per-Transcoder delegatorCount field to schema

Open
#237 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
5
Forks
7
Avg merge
4h 1m
Merged PRs (30d)
6

Description

## Problem

The `Transcoder` entity exposes its `delegators` only as a `@derivedFrom` collection. To learn how many unique delegators an orchestrator has, a client must paginate the `Delegator` entity (`where: { delegate: $orchestrator }`) using keyset pagination on `id`, because The Graph caps `first: 1000` and `skip: 5000`.

This is workable for a single orchestrator's detail page but breaks down for any view that needs the count across many orchestrators at once (e.g. the orchestrator list view in [`livepeer/explorer`](https://github.com/livepeer/explorer)). It also makes the per-orchestrator count an O(N/1000) operation client-side instead of a single field read.

`Protocol`, `Round`, and `Day` already expose `delegatorsCount: BigInt!` — `Transcoder` is the obvious gap.

## Proposal

Add a `delegatorCount` field to the `Transcoder` entity and maintain it in the bonding-related event handlers.

### Schema change

```graphql
type Transcoder @entity {
# ...existing fields...
"Number of unique delegators currently bonded to this transcoder"
delegatorCount: BigInt!
}
```

### Mapping logic

Increment / decrement `transcoder.delegatorCount` in the bonding manager event handlers, mirroring the patterns already used for `Protocol.delegatorsCount`:

- **Bond** (delegator with no prior delegate, or switching delegates): increment the new delegate's `delegatorCount`; if switching, decrement the old delegate's `delegatorCount`.
- **Unbond / Rebond** (full unbond to zero `bondedAmount`): decrement the delegate's `delegatorCount`.
- **TransferBond**: decrement the sender's delegate's count if the sender fully unbonds as a result; increment the receiver's delegate's count if this is the receiver's first bond to that delegate.

### Edge cases to confirm

- A self-delegating transcoder counts itself as a delegator (consistent with how `delegators` derives today, since the transcoder also has a `Delegator` entity for itself). Document this in the field comment.
- Partial unbonds that leave `bondedAmount > 0` must **not** decrement.
- Rebonding from an unbonding lock that brings a previously-zeroed delegator back must increment.

## Acceptance criteria

- [ ] `Transcoder.delegatorCount: BigInt!` exists in `schema.graphql`.
- [ ] Increment / decrement logic is wired in all bonding event handlers and covered by tests / fixtures consistent with how `Protocol.delegatorsCount` is tested.
- [ ] Backfill is correct from a full resync against historical chain data (sum of all `Transcoder.delegatorCount` equals `Protocol.delegatorsCount`).
- [ ] Field is documented in `schema.graphql` with a comment matching the style of neighbouring fields.

## Motivation / downstream

Unblocks [livepeer/explorer#106](https://github.com/livepeer/explorer/issues/106), which currently has to paginate to compute this count, and unlocks surfacing delegator counts in the orchestrator list view (not viable today because per-orchestrator pagination per row is too expensive).

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 schema.graphql and the existing Protocol.delegatorsCount implementation, then trace the bonding manager event handlers and their related tests or fixtures. Confirm how Bond, Unbond, Rebond, and TransferBond update delegate state, including self-delegation and partial unbond cases. Done means the field is documented, all handlers and tests are updated, and a full historical resync produces matching totals.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, typescript
Domain
backend-api-design, blockchain
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.