GIP-0060: Early allocation closure

GIP: “0060”
Title: Early allocation closure
Authors: Ariel Barmat ariel@edgeandnode.com
Created: 2023-09-25
Updated: 2023-09-25
Stage: Draft
Category: Protocol Change
Dependency: GIP 0051

Abstract

The protocol imposes over indexers a restriction to wait for at least one epoch must pass before they can close allocations. We propose removing it and allowing them to manage allocations as they see more convenient.

Motivation

The protocol relies on a Rebate mechanism to ensure that indexers assign a security deposit in GRT proportional to the amount of queries they serve. Before the Exponential Rebate upgrade, it worked by summing all the query fees collected and stake allocated in one pool per epoch in which allocations are closed. As a consequence, it was essential to ensure that allocations last for at least one epoch to calculate the rebates using the Cobbs-Douglas function.

Coordination issues arises when a subgraph developer publishes a subgraph versions multiple times within the span of an epoch. Indexers would allocate to the first version and won’t be able to unlock their stake for use on the second version until the epoch ends reducing the network flexibity and liveliness. This condition might present more often on the L2 because transactions are cheaper and potentially more frequent.

With the introduction of GIP-0051 the rebate formula is now continuous and the pools were removed which opens the possibility of implementing this proposal.

Specification

The following lines will need to be removed from the closeAllocation() function of the Staking contract.

// Validate that an allocation cannot be closed before one epoch
uint256 epochs = MathUtils.diffOrZero(alloc.closedAtEpoch, alloc.createdAtEpoch);
require(epochs > 0, "<epochs");

The effectiveAllocation parameter that depended on the closedEpochAt variable does not longer exist since the Exponential Rebates upgrade, however, we still store closedEpochAt to mark the allocation as closed.

Indexing Rewards

Indexing rewards could still be collected in this proposal because the calculation is performed at the block number level. However, because presenting a valid POI depends on the Epoch Block Oracle for some chains and indexers won’t have the information after an epoch, we recommend setting the POI=0x0 or enforce a restriction on distributions directly in the code:

Calculate the epoch diff:

uint256 epochsDiff = MathUtils.diffOrZero(alloc.closedAtEpoch, alloc.createdAtEpoch);

And then change the rewards distribution section to:

// Distribute rewards if proof of indexing was presented by the indexer or operator
if (isIndexer && _poi != 0 && epochDiff > 0) {
  _distributeRewards(_allocationID, alloc.indexer);
} else {
  _updateRewards(alloc.subgraphDeploymentID);
}

Backwards Compatibility

The change keeps the current interfaces and is backward compatible. Indexer will be able to close their allocations on the same epoch they opened them immediately after governance approves the upgrade.

Copyright Waiver

Copyright and related rights waived via CC0.

9 Likes

Thanks for putting this together @ari :handshake:

I’m in support of this proposal from the perspective of a typical Indexer that strives to be attentive and wants to support consumers by upgrading to their new subgraph version as soon as possible. It is quite common for an initial subgraph deployment to be upgraded very quickly due to some sort of issue identified after deployment. This can incur significant costs and operational management for an Indexer.

Now that transaction fees are greatly reduced, an Indexer is more likely to keep moving to the latest subgraph version and provide service continuity, whereas in the past they may, in a worst case scenario, just give up serving the subgraph if the deployer upgrades very frequently (because it resulted in significant transaction costs for the Indexer).

I’m in support of this proposal from the perspective of the Consumer that needs prompt service on their updated subgraph.

Does anyone have any more thoughts on whether this opens up any potential for gaming the rewards system? I cannot think of any scenarios off the top of my head, but that would be the one area I’d want to be confident about for this proposal to be considered.

7 Likes

This could prove to be extremely useful, especially in a situation when new subgraphs are released, subgraphs version gets updated the next minute, resulting in allocations getting stuck in the deprecated version of the subgraph until the next epoch.

As of now, I couldn’t identify any potential opportunities for rewards to be gamified.

3 Likes

An initial implementation of this GIP can be found here: feat: remove minimum allocation duration restriction by tmigone · Pull Request #902 · graphprotocol/contracts · GitHub

One thing worth noting: in accordance with the GIP this implementation will not distribute rewards when an allocation that is less than 1 epoch old is closed, even if the POI presented is valid. There are some edge cases where this could happen with subgraphs indexing Ethereum mainnet or Arbitrum One, however for simplicity and consistency we won’t be distributing rewards in this case.

For clarity, in order to get rewards the conditions that have to be met are:

  • the indexer or operator is closing the allocation
  • a valid POI is presented when closing the allocation
  • the allocation is at least 1 epoch old (i.e startEpoch < endEpoch)
4 Likes

Thanks for putting this together

2 Likes