[Pavé !] Ajout pour la RFC5 : Des noeuds qui ne stockent pas les UTXOs

v11
rfc
scaling

#61

Cette idée de ne pas stocker les UTXO a-t-elle évolué depuis ? Elle m’intéresse, je pourrais vouloir l’intégrer plus tôt que prévu dans Duniter.

Ce que je comprends, pourrais-tu le confirmer @nanocryk :

  • pour un nœud “light” qui calculerait des blocs, il n’y a pas besoin de stocker le moindre epochX ni même rootX sauf le Merkle root. Et encore moins stocker les UTXO.
  • pour qu’un client puisse connaître les preuves nécessaires à la dépense d’une UTXO, seul un nœud (ou un service basé sur un nœud) est capable de lui fournir cette information et ceci nécessite au préalable que le nœud soit configuré pour stocker ces preuves là a minima.

Une fois ces principes posés, peux-tu me dire :

  • ce qu’il en est des preuves « obsolètes » ? c’est-à-dire des preuves qu’un client aurait récupéré à l’instant t, puis que ces preuves soient périmées par l’impact d’autres UTXO consommées sur le même arbre à un instant t2, en-dehors de la fenêtre de fork ?

    Si j’ai bien suivi, étant donné que les epochX ne sont pas stockés sur les nœuds light, la transaction ne passera pas sans que le client ne mette à jour ses preuves, lesquelles auront été maintenues à jour par le nœud configuré pour ça.

  • concernant les DU, ne penses-tu pas qu’il serait plus intéressant de générer des UTXO « ex-nihilo » plutôt que de gérer un arbre supplémentaire de N feuilles ?

    Car si j’ai bien compris l’intérêt de cette idée que tu as eu de ne pas obligé de stocker les UTXO, alors mettre les DU dedans permet d’alléger encore plus ce qu’un nœud doit stocker.

Voilà, c’est un bon début pour les questions :slight_smile:


#62

Il faut quand même prendre le temps de faire ça bien. Et rédiger une RFC précise avant toute chose :slight_smile:

Je pense qu’au niveau du protocole il y a d’autres priorités a court-terme. Les sources utxo prennent encore très peu de place sur la Ğ1.
C’est les sources DU qui prennent de la place. Mais pour régler ce problèmes des sources DU il y a bien plus simple, il suffit de supprimer la notion de source pour les DU et de stocker plutôt une unique balance DU par membre donc le montant sera réduit a chaque tx qui pioche dedans et créditer a chaque block DU.

