Incohérence dans les données? -- certifications expirées

J’étais en train de travailler sur la ǦTest quand je suis tombé sur le cas suivant : des certifications dont la date d’expiration était passée mais qui n’avaient pas encore expiré. J’aimerais comprendre où est le problème pour savoir si on peut l’ignorer sans problème.

  • j’utilise dex pour lire la base de données, comme indiqué dans py-g1-migrator, j’ai ajouté quelques exports sur la branche hugo-dev
  • mon export a eu lieu au bloc 640233 avec un medianTime de 1688284294 (2023-07-02 T 07:51:34)
  • je lance ./main.py 1688284294 de py-g1-migrator sur ma branche hugo-gtest pour simuler un lancement de gtest au moment où a lieu l’export
  • le passage concerné est le suivant : lib/functions.py · 24ef87a2a612167e67524637324bf51fa0e980d3 · tools / py-g1-migrator · GitLab
    • les certifications avec expired_on non nul sont ignorées (cf ci-dessous)
    • reste les certifications avec expires_on (ci-dessous)
  • le problème est qu’il reste des certifications avec expires_on inférieur a la date d’export mais non encore expirées
certification reçues par Jovivant expirées
"expired_on": 1688259637,
"issuer": "12gdsZHdWEcahj8dUpvQrNE7qwbDuweG98qF8uXkZTNF",

"expired_on": 1688259228,
"issuer": "4ZK4amjrVdtdA4ybkt6MhpyQnvZVVmWXeDNfzAzb88gq",

"expired_on": 1688259228,
"issuer": "EBE9wtQREgFwR9Z5nGXc8MWnye6cpSgE7LQuiDJGgymv",

"expired_on": 1688257062,
"issuer": "FosBhXpP9YhpgfCM4VxHdVfQxCFrN8y5xZqnSL3YczBm",

"expired_on": 1688257062,
"issuer": "9Le6Bpfi6RkD2r9rPjKysNcFwVgFRzSPqPqZWrqNdtif",

"expired_on": 1688261896,
"issuer": "9kgbU7f3eBckpX3YrLEu6iS92gqcbQQeAscN9rhPmU76",

"expired_on": 1688258055,
"issuer": "Da99uD7wo3MyPYxJRPET5yEPs3XPERgXAEoUKWJk96AV",

"expired_on": 1688254133,
"issuer": "4ksLLJuqw8LpZeuhdv9C5EEfWK1QapWGWmDKy9vJt3RS",

"expired_on": 1688255395,
"issuer": "ER8fgx3nrsAEGNMwX5e5g1WAsG8fHSfEEQ9spudcqcSq",
certifications reçues par Jovivant non expirées
"expires_on": 1688259557,
"issuer": "12gdsZHdWEcahj8dUpvQrNE7qwbDuweG98qF8uXkZTNF",

"expires_on": 1688259103,
"issuer": "4ZK4amjrVdtdA4ybkt6MhpyQnvZVVmWXeDNfzAzb88gq",

"expires_on": 1688259103,
"issuer": "EBE9wtQREgFwR9Z5nGXc8MWnye6cpSgE7LQuiDJGgymv",

"expires_on": 1688256804,
"issuer": "FosBhXpP9YhpgfCM4VxHdVfQxCFrN8y5xZqnSL3YczBm",

"expires_on": 1688511127,
"issuer": "DM2JeCHNghqUPuFig1FjAZHAufQx5pKKDsyQPzDiFacH",

"expires_on": 1688256804,
"issuer": "9Le6Bpfi6RkD2r9rPjKysNcFwVgFRzSPqPqZWrqNdtif",

"expires_on": 1688261773,
"issuer": "9kgbU7f3eBckpX3YrLEu6iS92gqcbQQeAscN9rhPmU76",

"expires_on": 1688258022,
"issuer": "Da99uD7wo3MyPYxJRPET5yEPs3XPERgXAEoUKWJk96AV",

"expires_on": 1688635376,
"issuer": "2XvDfKtoHAS2bs8teoaafbPpFpF9BekdEnWm3RWczcjp",

"expires_on": 1688253898,
"issuer": "4ksLLJuqw8LpZeuhdv9C5EEfWK1QapWGWmDKy9vJt3RS",

"expires_on": 1688255156,
"issuer": "ER8fgx3nrsAEGNMwX5e5g1WAsG8fHSfEEQ9spudcqcSq",

Parmi ces 11 certifications restantes, seules 2 ont une date d’expiration postérieure au dernier bloc, les 9 autres sont censées avoir déjà expiré.

La question est donc : pourquoi reste-t-il des certifications actives alors que leur date d’expiration est passée (depuis plus de 7 heures) ?

