Recetario > Debugging rápido y sencillo de subgrafos mediante Forks

Debugging rápido y sencillo de subgrafos mediante Forks

Reading time: 4 min

Al igual que con muchos sistemas que procesan grandes cantidades de datos, los indexadores de The Graph (Graph Nodes) pueden tardar bastante en sincronizar su subgrafo con la blockchain de destino. La discrepancia entre los cambios rápidos con fines de debugging y los largos tiempos de espera necesarios para la indexación es extremadamente contraproducente y somos muy conscientes de ello. Por eso introducimos subgraph forking, desarrollados por LimeChain, y en este artículo te mostramos cómo se puede utilizar esta función para acelerar sustancialmente el debugging del subgrafo!

¿Bien, qué es?

Enlace a esta sección

Subgraph forking es el proceso de obtener entidades de otro almacén de subgrafos (por lo general uno remoto).

En el contexto de la depuración, subgraph forking te permite depurar tu subgrafo fallido en el bloque X sin necesidad de esperar a sincronizar para bloquear X.

¡¿Qué?! ¿Cómo?

Enlace a esta sección

Cuando implementas un subgrafo en un nodo Graph remoto para la indexación y falla en el bloque X, la buena noticia es que el nodo Graph seguirá atendiendo consultas de GraphQL usando su tienda, que está sincronizado para bloquear X. ¡Genial! Esto significa que podemos aprovechar esta tienda "actualizada" para corregir los errores que surgen al indexar el bloque X.

En pocas palabras, vamos a bifurcar el subgrafo fallido desde un nodo de Graph remoto que garantiza que el subgrafo se indexe para bloquear X para proporcionar al subgrafo implementado localmente que se está depurando en el bloque X una vista actualizada del estado de indexación.

¡Por favor, muéstrame algo de código!

Enlace a esta sección

Para mantenernos enfocados en el debugging de subgrafos, simplifiquemos las cosas y sigamos con el example-subgraph que indexa el contrato inteligente Ethereum Gravity.

Estos son los handlers definidos para indexar Gravatars, sin errores de ningún tipo:

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()
}

Uy, qué mala suerte, cuando despliego mi subgrafo de aspecto perfecto en el Servicio Alojado falla con el error "¡Gravatar no encontrado!".

La forma habitual de intentar una solución es:

  1. Realiza un cambio en la fuente de mapeos, que crees que resolverá el problema (aunque sé que no lo hará).
  2. Vuelve a desplegar el subgrafo en el Servicio Alojado (o en otro nodo Graph remoto).
  3. Espera a que se sincronice.
  4. Si se vuelve a romper vuelve a 1, de lo contrario: ¡Hurra!

De hecho, es bastante familiar para un proceso de depuración ordinario, pero hay un paso que ralentiza terriblemente el proceso: 3. Espera a que se sincronice.

Usando bifurcación de subgrafo podemos eliminar esencialmente este paso. Así es como se ve:

  1. Activa un nodo Graph local con el conjunto fork-base adecuado.
  2. Realiza un cambio en la fuente de mapeos, que crees que resolverá el problema.
  3. Implementa en el nodo Graph local, bifurcando el subgrafo defectuoso y ** a partir del bloque problemático**.
  4. Si se vuelve a romper, vuelve a 1, de lo contrario: ¡Hurra!

Ahora, puedes tener 2 preguntas:

  1. fork-base que???
  2. Bifurcando a quien?!

Y yo respondo:

  1. fork-base es la URL "base", de modo que cuando se agrega el id de subgrafo, la URL resultante (<fork- base>/<subgraph-id>) es un punto final de GraphQL válido para la tienda del subgrafo.
  2. Bifurcar es fácil, no hay necesidad de sudar:
$ graph deploy <subgraph-name> --debug-fork <subgraph-id> --ipfs http://localhost:5001 --node http://localhost:8020

Además, no olvides configurar el campo dataSources.source.startBlock en el manifiesto del subgrafo con el número del bloque problemático, para que puedas omitir la indexación de bloques innecesarios y aprovechar la bifurcación!

Entonces, esto es lo que hago:

  1. Hago girar un nodo graph local (aquí se explica cómo hacerlo) con la opción fork-base establecida en: https://api.thegraph.com/subgraphs/id/, ya que bifurcaré un subgrafo, el buggy que implementé anteriormente, desde el HostedService.
$ 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. Después de una inspección cuidadosa, noté que hay una falta de coincidencia en las representaciones de id utilizadas al indexar Gravatar en mis dos handlers. Mientras que handleNewGravatar lo convierte en hexadecimal (event.params.id.toHex()), handleUpdatedGravatar usa un int32 (event. params.id.toI32()) que hace que handleUpdatedGravatar entre en pánico con "¡Gravatar no encontrado!". Hago que ambos conviertan el id en un hexadecimal.
  2. Después de realizar los cambios, implemento mi subgrafo en el nodo Graph local, bifurcando el subgrafo defectuoso y configurando dataSources.source.startBlock a 6190343 en subgraph.yaml:
$ graph deploy gravity --debug-fork QmNp169tKvomnH3cPXTfGg4ZEhAHA6kEq5oy1XDqAxqHmW --ipfs http://localhost:5001 --node http://localhost:8020
  1. Inspecciono los registros producidos por el nodo Graph local y, ¡Hurra!, todo parece estar funcionando.
  2. ¡Deployo mi subgrafo ahora libre de errores en un nodo Graph remoto y vivo feliz para siempre! (aunque sin papas)
  3. Fin...
Editar página

Anterior
Actualizando un Subgrafo Existente a la Red de The Graph
Siguiente
Construcción de subgrafos en NEAR
Editar página