Releases: graphprotocol/indexer
v0.20.22
v0.20.21
v0.20.20
Adds the capacity for the Agent to interact with multiple protocol networks (blockchains that host The Graph Protocol) by running a single instance of the indexer-agent program.
Table of Contents
Multi-Network Mode
Multinetwork Mode can be enabled by setting the environment variable INDEXER_AGENT_MULTINETWORK_MODE
to "true".
While in multinetwork mode, the Indexer Agent will perform all of its usual routines, but for each
specified network.
In that mode, each protocol network is represented by one YAML file under the same directory, which can
be decalred in the command line argument --network-specifications-directory, which must be a path
the Indexer Agent can access during its startup.
Example Network Specification Files
Goerli
This example network specification YAML file represents all possible configuration fields and their
default values.
networkIdentifier: goerli  # could also be named "eipp155:5"
gateway:
  url: https://gateway.testnet.thegraph.com
indexerOptions:
  address: "0x391042eC4ae8ab799Efdfd82021d059a19c6ED86"
  mnemonic: "aunt what review ordinary initial rocket wheel enter private chef tree surface"
  url: http://localhost:7600
  allocationManagementMode: auto
  restakeRewards: true
  rebateClaimThreshold: 200
  rebateClaimBatchThreshold: 200
  rebateClaimMaxBatchSize: 100
  poiDisputeMonitoring: false
  poiDisputableEpochs: 1
  defaultAllocationAmount: 0.1
  voucherRedemptionThreshold: 200
  voucherRedemptionBatchThreshold: 2000
  voucherRedemptionMaxBatchSize: 100
  autoAllocationMinBatchSize: 1
  allocateOnNetworkSubgraph: false
  register: true
transactionMonitoring:
  gasPriceMax: 100
  gasIncreaseTimeout: 240 # in seconds
  gasIncreaseFactor: 1.2
  gasPriceMax: 100 # in gwei
  baseFeePerGasMax: 100 # in gwei
  maxTransactionAttempts: 0 # zero retries indefinitely
subgraphs:
  networkSubgraph:
    url: https://api.thegraph.com/subgraphs/name/graphprotocol/graph-network-goerli
    deployment: QmRFMZT2rmdo558S8GWPNYJ61qchSUTEMHirYnm4MRqHEP
  epochSubgraph:
    url: https://api.thegraph.com/subgraphs/name/graphprotocol/goerli-epoch-block-oracle
networkProvider:
  url: "<insert the URL of your Goerli JSON-RPC provider here>"
dai:
  # Mind that the cost model feature is only enabled for Ethereum Mainnet (see notes below)
  contractAddress: "0x11fE4B6AE13d2a6055C8D9cF65c55bac32B5d844"
  inject: trueArbitrum Goerli
In turn, this YAML network specification file represents just the required fields.
networkIdentifier: arbitrum-goerli # could also be named "eipp155:421613"
gateway:
  url: https://gateway-testnet-arbitrum.network.thegraph.com
indexerOptions:
  address: "0x79EB6E112a00A4b99B8ABf0B983159d54A8be316"
  mnemonic: "juice zebra sister column fit praise behind trust merit slab place general"
  url: http://localhost:7600
  allocationManagementMode: oversight
subgraphs:
  networkSubgraph:
    url: https://api.thegraph.com/subgraphs/name/graphprotocol/graph-network-arbitrum-goerli
    deployment: QmW8YxdkQjFb7wHMDo9u4DodLga4YHdByfKsBxCCcUx6cQ
  epochSubgraph:
    url: https://api.thegraph.com/subgraphs/name/graphprotocol/arb-goerli-epoch-block-oracle
networkProvider:
  url: "<insert the URL of your Goerli JSON-RPC provider here>"API Changes
