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
4 changes: 2 additions & 2 deletions docs/networks/arbitrum-sepolia.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ The Graph Network's testnet is on Arbitrum Sepolia (eip155:421614). Sepolia netw
| Component | Release |
| ------------------ | ------------------------------------------------------------------------------------ |
| contracts | [5.3.3](https://github.com/graphprotocol/contracts/releases/tag/v5.3.3) |
| indexer-agent | [0.25.4](https://github.com/graphprotocol/indexer/releases/tag/v0.25.4) |
| indexer-cli | [0.25.4](https://github.com/graphprotocol/indexer/releases/tag/v0.25.4) |
| indexer-agent | [0.25.5](https://github.com/graphprotocol/indexer/releases/tag/v0.25.5) |
| indexer-cli | [0.25.5](https://github.com/graphprotocol/indexer/releases/tag/v0.25.5) |
| indexer-service-rs | [1.0.0](https://github.com/graphprotocol/indexer-rs/releases/tag/v1.0.0) |
| tap-agent | [1.0.0](https://github.com/graphprotocol/indexer-rs/releases/tag/v1.0.0) |
| graph-node | [0.35.1](https://github.com/graphprotocol/graph-node/releases/tag/v0.35.1) |
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.25.4"
"version": "0.25.5"
}
4 changes: 2 additions & 2 deletions packages/indexer-agent/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@graphprotocol/indexer-agent",
"version": "0.25.4",
"version": "0.25.5",
"description": "Indexer agent",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -30,7 +30,7 @@
},
"dependencies": {
"@graphprotocol/common-ts": "3.0.1",
"@graphprotocol/indexer-common": "0.25.4",
"@graphprotocol/indexer-common": "0.25.5",
"@thi.ng/heaps": "^1.3.1",
"axios": "0.26.1",
"bs58": "5.0.0",
Expand Down
120 changes: 120 additions & 0 deletions packages/indexer-agent/src/__tests__/agent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
convertSubgraphBasedRulesToDeploymentBased,
consolidateAllocationDecisions,
resolveTargetDeployments,
} from '../agent'
import {
INDEXING_RULE_GLOBAL,
Expand Down Expand Up @@ -208,3 +209,122 @@ describe('consolidateAllocationDecisions function', () => {
expect(result).not.toContain(a)
})
})

describe('resolveTargetDeployments function', () => {
const alwaysDeployment = new SubgraphDeploymentID(
'QmXZiV6S13ha6QXq4dmaM3TB4CHcDxBMvGexSNu9Kc28EH',
)
const offchainDeployment = new SubgraphDeploymentID(
'QmRKs2ZfuwvmZA3QAWmCqrGUjV9pxtBUDP3wuc6iVGnjA2',
)
const allocationDeployment = new SubgraphDeploymentID(
'QmULAfA3eS5yojxeSR2KmbyuiwCGYPjymsFcpa6uYsu6CJ',
)
const offchainArgDeployment = new SubgraphDeploymentID(
'QmWmyoMoctfbAaiEs2G46gpeUmhqFRDW6KWo64y5r581Vz',
)

it('includes OFFCHAIN rules when allocationDecisions is empty (manual mode)', () => {
const rules = {
'eip155:42161': [
{
identifier: offchainDeployment.ipfsHash,
identifierType: SubgraphIdentifierType.DEPLOYMENT,
decisionBasis: IndexingDecisionBasis.OFFCHAIN,
} as IndexingRuleAttributes,
],
}

const result = resolveTargetDeployments({}, rules, [])

expect(result.size).toBe(1)
expect([...result].map(d => d.ipfsHash)).toContain(
offchainDeployment.ipfsHash,
)
})

it('includes offchainSubgraphs from startup args', () => {
const result = resolveTargetDeployments({}, {}, [offchainArgDeployment])

expect(result.size).toBe(1)
expect([...result].map(d => d.ipfsHash)).toContain(
offchainArgDeployment.ipfsHash,
)
})

it('includes deployments from allocationDecisions', () => {
const allocationDecisions = {
'eip155:42161': [{ deployment: allocationDeployment, toAllocate: true }],
}

const result = resolveTargetDeployments(allocationDecisions, {}, [])

expect(result.size).toBe(1)
expect(result).toContain(allocationDeployment)
})

/**
* BUG TEST: In manual allocation mode, networkDeploymentAllocationDecisions is empty
* because evaluateDeployments is skipped. This means decisionBasis: ALWAYS rules
* are not included in targetDeployments, causing those subgraphs to be paused.
*
* This test should FAIL with the current buggy code and PASS after the fix.
*/
it('includes ALWAYS rules when allocationDecisions is empty (manual mode)', () => {
const rules = {
'eip155:42161': [
{
identifier: alwaysDeployment.ipfsHash,
identifierType: SubgraphIdentifierType.DEPLOYMENT,
decisionBasis: IndexingDecisionBasis.ALWAYS,
} as IndexingRuleAttributes,
],
}

// In manual mode, allocationDecisions is empty because evaluateDeployments is skipped
const result = resolveTargetDeployments({}, rules, [])

// ALWAYS rules should still be included in targetDeployments
expect(result.size).toBe(1)
expect([...result].map(d => d.ipfsHash)).toContain(
alwaysDeployment.ipfsHash,
)
})

it('combines all sources correctly', () => {
const allocationDecisions = {
'eip155:42161': [{ deployment: allocationDeployment, toAllocate: true }],
}
const rules = {
'eip155:42161': [
{
identifier: offchainDeployment.ipfsHash,
identifierType: SubgraphIdentifierType.DEPLOYMENT,
decisionBasis: IndexingDecisionBasis.OFFCHAIN,
} as IndexingRuleAttributes,
{
identifier: alwaysDeployment.ipfsHash,
identifierType: SubgraphIdentifierType.DEPLOYMENT,
decisionBasis: IndexingDecisionBasis.ALWAYS,
} as IndexingRuleAttributes,
],
}

const result = resolveTargetDeployments(allocationDecisions, rules, [
offchainArgDeployment,
])

// Should include: allocationDeployment, offchainDeployment, alwaysDeployment, offchainArgDeployment
expect(result.size).toBe(4)
expect(result).toContain(allocationDeployment)
expect([...result].map(d => d.ipfsHash)).toContain(
offchainDeployment.ipfsHash,
)
expect([...result].map(d => d.ipfsHash)).toContain(
alwaysDeployment.ipfsHash,
)
expect([...result].map(d => d.ipfsHash)).toContain(
offchainArgDeployment.ipfsHash,
)
})
})
65 changes: 48 additions & 17 deletions packages/indexer-agent/src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,23 +425,13 @@ export class Agent {
}).tryMap(
async ({ indexingRules, networkDeploymentAllocationDecisions }) => {
logger.trace('Resolving target deployments')
const targetDeploymentIDs: Set<SubgraphDeploymentID> =
consolidateAllocationDecisions(networkDeploymentAllocationDecisions)

// Add offchain subgraphs to the deployment list from rules
Object.values(indexingRules)
.flat()
.filter(
rule => rule?.decisionBasis === IndexingDecisionBasis.OFFCHAIN,
)
.forEach(rule => {
targetDeploymentIDs.add(new SubgraphDeploymentID(rule.identifier))
})
// From startup args
this.offchainSubgraphs.forEach(deployment => {
targetDeploymentIDs.add(deployment)
})
return [...targetDeploymentIDs]
return [
...resolveTargetDeployments(
networkDeploymentAllocationDecisions,
indexingRules,
this.offchainSubgraphs,
),
]
},
{
onError: error =>
Expand Down Expand Up @@ -1231,3 +1221,44 @@ export function consolidateAllocationDecisions(
.map(decision => decision.deployment),
)
}

/**
* Resolves the set of target deployments that should be synced by graph-node.
* This combines:
* 1. Deployments from allocation decisions (where toAllocate=true)
* 2. Deployments with OFFCHAIN and ALWAYS decision basis from rules
* 3. Deployments from --offchain-subgraphs startup args
*/
export function resolveTargetDeployments(
networkDeploymentAllocationDecisions: Record<
string,
AllocationDecisionInterface[]
>,
indexingRules: Record<string, IndexingRuleAttributes[]>,
offchainSubgraphs: SubgraphDeploymentID[],
): Set<SubgraphDeploymentID> {
const targetDeploymentIDs: Set<SubgraphDeploymentID> =
consolidateAllocationDecisions(networkDeploymentAllocationDecisions)

// Add offchain and always subgraphs to the deployment list from rules.
// ALWAYS rules must be handled here because in manual allocation mode,
// evaluateDeployments is skipped, so ALWAYS rules would otherwise not
// be included in targetDeployments.
Object.values(indexingRules)
.flat()
.filter(
rule =>
rule?.decisionBasis === IndexingDecisionBasis.OFFCHAIN ||
rule?.decisionBasis === IndexingDecisionBasis.ALWAYS,
)
.forEach(rule => {
targetDeploymentIDs.add(new SubgraphDeploymentID(rule.identifier))
})

// From startup args
offchainSubgraphs.forEach(deployment => {
targetDeploymentIDs.add(deployment)
})

return targetDeploymentIDs
}
4 changes: 2 additions & 2 deletions packages/indexer-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@graphprotocol/indexer-cli",
"version": "0.25.4",
"version": "0.25.5",
"description": "Indexer CLI for The Graph Network",
"main": "./dist/cli.js",
"files": [
Expand All @@ -27,7 +27,7 @@
},
"dependencies": {
"@graphprotocol/common-ts": "3.0.1",
"@graphprotocol/indexer-common": "0.25.4",
"@graphprotocol/indexer-common": "0.25.5",
"@iarna/toml": "2.2.5",
"@thi.ng/iterators": "5.1.74",
"@urql/core": "3.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/indexer-common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@graphprotocol/indexer-common",
"version": "0.25.4",
"version": "0.25.5",
"description": "Common library for Graph Protocol indexer components",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion scripts/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ POSTGRES_TEST_DATABASE=indexer_tests \
POSTGRES_TEST_USERNAME=testuser \
POSTGRES_TEST_PASSWORD=testpass \
NODE_OPTIONS="--dns-result-order=ipv4first" \
yarn test:ci
${TEST_CMD:-yarn test:ci}
Loading