Docs
Vyhledávání⌘ K
  • Domov
  • O Grafu
  • Podporované sítě
  • Protocol Contracts
  • Podgrafy
    • Substreams
      • Token API
        • AI Suite
          • Indexing
            • Resources
              Podgrafy > Osvědčené postupy

              4 minutes

              Doporučený postup pro podgraf 4 - Zlepšení rychlosti indexování vyhnutím se eth_calls

              TLDR

              eth_calls are calls that can be made from a Subgraph to an Ethereum node. These calls take a significant amount of time to return data, slowing down indexing. If possible, design smart contracts to emit all the data you need so you don’t need to use eth_calls.

              Proč je dobré se vyhnout eth_calls

              Subgraphs are optimized to index event data emitted from smart contracts. A Subgraph can also index the data coming from an eth_call, however, this can significantly slow down Subgraph indexing as eth_calls require making external calls to smart contracts. The responsiveness of these calls relies not on the Subgraph but on the connectivity and responsiveness of the Ethereum node being queried. By minimizing or eliminating eth_calls in our Subgraphs, we can significantly improve our indexing speed.

              Jak vypadá eth_call?

              eth_calls are often necessary when the data required for a Subgraph is not available through emitted events. For example, consider a scenario where a Subgraph needs to identify whether ERC20 tokens are part of a specific pool, but the contract only emits a basic Transfer event and does not emit an event that contains the data that we need:

              1event Transfer(address indexed from, address indexed to, uint256 value);

              Předpokládejme, že příslušnost tokenů k poolu je určena stavovou proměnnou s názvem getPoolInfo. V takovém případě bychom k dotazu na tato data potřebovali použít příkaz eth_call:

              1import { Address } from '@graphprotocol/graph-ts'2import { ERC20, Transfer } from '../generated/ERC20/ERC20'3import { TokenTransaction } from '../generated/schema'45export function handleTransfer(event: Transfer): void {6  let transaction = new TokenTransaction(event.transaction.hash.toHex())78  // Bind the ERC20 contract instance to the given address:9  let instance = ERC20.bind(event.address)1011  // Retrieve pool information via eth_call12  let poolInfo = instance.getPoolInfo(event.params.to)1314  transaction.pool = poolInfo.toHexString()15  transaction.from = event.params.from.toHexString()16  transaction.to = event.params.to.toHexString()17  transaction.value = event.params.value1819  transaction.save()20}

              This is functional, however is not ideal as it slows down our Subgraph’s indexing.

              Jak odstranit eth_calls

              V ideálním případě by měl být inteligentní kontrakt aktualizován tak, aby v rámci událostí vysílal všechna potřebná data. Například úprava inteligentního kontraktu tak, aby v události obsahoval informace o bazénu, by mohla odstranit potřebu eth_calls:

              1event TransferWithPool(address indexed from, address indexed to, uint256 value, bytes32 indexed poolInfo);

              With this update, the Subgraph can directly index the required data without external calls:

              1import { Address } from '@graphprotocol/graph-ts'2import { ERC20, TransferWithPool } from '../generated/ERC20/ERC20'3import { TokenTransaction } from '../generated/schema'45export function handleTransferWithPool(event: TransferWithPool): void {6  let transaction = new TokenTransaction(event.transaction.hash.toHex())78  transaction.pool = event.params.poolInfo.toHexString()9  transaction.from = event.params.from.toHexString()10  transaction.to = event.params.to.toHexString()11  transaction.value = event.params.value1213  transaction.save()14}

              To je mnohem výkonnější, protože to odstranilo potřebu eth_calls.

              Jak optimalizovat eth_calls

              Pokud úprava inteligentního kontraktu není možná a eth_calls jsou nutné, přečtěte si článek “Improve Subgraph Indexing Performance Easily: Reduce eth_calls” od Simon Emanuel Schmid, kde se dozvíte různé strategie, jak optimalizovat eth_calls.

              Snížení běhové režie eth_calls

              U eth_calls, které nelze odstranit, lze jejich režii za běhu minimalizovat jejich deklarací v manifestu. Když graph-node zpracovává blok, provede všechny deklarované eth_calls paralelně před spuštěním obslužných programů. Volání, která nejsou deklarována, se při běhu obslužných programů provádějí postupně. Zlepšení běhu je způsobeno tím, že se volání provádějí paralelně, nikoliv sekvenčně - to pomáhá zkrátit celkový čas strávený voláním, ale zcela ho neeliminuje.

              V současné době lze eth_calls deklarovat pouze pro obsluhy událostí. V manifestu napište

              1event: TransferWithPool(address indexed, address indexed, uint256, bytes32 indexed)2handler: handleTransferWithPool3calls:4  ERC20.poolInfo: ERC20[event.address].getPoolInfo(event.params.to)

              Žlutě zvýrazněná část je deklarace volání. Část před dvojtečkou je pouze textový popisek, který se používá pouze pro chybová hlášení. Část za dvojtečkou má tvar Contract[address].function(params). Přípustné hodnoty pro adresu a params jsou event.address a event.params.<name>.

              Samotná obslužná rutina přistupuje k výsledku tohoto eth_call přesně tak, jak je uvedeno v předchozí části, a to navázáním na smlouvu a provedením volání. graph-node cachuje výsledky deklarovaných eth_call v paměti a volání obslužné rutiny získá výsledek z této paměťové cache místo skutečného volání RPC.

              Note: Declared eth_calls can only be made in Subgraphs with specVersion >= 1.2.0.

              Závěr

              You can significantly improve indexing performance by minimizing or eliminating eth_calls in your Subgraphs.

              Subgraph Best Practices 1-6

              1. Improve Query Speed with Subgraph Pruning

              2. Improve Indexing and Query Responsiveness by Using @derivedFrom

              3. Improve Indexing and Query Performance by Using Immutable Entities and Bytes as IDs

              4. Improve Indexing Speed by Avoiding eth_calls

              5. Simplify and Optimize with Timeseries and Aggregations

              6. Use Grafting for Quick Hotfix Deployment

              ⁠Edit on GitHub⁠

              Immutable Entities and Bytes as IDsTimeseries and Aggregations
              On this page
              • TLDR
              • Proč je dobré se vyhnout eth_calls
              • Jak vypadá eth_call?
              • Jak odstranit eth_calls
              • Jak optimalizovat eth_calls
              • Snížení běhové režie eth_calls
              • Závěr
              • Subgraph Best Practices 1-6
              The GraphStatusTestnetBrand AssetsForumSecurityPrivacy PolicyTerms of Service