The Indexer Agent GraphQL API was updated to accept (and in some cases require) a protocolNetwork
parameter to determine which network should be used for queries or mutations.
Likewise,the Indexer CLI was updated to accept the --network option as the context for most of its
commands.
GraphQL API Changes
# --------------------------------------------------------------------------------
# * inputs
# --------------------------------------------------------------------------------
input AllocationFilter {
  protocolNetwork: String # new optional filtering parameter
}
input ActionInput {
  protocolNetwork: String! # new required parameter
}
input ActionFilter {
  protocolNetwork: String # new optional filtering parameter
}
# New dedicated identifier type
input POIDisputeIdentifier {
  allocationID: String!
  protocolNetwork: String!
}
input POIDisputeInput {
  protocolNetwork: String! # new required parameter
}
input IndexingRuleInput {
  protocolNetwork: String! # new required parameter
}
# New dedicated identifier type
input IndexingRuleIdentifier {
  identifier: String!
  protocolNetwork: String!
}
# --------------------------------------------------------------------------------
# * types
# --------------------------------------------------------------------------------
type Allocation {
  protocolNetwork: String! # new non-nullable field
}
type CreateAllocationResult {
  protocolNetwork: String! # new non-nullable field
}
type CloseAllocationResult {
  protocolNetwork: String! # new non-nullable field
}
type ReallocateAllocationResult {
  protocolNetwork: String! # new non-nullable field
}
type Action {
  protocolNetwork: String! # new non-nullable field
}
type ActionResult {
  protocolNetwork: String! # new non-nullable field
}
type POIDispute {
  protocolNetwork: String! # new non-nullable field
}
type IndexingRule {
  protocolNetwork: String! # new non-nullable field
}
type IndexerRegistration {
  protocolNetwork: String # new non-nullable field
}
type IndexerEndpoint {
  protocolNetwork: String! # new optional filtering parameter
}
#--------------------------------------------------------------------------------
# * enums
# --------------------------------------------------------------------------------
enum ActionParams {
  protocolNetwork # new enum variant
}
# --------------------------------------------------------------------------------
# * queries
# --------------------------------------------------------------------------------
type Query {
  indexingRule(
    identifier: IndexingRuleIdentifier! # parameter type changed from String!
  ): IndexingRule
  indexingRules(
    protocolNetwork: String # new optional filtering parameter
  ): [IndexingRule!]!
  indexerRegistration(
    protocolNetwork: String! # new required parameter
  ): IndexerRegistration!
  indexerAllocations(
    protocolNetwork: String! # new required parameter
  ): [IndexerAllocation]!
  indexerEndpoints(
    protocolNetwork: String! # new required parameter
  ): [IndexerEndpoints!]!
  dispute(
    identifier: POIDisputeIdentifier! # parameter type changed from String!
  ): POIDispute
  disputes(
    protocolNetwork: String # new optional filtering parameter
  ): [POIDispute]!
  disputesClosedAfter(
    protocolNetwork: String # new optional filtering parameter
  ): [POIDispute]!
}
# --------------------------------------------------------------------------------
# * mutations
# --------------------------------------------------------------------------------
type Mutation {
  deleteIndexingRule(
    identifier: IndexingRuleIdentifier! # parameter type changed from String!
  ): Boolean!
  deleteIndexingRules(
    identifiers: [IndexingRuleIdentifier!]! # parameter changed from [String!]!
  ): Boolean!
  deleteDisputes(
    identifiers: [POIDisputeIdentifier!]! # parameter changed from [String!]!
  ): Int!
  createAllocation(
    protocolNetwork: String # new required parameter
  ): CreateAllocationResult!
  closeAllocation(
    protocolNetwork: String! # new required parameter
  ): CloseAllocationResult!
  reallocateAllocation(
    protocolNetwork: String! # new required parameter
  ): ReallocateAllocationResult!
}Indexer CLI command changes
Most indexer-cli commands now accept or require a network argument, to bring the protocol network
into the command's context
- 
Commands that now accept the
--networkoption to filter its results- indexer actions get
 - indexer allocations get
 - indexer disputes get
 - indexer rules get
 
 - 
