J’ai donc continué un peu l’expérimentation sur subsquid et ça en vaut vraiment la peine. En moins d’une heure, j’ai ajouté une indexation générique de tous les calls par leur nom, l’indexation des 42000 blocs se fait en une dizaine de secondes et je suis en mesure de vous sortir la liste de tous les calls appelé depuis le début de la ĞDev (hors Timestamp.Set
que j’ai exclu de l’indexation) :
Requête
query Query {
calls {
name
blockNumber
}
}
Réponse
{
"data": {
"calls": [
{
"name": "Balances.transfer",
"blockNumber": 14435
},
{
"name": "Identity.link_account",
"blockNumber": 14646
},
{
"name": "Balances.transfer_all",
"blockNumber": 15680
},
{
"name": "Balances.transfer_all",
"blockNumber": 16128
},
{
"name": "Balances.transfer",
"blockNumber": 30277
},
{
"name": "Identity.change_owner_key",
"blockNumber": 30287
},
{
"name": "SmithMembership.revoke_membership",
"blockNumber": 30420
},
{
"name": "Identity.change_owner_key",
"blockNumber": 30424
},
{
"name": "Identity.change_owner_key",
"blockNumber": 30504
},
{
"name": "SmithMembership.request_membership",
"blockNumber": 30516
},
{
"name": "SmithMembership.claim_membership",
"blockNumber": 30525
},
{
"name": "AuthorityMembers.set_session_keys",
"blockNumber": 30630
},
{
"name": "AuthorityMembers.set_session_keys",
"blockNumber": 30776
},
{
"name": "Identity.link_account",
"blockNumber": 30801
},
{
"name": "AuthorityMembers.set_session_keys",
"blockNumber": 30804
},
{
"name": "AuthorityMembers.go_online",
"blockNumber": 30813
},
{
"name": "Balances.transfer",
"blockNumber": 34943
},
{
"name": "Balances.transfer",
"blockNumber": 34960
},
{
"name": "Balances.transfer",
"blockNumber": 34964
},
{
"name": "Balances.transfer",
"blockNumber": 34991
},
{
"name": "Balances.transfer",
"blockNumber": 35005
},
{
"name": "Cert.add_cert",
"blockNumber": 35121
}
]
}
}
Bien entendu je peux filtrer uniquement un type de call :
query Query {
calls(where: {name_eq: "Identity.change_owner_key"}) {
name
blockNumber
}
}
{
"data": {
"calls": [
{
"name": "Identity.change_owner_key",
"blockNumber": 30287
},
{
"name": "Identity.change_owner_key",
"blockNumber": 30424
},
{
"name": "Identity.change_owner_key",
"blockNumber": 30504
}
]
}
}
et je peux facilement ajouter les arguments du call, les événements liés…
La facilité de développement et la puissance que ça offre est déconcertante, quand je compare au temps qu’il m’a fallu pour rentrer dans l’indexeur, et réaliser des modifications.
Avantages de subsquid :
- le code est fait pour les traitements par batch, et on peut générer une archive pour aller encore plus vite que l’indexation par RPC pour quand la blockchain sera plus grosse et plus fournie
- le même code peut être utilisé pour l’indexation du genesis et des blocs
- on n’a jamais à toucher à SQL, tout est derrière une couche typeorm
- tout est nativement typé
- tout est fait pour gérer les types substrate
- toutes les informations des blocs, événements, calls, extrinsics, sont accessibles facilement lors de l’indexation, il n’y a pas de gymnastique pour accéder à des infos comme le timestamp
Après l’avoir découvert, j’imagine mal me passer d’un tel outil pour débugger. En deux jours j’ai découvert tous les principes de base et en une semaine je devrais être capable d’avoir redéveloppé les fonctionnalités de duniter-indexer “en mieux”.
J’aimerais quand même faire un point sur les avantages de duniter-indexer :
- l’interface graphique hasura permet de bien comprendre la structure de la base de données et ajouter des relations sophistiquées facilement sans toucher manuellement à un schéma graphql
- hasura permet des réglages fins sur les droits par exemple pour limiter l’utilisation de requêtes lourdes en calcul
- le niveau de compréhension de substrate nécessaire pour développer sur l’indexeur est moindre
Pour l’instant je suis partagé entre les deux. Si je reste seul à développer l’indexeur, je préférerais travailler dans le framework subsquid. Si on était plusieurs, ça pourrait dépendre des préférences des autres.