Cookbook > Debugging de Subgraphs Rápido e Fácil Com Forks

Debugging de Subgraphs Rápido e Fácil Com Forks

Reading time: 4 min

Assim como vários sistemas que processam uma abundância de dados, os Indexadores do Graph (Graph Nodes) podem demorar um pouco para sincronizar o seu subgraph com a blockchain de destino. A discrepância entre mudanças rápidas para fins de debugging e os longos tempos de espera necessários para o indexing é extremamente contraprodutiva, e nós sabemos muito bem disso. É por isso que introduzimos o subgraph forking, desenvolvido pela LimeChain; neste artigo, veja como é possível acelerar bastante o debugging de subgraphs!

Ok, o que é isso?

Link para esta seção

Subgraph forking é o processo de retirar entidades tranquilamente do armazenamento de outro subgraph (sendo muitas vezes remoto).

No contexto do debugging, o subgraph forking permite debugar o seu subgraph falho no bloco X sem precisar esperar que ele sincronize até o bloco X.

O quê?! Como?!

Link para esta seção

Quando lanças um subgraph a um Graph Node remoto para o indexing e ele falha no bloco X, a boa notícia é que o Graph Node ainda servirá queries GraphQL com seu armazenamento, que é sincronizado até o bloco X. Ótimo! Podemos aproveitar este armazenamento "atualizado" para consertar os bugs que surgem ao indexar o bloco X.

Resumindo, faremos um fork do subgraph falho de um Graph Node remoto para garantir que o subgraph seja indexado até o bloco X, para fornecer ao subgraph lançado localmente uma visão atualizada do estado da indexação, sendo este debugado no bloco X.

Por favor, quero ver códigos!

Link para esta seção

Para manter o foco no debugging dos subgraphs, vamos simplificar as coisas e seguir o exemplo de subgraph com a indexação do contrato inteligente do Ethereum Gravity.

Aqui estão os handlers definidos para o indexamento dos Gravatars, sem qualquer bug:

export function handleNewGravatar(event: NewGravatar): void {
let gravatar = new Gravatar(event.params.id.toHex().toString())
gravatar.owner = event.params.owner
gravatar.displayName = event.params.displayName
gravatar.imageUrl = event.params.imageUrl
gravatar.save()
}
export function handleUpdatedGravatar(event: UpdatedGravatar): void {
let gravatar = Gravatar.load(event.params.id.toI32().toString())
if (gravatar == null) {
log.critical('Gravatar not found!', [])
return
}
gravatar.owner = event.params.owner
gravatar.displayName = event.params.displayName
gravatar.imageUrl = event.params.imageUrl
gravatar.save()
}

Que pena! Quando eu lanço o meu lindo subgraph ao Subgraph Studio, ele falha com o erro "Gravatar not found" (Gravatar não encontrado).

A maneira mais comum de tentar consertar este erro é:

  1. Fazer uma mudança na fonte dos mapeamentos, que talvez possa resolver o problema (mas é claro que não vai).
  2. Reeditar o subgraph ao Subgraph Studio (ou outro Graph Node remoto).
  3. Esperar que ele se sincronize.
  4. Se quebrar novamente, volte ao passo 1. Se não: Eba!

É um típico processo ordinário de debug, mas há um passo que retarda muito o processo: 3. Esperar que ele se sincronize.

Com o subgraph forking, podemos essencialmente eliminar este passo. Ele é algo assim:

  1. Crie um Graph Node local com o conjunto de fork-base apropriado.
  2. Faça uma mudança na fonte dos mapeamentos, que talvez possa resolver o problema.
  3. Lance ao Graph Node local, faça um fork do subgraph falho e comece do bloco problemático.
  4. Se quebrar novamente, volte ao passo 1. Se não: Eba!

Agora, você deve ter duas perguntas:

  1. Que fork-base???
  2. Forkar quem?!

E eu respondo:

  1. fork-base é o URL "base", tal que quando o subgraph id é atrelado, o URL resultante (<fork-base>/<subgraph-id>) se torna um endpoint GraphQL válido para o armazenamento do subgraph.
  2. Forking é fácil, não precisa se preocupar:
$ graph deploy <subgraph-name> --debug-fork <subgraph-id> --ipfs http://localhost:5001 --node http://localhost:8020

Aliás, não esqueça de preencher o campo dataSources.source.startBlock no manifest do subgraph com o número do bloco problemático, para pular a indexação de blocos desnecessários e tomar vantagem do fork!

Aqui está o que eu faço:

  1. Eu crio um Graph Node local (veja como) com a opção fork-base de https://api.thegraph.com/subgraphs/id/, já que eu vou forkar um subgraph, o bugado que eu lancei anteriormente, do Subgraph Studio.
$ cargo run -p graph-node --release -- \
--postgres-url postgresql://USERNAME[:PASSWORD]@localhost:5432/graph-node \
--ethereum-rpc NETWORK_NAME:[CAPABILITIES]:URL \
--ipfs 127.0.0.1:5001
--fork-base https://api.thegraph.com/subgraphs/id/
  1. Após vistoriar com cuidado, percebo uma discrepância nas representações de id usadas ao indexar Gravatars nos meus dois handlers. Enquanto handleNewGravatar o converte a um hex (event.params.id.toHex()), o handleUpdatedGravatar usa um int32 (event.params.id.toI32()). Assim, o handleUpdatedGravatar entra em pânico com o "Gravatar não encontrado!". Eu faço os dois converterem o id em um hex.
  2. Após ter feito as mudanças, lanço o meu subgraph ao Graph Node local, forkando o subgraph falho e programando o dataSources.source.startBlock em 6190343 no subgraph.yaml:
$ graph deploy gravity --debug-fork QmNp169tKvomnH3cPXTfGg4ZEhAHA6kEq5oy1XDqAxqHmW --ipfs http://localhost:5001 --node http://localhost:8020
  1. Eu verifico os logs produzidos pelo Graph Node local e... eba! Parece que deu tudo certo.
  2. Lanço o meu subgraph, agora livre de bugs, a um Graph Node remoto e vivo feliz para sempre! (mas sem batatas)
Editar página

Anterior
Python (Subgrounds)
Próximo
Construção de Subgraphs na NEAR
Editar página