Commands that now require the
--networkoption- indexer actions queue
 - indexer rules clear
 - indexer rules delete
 - indexer rules maybe
 - indexer rules offchain
 - indexer rules set
 - indexer rules start
 - indexer rules stop
 - indexer status
 
 - 
Commands that now require a
networkpositional argument- indexer allocations close
 - indexer allocations create
 - indexer allocations reallocate
 
 
The /network endopoint
The /network endpoint exposed by the Agent now requires an additional path segment to disambiguate
which protocol network it should target.
Assuming the Agent is configured with those networks, all the paths below are valid:
/network/mainnet/network/eip155:1/network/arbitrum-one/network/eip155:42161/network/goerli/network/eip155:5/network/arbitrum-goerli/network/eip155:421613
Database Migrations
A new database migration will create a...
v0.20.18
L2 Support for Indexer Agent
Adds the capacity for the Agent to interact with multiple protocol networks (blockchains that host The Graph Protocol) by running a single instance of the indexer-agent program.
Table of Contents
Multi-Network Mode
Multinetwork Mode can be enabled by setting the environment variable INDEXER_AGENT_MULTINETWORK_MODE
to "true".
While in multinetwork mode, the Indexer Agent will perform all of its usual routines, but for each
specified network.
In that mode, each protocol network is represented by one YAML file under the same directory, which can
be decalred in the command line argument --network-specifications-directory, which must be a path
the Indexer Agent can access during its startup.
Example Network Specification Files
Goerli
This example network specification YAML file represents all possible configuration fields and their
default values.
networkIdentifier: goerli  # could also be named "eipp155:5"
gateway:
  url: https://gateway.testnet.thegraph.com
indexerOptions:
  address: "0x391042eC4ae8ab799Efdfd82021d059a19c6ED86"
  mnemonic: "aunt what review ordinary initial rocket wheel enter private chef tree surface"
  url: http://localhost:7600
  allocationManagementMode: auto
  restakeRewards: true
  rebateClaimThreshold: 200
  rebateClaimBatchThreshold: 200
  rebateClaimMaxBatchSize: 100
  poiDisputeMonitoring: false
  poiDisputableEpochs: 1
  defaultAllocationAmount: 0.1
  voucherRedemptionThreshold: 200
  voucherRedemptionBatchThreshold: 2000
  voucherRedemptionMaxBatchSize: 100
  autoAllocationMinBatchSize: 1
  allocateOnNetworkSubgraph: false
  register: true
transactionMonitoring:
  gasPriceMax: 100
  gasIncreaseTimeout: 240 # in seconds
  gasIncreaseFactor: 1.2
  gasPriceMax: 100 # in gwei
  baseFeePerGasMax: 100 # in gwei
  maxTransactionAttempts: 0 # zero retries indefinitely
subgraphs:
  networkSubgraph:
    url: https://api.thegraph.com/subgraphs/name/graphprotocol/graph-network-goerli
    deployment: QmRFMZT2rmdo558S8GWPNYJ61qchSUTEMHirYnm4MRqHEP
  epochSubgraph:
    url: https://api.thegraph.com/subgraphs/name/graphprotocol/goerli-epoch-block-oracle
networkProvider:
  url: "<insert the URL of your Goerli JSON-RPC provider here>"
dai:
  # Mind that the cost model feature is only enabled for Ethereum Mainnet (see notes below)
  contractAddress: "0x11fE4B6AE13d2a6055C8D9cF65c55bac32B5d844"
  inject: trueArbitrum Goerli
In turn, this YAML network specification file represents just the required fields.
networkIdentifier: arbitrum-goerli # could also be named "eipp155:421613"
gateway:
  url: https://gateway-testnet-arbitrum.network.thegraph.com
indexerOptions:
  address: "0x79EB6E112a00A4b99B8ABf0B983159d54A8be316"
  mnemonic: "juice zebra sister column fit praise behind trust merit slab place general"
  url: http://localhost:7600
  allocationManagementMode: oversight
