Duniter-squid

Je ne sais pas comment sont gérés les rollbacks en interne, mais quand on regarde les logs subsquid, on voit de temps en temps des rollbacks (je n’en ai pas sous la main parce qu’apparemment on n’est plus que deux validateurs).

Donc à mon avis il utilise des transactions postgresql ou quelque chose similaire qu’il est capable de rollback si le bloc n’est plus dans la branche principale. Et la finalisation permet d’oublier les transactions.

Il y a aussi une histoire de checkpoints, je ne sais pas à quoi ça correspond.

duniter-gdev-subsquid-processor-1  | {"level":2,"time":1706260885014,"ns":"sqd:processor","msg":"819433 / 819433, rate: 0 blocks/sec, mapping: 6 blocks/sec, 17 items/sec, eta: 0s"}
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1706260891005,"ns":"sqd:processor","msg":"819434 / 819434, rate: 0 blocks/sec, mapping: 6 blocks/sec, 18 items/sec, eta: 0s"}
duniter-gdev-subsquid-db-1         | 2024-01-26 09:21:31.569 UTC [27] LOG:  checkpoint starting: time
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1706260897076,"ns":"sqd:processor","msg":"819435 / 819435, rate: 0 blocks/sec, mapping: 6 blocks/sec, 17 items/sec, eta: 0s"}
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1706260903021,"ns":"sqd:processor","msg":"819436 / 819436, rate: 0 blocks/sec, mapping: 6 blocks/sec, 18 items/sec, eta: 0s"}
duniter-gdev-subsquid-db-1         | 2024-01-26 09:21:48.863 UTC [27] LOG:  checkpoint complete: wrote 175 buffers (1.1%); 0 WAL file(s) added, 0 removed, 0 recycled; write=17.245 s, sync=0.028 s, total=17.295 s; sync files=45, longest=0.010 s, average=0.001 s; distance=1117 kB, estimate=1117 kB
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1706260909052,"ns":"sqd:processor","msg":"819437 / 819437, rate: 0 blocks/sec, mapping: 6 blocks/sec, 18 items/sec, eta: 0s"}
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1706260915039,"ns":"sqd:processor","msg":"819438 / 819438, rate: 0 blocks/sec, mapping: 6 blocks/sec, 18 items/sec, eta: 0s"}

D’après la doc, c’est bien cela qui se passe en cas de rollback. Comme on pourrait le penser intuitivement, le processor squid va revert les changements en bdd en cas de détection de block orphelin, jusqu’à retrouver un bloc commun, puis ré-indexer à partir de ce bloc.

The processor will periodically (interval setting for EVM, Substrate) poll the RPC endpoint for changes in consensus. When the consensus changes, it will re-run the batch handler with the new consensus data and ask the Database to adjust its state. The Database then must roll back the changes made due to orphaned blocks and apply the new changes. With this, the state of the Database reflects the current blockchain consensus at all times.

Les blocs non finalisé sont flag comme étant hot par squid. Il semble être possible de le configurer pour indexer ou non les blocs “hots”.

Les checkpoints quand à eux, servent en cas d’erreur, de coupure ou de corruption de la base de donnée. Ca permet au processor de reprendre au dernier checkpoint valide en cas de problème, plutôt que de devoir tout réindexer.


PS: quand on tape “subsquid rollback sql” sur google, la première réponse c’est ce forum x)
Manque un peu de ressources côté subsquid…


Ce serait intéressant de tester ces rollback squid pour observer ça concrètement, mais je ne sais pas comment provoquer un fork volontairement sur une chaine de test.

4 Likes

En fait je me suis mal exprimé : je n’ai pas de doute sur les rollback des blocs, mais plutot sur les données indexées à partir des blocs. Transactions ou pas, il faut bien que l’algo parte des bloc, pour retrouver les données liées. Ces données filles doivent donc être liées par une lien physique (foreign key de la base de données) ou un logique (une colonne, sans lien physique : exemple : id d’évenement, id de block, etc.)

Mais effectivement, tester un rollback puis vérifier que tous les index ont bien été nettoyés devrait suffire.

Excellent ><
(il fallait immortaliser ça)

1 Like

