Skip to content
Merged
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
14 changes: 14 additions & 0 deletions docs/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -873,3 +873,17 @@ Failed to query BlockHashFromNumber from graph node
**Solution**

Graph-node could not find the block hash given network and block number, check if graph-node has access to a network client that has synced to the required block.

## IE071

**Summary**

Epoch subgraph required for subgraphs indexing networks in which rpc is unprovided to the indexer agent

**Description**

This is a sub-error of `IE069`. It is reported when the indexer agent doesn't have access to an epoch subgraph endpoint to identify the epoch start block for chains other than the settlement network as indicated by start-up option `--ethereum-network`.

**Solution**

Please provide a `epoch-subgraph-endpoint` and make sure graph node has consistent network configurations (`mainnet`, `goerli`, `gnosis`) and is on or after version 0.28.0.
18 changes: 0 additions & 18 deletions packages/indexer-common/src/allocations/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { IndexingStatusResolver } from '@graphprotocol/indexer-common'
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */

import { Address, SubgraphDeploymentID, toAddress } from '@graphprotocol/common-ts'
import { BigNumber } from 'ethers'

Expand Down Expand Up @@ -197,18 +194,3 @@ export const alias = (identifier: string): string => {
throw new Error(`Failed to match chain ids to a network alias`)
}
}
/* eslint-disable @typescript-eslint/no-explicit-any */
export const buildEpochBlock = async (
status: IndexingStatusResolver,
block: any,
): Promise<NetworkEpochBlock> => {
return {
network: block.network.id,
epochNumber: +block.epochNumber,
startBlockNumber: +block.blockNumber,
startBlockHash: await status.blockHashFromNumber(
alias(block.network.id),
+block.blockNumber,
),
}
}
4 changes: 3 additions & 1 deletion packages/indexer-common/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export enum IndexerErrorCode {
IE068 = 'IE068',
IE069 = 'IE069',
IE070 = 'IE070',
IE071 = 'IE071',
}

export const INDEXER_ERROR_MESSAGES: Record<IndexerErrorCode, string> = {
Expand Down Expand Up @@ -154,7 +155,8 @@ export const INDEXER_ERROR_MESSAGES: Record<IndexerErrorCode, string> = {
IE067: 'Failed to query POI for current epoch start block',
IE068: 'User-provided POI did not match reference POI from graph-node',
IE069: 'Failed to query Epoch Block Oracle Subgraph',
IE070: 'Failed to query BlockHashFromNumber from graph-node',
IE070: 'Failed to query latest valid epoch and block hash',
IE071: 'Add Epoch subgraph support for non-protocol chains',
}

export type IndexerErrorCause = unknown
Expand Down
86 changes: 49 additions & 37 deletions packages/indexer-common/src/indexer-management/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
NetworkEpochBlock,
EpochSubgraph,
BlockPointer,
buildEpochBlock,
alias,
} from '@graphprotocol/indexer-common'
import {
Expand Down Expand Up @@ -576,9 +575,12 @@ export class NetworkMonitor {
if (network == this.networkAlias) {
return await this.epochManagerCurrentStartBlock(network)
}
this.logger.error(`Epoch start block not available for the network`, {
networkName: alias(network),
})
throw indexerError(
IndexerErrorCode.IE069,
`Epoch subgraph not available for indexed chains`,
IndexerErrorCode.IE071,
`Epoch start block not available for network: ${alias(network)}`,
)
}
try {
Expand Down Expand Up @@ -613,29 +615,37 @@ export class NetworkMonitor {
}

if (!result.data.network || !result.data.network.latestValidBlockNumber) {
throw indexerError(
IndexerErrorCode.IE069,
`Failed to query latest valid epoch number for ${network}`,
)
throw new Error(`Failed to query EBO for ${network}'s latest valid epoch number`)
}

const epochBlock = await buildEpochBlock(
this.indexingStatusResolver,
// Check for validity with epoch manager currentEpoch, and fetch block hash
const validBlock =
result.data.network.latestValidBlockNumber.epochNumber ==
(await this.currentEpoch())
(await this.currentEpoch())
? result.data.network.latestValidBlockNumber
: result.data.network.latestValidBlockNumber.previousBlockNumber,
: result.data.network.latestValidBlockNumber.previousBlockNumber
const startBlockHash = await this.indexingStatusResolver.blockHashFromNumber(
alias(network),
validBlock.startBlockNumber,
)

return epochBlock
return {
network,
epochNumber: +validBlock.epochNumber,
startBlockNumber: +validBlock.blockNumber,
startBlockHash,
}
} catch (err) {
this.logger.error(
`Failed to query latest global epoch number from epoch block oracle`,
{
if (err instanceof indexerError) {
throw err
} else {
this.logger.error(`Failed to query latest epoch number`, {
err,
},
)
throw err
msg: err.message,
networkName: alias(network),
})
throw indexerError(IndexerErrorCode.IE069, err)
}
}
}

Expand All @@ -645,32 +655,34 @@ export class NetworkMonitor {
allocation.subgraphDeployment.id,
])
if (indexingStatuses.length != 1 || indexingStatuses[0].chains.length != 1) {
throw `Failed to match allocation with an indexing status or chain`
this.logger.error(
`Failed to query indexing status for ${allocation.subgraphDeployment.id.ipfsHash}`,
)
throw indexerError(
IndexerErrorCode.IE020,
`Failed to query indexing status for ${allocation.subgraphDeployment.id.ipfsHash}`,
)
}
const networkID = indexingStatuses[0].chains[0].network
const epoch = await this.latestValidEpoch(CAIPIds[networkID])
const epochStartBlock = {
number: epoch.startBlockNumber,
hash: epoch.startBlockHash,
}

