Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: Add support for local querying of Epoch and TAP subgraphs #1063

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions docs/networks/arbitrum-one.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,19 @@ Other network contracts can be found in [graphprotocol/contracts](https://github
### Indexer Agent

| Environment Variable | CLI Argument | Value |
| ------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|---------------------------------------------|---------------------------------| ------------------------------------------------------------------------------------------------------------------------- |
| `INDEXER_AGENT_ETHEREUM` | `--ethereum` | An Arbitrum mainnet node/provider |
| `INDEXER_AGENT_INDEXER_ADDRESS` | `--indexer-address` | Ethereum address of mainnet indexer |
| `INDEXER_AGENT_INDEXER_GEO_COORDINATES` | `--indexer-geo-coordinates` | Geo coordinates of mainnet indexer infrastructure |
| `INDEXER_AGENT_MNEMONIC` | `--mnemonic` | Ethereum mnemonic for mainnet operator |
| `INDEXER_AGENT_NETWORK_SUBGRAPH_DEPLOYMENT` | `--network-subgraph-deployment` | [![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fthegraph.com%2Fexplorer%2F_next%2Fdata%2F5PBypsdmUEy39BcWLsyp0%2Fsubgraphs%2FDZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp.json%3Fview%3DAbout%26chain%3Darbitrum-one%26id%3DDZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp&query=%24.pageProps.subgraph.currentVersion.subgraphDeployment.ipfsHash&label=deployment-id)](https://thegraph.com/explorer/subgraphs/DZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp) |
| `INDEXER_AGENT_NETWORK_SUBGRAPH_ENDPOINT` | `--network-subgraph-endpoint` | `https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/DZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp` |
| `INDEXER_AGENT_GATEWAY_ENDPOINT` | `--gateway-endpoint` | `https://gateway-arbitrum.network.thegraph.com/` |
| `INDEXER_AGENT_GAS_PRICE_MAX` | `--gas-price-max` | `50` |
| `INDEXER_AGENT_NETWORK_SUBGRAPH_DEPLOYMENT` | `--network-subgraph-deployment` | [![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fthegraph.com%2Fexplorer%2F_next%2Fdata%2F5PBypsdmUEy39BcWLsyp0%2Fsubgraphs%2FDZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp.json%3Fview%3DAbout%26chain%3Darbitrum-one%26id%3DDZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp&query=%24.pageProps.subgraph.currentVersion.subgraphDeployment.ipfsHash&label=deployment-id)](https://thegraph.com/explorer/subgraphs/DZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp) |
| `INDEXER_AGENT_NETWORK_SUBGRAPH_ENDPOINT` | `--network-subgraph-endpoint` | `https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/DZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp` |
| `INDEXER_AGENT_EPOCH_SUBGRAPH_DEPLOYMENT` | `--epoch-subgraph-deployment` | [![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fthegraph.com%2Fexplorer%2F_next%2Fdata%2F5PBypsdmUEy39BcWLsyp0%2Fsubgraphs%2F4KFYqUWRTZQ9gn7GPHC6YQ2q15chJfVrX43ezYcwkgxB.json%3Fview%3DAbout%26chain%3Darbitrum-one%26id%3D4KFYqUWRTZQ9gn7GPHC6YQ2q15chJfVrX43ezYcwkgxB&query=%24.pageProps.subgraph.currentVersion.subgraphDeployment.ipfsHash&label=deployment-id)](https://thegraph.com/explorer/subgraphs/4KFYqUWRTZQ9gn7GPHC6YQ2q15chJfVrX43ezYcwkgxB) |
| `INDEXER_AGENT_EPOCH_SUBGRAPH_ENDPOINT` | `--epoch-subgraph-endpoint` | `https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/4KFYqUWRTZQ9gn7GPHC6YQ2q15chJfVrX43ezYcwkgxB` |
| `INDEXER_AGENT_TAP_SUBGRAPH_ENDPOINT` | `--tap-subgraph-endpoint` | `https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/4sukbNVTzGELnhdnpyPqsf1QqtzNHEYKKmJkgaT8z6M1` |
| `INDEXER_AGENT_TAP_SUBGRAPH_DEPLOYMENT` | `--tap-subgraph-deployment` | [![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fthegraph.com%2Fexplorer%2F_next%2Fdata%2F5PBypsdmUEy39BcWLsyp0%2Fsubgraphs%2F4sukbNVTzGELnhdnpyPqsf1QqtzNHEYKKmJkgaT8z6M1.json%3Fview%3DAbout%26chain%3Darbitrum-one%26id%3D4sukbNVTzGELnhdnpyPqsf1QqtzNHEYKKmJkgaT8z6M1&query=%24.pageProps.subgraph.currentVersion.subgraphDeployment.ipfsHash&label=deployment-id)](https://thegraph.com/explorer/subgraphs/4sukbNVTzGELnhdnpyPqsf1QqtzNHEYKKmJkgaT8z6M1) |
| `INDEXER_AGENT_TAP_SUBGRAPH_ENDPOINT` | `--tap-subgraph-endpoint` | `https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/4sukbNVTzGELnhdnpyPqsf1QqtzNHEYKKmJkgaT8z6M1` |


In order to avoid collecting or claiming query fees below a certain threshold
Expand Down
6 changes: 4 additions & 2 deletions docs/networks/arbitrum-sepolia.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,17 @@ testnet (for now) are Mainnet subgraphs. This means:
### Indexer Agent

| Environment Variable | CLI Argument | Value |
| ------------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|---------------------------------------------|---------------------------------| ----------------------------------------------------------------------------------------------------------------------- |
| `INDEXER_AGENT_ETHEREUM` | `--ethereum` | An Arbitrum Sepolia node/provider |
| `INDEXER_AGENT_INDEXER_ADDRESS` | `--indexer-address` | Ethereum address of testnet indexer |
| `INDEXER_AGENT_INDEXER_GEO_COORDINATES` | `--indexer-geo-coordinates` | Geo coordinates of testnet indexer infrastructure |
| `INDEXER_AGENT_MNEMONIC` | `--mnemonic` | Ethereum mnemonic for testnet operator |
| `INDEXER_AGENT_GATEWAY_ENDPOINT` | `--gateway-endpoint` | `https://gateway-arbitrum.testnet.thegraph.com/` |
| `INDEXER_AGENT_NETWORK_SUBGRAPH_DEPLOYMENT` | `--network-subgraph-deployment` | `QmXnGVrg6DvscnvJd86aHAPLGyGrkM17weMrAsFAEMmQLL` |
| `INDEXER_AGENT_NETWORK_SUBGRAPH_ENDPOINT` | `--network-subgraph-endpoint` | `https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/3xQHhMudr1oh69ut36G2mbzpYmYxwqCeU6wwqyCDCnqV` |
| `INDEXER_AGENT_GATEWAY_ENDPOINT` | `--gateway-endpoint` | `https://gateway-arbitrum.testnet.thegraph.com/` |
| `INDEXER_AGENT_EPOCH_SUBGRAPH_DEPLOYMENT` | `--epoch-subgraph-deployment` | `QmNNn48AU8CZei8sYLXrXABMHkiXAuQDvFaZHYYPryKEvF` |
| `INDEXER_AGENT_EPOCH_SUBGRAPH_ENDPOINT` | `--epoch-subgraph-endpoint` | `https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/BhnsdeZihU4SuokxZMLF4FQBVJ3jgtZf6v51gHvz3bSS` |
| `INDEXER_AGENT_TAP_SUBGRAPH_DEPLOYMENT` | `--tap-subgraph-deployment` | `QmUiLdbsk6c51UMdcNBxsP3KadJpkmp6a3k2NCprR4ZFeM` |
| `INDEXER_AGENT_TAP_SUBGRAPH_ENDPOINT` | `--tap-subgraph-endpoint` | `https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/7ubx365MiqBH5iUz6XWXWT8PTof5BVAyEzdb8m17RvbD` |

In order to avoid collecting or claiming query fees below a certain threshold
Expand Down
78 changes: 48 additions & 30 deletions packages/indexer-agent/src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ export class Agent {
async ({ network, operator }: NetworkAndOperator) => {
try {
await operator.ensureGlobalIndexingRule()
await this.ensureNetworkSubgraphIsIndexing(network)
await this.ensureAllSubgraphsIndexing(network)
await network.register()
} catch (err) {
this.logger.critical(
Expand Down Expand Up @@ -1241,38 +1241,56 @@ export class Agent {
)
}

// TODO: This could be a initialization check inside Network.create() once/if the Indexer Service
// uses Network instances.
async ensureNetworkSubgraphIsIndexing(network: Network) {
// TODO: After indexer-service deprecation: Move to be an initialization check inside Network.create()
async ensureSubgraphIndexing(deployment: string, networkIdentifier: string) {
try {
// TODO: Check both the local deployment and the external subgraph endpoint
// Make sure the subgraph is being indexed
await this.graphNode.ensure(
`indexer-agent/${deployment.slice(-10)}`,
new SubgraphDeploymentID(deployment),
)

// Validate if the Network Subgraph belongs to the current provider's network.
// This check must be performed after we ensure the Network Subgraph is being indexed.
await validateProviderNetworkIdentifier(
networkIdentifier,
deployment,
this.graphNode,
this.logger,
)
} catch (e) {
this.logger.warn(
'Failed to deploy and validate Network Subgraph on index-nodes. Will use external subgraph endpoint instead',
e,
)
}
}
async ensureAllSubgraphsIndexing(network: Network) {
// Network subgraph
if (
network.specification.subgraphs.networkSubgraph.deployment !== undefined
) {
try {
// TODO: Check both the local deployment and the external subgraph endpoint
// Make sure the network subgraph is being indexed
await this.graphNode.ensure(
`indexer-agent/${network.specification.subgraphs.networkSubgraph.deployment.slice(
-10,
)}`,
new SubgraphDeploymentID(
network.specification.subgraphs.networkSubgraph.deployment,
),
)

// Validate if the Network Subgraph belongs to the current provider's network.
// This check must be performed after we ensure the Network Subgraph is being indexed.
await validateProviderNetworkIdentifier(
network.specification.networkIdentifier,
network.specification.subgraphs.networkSubgraph.deployment,
this.graphNode,
this.logger,
)
} catch (e) {
this.logger.warn(
'Failed to deploy and validate Network Subgraph on index-nodes. Will use external subgraph endpoint instead',
e,
)
}
await this.ensureSubgraphIndexing(
network.specification.subgraphs.networkSubgraph.deployment,
network.specification.networkIdentifier,
)
}
// Epoch subgraph
if (
network.specification.subgraphs.epochSubgraph.deployment !== undefined
) {
await this.ensureSubgraphIndexing(
network.specification.subgraphs.epochSubgraph.deployment,
network.specification.networkIdentifier,
)
}
// TAP subgraph
if (network.specification.subgraphs.tapSubgraph?.deployment !== undefined) {
await this.ensureSubgraphIndexing(
network.specification.subgraphs.tapSubgraph.deployment,
network.specification.networkIdentifier,
)
}
}
}
Expand Down
18 changes: 15 additions & 3 deletions packages/indexer-agent/src/commands/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export const start = {
},
})
.option('network-subgraph-deployment', {
description: 'Network subgraph deployment',
description: 'Network subgraph deployment (for local hosting)',
array: false,
type: 'string',
group: 'Network Subgraph',
Expand All @@ -151,6 +151,12 @@ export const start = {
type: 'string',
group: 'Network Subgraph',
})
.option('tap-subgraph-deployment', {
description: 'TAP subgraph deployment (for local hosting)',
array: false,
type: 'string',
group: 'TAP Subgraph',
})
.option('tap-subgraph-endpoint', {
description: 'Endpoint to query the tap subgraph from',
array: false,
Expand All @@ -163,6 +169,12 @@ export const start = {
default: false,
group: 'Network Subgraph',
})
.option('epoch-subgraph-deployment', {
description: 'Epoch subgraph deployment (for local hosting)',
array: false,
type: 'string',
group: 'Network Subgraph',
})
.option('epoch-subgraph-endpoint', {
description: 'Endpoint to query the epoch block oracle subgraph from',
array: false,
Expand Down Expand Up @@ -370,11 +382,11 @@ export async function createNetworkSpecification(
url: argv.networkSubgraphEndpoint,
},
epochSubgraph: {
// TODO: We should consider indexing the Epoch Subgraph, similar
// to how we currently do it for the Network Subgraph.
deployment: argv.epochSubgraphDeployment,
url: argv.epochSubgraphEndpoint,
},
tapSubgraph: {
deployment: argv.tapSubgraphDeployment,
url: argv.tapSubgraphEndpoint,
},
}
Expand Down
4 changes: 2 additions & 2 deletions packages/indexer-agent/src/syncing-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import { Logger } from '@graphprotocol/common-ts'
import { parse } from 'graphql'
import {
NetworkMapped,
NetworkSubgraph,
SubgraphClient,
resolveChainId,
} from '@graphprotocol/indexer-common'

export interface CreateSyncingServerOptions {
logger: Logger
networkSubgraphs: NetworkMapped<NetworkSubgraph>
networkSubgraphs: NetworkMapped<SubgraphClient>
port: number
}

Expand Down
2 changes: 1 addition & 1 deletion packages/indexer-common/src/__tests__/subgraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ProviderInterface,
SubgraphQueryInterface,
} from '../subgraphs'
import { QueryResult } from '../network-subgraph'
import { QueryResult } from '../subgraph-client'
import gql from 'graphql-tag'
import { mergeSelectionSets } from '../utils'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Address, Eventual, createLogger, createMetrics } from '@graphprotocol/c
import {
Allocation,
AllocationsResponse,
NetworkSubgraph,
SubgraphClient,
QueryFeeModels,
QueryResult,
TapCollector,
Expand All @@ -11,7 +11,6 @@ import {
TransactionManager,
} from '@graphprotocol/indexer-common'
import { NetworkContracts as TapContracts } from '@semiotic-labs/tap-contracts-bindings'
import { TAPSubgraph } from '../../tap-subgraph'
import { NetworkSpecification } from 'indexer-common/src/network-specification'
import { createMockAllocation } from '../../indexer-management/__tests__/helpers.test'
import { getContractAddress } from 'ethers/lib/utils'
Expand Down Expand Up @@ -155,10 +154,10 @@ const setup = () => {

const tapSubgraph = {
query: mockQueryTapSubgraph,
} as unknown as TAPSubgraph
} as unknown as SubgraphClient
const networkSubgraph = {
query: mockQueryNetworkSubgraph,
} as unknown as NetworkSubgraph
} as unknown as SubgraphClient

tapCollector = TapCollector.create({
logger,
Expand Down
4 changes: 2 additions & 2 deletions packages/indexer-common/src/allocations/escrow-accounts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Address, toAddress } from '@graphprotocol/common-ts'
import { TAPSubgraph } from '../tap-subgraph'
import { SubgraphClient } from '../subgraph-client'
import gql from 'graphql-tag'

type U256 = bigint
Expand Down Expand Up @@ -44,7 +44,7 @@ export class EscrowAccounts {
}

export const getEscrowAccounts = async (
tapSubgraph: TAPSubgraph,
tapSubgraph: SubgraphClient,
indexer: Address,
): Promise<EscrowAccounts> => {
const result = await tapSubgraph.query<EscrowAccountResponse>(
Expand Down
6 changes: 3 additions & 3 deletions packages/indexer-common/src/allocations/query-fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ import {
ensureAllocationSummary,
TransactionManager,
specification as spec,
SubgraphClient,
} from '..'
import { DHeap } from '@thi.ng/heaps'
import { BigNumber, BigNumberish, Contract } from 'ethers'
import { Op } from 'sequelize'
import pReduce from 'p-reduce'
import { NetworkSubgraph } from '../network-subgraph'

// Receipts are collected with a delay of 20 minutes after
// the corresponding allocation was closed
Expand Down Expand Up @@ -71,7 +71,7 @@ export interface AllocationReceiptCollectorOptions {
allocations: Eventual<Allocation[]>
models: QueryFeeModels
networkSpecification: spec.NetworkSpecification
networkSubgraph: NetworkSubgraph
networkSubgraph: SubgraphClient
}

export interface ReceiptCollector {
Expand All @@ -94,7 +94,7 @@ export class AllocationReceiptCollector implements ReceiptCollector {
declare voucherRedemptionBatchThreshold: BigNumber
declare voucherRedemptionMaxBatchSize: number
declare protocolNetwork: string
declare networkSubgraph: NetworkSubgraph
declare networkSubgraph: SubgraphClient

// eslint-disable-next-line @typescript-eslint/no-empty-function -- Private constructor to prevent direct instantiation
private constructor() {}
Expand Down
11 changes: 5 additions & 6 deletions packages/indexer-common/src/allocations/tap-collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import {
} from '..'
import { BigNumber } from 'ethers'
import pReduce from 'p-reduce'
import { TAPSubgraph } from '../tap-subgraph'
import { NetworkSubgraph, QueryResult } from '../network-subgraph'
import { SubgraphClient, QueryResult } from '../subgraph-client'
import gql from 'graphql-tag'
import { getEscrowAccounts } from './escrow-accounts'

Expand All @@ -52,8 +51,8 @@ interface TapCollectorOptions {
allocations: Eventual<Allocation[]>
models: QueryFeeModels
networkSpecification: spec.NetworkSpecification
tapSubgraph: TAPSubgraph
networkSubgraph: NetworkSubgraph
tapSubgraph: SubgraphClient
networkSubgraph: SubgraphClient
}

interface ValidRavs {
Expand Down Expand Up @@ -107,8 +106,8 @@ export class TapCollector {
declare allocations: Eventual<Allocation[]>
declare ravRedemptionThreshold: BigNumber
declare protocolNetwork: string
declare tapSubgraph: TAPSubgraph
declare networkSubgraph: NetworkSubgraph
declare tapSubgraph: SubgraphClient
declare networkSubgraph: SubgraphClient
declare finalityTime: number
declare indexerAddress: Address

Expand Down
4 changes: 2 additions & 2 deletions packages/indexer-common/src/allocations/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BigNumber } from 'ethers'
import { NetworkSubgraph, SubgraphDeployment } from '@graphprotocol/indexer-common'
import { SubgraphClient, SubgraphDeployment } from '@graphprotocol/indexer-common'

import { Logger, Address } from '@graphprotocol/common-ts'

Expand Down Expand Up @@ -31,7 +31,7 @@ export enum AllocationStatus {
export interface MonitorEligibleAllocationsOptions {
indexer: Address
logger: Logger
networkSubgraph: NetworkSubgraph
networkSubgraph: SubgraphClient
interval: number
protocolNetwork: string
}
Loading
Loading