subgraphs:
  networkSubgraph:
    url: https://api.thegraph.com/subgraphs/name/graphprotocol/graph-network-arbitrum-goerli
    deployment: QmW8YxdkQjFb7wHMDo9u4DodLga4YHdByfKsBxCCcUx6cQ
  epochSubgraph:
    url: https://api.thegraph.com/subgraphs/name/graphprotocol/arb-goerli-epoch-block-oracle
networkProvider:
  url: "<insert the URL of your Goerli JSON-RPC provider here>"API Changes
The Indexer Agent GraphQL API was updated to accept (and in some cases require) a protocolNetwork
parameter to determine which network should be used for queries or mutations.
Likewise,the Indexer CLI was updated to accept the --network option as the context for most of its
commands.
GraphQL API Changes
# --------------------------------------------------------------------------------
# * inputs
# --------------------------------------------------------------------------------
input AllocationFilter {
  protocolNetwork: String # new optional filtering parameter
}
input ActionInput {
  protocolNetwork: String! # new required parameter
}
input ActionFilter {
  protocolNetwork: String # new optional filtering parameter
}
# New dedicated identifier type
input POIDisputeIdentifier {
  allocationID: String!
  protocolNetwork: String!
}
input POIDisputeInput {
  protocolNetwork: String! # new required parameter
}
input IndexingRuleInput {
  protocolNetwork: String! # new required parameter
}
# New dedicated identifier type
input IndexingRuleIdentifier {
  identifier: String!
  protocolNetwork: String!
}
# --------------------------------------------------------------------------------
# * types
# --------------------------------------------------------------------------------
type Allocation {
  protocolNetwork: String! # new non-nullable field
}
type CreateAllocationResult {
  protocolNetwork: String! # new non-nullable field
}
type CloseAllocationResult {
  protocolNetwork: String! # new non-nullable field
}
type ReallocateAllocationResult {
  protocolNetwork: String! # new non-nullable field
}
type Action {
  protocolNetwork: String! # new non-nullable field
}
type ActionResult {
  protocolNetwork: String! # new non-nullable field
}
type POIDispute {
  protocolNetwork: String! # new non-nullable field
}
type IndexingRule {
  protocolNetwork: String! # new non-nullable field
}
type IndexerRegistration {
  protocolNetwork: String # new non-nullable field
}
type IndexerEndpoint {
  protocolNetwork: String! # new optional filtering parameter
}
#--------------------------------------------------------------------------------
# * enums
# --------------------------------------------------------------------------------
enum ActionParams {
  protocolNetwork # new enum variant
}
# --------------------------------------------------------------------------------
# * queries
# --------------------------------------------------------------------------------
type Query {
  indexingRule(
    identifier: IndexingRuleIdentifier! # parameter type changed from String!
  ): IndexingRule
  indexingRules(
    protocolNetwork: String # new optional filtering parameter
  ): [IndexingRule!]!
  indexerRegistration(
    protocolNetwork: String! # new required parameter
  ): IndexerRegistration!
  indexerAllocations(
    protocolNetwork: String! # new required parameter
  ): [IndexerAllocation]!
  indexerEndpoints(
    protocolNetwork: String! # new required parameter
  ): [IndexerEndpoints!]!
  dispute(
    identifier: POIDisputeIdentifier! # parameter type changed from String!
  ): POIDispute
  disputes(
    protocolNetwork: String # new optional filtering parameter
  ): [POIDispute]!
  disputesClosedAfter(
    protocolNetwork: String # new optional filtering parameter
  ): [POIDispute]!
}
# --------------------------------------------------------------------------------
# * mutations
# --------------------------------------------------------------------------------
type Mutation {
  deleteIndexingRule(
    identifier: IndexingRuleIdentifier! # parameter type changed from String!
  ): Boolean!
  deleteIndexingRules(
    identifiers: [IndexingRuleIdentifier!]! # parameter changed from [String!]!
  ): Boolean!
  deleteDisputes(
    identifiers: [POIDisputeIdentifier!]! # parameter changed from [String!]!
  ): Int!
  createAllocation(
    protocolNetwork: String # new required parameter
  ): CreateAllocationResult!
  closeAllocation(
    protocolNetwork: String! # new required parameter
  ): CloseAllocationResult!
  reallocateAllocation(
    protocolNetwork: String! # new required parameter
  ): ReallocateAllocationResult!
}Indexer CLI command changes
Most indexer-cli commands now accept or require a network argument, to bring the protocol network
into the command's context
- 
Commands that now accept the
--networkoption to filter its results- indexer actions get
 - indexer allocations get
 - indexer disputes get
 - indexer rules get
 
 - 