La conséquence est que le parsing du genesis ĞTest n’est pas content. Il fait un check sur Jovivant qui est censé être membre (member: true) et trouve uniquement 2 certifications sur 5 minimum attendues :

[Jovivant] has received only 2/5 certifications

J’essaie de me plonger dans py-g1-migrator.

Peux-tu exporter tes données sur le web, car en important le contenu de https://g1-migrator.axiom-team.fr/inputs/

le format des données est incompatible avec ta branche hugo-gtest:sweat_smile:

Cela m’éviterait de me plonger sur la partie export dex

1 Like

Ok, j’ai mis mon export ici : https://files.coinduf.eu/NytLNvvawd5RvFjr/. Est-ce que @poka tu pourras mettre à jour ton script ?

Et si jamais tu veux tester les données avec les checks faits au parsing du genesis, tu peux prendre le code de la MR !176.

1 Like

Je veux bien des informations supplémentaires pour essayer (modestement) d’aider sur le sujet, si c’est dans le code python qu’il y a un souci…

A quel endroit de la chaîne ETL (extract, transform, load) de migration, ou du workflow de migration si on préfère, les 9 certifications expirées apparaissent non expirées ?

La chaîne est bien :

LevelDB – dex → certs.json – py-g1-migrator → gtest_genesis.json ?

Quelle application fait le parsing du genesis de Gtest et pourquoi/où voit-elle Jovivant comme étant membre ? Alors qu’il ne lui reste manifestement (dans certs.json) que 2 certifications valides.

Non, je pense avoir réglé tous les soucis dans le code python, ce dont je parle sort de Duniter v1 avec dex.

docs/generate_inputs_data.sh · d2e819f3f46e831a1434bd423139c0ab8ba53424 · tools / py-g1-migrator · GitLab

C’est Duniter v2, on peut l’ajouter à ta chaîne :

LevelDB → dex → certs.json → py-g1-migrator → gtest_genesis.json → Duniter v2 → chainspecs

node/src/chain_spec/gtest_genesis.rs · c837c2d387702a02f166ce2cd4711f109b098006 · nodes / rust / Duniter v2S · GitLab

Et c’est dans idty.json qu’on voit que Jovivant est membre.

1 Like

Dans le fichier que tu as mis en ligne, il ne l’est pas, mais je suppose qu’au moment de ton export, il l’était.

