diff --git a/packages/indexer-common/src/errors.ts b/packages/indexer-common/src/errors.ts index 0b1c0ddbd..56b4c18b2 100644 --- a/packages/indexer-common/src/errors.ts +++ b/packages/indexer-common/src/errors.ts @@ -100,6 +100,7 @@ export enum IndexerErrorCode { IE087 = 'IE087', IE088 = 'IE088', IE089 = 'IE089', + IE090 = 'IE090', } export const INDEXER_ERROR_MESSAGES: Record = { @@ -193,6 +194,7 @@ export const INDEXER_ERROR_MESSAGES: Record = { IE087: 'Failed to resize allocation', IE088: 'Failed to present POI', IE089: 'Failed to collect indexing rewards', + IE090: 'Failed to reallocate: indexer is overallocated', } export type IndexerErrorCause = unknown diff --git a/packages/indexer-common/src/indexer-management/allocations.ts b/packages/indexer-common/src/indexer-management/allocations.ts index 344e0cc42..f30356861 100644 --- a/packages/indexer-common/src/indexer-management/allocations.ts +++ b/packages/indexer-common/src/indexer-management/allocations.ts @@ -2123,6 +2123,39 @@ export class AllocationManager { } } } else { + // Check if indexer is over-allocated - if so, collect() will auto-close the allocation + // and new allocations won't be able to be created until the condition is cleared. + // In this case indexer should manually remediate the issue. + const isOverAllocated = + await this.network.contracts.SubgraphService.isOverAllocated(params.indexer) + + logger.debug('Checking over-allocation status for reallocate allocation', { + allocationId: params.closingAllocationID, + isOverAllocated, + }) + + if (isOverAllocated) { + const allocatedTokens = + await this.network.contracts.SubgraphService.allocationProvisionTracker( + params.indexer, + ) + const delegationRatio = + await this.network.contracts.SubgraphService.getDelegationRatio() + const tokensAvailable = + await this.network.contracts.HorizonStaking.getTokensAvailable( + params.indexer, + this.network.contracts.SubgraphService.target, + delegationRatio, + ) + const overallocatedAmount = allocatedTokens - tokensAvailable + throw indexerError( + IndexerErrorCode.IE090, + `Overallocated by ${formatGRT( + overallocatedAmount, + )} GRT, please manually unallocate that amount.`, + ) + } + // Horizon: Need to multicall collect and stopService // collect diff --git a/packages/indexer-common/src/indexer-management/resolvers/allocations.ts b/packages/indexer-common/src/indexer-management/resolvers/allocations.ts index b35e81cc5..6108d8d82 100644 --- a/packages/indexer-common/src/indexer-management/resolvers/allocations.ts +++ b/packages/indexer-common/src/indexer-management/resolvers/allocations.ts @@ -1207,6 +1207,34 @@ async function reallocateHorizonAllocation( epoch: currentEpoch.toString(), }) + // Check if indexer is over-allocated - if so, collect() will auto-close the allocation + // and new allocations won't be able to be created until the condition is cleared. + // In this case indexer should manually remediate the issue. + const isOverAllocated = await contracts.SubgraphService.isOverAllocated(address) + + logger.debug('Checking over-allocation status for reallocate allocation', { + allocationId: allocation.id, + isOverAllocated, + }) + + if (isOverAllocated) { + const allocatedTokens = + await contracts.SubgraphService.allocationProvisionTracker(address) + const delegationRatio = await contracts.SubgraphService.getDelegationRatio() + const tokensAvailable = await contracts.HorizonStaking.getTokensAvailable( + address, + contracts.SubgraphService.target, + delegationRatio, + ) + const overallocatedAmount = allocatedTokens - tokensAvailable + throw indexerError( + IndexerErrorCode.IE090, + `Overallocated by ${formatGRT( + overallocatedAmount, + )} GRT, please manually unallocate that amount.`, + ) + } + // Identify how many GRT the indexer has staked const freeStake = (await network.networkMonitor.freeStake()).horizon