graphprotocol / graphprotocol/graph-node

Address certain corner cases of time-travel queries by block hash

Offen
#1,405 6 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

area/graphql area/store bug determinism
Vorherrschende Sprache
Rust
Sterne
3.2k
Forks
1.1k
Ø Merge
4 T. 1 Std.
Gemergte PRs (30 T.)
1

Beschreibung

Time-travel queries introduced in PR #1397 might still return incorrect results in certain circumstances. A query like query { things(block: { hash: $hash }) { ... } } might return data from different blocks if either

  • [H1] the block with the given hash is not on the chain starting at the subgraph's current head
  • [H2] the block gets removed from the subgraph's chain because of a block reorganization running concurrently with query execution (solved by PR #1801, not an issue anymore, only mentioned for documentation purposes)

Users can make sure they do not encounter this problem by only querying per block hash for blocks that are final, and by ensuring that the block hash is on the main chain.

Problem H1 can happen if we downloaded a block with $hash that was later removed from the subgraph's chain because of a reorganization, and is possible for any block, no matter whether it can be considered final or not. The query should return an error, as the block is not on the main chain, but might return successfully. The data returned will be from the block on the main chain that has the same number as block $hash.

Problem H2 can only happen for blocks that can not be considered final yet; for graph_node, that means that they are within REORG_THRESHOLD of the current chain head, but in practice only affects blocks within two or three blocks of the chain head. The query should return an error, as the block $hash is no longer on the main chain when the query finishes, but will return successfully with data that might come from either the block with $hash or one of the siblings with the same number that graph-node downloaded while it was processing the query.

Solving H1

Solving this issue requires that we have the infrastructure in place to answer the question "Is the block $hash on the chain starting at the subgraph's current head?"

Phase 1 of the block explorer will make it possible to distinguish between blocks on the main chain and ommers. If block $hash is at least REORG_THRESHOLD away from the chain head, we reject the query if the block is an ommer. For blocks $hash within REORG_THRESHOLD of the chain head, we will keep a list of (block_hash, block_number) for each subgraph, tying the subgraph's current head to the finalized chain, and reject the query if $hash is not in that list.

Solving H2

For this, we need to detect that the subgraph's view of the chain was reorganized while the query was running; this is only necessary for blocks that are not final yet, i.e., that are within REORG_THRESHOLD of the chain head. To support this check, we will add a generation attribute to each SubgraphDeployment that is incremented every time the subgraph's chain is reorganized. We retrieve the generation attribute before we start executing the query, and check that it has not changed after we have finished executing the query. If it did change, we report an error to the user.

Time-travel queries by block number

Problem H1 does not affect these queries, but problem H2 could. It might be worth putting these checks in place when doing a time-travel query by block number, i.e. get the hash of the block with the given number before executing the query, and then executing as if the user had given us that hash. That ensures that the result of such a query comes from a consistent state of the chain.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit der Durchsicht von PR #1397 und der Block-Explorer-Arbeit in PR #1383, um den bestehenden Pfad für Zeitreiseabfragen zu verstehen. Verfolge die hier beschriebenen Fälle H1 und H2, einschließlich der Prüfungen der finalisierten Chain und der Chain-Reorganisationen des Subgraphs. Die Arbeit ist abgeschlossen, wenn Abfragen Hashes ablehnen, die nicht auf der Main Chain liegen, und Reorganisationen während der Ausführung erkennen, wobei das vorgeschlagene Verhalten zur Konsistenz der Blocknummer bewertet wurde.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
blockchain, graphql, rust
Bereich
api, backend, blockchain
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.