Skip to content

v0.20.20

Compare
Choose a tag to compare
@tilacog tilacog released this 21 Aug 23:18
· 271 commits to main since this release

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: true

Arbitrum 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

  1. Commands that now accept the --network option to filter its results

    • indexer actions get
    • indexer allocations get
    • indexer disputes get
    • indexer rules get
  2. Commands that now require the --network option

    • 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
  3. Commands that now require a network positional 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 new protocolNetwork colum in the following tables

  • Actions
  • IndexingRules
  • POIDisputes
  • allocation_receipts
  • allocation_summaries
  • transfer_receipts
  • transfers
  • vouchers

This will let the Indexer Agent contextualize the target protocol network when operating on these
elements.

To ensure correctness, this migration requires that the Agent starts with only one configured
protocol network or an empty database. In the first case, the migration will assign the single
configured protocol network to all existing data in the tables listed above. After this migration
runs successfully, the Indexer Agent can be started with multiple configured protocol networks.

Put simply: to migrate your database to the new Agent version, just run it using the same configuration
you have been using for the previous version.

Keep in mind that it is very important to back up your Indexer Agent database before running any
migrations. This can be achieved with pg_dump:

$ pg_dump -U "$USERNAME" -h $"HOST" -p $"PORT" -Fc $"DB_NAME" > db.dump

Please refer to the pg_dump command manual for more instructions.

Cost Model feature restrictions in multi-network context:

The Cost Model feature can only be enabled for Ethereum Mainnet.
If other networks specify the DAI option group in their specification files, it will be ignored.

Automatic Allocation Transfer to L2

The Agent can be configured to automatically support subgraph transfers from L1 to L2. To enable
this feature, set the enable-auto-migration-support startup option to true.

If enabled, the Agent will inspect if any synced and healthy subgraph deployments have been
transferred from L1 (Ethereum) to L2 (Arbitrum One) in the past seven days. If so, the Agent will:

  1. Queue an allocate Action towards the subgraph deployment on L1, during one week.
  2. If the transfer has been completed, queue an allocate Action towards the subgraph
    deployment on L2, during one week, using the default amount.

Note that the Agent will not automatically close allocations on L1 after a subgraph has been transferred.

Other Changes and Fixes:

Fixed

  • Contract interface changes involving Exponential Rebates
  • Included the protocolNetwork field when checking for duplicate action targets

Added

  • Enforced active connections with Graph-Node and the database during startup
  • PostgreSQL connection pool size can be configured with the postgres-pool-size (defaults to 50).

Changed

  • Skip dispute checking on epochs with unavailable start block hash