Ah c’est marrant chez moi même en nav privée c’est vraiment le premier résultat

Si je tape juste “subsquid rollback” on arrive en 3ème position avec un message de moi …

bref ça m’est déjà arrivé de rechercher des choses sur substrate et tomber sur ce forum en premier aussi, on reste quand sur des sujets pas si répandu que ça ^^

1 Like

Hello,

Je viens de mettre en route mon instance d’indexer squid : https://indexer-gdev.pini.fr/graphql.

Ça a l’air de tourner.

1 Like

C’est une façon de voir le choses :face_with_raised_eyebrow:

Si ça a fonctionné un temps, je suis curieux d’avoir ta méthode car pour moi ça a semblé marcher, et puis non.

1 Like

Oui, pardon, j’ai dû le stopper hier soir car un autre service faisait la gueule sur mon serveur, et j’ai cru que ça venait de la charge CPU. Mais en fait non.

Je viens de le redémarrer.

EDIT: j’avais zappé la question sur la méthode. J’ai juste repris le fichier docker-compose.yml présent dans le dépôt duniter-squid, et j’ai adapté à mon infra.

4 Likes

Dès que Hugo valide ma MR on push une nouvelle image de squid, qui va changer un peu le schéma des identités notamment, donc attendez un peu avant d’adapter vos clients.

1 Like

Voici un exemple :

duniter-gdev-subsquid-processor-1  | {"level":2,"time":1707741258849,"ns":"sqd:processor","msg":"112204 / 112204, rate: 0 blocks/sec, mapping: 52 blocks/sec, 157 items/sec, eta: 0s"}
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1707741264854,"ns":"sqd:processor","msg":"112205 / 112205, rate: 0 blocks/sec, mapping: 53 blocks/sec, 158 items/sec, eta: 0s"}
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1707741270844,"ns":"sqd:processor","msg":"navigating a fork between 112205#07dcbf98 to 112206#dd639338 with a common base 112204#4b8068fa"}
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1707741270891,"ns":"sqd:processor","msg":"112206 / 112206, rate: 0 blocks/sec, mapping: 48 blocks/sec, 145 items/sec, eta: 0s"}
duniter-gdev-subsquid-processor-1  | {"level":2,"time":1707741276868,"ns":"sqd:processor","msg":"112207 / 112207, rate: 0 blocks/sec, mapping: 48 blocks/sec, 145 items/sec, eta: 0s"}
3 Likes

Nouvelle image Docker de l’indexer Squid disponible v0.1.1: https://hub.docker.com/r/h30x/duniter-squid/tags

Nouveautés:

  • fix identity statuts changes events
  • refactor membership fields in identity root field
  • add history of certifications by identity
  • add event foreignkey to memberships events to retrives timestamps and events stuff
  • convert identity username to utf8
  • add new history.json for gdev 0.8.0
  • mise à jour de la doc
  • add Universal Dividends list, UD revals and UD history by Identity

@kimamila cette version doit te permettre d’afficher la liste des DU par identités dans Cesium.
Si c’est galère de merger les historiques de transactions et les historiques de DU par identités, je ferais peut être une requête SQL qui merge les deux, je verrais si c’est pertinent (tu me diras).

L’historiques des DU par identité est calculé à la volé à partir des événements de création et de suppression successive de membership: src/server-extension/sql/du_history_query.sql · main · nodes / duniter-squid · GitLab

Exemple d’instance en prod sur cette version: https://gdev-squid.axiom-team.fr

Contrib de la release: @HugoTrentesaux @poka @cgeek (doc)


C’est la qu’on ce rends compte de l’utilité de Hasura, quand on ne l’a plus ^^
Il aurait permit de faire un computed field pour la requête SQL udHistory sans avoir à gérer manuellement le resolver graphql.

3 Likes

Heureusement que personne ne lit les commits :rofl:

3 Likes

oups:

