Docs
La Recherche⌘ K
  • Accueil
  • À propos de The Graph
  • Réseaux pris en charge
  • Contrats du Protocole
  • Subgraphs
    • Substreams
      • Token API
        • AI Suite
          • Indexing
            • Resources
              Subgraphs > Les meilleures pratiques

              5 minutes

              Meilleure Pratique Subgraph 4 - Améliorer la Vitesse d'Indexation en Évitant les eth_calls

              TLDR

              Les eth_calls sont des appels qui peuvent être effectués depuis un Subgraph vers un nœud Ethereum. Ces appels prennent beaucoup de temps pour renvoyer les données, ce qui ralentit l’indexation. Si possible, concevez des contrats intelligents pour émettre toutes les données dont vous avez besoin afin de ne pas avoir à utiliser les eth_calls.

              Pourquoi Éviter les eth_calls est une Bonne Pratique

              Les subgraphs sont optimisés pour indexer les données d’événements émises par les contrats intelligents. Un subgraph peut également indexer les données provenant d’un eth_call, mais cela peut ralentir considérablement l’indexation du subgraph car les eth_calls nécessitent de faire des appels externes aux smart contracts. La réactivité de ces appels ne dépend pas du subgraph mais de la connectivité et de la réactivité du nœud Ethereum interrogé. En minimisant ou en éliminant les eth_calls dans nos subgraphs, nous pouvons améliorer de manière significative notre vitesse d’indexation.

              À quoi ressemble un eth_call ?

              Les eth_calls sont souvent nécessaires lorsque les données requises pour un Subgraph ne sont pas disponibles par le biais des événements émis. Par exemple, considérons un scénario dans lequel un Subgraph doit identifier si les tokens ERC20 font partie d’un pool spécifique, mais le contrat n’émet qu’un événement Transfer de base et n’émet pas d’événement contenant les données dont nous avons besoin :

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

              Supposons que l’appartenance au pool des tokens soit déterminée par une variable d’état nommée getPoolInfo. Dans ce cas, nous devrions utiliser un eth_call pour interroger ces données :

              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  // Liez l'instance du contrat ERC20 à l'adresse donnée:9  let instance = ERC20.bind(event.address)1011  // Récupérez les informations du pool 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}

              Cette méthode est fonctionnelle, mais elle n’est pas idéale car elle ralentit l’indexation de notre Subgraph.

              Comment Éliminer les eth_calls

              Idéalement, le smart contract devrait être mis à jour pour émettre toutes les données nécessaires dans les événements. Par exemple, modifier le smart contract pour inclure les informations du pool dans l’événement pourrait éliminer le besoin de eth_calls:

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

              Grâce à cette mise à jour, le Subgraph peut indexer directement les données requises sans appel externe :

              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}

              Ceci est beaucoup plus performant car cela a éliminé le besoin de eth_calls.

              Comment Optimiser les eth_calls

              Si la modification du smart contract n’est pas possible et que les eth_calls sont nécessaires, lisez “Améliorer les Performances d’Indexation du Subgraph Facilement : Réduire les eth_calls” par Simon Emanuel Schmid pour apprendre diverses stratégies sur la façon d’optimiser les eth_calls.

              Réduire le Surcharge d’Exécution des eth_calls

              Pour les eth_calls qui ne peuvent pas être éliminés, la surcharge d’exécution qu’ils introduisent peut être minimisée en les déclarant dans le manifeste. Lorsque graph-node traite un bloc, il exécute tous les eth_calls déclarés en parallèle avant que les gestionnaires (handlers) soient exécutés. Les appels qui ne sont pas déclarés sont exécutés séquentiellement lorsque les gestionnaires sont exécutés. L’amélioration de la durée d’exécution vient du fait que les appels sont effectués en parallèle plutôt que séquentiellement - cela aide à réduire le temps total passé en appels mais ne l’élimine pas complètement.

              Actuellement, les eth_calls ne peuvent être déclarés que pour les gestionnaires d’événements. Dans le manifeste, écrivez

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

              La partie mise en évidence en jaune est la déclaration d’appel. La partie avant le deux-points est simplement une étiquette de texte utilisée uniquement pour les messages d’erreur. La partie après le deux-points a la forme Contract[address].function(params). Les valeurs permises pour l’adresse et les paramètres sont event.address et event.params.<name>.

              Le handler lui-même accède au résultat de ce eth_call exactement comme dans la section précédente en se liant au contrat et en effectuant l’appel. graph-node met en cache les résultats des eth_calls déclarés en mémoire et l’appel depuis le handler récupérera le résultat depuis ce cache en mémoire au lieu d’effectuer un appel RPC réel.

              Remarque : les appels eth_call déclarés ne peuvent être effectués que dans les Subgraphs dont la version specVersion est >= 1.2.0.

              Conclusion

              Vous pouvez améliorer de manière significative les performances d’indexation en minimisant ou en éliminant les eth_calls dans vos Subgraphs.

              Bonnes pratiques pour les subgraphs 1-6

              1. Améliorer la vitesse des requêtes avec l’élagage des Subgraphs

              2. Améliorer l’indexation et la réactivité des requêtes en utilisant @derivedFrom

              3. Améliorer l’indexation et les performances des requêtes en utilisant des entités immuables et des Bytes comme IDs

              4. Améliorer la vitesse d’indexation en évitant les eth_calls

              5. Simplifier et optimiser avec les séries chronologiques et les agrégations

              6. Utiliser le greffage pour un déploiement rapide des correctifs

              ⁠Edit on GitHub⁠

              Entités immuables et Bytes comme IDsSéries chronologiques et agrégations
              On this page
              • TLDR
              • Pourquoi Éviter les eth_calls est une Bonne Pratique
              • À quoi ressemble un eth_call ?
              • Comment Éliminer les eth_calls
              • Comment Optimiser les eth_calls
              • Réduire le Surcharge d’Exécution des eth_calls
              • Conclusion
              • Bonnes pratiques pour les subgraphs 1-6
              The GraphStatusTestnetActifs de la MarqueForumSécuritéPolitique de confidentialitéConditions d'utilisation