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

v11
rfc
scaling

#21

C’est le travail des logiciels de rendre ça pratique :wink: L’utilisateur lambda doit avoir un usage simple, mais l’utilisateur avancé doit pouvoir maîtriser ce qui est fait de ses données.

D’ailleur pour une personne lambda qui voudrait faire tourner un noeud calculateur chez lui, ça ne lui sert à rien de stocker toutes les UTXOs. Il peut juste stocker les siennes pour l’utiliser en priorité avec son logiciel client, et avoir ses UTXOs sur des machines tenues par d’autres personnes au cas il a un problème. En encore au cas où, avoir un ensemble de machines se répartissant toutes les UTXOs sur lequel il peut compter.


#22

L’utilisateur lambda n’a pas de noeud chez lui, voir peut se connecter sur des clients qui ne sont pas les siens :slight_smile:

L’autre problème c’est que ça induit une certaine centralisation du réseau. Si tu sais que les UTXO sont réparties et ne sont pas répliquées sur tous le réseau, en tant qu’attaquant tu peux chercher à faire tomber juste des bouts du réseau. Ainsi tu rends des UTXO inaccessibles et tu empêches le fonctionnement de la monnaie pour une partie des d’utilisateurs.


#23

Au contraire, un attaquant devrait savoir chez qui sont stockées les données de la personne, alors que ce n’est pas une donnée publique.

De plus si l’utilisateur se connecte depuis un autre client (ce qui n’est pas très bien soit dit en passant) alors il pourra demander les preuves aux groupes de serveurs se répartissant les preuves. La solution du DHT est interessante et sera à developper par dessus.

Bref, autant permettre les 2 solutions : celle à la main et celle des DHT qui demandera un protocole supplémentaire.


#24

Moi je suis toujours contre la solution à la main :slight_smile: Allez, encore un autre argument. En terme de topologie dans ce schéma, les utilisateurs vont dépendre de centres auxquels ils devront faire confiance.
Ca pose problème pour :

  • la capacité des attaquants à s’attaquer à ces centres (pas très difficile de connaitre chez qui un utilisateur stock ses UTXO… Rien qu’en observant les metadonnées sur le réseau)
  • la capacité donnée à ces centres qui auront alors la capacité de tricher, de mentir sur les UTXO etc.

Ca affaiblit beaucoup le réseau pour un avantage très léger (160 Go la blockchain de btc au bout de 10 ans, franchement, on est tranquille avec les full nodes pour un moment).


#25

Autant laisser le choix. Tous les membres d’une communauté locale peut très bien stocker les UTXOs des autres membres, et rien que là c’est déjà difficile à attaquer. Et il reste les full nodes publics en cas de problème. Des noeuds peuvent très bien suivre mes UTXOs sans que je le contacte ensuite.

La seule attaque possible est une attaque par ommission, et un seul noeud coopérant la contre. Pas de grosses craintes là dessus non plus.

Bref, je pense que restreindre les choix des utilisateurs est une mauvaise chose. L’idée au dessus marche sans DHT, mais un DHT peut très bien être déployé et aider à gérer des attaques quand le réseau sera plus grand.

Note : les full nodes non-archive n’ont a stocker que l’ensemble des UTXOs, donc autour de 3Go pour Bitcoin. Après si je pouvais faire tourner pendant des années un noeud sur ma Raspi 1B avec 500Mo de RAM, même avec un trafic du Bitcoin, ça me tenterais bien. En plus si Duniter prend de l’empleur, on pourrait toujours vendre des petites machines préinstallées pour faire fonctionner un noeud Duniter et servir de stockage des preuves pour l’utilisateur. Vu les besoins revus à la baisse en matière de stockage et de mémoire, ça ne dévrait pas couter très cher et être plutot accessible.

En multipliant le nombre de noeuds, on rend beaucoup plus difficile les attaques.


#26

Petite modif pour la proposition : il n’est en fait pas nécéssaire de stocker tous les epochX/rootX, seul la preuve de Merkle de la dernière UTXO insérée suffit.


#27

Concernant le stockage distribué des UTX0 il est possible de développer sur la couche WS2P, un système de requêtes de preuves (pourquoi pas s’inspirer de DHT pour le concevoir) mais se sera long a développer donc je propose les étapes suivantes :

  1. pour le déploiement de la v11 tout les nœuds seront en full node par défaut. Sauf la release pour arm qui peut être en ligth node par défaut. Il faut donc déjà un premier système primitif de requête de preuve, pour les nœuds arm, on peut faire ça facilement en ws2p.
  2. On développe un système poussé de DHT mais facultatif : Les clients enverrait alors par défaut toute nouvelle UTX0 au réseau DHT, mais l’utilisateur pourrait choisir dans les options avancés de son client de ne pas envoyer ses UTX0 au réseau DHT et de choisir lui mêmes les machines a qui il envoi quoi. Ainsin on associe le coté user-friendly avec le coté libre de maitriser ou sont stocker mes UTXO.
  3. Une fois le système DHT bien en place et fonctionnel, on change la config par défaut des noeud duniter : ils seront light node par défaut.