duniter-squid-api-1        | 
duniter-squid-api-1        | <--- JS stacktrace --->
duniter-squid-api-1        | 
duniter-squid-api-1        | FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
duniter-squid-api-1        | ----- Native stack trace -----
duniter-squid-api-1        | 
duniter-squid-processor-1  | {"level":2,"time":1708122000110,"ns":"sqd:processor","msg":"175555 / 175555, rate: 0 blocks/sec, mapping: 76 blocks/sec, 227 items/sec, eta: 0s"}
duniter-squid-processor-1  | {"level":2,"time":1708122006087,"ns":"sqd:processor","msg":"175556 / 175556, rate: 0 blocks/sec, mapping: 77 blocks/sec, 231 items/sec, eta: 0s"}

Nécessite la résolution de ce ticket pour protéger le moteur graphql des DoS: Define @cardinality for every type in graphql.schema (#12) · Issues · nodes / duniter-squid · GitLab

(encore un sujet qui n’en serait pas avec Hasura qui permet de régler les limites générales en 3 clics).


edit: bon bah voilà j’ai craqué: Draft: Hasura as GraphQL engine (!14) · Merge requests · nodes / duniter-squid · GitLab

cc @ManUtopiK

https://gdev-squid.axiom-team.fr/console

my_hasura_password

2 Likes

Finalement tu as remis Hasura dans Subsquid !

La version gratuite de Hasura n’est pas non plus super sécurisée. Par défaut, il n’y a pas de rate limiter ni de limite de profondeur des requêtes.

2 Likes

Oui mais on peut le régler par table. J’avoue que je n’ai pas conscience des restructions de la version.

Mais rien que les computed fields pour la requête udHistory ça change tout.
Pas besoin de se taper tout le resolver graphql à la main avec la génération des champs et des clauses.

Ce qui est bien c’est que j’ai fait les deux implémentation donc on peut comparer.

Je vais prendre le temps de faire un poste pour détailler tous les avantages du combo subsquid pour le processor/generation typeORM model TS, et Hasura pour le moteur GraphQL.

2 Likes

Quand on fait une mise à jour de duniter squid, il faut tout réindexer de zéro, ou bien on peut conserver les données et ça se débrouille tout seul ?

Ça dépend de ce qu’on fait de notre côté. Jusque là comme on change pas mal de choses on regénère les migrations de la base de zéro, mais à terme si on ne fait plus que des runtime upgrade ou des changement mineurs on pourra fournir les migrations et continuer l’indexation sans repartir de zéro.

Pas besoin de tout réindexer, les migrations Hasura font leur boulo, ça se débrouille tout seul.

1 Like

Ça c’est vrai que si on génère des migrations incrémentales (que ce soir Hasura ou Squid). Et ça n’a d’intérêt de faire des migrations incrémentales que si on prévoit de ne pas ré-indexer. Mais si on ajoute quelque chose (par exemple le DU), il ne sera indexé qu’à partir de la mise à jour, d’où l’intérêt de ré-indexer depuis le début quand on ajoute quelque chose. Tant qu’on est sur un réseau de test récent, c’est assez court de tout ré-indexer (quelques minutes). Quand on aura plusieurs années de blockchain, on évitera de ré-indexer sauf pour les grosses modifications de l’indexeur.

3 Likes

Je viens de regarder sur le nouveau endpoint. Toutes mes requetes Cs² ne passent plus :frowning: snifff car le schema graphql a changé.
par exemple, pour récupérer les certifications, j’avais cette requete :

query CertsConnectionByIssuer($address: String!, $limit: Int!, $orderBy: [CertOrderByInput!]!, $after: String) {
  certsConnection(
    first: $limit,
    after: $after,
    orderBy: $orderBy,
    where: {issuer: {account: {id_eq: $address}}}
  ) {
    totalCount
    pageInfo {
      endCursor
      hasNextPage
    }
    edges {
      node {
        ...Cert
        identity: receiver {
          ...LightIdentity
        }
      }
    }
  }
}
 fragment Cert on Cert {
    __typename
    id
    expireOn
    createdOn
    creation {
      id
      blockNumber
    }
    renewal {
      id
      blockNumber
    }
    removal {
      id
      blockNumber
    }
  }
fragment LightIdentity on Identity {
  __typename
  id
  name
  account {
    __typename
    id
  }
  membership {
    __typename
    id
  }
}

Comment faire de même sur le endpoint Hasura ?

1 Like