Export sqlite pour wotwizard

Ce sujet sera essentiellement une discussion avec @gerard94 mais je la rend publique parce d’autres personnes seront peut-être intéressées de la lire.

Résumé de la situation d’après ce que j’ai compris :

  • wotwizard utilisait une base de données sqlite dans laquelle étaient stockés les index de Duniter
  • pour maintenir la compatibilité suite à un changement de base de donnée, cgeek a ajouté une option dans Duniter pour mettre à jour cette base de données à chaque ajout de bloc
"storage": {
    # exporte le fichier wotwizard-export.db
    "wotwizard": true
}
  • cette option ne fonctionne plus dans les versions récentes de Duniter

Jusqu’à présent, la solution retenue était de faire fonctionner wotwizard à côté d’une vieille version de Duniter, mais cela rend assez compliqué l’ouverture de nouveaux endpoints GraphQL wotwizard.

Objectifs de la discussion :

Pour découpler wotwizard du nœud Duniter, et ainsi faciliter son installation, il faut comprendre ce dont a besoin wotwizard et le lui fournir d’une autre manière. Pour minimiser les modifications à faire dans wotwizard et Duniter, la stratégie envisagée est de reconstruire la base de données contenant les index à l’identique, mais hors Duniter.

# exploration de la base wotwizard-export.db avec sqlite3

# ===== tables =====
sqlite> .tables
block       cert        i_index     idty        membership

# ===== block =====
sqlite> select * from block where number = 1 ;
           fork = 0
         legacy = 1
           hash = 0000238EB40E6A04B4E631FD4E2A757106D8C72C192BAE868D409D6359087C02
     inner_hash = 64B858824682AB9D046F31DDACF7524FCD2501AEF269EE09E95EF2414DC9F7DB
      signature = zcF6EZF+i+U4KWsNjXGXbNNRRwO0BFjKl4EVsmpyv1qB4xzT+O2PRdkYoi8rH7/XX9stAhF+M/4pAA8YhkXKCQ==
       currency = g1
         issuer = 2ny7YAdmzReQxAayyJZsyVYwYhVyax2thKcGknmQy5nQ
   issuersFrame = 1
issuersFrameVar = 5
   issuersCount = 1
            len = 
     parameters = 
   previousHash = 000003D02B95D3296A4F06DBAC51775C4336A4DC09D0E958DC40033BE7E20F3D
 previousIssuer = 2ny7YAdmzReQxAayyJZsyVYwYhVyax2thKcGknmQy5nQ
        version = 10
   membersCount = 59
   monetaryMass = 59000
         UDTime = 
     medianTime = 1488987127
       dividend = 1000
       unitbase = 0
           time = 1488987233
         powMin = 70
         number = 1
          nonce = 10100000025565
   transactions = []
 certifications = []
     identities = []
        joiners = []
        actives = []
        leavers = []
        revoked = []
       excluded = []
        created = 
        updated =
# ===== cert =====

sqlite> select * from cert limit 1 ;
         from = 2pBTBgjjG7pUPMto6nWHEu6MNCAVyrZfHQ9gSLUD5s1y
           to = 7vN7bh1C7AC2TAoTkewGtjpmfzAkRss1CcVLWoKJFZGv
       target = F9EFC17BFFDEC3CF1F402EF3BFB4E4DD5A131140FE25AD8F87FB0B81260704A9
          sig = Xsz7F2dhLLFTGJylao48qp1rd/gep4aQL1mMRrA/7MFNhV4OqVKR01TI5fHdLYKX4Zr4pVzmqQluL4pHQHvyBQ==
 block_number = 516888
   block_hash = 0000002E32633BA1B4006FBB8D65690B32C2F1C2AE56E42780C5AE5D7F6F7A5B
        block = 516888
       linked = 0
      written = 0
written_block = 
 written_hash = 
   expires_on = 1655257132
      expired = 0

# ===== i_index =====
sqlite> select * from i_index limit 1 ;
        op = CREATE
       uid = AnneAmbles
       pub = 9DDn592RMWfka6fPtTGkmAS54CkYxohDGuk41EECxioD
      hash = 2AF67004F77A90BA82B2F72556040194EF8A19C07700C4A5EE6111E0E94AA1BF
       sig = L70UibCbqHZrni3Rwvi5hwWKOTQbnuvMS24AXkFei8WOuPB5ROCwlMQabxR6r/74wDh4WPhKgUECABYT3z0sAQ==
created_on = 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
written_on = 0-000003D02B95D3296A4F06DBAC51775C4336A4DC09D0E958DC40033BE7E20F3D
 writtenOn = 0
    member = 1
 wasMember = 1
      kick = 0
    legacy = 1
   wotb_id = 1

# ===== idty =====
sqlite> select * from idty limit 1 ;
       revoked = 0
    currentMSN = 
    currentINN = 
          buid = 514133-00000034F6F471A3EB1658D04A1AA8CD1BE98269E6C5DD8AEC9447C705D623C9
        member = 0
          kick = 0
       leaving = 0
     wasMember = 0
        pubkey = 7vN7bh1C7AC2TAoTkewGtjpmfzAkRss1CcVLWoKJFZGv
           uid = LaFlourie
           sig = czUGoZoFwKVxnBGxLFIrO0qs1iRrQd7ZEzrPbXSr4cKQPVD1Bnx856TOYc2WlerPb20HbLoUv8eB2H/f1ZPjCA==