#28

Bon, du coup je vais intégrer ce concept à la RFC5, ainsi que développer une crate pour gérer la création, mise à jour et vérification des preuves de Merkle :slight_smile: Une idée de comment intégrer les schemas dans la RFC ? Je les laisse sur imgur ?


#29

Idéalement faudrait les écrire au format texte pour ne pas avoir de dépendance externe :slight_smile:


#30

Bon, vu qu’ils ne sont pas trop gros je peux faire l’effort de les réécrire en ASCII-art :wink:

Sinon en dehors de la mise en place logistique des noeuds, tu ne vois aucun problème dans le fonctionnement ?


#31

Techniquement, je ne vois rien à en redire (je ne vois que des avantages). J’aimerais bien avoir l’avis de @cgeek, mais on a tellement discuté cette semaine que je sens que ça va être chaud pour lui de nous commenter ces échanges à court-terme. Il rattrapera lorsqu’on fera une dernière passe sur la RFC5 avant de demander des reviews externes j’imagine :slight_smile: , mais je le laisse se prononcer :stuck_out_tongue:


#32

Comme @Inso l’avaiy suggéré, je me suis posé la question de l’utilisation de cette structure pour autre chose que les UTXOs, notamment les données de la WoT (identités, certifications, etc). Pour tout action directe de l’utilisateur (création d’identité, certification, revocation explicite) je ne vois aucun problème à utiliser ce système. Par contre pour tout ce qui est déclenché après une certaines durée, je vois mal comment faire. Ca serait possible de distribuer les informations sur les différents noeuds, mais ça oblige à les récupérer tous les jours pour le DU par exemple.

Si vous avez idée de comment faire fonctionner ce genre d’évènements avec cette structure, ça serait une grande avancée car on pourra potentiellement dévlopper de nouveaux usages plus ou moins complexes sans demander plus d’espace de stockage, et serait une véritable solution de scaling.

En tout cas, voila une première idée pour gérer les action explicits des utilisateurs avec des conditions (des scripts ?) :

Il serait bien de pouvoir mettre à jour une information sans qu’elle puisse être replay plus tard, et sans déplacer cette information dans l’arbre (elle reste toujours au même endroit et est facile a trouver). Une possibilité est d’utiliser des jetons qui eux sont consommés et créés. On pourrait imaginer qu’a la création de son document d’adhésion, il y a aussi la création d’un jeton. Pour mettre à jour l’adhésion (la renouveler en mettant à jour la date de début), il faudrait fournir ce jeton en entrée et un nouveau jeton serait créé en sortie pour la prochaine fois. Ce qui est super c’est que l’on peut utiliser un système de script pour définir les limites temporelles de renouvellement (pendant 2 mois ce jeton d’adhésion est verrouillé par une sorte de time lock).

Edit : j’ai peut-être une amorce de solution. Le token pourrait être consommé par le protocol en cas de mise à jour, et créer une nouvelle donnée qui stocke les changements à apporter à l’identité (ou autre document). Quand l’utilisateur veut se servir de son identitée, il doit utiliser le nouveau token qui l’oblige à prendre en compte les modifications apportées par le noeud. De cette manière le noeud a juste a stocker la liste des tokens, appliquer des événement réguliers dessus et c’est l’utilisateur qui va “appliquer les modifications du token sur le document” à son utilisation.

Par exemple en considérant les certifications comme des tokens, on peut leur programmer une longévité de 2 ans, et a leur expiration mettre à jour indirectement (via le token) les adhésions affectées et qui seront appliquées à leur prochaine utilisation par le membre. Pour recevoir son DU, il faudrait alors donner la preuve du document d’adhésion ainsi que le token correspondant. (c’est un peu flou mais je pense que c’est une bonne piste).


#33

Avant de ce lancer dans un tel chantier il faudrait calculer l’espace de stockage maximal que prendrais une wot pleine en base de données sur l’hypothèse de 1 millions de membres et de 50 certifications émises par membre en moyenne.

Sur cette hypothèse le nouveau format binaire de wotb que je conçois ne pèsera que 150 Mo, pour la bdd se sera bien plus puisqu’il faut enregistrer au moins les hahs des identités mais ça devrait rester raisonnable pour être stocké par tout les noeuds :slight_smile:

En revanche on peut partir sur un format ou les nœuds ne stockent que les hashs des identités et les hahs des memberships et demande la preuve (=le document complet) seulement lors de l’écriture d’un acte utilisateur. Il faut en tout les cas stocker les données permettant de savoir quand est ce qu’il y a expiration, mais pas besoin de stocker le document complet pour ça, un hash associé a un timestamp suffit :slight_smile:


#34

Pour les UTXOs, un noeud léger à juste à stocker 32o pour la racine de Merkle.
Pour chaque UTXOs de transactions dans la mempool, il faut stocker sa preuve qui est de 32o * nombre de hash de la preuve, sachant que toutes les preuves peuvent être combinées par leurs parties communes.

