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). 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
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
Motivation / downstream
Unblocks livepeer/explorer#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).
Problem
The
Transcoderentity exposes itsdelegatorsonly as a@derivedFromcollection. To learn how many unique delegators an orchestrator has, a client must paginate theDelegatorentity (where: { delegate: $orchestrator }) using keyset pagination onid, because The Graph capsfirst: 1000andskip: 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). It also makes the per-orchestrator count an O(N/1000) operation client-side instead of a single field read.Protocol,Round, andDayalready exposedelegatorsCount: BigInt!—Transcoderis the obvious gap.Proposal
Add a
delegatorCountfield to theTranscoderentity and maintain it in the bonding-related event handlers.Schema change
Mapping logic
Increment / decrement
transcoder.delegatorCountin the bonding manager event handlers, mirroring the patterns already used forProtocol.delegatorsCount:delegatorCount; if switching, decrement the old delegate'sdelegatorCount.bondedAmount): decrement the delegate'sdelegatorCount.Edge cases to confirm
delegatorsderives today, since the transcoder also has aDelegatorentity for itself). Document this in the field comment.bondedAmount > 0must not decrement.Acceptance criteria
Transcoder.delegatorCount: BigInt!exists inschema.graphql.Protocol.delegatorsCountis tested.Transcoder.delegatorCountequalsProtocol.delegatorsCount).schema.graphqlwith a comment matching the style of neighbouring fields.Motivation / downstream
Unblocks livepeer/explorer#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).