this.logger.trace(`Fetched block pointer to use in resolving POI`, {
deployment: allocation.subgraphDeployment.id.ipfsHash,
networkID,
epochStartBlock,
number: epoch.startBlockNumber,
hash: epoch.startBlockHash,
})
return epochStartBlock
return {
number: epoch.startBlockNumber,
hash: epoch.startBlockHash,
}
} catch (error) {
const err = indexerError(IndexerErrorCode.IE070, error.message)
this.logger.error(
`Failed to fetch block for resolving allocation POI ${allocation.subgraphDeployment.id}`,
{
err: error.message,
allocationID: allocation.id,
deployment: allocation.subgraphDeployment.id,
},
)
throw err
this.logger.error(`Failed to fetch block for resolving allocation POI`, {
err: error.cause ?? error.message,
allocationID: allocation.id,
deployment: allocation.subgraphDeployment.id.ipfsHash,
})
throw error
}
}

Expand All @@ -679,7 +691,6 @@ export class NetworkMonitor {
poi: string | undefined,
force: boolean,
): Promise<string> {
const epochStartBlock = await this.fetchPOIBlockPointer(allocation)
// poi = undefined, force=true -- submit even if poi is 0x0
// poi = defined, force=true -- no generatedPOI needed, just submit the POI supplied (with some sanitation?)
// poi = undefined, force=false -- submit with generated POI if one available
Expand All @@ -694,13 +705,14 @@ export class NetworkMonitor {
return (
(await this.indexingStatusResolver.proofOfIndexing(
allocation.subgraphDeployment.id,
epochStartBlock,
await this.fetchPOIBlockPointer(allocation),
allocation.indexer,
)) || utils.hexlify(Array(32).fill(0))
)
}
break
case false: {
const epochStartBlock = await this.fetchPOIBlockPointer(allocation)
// Obtain the start block of the current epoch
const generatedPOI = await this.indexingStatusResolver.proofOfIndexing(
allocation.subgraphDeployment.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,6 @@ async function resolvePOI(
poi: string | undefined,
force: boolean,
): Promise<string> {
// Obtain epoch start block based on subgraph deployment network's
const currentEpochStartBlock = await networkMonitor.fetchPOIBlockPointer(allocation)
// poi = undefined, force=true -- submit even if poi is 0x0
// poi = defined, force=true -- no generatedPOI needed, just submit the POI supplied (with some sanitation?)
// poi = undefined, force=false -- submit with generated POI if one available
Expand All @@ -310,13 +308,14 @@ async function resolvePOI(
return (
(await indexingStatusResolver.proofOfIndexing(
allocation.subgraphDeployment.id,
currentEpochStartBlock,
await networkMonitor.fetchPOIBlockPointer(allocation),
allocation.indexer,
)) || utils.hexlify(Array(32).fill(0))
)
}
break
case false: {
const currentEpochStartBlock = await networkMonitor.fetchPOIBlockPointer(allocation)
const generatedPOI = await indexingStatusResolver.proofOfIndexing(
allocation.subgraphDeployment.id,
currentEpochStartBlock,
Expand Down
2 changes: 1 addition & 1 deletion packages/indexer-common/src/indexing-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export class IndexingStatusResolver {
.toPromise()

if (!result.data || !result.data.blockHashFromNumber || result.error) {
throw indexerError(IndexerErrorCode.IE070)
throw new Error(`Failed to query graph node for blockHashFromNumber`)
}

this.logger.trace('Resolved block hash', {
Expand Down