Pour les noeuds complets (avec répartitions des preuves avec un DHT par exemple), le nombre d’UTXOs serait de total / nombre de secteurs de partage, tout en prenant en compte que les preuves sont combinables.

ca, c’est pour les UTXOs. Mais si on arrive à appliquer la même logique de Merklization à toutes les informations de la blockchain, la combinaison de preuve permettra à chaque information de prendre en moyenne moins de place que la précédente.

Tout ce qu’il manque c’est la gestion d’information a état, ainsi que des actions “automatiques” effectuées par le système sans nécessiter les informations complètes, d’où mon idée de “tokens d’action”. Le système aurait le controle sur les tokens qui permettent d’empiler (plutot avec une file qu’une pile d’ailleurs) des modifications qui seraient obligatoirement appliquées à l’information quand elle est utilisée.

Edit : sur le chemin pour rentrer chez moi j’ai trouvé une idée proche mais différente qui permettrait de répondre au problèmes posés plus haut. Il faut que je mette ça sur papier pour vous donner un exemple concret, mais si ça fonctionne ça va être du très très lourd :wink:


#35

Bon, j’ai du retard à rattraper … je commence :

Peux-tu préciser le mode d’attachement ? Dans l’exemple il semble que ce soit une file (root2, root3, …).

N’est-il pas suffisant de stocker 3 et c ?

Que fait-on des nœuds vides ensuite ? On les réutilise ? Et les branches, on les recalcule ? Est-ce que les epoch peuvent changer de valeur suite à des branches elles-mêmes changeantes, du fait d’UTXO qui se vident ?

Si je comprends bien : grâce à l’epoch fourni, le nœud peut vérifier que cet epoch a bien existé et doit ensuite prendre la dernière version de cet epoch pour vérifier que l’UTXO en question est toujours présente ?

Tu veux dire au sein d’un bloc et des transactions en mempool ?

Comment peut-on perdre cette information, hormis la perte de l’information de l’UTXO elle-même ?

Il faut tout de même stocker les epoch, non ? Or ceux-ci n’ont pas une taille nulle, notamment si l’on stocke les versions à chaque fois (ex : un epoch full puis dont une UTXO est vidée : on stocke au moins 2 versions). Par ailleurs même si l’on ne stocke pas les UTXO elles-mêmes, une epoch de taille 8 représente 8 UTXOs. Or pour représenter ces 8 UTXOs, on stocke a, b, c, d , e, f, g si j’ai bien compris.

Au final et dans le meilleur de cas, avec un UTXO de taille 8 on stocke 7 hashs. C’est certainement moins que les potentielles UTXO elles-mêmes, mais le gain est-il si grand que ça ?

À noter que j’ai pu mal comprendre le raisonnement ou oublier des éléments, merci de m’aiguiller si c’est le cas.


#36

De cette façon :

           /\
          /  tree2
         /\
        /  tree1
       /\
nothing  tree0

Un noeud vide sera en fait un noeud qui contient le hash 000…000, on utilise cette valeur pour pouvoir continuer a calculer la racine de l’arbre même s’il est partiellement vide.

Oui a chaque supression d’un noeud il faut recalculer tout les nœuds en amont de sa propre branche pour pouvoir obtenir le nouveau root de l’arbre.

Il me semble qu’on ne parle ici que des blocs, il me semble que les transactions en piscine ne contiendront pas leurs preuves, mais que les preuves nécessaire seront demander par chaque noeud calculant au moment de générer son prochain bloc. mais peut etre que nano a une autre idée en tête.

En fait nano a en tête que le stockage des preuves soit également privé. Perso je préfèrerai qu’on stoke les preuves dans un grand DHT global, ce qui est par ailleurs indispensable pour les données de la wot. Après pour les transactions monétaires la perte des preuves de mes UTXO n’impacte que moi et pas le reste de la communauté monétaire, donc c’est envisageable. Je n’ai pas d’avis tranché sur ce point :slight_smile:

alors oui mais seulement ceux des blocs de la fenêtre de fork ce qui ferai au plus 256 Mo avec des blocs de taille max 10Mbit.

En fait la profondeur 3 est un exemple pour illustrer le concept, dans la pratique les epoch seront beaucoup plus profond. Et plus la profondeur est élevée plus le gain de place est grand :slight_smile:


#37

Arh tu m’as doublé xD

Si, les clients donnent les preuves avec les tokens utilisés, et le noeuds les stocke de manière agrégée. S’il y a le DHT en effet il peut aller les demander ailleurs, mais seulement dans le cas où tous les tokens sont dans le DHT.


#38

Ben j’essaye d’expliquer a ma façon avec mes mots comme ça ça double les chances de compréhension :wink:

EDIT:

Ça me fait penser qu’on a pas aborder la question du stockage des piscines, ça risque de peser plus que les blocs eux-même !


#39

Surement x) Mais ça je ne vois pas comment faire autrement, et ça sera pas pire que les blockchains actuelles :wink:

Au niveau des données la piscine sera une sorte de block géant. Même stockage des preuves, des tokens, des scripts ^^


#40

Non, seulement la Merkle root est nécéssaire.