Commands that now require the
--networkoption- indexer actions queue
 - indexer rules clear
 - indexer rules delete
 - indexer rules maybe
 - indexer rules offchain
 - indexer rules set
 - indexer rules start
 - indexer rules stop
 - indexer status
 
 - 
Commands that now require a
networkpositional argument- indexer allocations close
 - indexer allocations create
 - indexer allocations reallocate
 
 
The /network endopoint
The /network endpoint exposed by the Agent now requires an additional path segment to disambiguate
which protocol network it should target.
Assuming the Agent is configured with those networks, all the paths below are valid:
/network/mainnet/network/eip155:1/network/arbitrum-one/network/eip155:42161/network/goerli/network/eip155:5/network/arbitrum-goerli/network/eip155:421613
Database Migrations
A ne...
v0.20.16
Table of Contents
- Intro
 - Network
 - Introducing the Action Queue
 - Rules
 - Cost model
 - Vouchers and Receipts
 - Configuration
 - Subgraph Deployments Handling
 - Observability & Monitoring
 - Interfacing
 
Intro
The v0.20.3 mainnet release includes a wide range of new features and a significant overhaul of the internal code structure.
It's the first mainnet release since v0.18.6.
Check out the full changelog for the complete list of changes.
The following packages are part of this release:
indexer-agentv0.20.13indexer-servicev0.20.13indexer-cliv0.20.13indexer-commonv0.20.13indexer-nativev0.20.13
Network
The latest release includes several Network updates:
Thanks to the Epoch Subgraph, indexers can now connect to any protocol network and claim rewards for indexing sugraphs form the new supported networks:
- Gnosis (
eip155:100) - Avalanche (
eip155:43114) - Celo (
eip155:42220) - Arbitrum One (
eip155:42161) 
Our testnet is also live on Goerli, where the following networks are also available for indexing:
- Goerli (
eip155:5) - Fantom (
eip155:250) - Polygon (
eip155:137) - Optimism (
eip155:10) 
We are also on L2! Arbitrum-One and Arbitrum-Goerli (testnet) are now live protocol chains.
For more details on the Networking improvements, check out the relevant PRs:
- Integrate Epoch Block Oracle by @hopeyen in #479
 - Support connecting to any protocol network by @fordN in #513
 - Add support L2 protocol chains (i.e Arbitrum-Goerli and Arbitrum-One) by using 
EpochSubgraphto fetch block numbers instead ofEpochManagerby @tilacog in #573 - Add support for Hardhat, Avalanche, Polygon, Celo, & Optimism to chain alias lookups by @fordN in #577
 - Add option to allocate on network subgraph by @Theodus in #339
 - Allow 0 staked allocations by @hopeyen in #471
 - Remove max signal check, towards deprecating max signal by @fordN in #482
 