revocation_sig = 
          hash = F9EFC17BFFDEC3CF1F402EF3BFB4E4DD5A131140FE25AD8F87FB0B81260704A9
       written = 0
       wotb_id = 
    expires_on = 1654355172
       expired = 
    revoked_on = 
       removed = 

# ===== membership =====
sqlite> select * from membership limit 1 ;
    membership = IN
        issuer = EqH5zrYhuzDLSF78sZSGHerG5t29yBBL9iodHrftQ6me
        number = 516898
   blockNumber = 516898
     blockHash = 00000009D3476DFD43BB2AAD5D7561B37E52339BE18B51AEAFE28D0D8D614E01
        userid = cholesfer
        certts = 516898-00000009D3476DFD43BB2AAD5D7561B37E52339BE18B51AEAFE28D0D8D614E01
         block = 516898-00000009D3476DFD43BB2AAD5D7561B37E52339BE18B51AEAFE28D0D8D614E01
           fpr = 00000009D3476DFD43BB2AAD5D7561B37E52339BE18B51AEAFE28D0D8D614E01
      idtyHash = 6D032BB0F830115BDC1E3860D4E8237DF99CB528369666E65203C9B159B6FBD7
       written = 0
written_number = 
    expires_on = 1655260517
     signature = dLr/gfBeukhVq0/2dFM0YW0Pw6Y3zcd2asIJceZUaHJ51uJMyS75FYproZ/fYZyPeW8VyGf7wfKDO3p7U/WzBA==
       expired = 

Le chemin vers cette base de données est défini deux fois en dur dans le code de wotwizard :

  1. https://git.duniter.org/gerard94/WotWizard/-/blob/master/src/duniter/blockchain/blockchain.go#L50
  2. https://git.duniter.org/gerard94/WotWizard/-/blob/master/src/duniter/basic/basic.go#L43

Wotwizard utilise cette base de données pour lire les paramètres de la ğ1 dans le bloc zéro :

https://git.duniter.org/gerard94/WotWizard/-/blob/master/src/duniter/blockchain/blockchain.go#L1801

Wotwizard utilise l’index des identités pour obtenir la liste des entrées et sorties :

https://git.duniter.org/gerard94/WotWizard/-/blob/master/src/duniter/blockchain/blockchain.go#L1962

Et ainsi de suite.

Conclusion de tout ça :

voici les champs de la db utilisés par wotwizard :

  • block
    • (tous)
  • cert
    • from, to, target, block_number, expires_on [edit : +block_hash]
  • i_index
    • hash, pub, writtenOn
  • idty
    • pubkey, uid, buid, expires_on, revocation_sig, hash
  • membership
    • idtyHash, membership, issuer, number, userid, expires_on, blockHash, blockNumber

Donc si on arrive par un moyen quelconque à reproduire une base de données identique, à la mettre à jour à chaque bloc, et à prévenir wotwizard de chaque modification, on peut se passer des vieilles versions de Duniter.

Est-ce que ça te semble bon sur ce point @gerard94 ?

1 « J'aime »

Oui, merci pour cette analyse.

Quelques points de détail :

C’est une erreur, qui sera corrigée dans la prochaine version. Une seule définition est suffisante, bien sûr.

  • Voici les tables SQLite et leurs champs qui sont nécessaires à WW :

    • block

      • fork
      • hash
      • parameters
      • medianTime
      • time
      • number
      • certifications
      • joiners
      • actives
      • leavers
      • revoked
      • excluded
    • i_index

      • pub
      • hash
      • writtenOn
    • membership

      • membership
      • issuer
      • number
      • blockNumber
      • blockHash
      • userid
      • idtyHash
      • expires_on
    • idty

      • buid
      • pubkey
      • uid
      • revocation_sig
      • hash
      • expires_on
    • cert

      • from
      • to
      • target
      • block_number
      • block_hash
      • expires_on

Il y a un mécanisme mis au point avec cgeek et utilisant un fichier qui permet cette communication.

1 « J'aime »

Bon, dans ce cas ça va être assez simple. J’imagine qu’un cron toutes les 5 min qui interroge Duniter pour ajouter le nouveau bloc aux index dans la db devrait suffire. Il y aura juste à calculer expires_on il me semble. Des connaissances minimales en SQL et n’importe quel langage de programmation devraient le faire. D’ici là deux options : soit je m’y colle mais je ne sais pas quand je trouverai le temps de le faire, soit on trouve un nouveau contributeur intéressé par faire ça et je le forme. Je vais faire un tour des posts de présentation, ça me semble jouable de dénicher quelqu’un qui sera très content de faire ça :slight_smile:

1 « J'aime »

Qui interroge comment ? Je me souviens d’une discussion avec @Moul à propos de Silkaj où il me disait qu’en interrogeant duniter avec les interfaces habituelles, on n’obtenait pas toutes les informations que WW peut obtenir en scannant la base de données

1 « J'aime »

Bon, après mon recensement il semble bien que je doive m’y coller.

Un programme tiers installé à côté de wotwizard pourrait interroger n’importe quel nœud (local ou distant) via l’API BMA tout simplement. C’est possible qu’il manque certaines informations, mais je pense qu’il y a tout ce qu’il nous faut dans les blocs servis par BMA.

On verra.