Je compte utiliser cette fonction pour Gecko, mais pour le moment, je n’utilise pas encore de nœud squid, et je n’ai pas vraiment envie de le faire gérer 3 types de nœuds différentes, sans compter les datapods non encore implémentés…
J’ai l’impression que Squid rempli toutes les fonctions qu’on attendrais d’un indexer clé en main, adapté pour substrate et personnalisable. Et tu sembles bien le manier désormais.
Mon avis est de lâcher l’indexer hasura pour passer sur squid, histoire de simplifier la stack et concentrer les forces.
La seule chose qui va me manquer avec squid est la fonctionnalité de recherche naturelle des noms d’identités que Manu avait intégré, ça c’est quand même très utile.
Je ne sais pas si c’est possible de migrer cette fonctionnalité vers notre squid.
Ce n’est que mon avis, peut-être qu’en creuser plus je vais m’apercevoir d’autres intérêts de garder l’indexer hasura.
Je suis d’accord, il ne faut pas que les clients aient à gérer deux indexeurs différents. Je voulais expérimenter squid pour l’indexation générique, et je suis tombé dans le trou parce que c’était trop tentant d’implémenter un indexeur.
L’avantage de squid est la génération automatique des types à partir des runtime metadata (sqd typegen) et la génération automatique des classes typeorm à partir du schéma dans leur dialecte graphql (sqd codegen). Cela rend l’ingestion facile (les types sont connus) et le dépôt dans la base facile (pas besoin de connaître sql, juste des objets typescript).
Il faut que je discute avec Manu pour voir si on peut pas brancher Hasura sur la base postgresql-15 pour bénéficier de ce qu’il sait faire avec (tables virtuelles, fonctions sql…) mais sans utiliser la partie migrations qui est gérée par squid. Et pour l’API relay, je ne sais pas. On dirait que le système de pagination de squid ne fonctionne pas comme celui de Hasura.
Autre avantage, il y a un bug que je n’ai pas réussi à résoudre dans l’indexeur mais que j’ai réglé dans squid : l’ajout du compte avant la transaction qui le crée. C’est toujours dans les logs de l’indexeur malgré la priorisation des événements mise en place par manu, et il manque donc les transactions qui créent un compte.
Configurer PostgreSQL peut se faire sans Hasura, il suffit du client Pgadmin officiel ou de n’importe quel éditeur de BDD compatible Postgresql.
Je connais assez bien PostgreSQL et je peux aider.
Après je ne sais pas comment faire dans Squid pour qu’il expose les configs Postgresql maisons en GraphQL…
C’est dommage que Squid ait abandonné Hasura…(si je comprends bien).
First of all, thanks a lot for choosing Subsquid for indexing your Substrate data and posting this issue. We definitely considered Hasura and GraphiQL before building OpenReader. Keep in mind that Squid API is designed to be lightweight and easily deployable yet expressive, as we progress towards complete decentralization.
Here’s why:
We wanted a smooth and vertically integrated solution for building the schema, typescript models, migrations and GraphQL API from a single schema file.
We wanted to have full control of how data is fetched and what GraphQL features we want to support off the shelf. Hasura does not provide a feasible solution to the features we’d like to have. To name a few:
Custom scalars with full control of marshalling/unmarshalling (e.g. BigInt, Float. Address scalars)
JSONB queries (Hasura offers very limited filtering support)
Interfaces and Union types
Full-text search support
We wanted to support custom GraphQL resolvers/API extensions while keeping it simple and easily portable
Unified codebase (Typescript)
Minimal external dependencies to make decentralisation easier (remember, we’re not just building a centralized bespoke API but a decentralized marketplace for hosting Squid APIs)
Also, we don’t need an ORM with Hasura. Hasura is an ORM on top of database!
Why using typeorm in squid to build the graphql api when Hasura could do that out of the box?
I am not sure what you mean here. GraphQL server does not use TypeORM. TypeORM is indeed used under the hood by the Squid Processor, which is an ETL process which runs independently from the presentation layer.
At the same time it’s a totally legit case to use Squid API as a part of a top-level Hasura endpoint or do schema stitching any other way, if it suits you best.
I’m genuinely interested in your use-case and would be happy to discuss more in TG – feel free to ping me @dzlzv on Telegram.
Hormis le fait qu’il essai de me vendre leur solution payante de cloud ArrowSquid, voici une partie de ses réponses qui semblent confirmer les propos de @vit . Il semble aussi dire qu’on peut tout à fait remplacer le serveur graphql de squid qui est optionnel, par hasura.
The ArrowSquid solution is a decentralized data lake, where the whole historical data is compressed and distributed across a swarm of workers. This is what makes the indexing part so fast, as you don’t ingest this data from the RPC but rather from a data lake
As it only can be deployed to a decentralized network, there’s no option to self-host this part
Yet, you can use the ArrowSquid sdk using only the RPC, but it’s slow
the sdk is open-sourced
in this repo this seems to be exactly the case — RPC-only setup, which indeed you can fully self-host without integrating to the data lake (which would enable the archive: endpoint)
as for the FTS queries — yes, you can certainly do that, either by using the built-in PG capabilities or additionally pushing the data to ElasticSearch or smth else from your processor
you can also ditch our built-in graphql server and go for hasura if you want, it’s 100% optional
Moi:
Sound squid is quite flexible. thank you for this confirmation.
I don’t understand why arrowsquid swarm should offer faster solution than simple RPC setup. Do you have a technical documentation about the way ArrowSquid works ?
the data lake enables batch-queries, so you extract tens of thousands of events from hundreds of blocks in a single call, then batch-transform it. So it normally takes just a couple of minutes vs hours/days from the rpc
the rpc essentially goes through each and every block so the longer is the chain the more requests you’d need to backfill
Moi:
thank you for this informations, we will discuss about all of this
I think we will try to replace you graphql server by Hasura, but that mean we need to dig how squid is build.
why? you can just spin it on top of the db, and you have full control over the schema (it’s in the migrations folder)
so integrating hasura should be very straightforward
Moi:
In fact I didn’t work on this part yet, just my friends, so yes maybe it’s just simple
En fait c’est pas tout à fait vrai qu’on a total contrôle sur la structure de la db avec squid si on veut bénéficier de la génération de code, parce qu’on doit avoir un ID string, alors que parfois on serait content d’utiliser directement des int.
Mais c’est un compromis totalement acceptable, et oui, on peut brancher Hasura dessus, pour servir les données avec un autre schéma, mais ça reste quand même assez lié aux relations qu’on choisit entre les objets.
Aha, il se fait attaquer par une orde de juniste de tous les côtés ^^
Ok c’est bien ce que je constatais dans le json du dossier db/migrations, je ne comprennais ce que c’était que tous ces ID.
Mais il va falloir que je mette la main à la patte une bonne fois pour toute sur cette stack comme tu l’as fait pout bien comprendre, et arreter de tourner autour du pot.
Ah oui je suis en train de retracer tes questions/réponses depuis le 21 Novembre, c’est drôle ^^
En tout cas il est réactif!
soit je prends directement l’ID de l’événement qui ressemble à
numéro de bloc - début du hash du bloc - numéro de l’événement dans le bloc
Voilà. Simple et efficace, ça me convient comme compromis même si c’est moins élégant que les primary keys multiples qu’on avait mis dans l’autre indexeur.
Si tu veux qu’on se fasse un peu de peer coding, je crois que @flodef aussi était preneur.
Si, avec le modèle de données que j’ai choisi, c’est unique. Le idty_index est unique par design dans Duniter, et la certification est unique, les renouvellements sont gérés dans d’autres événements rattachés à la certification.
Il reste le problème des différentes branches, par exemple si une même certification est créée sur deux branches différentes, mais je n’ai pas encore creusé ça.
Tu peux regarder un peu le schéma que j’ai mis, ça permet ce genre de choses :
query MyQuery {
identities(where: {name_eq: "HugoTrentesaux"}) {
id
index
name
certIssued(where: {receiver: {name_eq: "pokaa"}}) {
id
createdOn
renewal {
id
blockNumber
}
receiver {
name
index
}
}
}
}
Ça permet pour une certification (en l’occurrence de moi vers toi) de voir tous les renouvellements. Et d’ailleurs je me rends compte que j’ai mal géré l’événement NewCert, que je devrais traiter comme un renouvellement si la certification existe déjà. Mais c’est aussi un problème de l’API des événements de Duniter, ça n’a pas tellement de sens de distinguer NewCert et RenewedCert, ça pourrait être le même événement éventuellement avec un booléen “renewal”, ce serait plus clair je trouve.
J’ai re-réfléchi à ça en dormant, et je vais probablement changer le modèle de la certification pour prendre ceci en compte. En gros, chaque objet certification serait une certification continue dans le temps associée à une liste de renouvellements. Si une certification expire et est recréée, ça ferait un nouvel objet certification. Et donc le champ createdOn serait le bloc de création de la certification et expiredOn ne serait défini que si la certification a expiré. Mais je suis pas sûr. Voilà les deux choix de modèles que je propose :
Modèle certification unique
On a une unique instance d’une certification de A→B, associée à une liste de créations, renouvellements, expirations. Il peut y avoir des discontinuités, c’est-à-dire des périodes où la certification n’est plus valide entre une expiration et la re-création qui la suit.
Modèle de certification continue
On a une instance de certification par période de validité continue. Donc on peut avoir une instance A→B pour la période 1 avec des renouvellements, puis une nouvelle instance de la certification A→B pour la période 2 avec encore des renouvellements.
J’aimerais des avis là dessus, pour éviter d’implémenter quelque chose à chaque fois que j’ai une nouvelle idée et de jamais stabiliser
Par rapport à l’identité, l’id pourrait être celui de l’événement de création d’identité.
En effet, je suis chaud. J’avais plein de choses à gérer en off, mais c’est toujours un plaisir de passer un moment productif et rigolo ensemble. Joindre l’utile à l’agréable
query MyQuery {
identities(where: {name_eq: "HugoTrentesaux"}) {
name
certIssued(where: {createdOn_not_eq: 0}) {
id
active
createdOn
expireOn
issuer {
name
id
}
receiver {
name
id
}
creation {
id
}
renewal {
id
}
removal {
id
}
}
}
}
chaque certification A→B n’existe qu’en un seul exemplaire, mais avec createdOn et expireOn actualisés
on peut savoir si une certification est active avec le champ “active”
les id des certifications sont uniques et correspondent (sauf genesis) à l’event id de l’événement de création de la certification
les id des identités correspondent (sauf genesis) à l’event id de l’événement de création d’identité
à chaque certification est associée sa liste de création, renouvellement, suppression
Cela veut dire que si une certification est créée, puis supprimée, puis recréée, son id sera quand même celui de l’événement de la première création. Est-ce que ça te semble mieux @poka ?
Il faut juste que je répare le son sur mon ordi sinon ça va pas être pratique
Tu as suivi un peu sur le forum, quand même ? Il s’est passé pas mal de choses.
Je viens de regarder vite fait, ils ont viré Hasura j’ai l’impression. Du coup mes remarques sur le fait que c’était monté à l’envers ne tiennent plus.
En regardant le code de @HugoTrentesaux, ça a l’air moins usine à gaz qu’avant.
Hasura n’a besoin que d’une bdd postgresql, donc c’est toujours possible…
query MyQuery {
certById(id: "5CQ8T4qpbYJq7uVsxGPQ5q2df7x3Wa4aRY6HUWMBYjfLZhnn") {
id
}
}
→
{
"data": {
"certById": null
}
}
Donc tous les champs id subsquid correspondent aux clés publique en hexadécimal, sauf pour certaines requêtes que tu écris toi même ?
Tu penses que ce serait possible de faire en sorte que le champs id corresponde toujours aux adresses ss58 ?
Ca éviterai de devoir générer les trousseaux à partir des adresses ss58 pour retrouver la pubkey pour chaque adresse requêté côté client.
Ce n’est pas bloquant, mais ce serait une petite optimisation côté client.
Et ce serait surtout plus pratique pour manipuler le graphiql à la main.
J’attends avant d’implémenter ce subsquid pour remplacer l’indexer hasura, car on évoque l’idée d’y branché hasura de nouveau, ou pas, ce qui changerait probablement encore les requêtes donc je ne veux pas repasser dessus pour rien (je l’ai déjà assez fait depuis l’époque GVA/cs+…).
L’id des certifications genesis sont sous la forme : genesis-{issuer_index}-{receiver_index}, l’id des évenements sont sous la forme : {block_number}-{block_hash}-{event_number}. Et l’intérêt de ça que je n’avais pas expliqué est que subsquid indexe tous les blocs (pas uniquement finalisés) et gère lui-même le rollback si nécessaire. Donc c’est bien d’avoir le hash du bloc dans l’identifiant.