Introducing the Action Queue
The Action Queue is a new sub-component responsible for managing a set of Actions (allocate, unallocate, and reallocate) for an Indexer in a predictable and efficient way. Those Actions can be generated both by the Indexer's rules and by direct input, and are sent to a dedicated worker process to be executed.
A new startup parameter, --allocation-management, has been introduced to let Indexers choose betweeen different allocation management modes:
- The 
automode, which is similar to the agent's behavior in the past, continuously monitors the network and uses the indexing rules to determine and execute allocation management actions. Actions are added to the queue with theapprovedstatus. - In 
oversightmode, theindexer-agentruns its reconciliation loop to make allocation decisions and propose new Actions by adding them to the Action Queue with a status ofqueued. These actions will then require explicit approval before they will be executed. - In 
manualallocation management mode, the agent will not take any allocation management Actions on its own (meaning it doesn't use the Action Queue at all), and indexers can take all allocation management actions manually using the GraphQL orindexer-cliinterfaces. 
In summary:
| Allocation Mode | Propose Actions? | Action initial state | 
|---|---|---|
auto | 
Yes | approved | 
oversight | 
Yes | queued | 
manual | 
No | (manual mode doesn't use the Action Queue) | 
New Allocation Management modes
Manual Mode
Indexers can now manage allocations manually via the GraphQL interface and indexer-cli, allowing indexers and external tools to have more granular and direct control over allocation strategy.
This feature allows for direct requests to be sent to create, close, or reallocate allocations, which will send a transaction to the Protocol Contracts and update the indexing rules at the same time. For example: when closing an allocation manually the agent will update existing rules for that deployment to be decisionBasis = offchain so the agent will not attempt to reopen that allocation.
For more, check out the original PRs:
Oversight Mode
The oversight mode is very similar to the auto mode, with the distinction of not auto-approving the Actions proposed in the reconciliation loop.
Here's a quick summary of how Actions flow through the Action Queue in oversight mode:
- A user initiates an action through either a manual interaction or via 3rd party tools integrated with the indexer-management server.
 - The action is added to the Action Queue with the 
queuedstatus. - In the meantime, the 
indexer-agentruns its reconciliation loop to make allocation decisions and propose actions to the Action Queue, also with a status ofqueued. - An approver (a human or automated system) reviews the proposed actions in the Action Queue and approves them for execution by changing their status to 
approved. - The action-queue worker, which runs as a separate process, polls the Action Queue for items with a status of 
approvedand executes them on-chain. - The action status is updated to 
successin the Action Queue, and the process is complete.
(Actions can also be finalized withfailedandcanceledstatus.) 
Batching Options in auto Mode
With auto management mode, the agent automatically proposes and approves Actions for the worker to execute. But to give indexers more control over how these Actions are batched in transactions for execution, we've added two optional startup parameters:
--auto-min-batch-size: Specify a minimum batch size to wait for before singing a transaction with the batched Actions.--auto-max-wait-time: Set a maximum time to wait after the first approved Action before executing the batched Actions transaction.
These parameters are particularly useful for indexers who want to save on gas costs by allowing the agent to perform automatic batched transactions, while still having the flexibility to modify actions if needed.
For more, check out the original PR:
CLI improvements
New Action query commands are available to inspect and manage the Action Queue using the indexer-cli:
- Action commands:
 - Actions Query:
 
Safety improvements
- Avoid recreating recently failed Actions #506
 - Implement a stake feasibility check before executing batched Actions transactions #579
 
Rules
Indexing rues can now be:
v0.20.12
What's Changed
- indexer-agent: remove input allocation-exchange-contract by @hopeyen in #598
 - indexer-common: network pauses exit message by @hopeyen in #472
 - indexer-agent: Remove networkCurrentEpoch() from critical path by @fordN in #602
 - common: split checks and refine error messages when querying the EBO by @tilacog in #601
 - indexer-agent: Fix bug in startup argument parser by @fordN in #603
 - common: refactor epoch sync check when resolving current epoch block by @tilacog in #604
 - indexer-common: Add misssing 
axiosdependency by @tilacog in #605 - indexer-agent,-common: query fee metrics for Prometheus by @hopeyen in #597
 - indexer-cli,-common: indexing rules safety by @hopeyen in #542
 
Full Changelog: v0.20.11...v0.20.12
v0.20.11
What's Changed
- indexer-common: Implement stake feasibility check by @tilacog in #579
 - github actions: Add node v17 and v18 support, remove v13 by @fordN in #578
 - indexer-service: Add 'yaml' dependency by @fordN in #587
 - Update publish build binaries action strategies matrix by @fordN in #588
 - Use configured provider for resolving protocol chain blocks by @tilacog in #591
 - Clean and validate 
Action.amountby @tilacog in #590 - Remove unused code by @tilacog in #592
 
Full Changelog: v0.20.9...v0.20.11
v0.20.9
Summary
- Added support for L2 protocol chains (i.e Arbitrum-Goerli and Arbitrum-One)
 - Added support for some subgraph indexing chains: Hardhat, Avalanche, Celo, Optimism, Arbitrum, Arbitrum-Goerli
 - Support using a config file to set startup arguments in indexer-service (already supported in indexer-agent)
 - Fix: add network-subgraph-deployment startup argument to indexer-service, so indexer-service can use a local network subgraph
 
What's Changed (PRs)
- Add CAIP-2 entry for chain 1337 by @Theodus in #571
 - indexer-agent,indexer-service: Startup argument parsing updates and cleanup by @fordN in #572
 - indexer-common: Support arbitrum-goerli, and arbitrum by @fordN in #561
 - Support L2 protocol chains in indexer-agent: Use 
EpochSubgraphto fetch block numbers instead ofEpochManagerby @tilacog in #573 - indexer-common: Add avalanche, polygon, celo, & optimism to chain alias lookups by @fordN in #577
 - Forward graph-attestable header for free queries by @Theodus in #576
 
Full Changelog: v0.20.8...v0.20.9
v0.20.8
v0.20.6
What's Changed
- indexer-common: Use consistent deployment names by @fordN in #490
 - security: resurrect comment deleted in f7fa658 by @That3Percent in #492
 - AQI: actions delete command by @hopeyen in #491
 - Make 0.28.0 the official Graph Node version by @azf20 in #494
 - Update to 0.28.1 by @azf20 in #501
 - Update to use 0.28.2 by @azf20 in #503
 - k8s: Update resources/configs to use the latest recommendations by @fordN in #493
 - indexer-common: Trace log data used to evaluate each deployment by @fordN in #505
 - indexer-common: re-organize error logging by @hopeyen in #507
 - indexer-common: Avoid recreating recently failed actions by @tilacog in #506
 - Update network parameters for Goerli testnet by @tmigone in #510
 - indexer-agent,-common: Use consistent clear network/epoch var naming by @fordN in #511
 - Fix indexer-cli docker image by @cause1ove in #509
 - indexer-agent,-service: remove index-node configs by @hopeyen in #512
 - indexer-common: Support connecting to any protocol network by @fordN in #513
 indexer-cli,indexer-common: Introduce the--firstCLI option by @tilacog in #514- Update indexer components to 0.20.4 on testnet by @azf20 in #519
 - agent: update @graphprotocol/contracts to v1.16.0 by @tilacog in #520
 - Reorganising networks.md by @azf20 in #518
 - indexer-agent,-common: fix resolve latest epoch by @hopeyen in #523
 - docs: update network.md and errors.md by @hopeyen in #528
 - indexer-common,-agent: Various robustness and UX improvements by @fordN in #541
 - Update networks.md configuration & add initial feature matrix by @azf20 in #531
 - Fix: indexer-common schema allow null node by @hopeyen in #550
 - indexer-cli: add the --fields option by @tilacog in #547
 - Release 
graph-nodev0.29.0on testnet by @neysofu in #553 - Auto-detect 
ethereum-networkby @tilacog in #554 - Upgrade contracts dependency by @fordN in #544
 - indexer-common,cli: actions update command by @fordN in #551
 - Indexer-cli: add actions delete options by @hopeyen in #549
 - indexer-common,-cli: add cost models delete by @hopeyen in #530
 - docs: Update action queue docs, include recent 
actions updatesupport by @fordN in #559 
New Contributors
- @tmigone made their first contribution in #510
 - @cause1ove made their first contribution in #509
 - @neysofu made their first contribution in #548
 
Full Changelog: v0.20.4...v0.20.6