EDIT : et encore les sources DU peuvent dés a présent prendre moins de place sans rien changer au protocole, il suffit de modifier le façon de les stocker, dans durs l’ensemble de toutes les sources DU me prennent exactement 630,5 Ko (au bloc #124968)


#63

Si je pars sur le principe que les preuves ne font pas parti de la partie signée d’un document, n’importe quel noeud sur le réseau est capable de mettre à jour les preuves après 1 bloc. Si par contre aucun noeud ne le fait, les jetons deviennent inutilisable. Il faut donc qu’il y ait toujours un noeud avec les preuves à jour (dans la fenetre de fork, qu’il puisse empiler les blocs et optenir les preuves au niveau du HEAD), les autres noeuds pourront potentiellement les lui demander. Mais par contre si on a que des preuves qui datent d’en dehors de la fenetre de fork, les jetons associés sont considérés comme perdus (il pourrait y avoir des cas particulier où on pourrait utiliser d’autres UTXOs “proches” dans l’abres pour les ratacher à une preuve valide, mais il y a peu de chance que ça marche.

Je vais te dire comment je compte faire ça avec des jetons dans fygg, tu pourras surement le faire dans le protocole Duniter “à la main”. On insère dans la blockchain uniquement les évenements de recalcul du DU. Pour les membres, on stocke à quelle date ils ont récupéré leur ancien DU. Enfin, quand ils veulent l’utiliser, on peut regarder combien de DU ont eu lieu entre cette date et maintenant, calculer la valeur crée (en prenant en compte les changements de valeurs du DU), autoriser cette création monétaire “ex-nihilo” et enfin inscrire la nouvelle date de “j’ai recupéré mon DU”. Car oui en effet créer une UTXO par membre chaque jour n’est pas envisageable à long terme, et je n’ai pas envie d’imaginer le poids des blocs créés à midi :stuck_out_tongue:


#64

Il y a aussi le problème des clients : si Sakia met autant de temps à récupérer les données d’un compte, c’est parce qu’il doit :

  • Calculer à la main la destruction des sources (en se retapant la blockchain)
  • Calculer à la main les DU qui ont été générés précédemment (les sources Duniter étant actualisées, les DU déja consommés ne sont plus historisés)

La solution la plus simple à court terme (et que je compte mettre en oeuvre) et de ne plus charger l’historique complet mais seulement les 3 derniers mois.

Sur Cesium c’est rapide car le noeud Elastic Search fait le boulot à la place du client et indexe les données en continu.

En attendant, si on trouve un moyen de compresser les UTXO, alors dans ce cas :

  • Le problème de la destruction des sources n’existe plus (les sources non utilisées seront tout simplement oubliées par les noeuds) et ça simplifie grandement le traitement des données
  • La génération de l’historique des DU générés peut être fait par le module orienté client. Il pourra stocker à la fois l’historique des transactions et l’historique des périodes de génération de dividendes (et non la liste complète des dividendes).

Pour éviter de multiplier les requêtes en comparant les réponses de multiples noeuds, l’historique des DU devrait s’appuyer sur un mécanisme de preuve de création à un block donné (avec un chemin dans un arbre de merkle qui remonte jusqu’au header d’un block. Sakia ne téléchargerait alors plus que les headers de la chaine + les historiques prouvés + les UTXO courantes).


#65

Exactement, le noeud ne stocke que ce qui est encore valide dans la fenetre de fork, et le client ne fait que demander les informations aux noeuds, les afficher pour l’utilisateur et signer les transactions.


#66

Si tu migre Sakia en Rust ça te prendra moins d’1minute, c’est le temps de téléchargement de la blockchain qui deviendra limitant :stuck_out_tongue:

En effet :slight_smile:


#67

Oui, donc un nœud qui a été configuré pour tenir à jour certaines preuves (par exemple celles impliquant des UTXO contenant une clé publique à suivre) ne devrait pas avoir de difficulté à le faire.

Mais justement si l’on utilise la mécanique d’UTXO proposée dans ce fil, alors un nœud light ne stocke absolument pas le DU pour chaque membre : il fait juste N insertions dans l’arbre courant. Ce qui revient juste à faire tourner la roue si je puis dire. Ça ne consomme que du CPU.


#68

Si le bloc ne contient qu’un marqueur “création du DU”, que le noeud stocke la liste des membres valides à ce moment là et que l’ordre est déterministe, alors oui ça passe :slight_smile:

Note : je ne compte pas faire comme ça dans fygg, car ça demande justement que tous les noeuds stockent la liste de tous les membres actifs.


#69

C’est le cas, oui. Bonne nouvelle :slight_smile:


#70

Mais je fais toujours les choses bien :slight_smile: quant à rédiger une “RFC précise”, je rédigerai un document oui.

Je pense au contraire qu’il s’agit d’une priorité désormais (avec les 3 autres points que sont la PoW, la difficulté personnalisée et le flag de fonctionnalité).

C’est un tel boulet de devoir stocker toutes ces sources, ça nous ajoute une contrainte très forte d’avoir un logiciel qui fonctionne partout de la même façon, alors même qu’un Raspi sous SQLite n’est pas un serveur BigData sous MongoDB ou Postgre qui eux peuvent faire des merveilles.

Personnellement en tout cas, si ce qu’a proposé nanocryk fonctionne effectivement, je ne vais pas attendre pour l’implémenter. On pourra enfin dire « oui oui vas-y spamme le réseau de transactions, osef ».

Pour l’instant on ne peut avoir cette réponse que pour la WoT. Si on l’avait aussi pour les TX, ce serait juste génial. Personnellement je dormirais beaucoup mieux.

Non car tu ne vérifies plus la double dépense.

Par contre oui on peut les stocker différemment, mais ce n’est que repousser le problème.


#71

Mais de toute façon, si l’on part du principe que des nœuds ont pour rôle de maintenir des preuves pour tel ou tel “compte”, alors l’API résultante ne sera plus aussi générique que BMA et donnera directement ce dont a besoin le client.

Qu’il s’agisse de Duniter ou d’un autre service, d’ailleurs.


#72

Oui, mais il serait bien que les clients puissent quand même vérifier localement les données fournies par les noeuds. La confiance aveugle dans les données fournies par les noueds ça aboutit à des risques en cas de bugs ou de corruption logicielle (cf l’évènement Cesium post RML11)

Aujourd’hui, Sakia fait cette vérification en sondant le réseau. C’est plutôt lent comme comportement. SI sakia pouvait s’appuyer sur des preuves de merkle permettant de reconstituer des headers, ça serait quand même beaucoup plus propre et robuste je pense. Et même pour des clients comme Silkaj ou Cesium, l’implémentation serait beaucoup plus simple sans nécessiter de requêtes distribuées.


#73

Je parlais d’une proposition qui avait été faite sur un autre fil de supprimer la notion de source DU au niveau du protocole.
Mais sinon il y a une autre solution niveau protocole : forcer la consommation des sources DU dans l’ordre de de leur création. Ainsi il suffirait de stocker un seul BlockId par membre : le BlockId du plus ancien DU non consommé.
Une tx qui consommerai des DU dans le désordre serait considérée comme invalide.


#74

Comme proposé au dessus on peut simplement stocker la date de derniere consommation du DU. Car si on stocke uniquement le BlockID il faut alors les stocker pour pouvoir récupérer les dates et savoir combien de DU ont été créés.


#75

Je ne comprend pas ce que ça change. Les sources DU sont déclarés en input sous le format PubKey:BlockId.
Stocker un timestamp plutôt qu’un BlockId me semble au contraire plus compliqué. Avec un BlockId il est facile de vérifier que le bloc correspondant est bien on block créateur de DU. Les blocks ne sont pas indexé par leur timestamp mais par leur number.


#76

Mais c’est exactement ce dont on parle, non ? Le nœud configuré pour cela stockerait toutes les preuves du compte à suivre, et pourrait les fournir sur demande.

Du coup le client n’a qu’à vérifier ces preuves localement et à vérifier la présence de ce Merkle root comme HEAD sur le réseau.


@nanocryk @elois

Mais quitte à faire un changement de protocole, pourquoi ne pas utiliser les arbres à UTXO dont ce fil est le sujet ? Vous trouvez ça trop compliqué ? Je trouve au contraire la solution plutôt simple à implémenter, assez courte en code même.


#77

Ben comme l’avais préconisé inso par le passé je préfèrerai qu’on fasse les choses par étapes, et qu’on s’occupe déjà d’un nouveau protocole qui permet de gérer les changement de règles en soft fork et qui change la pow. Puis qu’on s’occupe de ces points-ci dans l’ordre : Évolutions du protocole vers v11, v12, etc

EDIT : Je crains qu’a vouloir en faire trop d’un coup, on mette trop de temps a stabiliser cette nouvelle version et que la Ğ1 en pâtisse entre temps. Je pense qu’il est préférable de subdiviser les évolutions et plusieurs étapes.


#78

Oui Ok, c’est bien ce dont on parle ici :slight_smile: J’insiste pour que la conception de la structure des arbres pour avoir les bonnes preuves en face pour les DU, UTXO, etc. soit utilisable par les clients et pas juste la mise à jour de la blockchain :slight_smile:


#79

Le timestamp est stocké dans les données du membre, et la “source DU” est simplement “je prend le DU accumulé”. Tout est décompté, ce qui n’est pas utiliser dans la TX est mis dans une UTXO avec sa clé publique (classique pour le reste) et on stocke dans les données du membre la nouvelle date. Ainsi, on a pas besoin de stocker l’historique des blocks nécéssaire pour “vérifier que le bloc correspondant est bien on block créateur de DU.” Comment le vérifier si on ne stocke plus les blocs ?

Je suis tout à fait d’accord pour utiliser les abres à UTXO. Mais si on pouvait éviter d’avoir autant d’UTXO créés que de membre dans un bloc de DU ça serait pas mal. Ca me semble plus simple d’insérer des infos en blocs uniquement quand le DU est consommé (moins fréquent que 1 fois/jour pour tous les membres).


#80

Il y a quiproquo, je parlais de comment stocker les sources DU de façon très légère en gardant le protocole actuel mais juste en ajoutant une règle qui dit que les sources DU doivent être consommes dans l’ordre de leur création.
La tu parle d’un tout autre paradigme, mais même dans ce cas je ne comprend pas, pourquoi veut tu stocker un timestamp dans les données du membre ?