{
    "key": "4uaHR5Ue8JtbigtcLGMwiZb8e4ESm1QJhwWMrnCcj14e",
    "value": [
      {
        "created_on": "431536-00000038D8BCF62B47F4BD0EAD5EA19FDA2717E33C586D59AC60C0BA33129B2F",
        "member": false,
        "uid": "Jovivant",
        "wotb_id": 5275,
        "writtenOn": 537466
      },

Y a -t-il déjà des tests d’intégrité des données dans Duniter (pré export dex) et on cherche le bug dans dex, ou bien il serait intéressant que j’implémente un équivalent de dex en Python avec Plyvel, pour analyser/exporter les index levelDB et vérifier leur cohérence ?

Effectivement, j’avais oublié que je l’avais remplacé par member: false pour pouvoir booter la gdev, et effectivement au moment de l’export il l’était.

Je ne sais pas s’il y a des tests d’intégrité dans Duniter v1, je ne sais pas si ça vaut le coup d’implémenter un autre outil pour lire la db. Je le signalais juste ici au cas où quelqu’un rencontre un problème similaire pour que ce soit un minimum documenté.

1 Like

Bon alors comme cela avait l’air trivial, j’ai fait un script pour lire l’index des identités avec Python et vérifier sur mon serveur Duniter V1 au bloc 642590 environ, que l’UID Jovivant n’est pas membre :

{'index': 'IINDEX', 'op': 'UPDATE', 'uid': 'Jovivant', 'pub': '4uaHR5Ue8JtbigtcLGMwiZb8e4ESm1QJhwWMrnCcj14e', 'hash': 'E9D981B36B1D9A7BE34B05F7A56EFA89E99E59B6126FBC7FCC4238B60E230FD7', 'sig': 'EtGaLzvDFEH/uWCmmH12miQWdwoQKnHWCfGCOVZryTZVjeIaY6pp+neFyg8SrJGZ+SMCiugytuZ7olOtO0HpAA==', 'created_on': '431536-00000038D8BCF62B47F4BD0EAD5EA19FDA2717E33C586D59AC60C0BA33129B2F', 'written_on': '640157-0000000ADFD7A61413815411C00328E71944289AC377A30EEA0FA3D95F34E6F5', 'writtenOn': 640157, 'age': 0, 'member': False, 'wasMember': True, 'kick': False, 'wotb_id': 5275, 'uidUnique': True, 'pubUnique': True, 'excludedIsMember': True, 'isBeingKicked': True, 'hasToBeExcluded': True}

Il ne l’est pas.

SI dex le présente toujours comme membre, et que ni mon script, ni wotwizard ne le voit membre, alors il y a peut-être un bug dans dex.(et par extension dans le workflow de migration…).

Pour les curieux du Python :

#!/usr/bin/env python

import plyvel
import json

# open copy of leveldb folder, copy made from a running Duniter server
db = plyvel.DB('/home/vit/level_iindex',)

for key, json_string in db:
	value = json.loads(json_string)[0]
	if value["uid"] == "Jovivant":
		print(value)

Évidemment si tu regardes après, il n’est plus membre. Le problème était au bloc de l’export. Dans d’autres blocs il y aura peut-être d’autres problèmes, mais je ne sais pas encore lesquels.

J’ai recommencé l’aventure, et j’ai maintenant :

2023-07-11 17:04:08 [Jizo] has received only 4/5 certifications    
2023-07-11 17:04:08 [Moonvaudeurs] has received only 4/5 certifications

J’ai mis à jour les données sur https://files.coinduf.eu/NytLNvvawd5RvFjr/, cette fois-ci pour l’export au bloc 642842.

Voici les logs de py-g1-migrator

Export wallets data in progress...
Export certs data in progress...
Export identities data in progress...
Export membership data in progress...
Export blocs dates data in progress...
Export UD value in progress...
Starting python script to generate genesis data
Generate ĞTest genesis with up-to-date Ğ1 data
    get ĞTest parameters...
    dump ĞTest parameters...
    parse identities...
⚠️ initial monetary mass 7,281,486,307 does not equal wallet sum 7,281,461,465
money on the wallets: 7,281,376,601
money from ignored sources: 84,864
missing money (added to treasury): 24,842
    parse certification...
⚠️ lumi → DCat cert expired between export and start
    add simple wallets...
Done
Copying genesis data to bootstrap server
gtest_genesis.json     

Il y a une seule certification qui semble avoir expiré entre le moment de l’export et le moment de l’écriture du genesis (lumi → DCat). Mais cela n’explique pas pourquoi Jizo et Moonvaudeurs n’ont que 4 certifications sur 5.

Je trouve que le workflow est difficile à déboguer car trois logiciels sont impliqués dans les transformations de données dans deux langages différents.

L’idéal serait de simplifier ce workflow, en faisant, selon que l’on veuille plus de Rust ou plus de Python :

  • Rust : intégrer le code de génération de genesis.json de py-g1-migrator dans dex (nécessite un bon dev Rust).
  • Python : intégrer le code d’extraction des index V1 de dex dans py-g1-migrator (assez trivial avec la lib plyvel, qui est très rapide, et peu de logique dans l’extraction il me semble).

Le but étant d’avoir un des workflows suivants :

LevelDB → dex → gtest_genesis.json → Duniter v2 → chainspecs

ou

LevelDB → py-g1-migrator → gtest_genesis.json → Duniter v2 → chainspecs

Par rapport aux incohérences, elles semblent être dans la base leveldb. Changer la manière de lire cette base ne changera rien aux incohérences. La raison est plus probablement interne à Duniter et il faut juste décider ce qu’on en fait. Probablement désactiver le statut membre des personnes ayant moins que cinq certifications.

Mais si tu veux ajouter l’export leveldb avec plyvel dans py-g1-migrator, pourquoi pas. Poka avait fait avec l’existant et du bash comme d’habitude, et ça me parait très bien pour un programme qui ne va servir qu’une fois.

1 Like

Effectivement si l’incohérence des données vient de la base leveldb elle-même, alors ce travail est inutile pour le script de migration de @poka qui fonctionne bien.

Je vais essayer de détecter des incohérences dans la base leveldb avec plyvel, si ce n’est pas trop de travail. Cela peut éventuellement permettre d’améliorer Duniter V1 en attendant la migration.

1 Like

Le script est fait et ne détecte pas d’incohérence dans Duniter V1.

1 Like

Suite à la visio d’hier, pour l’implémentation de l’import leveldb 1.8 en python, sur quelle branche veux-tu que je me base ? Je vois que trois personnes ont des branches.

J’ai ouvert un ticket sur lequel on peut continuer à discuter.

2 Likes

J’ai fait le ménage de mes branches, tu peux partir sur master. Il y a un détail sur la date de génération du DU qui a été changé côté Duniter-v2s et qu’il faudra gérer dans py-g1-migrator, mais c’est vraiment un détail, donc pas de problème :slight_smile:

1 Like