diff --git a/packages/indexer-agent/src/agent.ts b/packages/indexer-agent/src/agent.ts index 517f75e03..70f896ad1 100644 --- a/packages/indexer-agent/src/agent.ts +++ b/packages/indexer-agent/src/agent.ts @@ -567,6 +567,34 @@ export class Agent { }, ) + const deploymentTags: Eventual> = join({ + ticker: timer(60_000), + indexingRules, + }).tryMap( + async ({ indexingRules }) => { + logger.trace('Resolving deployment tags') + const deploymentTags: Map = new Map() + + // Add offchain subgraphs to the deployment list from rules + Object.values(indexingRules) + .flat() + .filter(rule => rule?.identifier !== 'global') + .forEach(rule => { + deploymentTags.set( + new SubgraphDeploymentID(rule.identifier).toString(), + rule.tag, + ) + }) + return new Map(deploymentTags) + }, + { + onError: error => + logger.warn(`Failed to resolve deployment tags, trying again later`, { + error, + }), + }, + ) + const activeAllocations: Eventual> = timer( 120_000, ).tryMap( @@ -708,10 +736,12 @@ export class Agent { switch (this.deploymentManagement) { case DeploymentManagementMode.AUTO: try { + const resolvedDeploymentTags = await deploymentTags.value() await this.reconcileDeployments( activeDeployments, targetDeployments, eligibleAllocations, + resolvedDeploymentTags, ) } catch (err) { logger.warn( @@ -904,6 +934,7 @@ export class Agent { activeDeployments: SubgraphDeploymentID[], targetDeployments: SubgraphDeploymentID[], eligibleAllocations: Allocation[], + deploymentTags: Map, ): Promise { const logger = this.logger.child({ function: 'reconcileDeployments' }) logger.debug('Reconcile deployments') @@ -974,7 +1005,9 @@ export class Agent { // Index all new deployments worth indexing await queue.addAll( deploy.map(deployment => async () => { - const name = `indexer-agent/${deployment.ipfsHash.slice(-10)}` + const name = `${ + deploymentTags.get(deployment.toString()) || 'indexer-agent' + }/${deployment.ipfsHash.slice(-10)}` logger.info(`Index subgraph deployment`, { name, diff --git a/packages/indexer-agent/src/db/migrations/14-indexing-rules-add-deployment-tag.ts b/packages/indexer-agent/src/db/migrations/14-indexing-rules-add-deployment-tag.ts new file mode 100644 index 000000000..213fb9e7d --- /dev/null +++ b/packages/indexer-agent/src/db/migrations/14-indexing-rules-add-deployment-tag.ts @@ -0,0 +1,53 @@ +import { Logger } from '@graphprotocol/common-ts' +import { DataTypes, QueryInterface } from 'sequelize' + +interface MigrationContext { + queryInterface: QueryInterface + logger: Logger +} + +interface Context { + context: MigrationContext +} + +export async function up({ context }: Context): Promise { + const { queryInterface, logger } = context + + logger.debug(`Checking if indexing rules table exists`) + const tables = await queryInterface.showAllTables() + if (!tables.includes('IndexingRules')) { + logger.info(`Indexing rules table does not exist, migration not necessary`) + return + } + + logger.debug(`Checking if 'IndexingRules' table needs to be migrated`) + const table = await queryInterface.describeTable('IndexingRules') + const subgraphTagColumn = table.tag + if (subgraphTagColumn) { + logger.info(`'tag' column already exists, migration not necessary`) + return + } + + logger.info(`Add 'tag' column to 'IndexingRules' table`) + await queryInterface.addColumn('IndexingRules', 'tag', { + type: DataTypes.STRING, + primaryKey: false, + allowNull: false, + defaultValue: 'indexer-agent', + }) +} + +export async function down({ context }: Context): Promise { + const { queryInterface, logger } = context + + return await queryInterface.sequelize.transaction({}, async transaction => { + const tables = await queryInterface.showAllTables() + + if (tables.includes('IndexingRules')) { + logger.info(`Remove 'tag' column`) + await context.queryInterface.removeColumn('IndexingRules', 'tag', { + transaction, + }) + } + }) +} diff --git a/packages/indexer-cli/src/rules.ts b/packages/indexer-cli/src/rules.ts index e50027849..12526bfc3 100644 --- a/packages/indexer-cli/src/rules.ts +++ b/packages/indexer-cli/src/rules.ts @@ -37,6 +37,7 @@ const INDEXING_RULE_PARSERS: Record requireSupported: x => parseBoolean(x), safety: x => parseBoolean(x), protocolNetwork: x => x, + tag: x => x, } const INDEXING_RULE_FORMATTERS: Record< @@ -61,6 +62,7 @@ const INDEXING_RULE_FORMATTERS: Record< requireSupported: x => x, safety: x => x, protocolNetwork: resolveChainAlias, + tag: x => x, } const INDEXING_RULE_CONVERTERS_FROM_GRAPHQL: Record< @@ -85,6 +87,7 @@ const INDEXING_RULE_CONVERTERS_FROM_GRAPHQL: Record< requireSupported: x => x, safety: x => x, protocolNetwork: x => x, + tag: x => x, } const INDEXING_RULE_CONVERTERS_TO_GRAPHQL: Record< @@ -109,6 +112,7 @@ const INDEXING_RULE_CONVERTERS_TO_GRAPHQL: Record< requireSupported: x => x, safety: x => x, protocolNetwork: x => x, + tag: x => x, } /** @@ -267,6 +271,7 @@ export const indexingRules = async ( decisionBasis requireSupported safety + tag } } `, @@ -307,6 +312,7 @@ export const indexingRule = async ( requireSupported safety protocolNetwork + tag } } `, @@ -350,6 +356,7 @@ export const setIndexingRule = async ( requireSupported safety protocolNetwork + tag } } `, diff --git a/packages/indexer-common/src/indexer-management/__tests__/resolvers/indexing-rules.test.ts b/packages/indexer-common/src/indexer-management/__tests__/resolvers/indexing-rules.test.ts index 930bc1523..4023381eb 100644 --- a/packages/indexer-common/src/indexer-management/__tests__/resolvers/indexing-rules.test.ts +++ b/packages/indexer-common/src/indexer-management/__tests__/resolvers/indexing-rules.test.ts @@ -45,6 +45,7 @@ const SET_INDEXING_RULE_MUTATION = gql` requireSupported safety protocolNetwork + tag } } ` diff --git a/packages/indexer-common/src/indexer-management/__tests__/util.ts b/packages/indexer-common/src/indexer-management/__tests__/util.ts index 1e08341dd..2a8628119 100644 --- a/packages/indexer-common/src/indexer-management/__tests__/util.ts +++ b/packages/indexer-common/src/indexer-management/__tests__/util.ts @@ -101,6 +101,7 @@ export const createTestManagementClient = async ( requireSupported: true, safety: true, protocolNetwork: 'sepolia', + tag: 'indexer-agent', }, } @@ -137,6 +138,7 @@ export const defaults: IndexerManagementDefaults = { parallelAllocations: 1, requireSupported: true, safety: true, + tag: 'indexer-agent', }, } diff --git a/packages/indexer-common/src/indexer-management/client.ts b/packages/indexer-common/src/indexer-management/client.ts index 648dea8cc..5d39b8869 100644 --- a/packages/indexer-common/src/indexer-management/client.ts +++ b/packages/indexer-common/src/indexer-management/client.ts @@ -263,6 +263,7 @@ const SCHEMA_SDL = gql` requireSupported: Boolean! safety: Boolean! protocolNetwork: String! + tag: String } input IndexingRuleInput { @@ -282,6 +283,7 @@ const SCHEMA_SDL = gql` requireSupported: Boolean safety: Boolean protocolNetwork: String! + tag: String } input IndexingRuleIdentifier { diff --git a/packages/indexer-common/src/indexer-management/models/indexing-rule.ts b/packages/indexer-common/src/indexer-management/models/indexing-rule.ts index 76ee2b265..48cba049b 100644 --- a/packages/indexer-common/src/indexer-management/models/indexing-rule.ts +++ b/packages/indexer-common/src/indexer-management/models/indexing-rule.ts @@ -31,6 +31,7 @@ export interface IndexingRuleAttributes { requireSupported: boolean safety: boolean protocolNetwork: string + tag: string } // Unambiguously identify a Indexing Rule in the Database. @@ -60,6 +61,7 @@ export interface IndexingRuleCreationAttributes | 'requireSupported' | 'safety' | 'protocolNetwork' + | 'tag' > {} export class IndexingRule @@ -83,6 +85,7 @@ export class IndexingRule public requireSupported!: boolean public safety!: boolean public protocolNetwork!: string + public tag!: string public createdAt!: Date public updatedAt!: Date @@ -267,6 +270,12 @@ export const defineIndexingRuleModels = (sequelize: Sequelize): IndexingRuleMode is: caip2IdRegex, }, }, + tag: { + type: DataTypes.STRING, + primaryKey: false, + allowNull: false, + defaultValue: 'indexer-agent', + }, }, { modelName: 'IndexingRule', diff --git a/packages/indexer-common/src/operator.ts b/packages/indexer-common/src/operator.ts index 1d97904c4..dde4f39a5 100644 --- a/packages/indexer-common/src/operator.ts +++ b/packages/indexer-common/src/operator.ts @@ -109,6 +109,7 @@ export class Operator { decisionBasis requireSupported protocolNetwork + tag } } `, diff --git a/packages/indexer-common/src/rules.ts b/packages/indexer-common/src/rules.ts index e03bfd40e..eabe3ec14 100644 --- a/packages/indexer-common/src/rules.ts +++ b/packages/indexer-common/src/rules.ts @@ -36,6 +36,7 @@ const INDEXING_RULE_READABLE_TO_MODEL_PARSERS: Record< requireSupported: (x) => parseBoolean(x), safety: (x) => parseBoolean(x), protocolNetwork: (x: string) => validateNetworkIdentifier(x), + tag: (x: string) => x, } export const parseIndexingRule = (