Bêta-test Duniter 1.6 WS2P

@Pafzedog a ma connaissance tu n’utilise pas de path, ton endpoint ws2p public est bien accessible pas de souci :slight_smile:

1 Like

oups, j’avais lu un peu vite :slight_smile:

Il s’est passé quelque chose ce matin vers 9h (heure BC UTC) qui semble poser problème : 10 membres ont soudainement perdu le statut de membre par expiration de leur membership !
Les nouveaux nœuds vierges qui tentent de ce synchroniser n’arrivent pas a appliquer cet événement et restent bloqués à un bloc juste avant l’événement (qui se produit a bloc 79034).

Impossible donc de rajouter des nouveaux nœuds sur g1-test, ils ne se synchronisent pas jusqu’au bout.
Si l’on tente une deuxième synchronisation ont a l’impression que ça passe mais une fois qu’on lance le nœud il dépile au point de fork :

Fork resolution: suite 1/1 (-> #79134-00004F) revert to fork point block#79034

https://github.com/duniter/duniter/issues/1168

Peux-tu montrer où tu constates cela ? Car moi je ne vois rien :

J’essaierai de reproduire le bug de synchro plus tard, là j’ai une connexion trop lente :confused:

@cgeek pour être plus précis c’est un bug du a un non respect de l’identifiant unique d’un enregistrement dans m_index, et cela est survenu lors de la révocation des comptes g1-test de @florck et @gerard94.

Si c’est bien ce que je pense c’est un bug critique qui se produira aussi sur la monnaie de prod lorsque des anciens membres seront automatiquement révoques après 1 ans d’expiration de leur compte. Duniter tente alors d’écrire deux enregistrement m_index en même temps !

EDIT : vraisemblablement c’est une erreur dans la logique du protocole, les règles BR_G93 et BR_G96 s’appliquent en même temps, ce qui pose problème.
une solution serait de changer l’ordre des règles dans quickSync, c’est a dire d’appliquer d’abord la règle de révocation (BR_G96) puis en suite la règle d’expiration (BR_G93).
je ne sais pas du tout si ça résout le problème mais je vais tester ça :slight_smile:

EDIT2 : test effectué ça ne fonctionne pas, il faut donc modifier l’implémentation de la règle BR_G93 pour qu’elle ne s’applique pas aux membres sur le point d’être révoqués

Problème résolu :sunglasses:

2 Likes

hop ceci implique une modification du protocole :

l’idée est simple il s’agit d’ajouter une condition :

l’ancienne règle : faire expirer tout les membres dont la date d’expiration est atteinte au bloc courant

la nouvelle règle : faire expirer tout les membres dont la date d’expiration est atteinte au bloc courant ET dont la date de révocation n’est pas atteinte au bloc courant

Oui car les membres dont la date de révocation est atteinte seront déjà traités par la règle BR_G96, donc pas besoin de les traiter ici.

Je n’ai pas encore le temps de vérifier tout ce que tu dis ni si la correction apportée est bonne, mais pour s’en convraincre il suffirait d’un test automatisé reproduisant le bug !

Si à l’occasion tu arrives à réaliser un tel test (en t’inspirant d’un test existant avec de la révocation), ce serait royal :sunglasses:

1 Like

En tout cas maintenant j’arrive sans problème a rajouter des nœuds au réseau g1-test, même sans les resynchroniser ils rattrapent tout seul leur retard la ou avant ils bloquaient au bloc 79134 :slight_smile:

Faire un test qui reproduis cela consisterai a tester l’expiration d’un membre au bout d’un temps msValidity * EXCLUSION_FACTOR. Ça me semble un peu longs et fastidieux a faire :stuck_out_tongue:
peut-etre plus tard mais la j’ai un rdv…

Alors je vois qu"il existe déjà un test identify-implicit-revocation.js qui passait sans problème malgré l’erreur dans le protocole (et qui passe toujours d’après travis-ci) ce qui est cohérent avec les observations (les nœuds sur g1-test ne se sont pas mis a planter).

Le problème ne se produisais que lors de la synchronisation, c’est donc un test de la commande sync qu’il faut faire.
Il existe bien le test peering.js mais il ne teste pas le cas de révocation implicite, nous sommes donc bien face a un cas non-testé !

Reste que je ne comprend pas pourquoi le problème ne se produit pas lors de la procédure normale d’empilement d’un bloc, je pense qu’il doit y avoir un système de prévention des insert multiples qui n’est pas présent dans quickSync, ou alors il s’est bien produit un problème au niveau ds nœuds g1-test mais on ne le perçoit pas.

Ce ne sont pas les même règles sont appliquées sur une synchro full et une synchro en continue ?

@Inso Si c’est les mêmes règles justement c’est ça qui me chiffonne, un test déjà existant ne devrait en toute logique pas passer et pourtant il passe, je n’ai pas encore trouver la cause de cette différence de comportement, ce qui est certain c’est que le protocole comportais une erreur de logique et qu’une cause inconnue nous empêchais de la détecter dans les tests existant. Quand a savoir s’il il y a réellement eu un problème ou pas sur les nœuds G1-test qui étaient sur le réseau pendant l’événement, difficile a dire, pas un problème bloquant en tout cas, j’ai tout de même remarquer ce comportement bizarre mais c’est peut être du au client : http://g1-test.duniter.fr/#/app/wot/FWz9kYRfEGmqbJbpiV9QL6N8cPqH4t8tBYHWiPnChYg4/florck

Il faut investiguer plus, ça cache peut être un problème plus profond cette histoire…

1 Like

Oui évidemment il faut continuer à chercher tant que l’on a pas trouver l’explication du problème :wink:

J’ai investigué d’avantage et je crois avoir percé le mystère :slight_smile:

La raison pour laquelle le réseau g1-test n’a pas buggé, l’empilement des blocs ne bug pas, l’ancien protocole ne posait pas de problème graçe a une sécurité introduite dans l’implémentaion de la règle BR_G93, un membership déjà expiré ne peut pas expirer de nouveau, c’est la fameuse condition !MS.expired_on ici : https://github.com/duniter/duniter/blob/dev/app/lib/indexer.ts#L1630

La vrai raison du bug proviens de l’algo de synchronisation rapide (vous vous souvenez des sync interminables autrefois ?). Plus précisément la règle BR_G93 n’est pas appliquée a chaque bloc lors de la sync, mais seulement aux blocs pour lequels l’algo pense que qqch va expirer (ça peut etre un membership, une certification, etc)

Le problème c’est que la détection du “quelquechose va expirer” ne fonctionne pas correctement dans l’algo de sync rapide actuel, et deux anciens membres (@gerard94 et @florck) se retrouvent lors d’une sync a être expirés en même temps qu’ils sont révoqués, ce qui à conduit au bug que j’ai constater quand j’ai voulu rajouter un nœud sur g1-test ce matin.

Venons en aux faits : la détection de l’algo de sync rapide par du principe que seul un enregistrement de type CREATE est susceptible d’expirer, ce qui est faux, d’où le bug. Je viens de corriger ça :

Autant garder quand même la nouvelle version du protocole elle est plus robuste et si un jours duniter est réimplémenté dans d’autres langages ça leur fera toujours un problème de moins :slight_smile:

4 Likes

Voilà. Car la synchro rapide, pour être rapide, ne fait pas comme l’empilement « normal » des blocs qui est trop lent pour synchroniser la blockchain entière, à la place cet algorithme rapide ne fait aucune vérification et génère simplement les événements qu’il croise.

Comme ce n’est pas exactement le même algorithme mais une reproduction du vrai, il se peut que des différences existent, et donc que des bugs se nichent dedans.

2 Likes

Si aucun autre dev n’a de projets en cours pour la 1.6 je prévois d’essayer de faire une nouvelle release 1.6.11 lundi soir :slight_smile:

Avec WS2PTOR j’ai aussi apporter quelques modifications qui concernent les nœuds classiques, les voici :

  1. Le timeout d’une connexion WS2p est passé de 10 à 15 secondes. C’est pour permettre aux nœuds tor d’avoir une chance de contacter un nœud classique, le réseau tor est très lent, et 10 secondes c’est trop court, 15 secondes ça reste court mais ça fait déjà fortement la différence d’après mes tests. Il faut garder un timeout court pour les nœuds classiques, afin d’éviter qu’ils attendent trop dans le vide, voici pourquoi je ne suis passer que de 10 à 15 secondes.

  2. Le crawler BMA est désormais désactivé par défaut, même si vous activez BMA ! Pour avoir quand même la crawler BMA vous pouvez utiliser la commande : duniter config --bma-with-crawler
    Ceci étant, si vous avez WS2P Privé (et c’est le cas par défaut), vous n’avez pas besoin du crawler BMA.

  3. J’ai modifier la regex des heads ws2p en vue de permettre a l’avenir aux nœuds duniter de transmettre des informations sur leur configuration réseau, ceci a des fins de statistiques. L’inertie de la mise à jours du réseau devenant très grande, je ne développerai cette fonctionnalité que pour duniter 1.7, mais les nœuds 1.6 accepteront les heads des nœuds 1.7 graçe a l’adaptation de la regex en amont, en fait je prépare une compatibilité descendante. Les explications sont ici : https://github.com/duniter/duniter/issues/1177

1 Like

Encore deux petits ajouts pour la 1.6, ça me démangeais :

  1. Modif des regex SOFTWARE et SOFT_VERSION. SOFTWARE pour autoriser les caractères ._- nottament en vue de renommer duniter en duniter-ts pour bien distinguer le projets des différentes implémentations :slight_smile:
    Quand à la regex SOFT_VERSION elle était incorrecte, le - doit toujours être placé a la fin d’une classe dans une regex (je le dit pour les observateurs qui lirai les commit en vue de les comprendres, moi c’est comme ça que j’ai réussi a rentrer dans le code, en lisant les commits que faisait cgeek) !
    Concernant les regex, j’utilise le super site https://regex101.com/ pour les vérifier (et pour les créer aussi).
  2. Ajout des options --ws2p-prefered-only et --ws2p-privileged-only pour permettre aux utilisateurs qui le souhaiterait d’avoir un contrôle absolu sur les connexions ws2p que peuvent établir leur nœud. Ces options sont évidemment désactiver par défaut car il y a un risque d’isolement du nœud si les listes en question ne sont pas assez fournis. Je n’ai pas fait cet ajout juste pour le fun il s’inscrit dans un objectif plus global qui est de permettre a terme une anonymisation poussée sur le réseau Duniter, c’est en lien avec ws2ptor donc mais aussi avec ce ticket que je prévois pour la 1.7 : https://github.com/duniter/duniter/issues/1182

Le besoin auquel j’ai envie que Duniter puisse répondre le mieux possible, c’est qu’un individu puisse contribuer pleinement au réseau Duniter, sans que personne ne puisse le savoir. Sauf des personnes de confiance que l’individu concerné aura choisi. Ceci afin que d’éventuelles pressions ne dissuadent pas les utilisateurs victime de ces pressions à contribuer activement au réseau de leur monnaie. J’anticipe de loin, mais mieux vaut prévenir que guérir et prévoir au plus tôt la faisabilité technique !

Je réfléchi donc aussi a la possibilité que la fameuse clé déléguée dont l’idée a déjà été évoquée soit associée a un membre de façon totalement anonyme, tout en sachant qu’il faut que le réseau est la garantie qu’a tout instant t chaque membre ne puisse avoir qu’une seule clé déléguée valide, cela est nécessaire pour la bonne application de la difficulté personnalisée. Je ne sais pas encore si c’est mathématiquement possible mais si l’un d’entre vous trouve un concept mathématique ou cryptographique permettant cela alors je l’implémenterai :slight_smile:

2 Likes

En même temps, cela permet aussi à une poignée d’attaquants potentiels de se cacher. Mais dans la mesure où seuls les membres peuvent calculer des blocs, l’impact est limité.

je ne vois pas en quoi on peut attaquer. Sachant que chaque nœud a un trousseau de clé réseau et que tout les échanges sont signés, les clients peuvent choisir des nœuds en lesquels la communauté qui les utilisent a confiance.
Effectivement dans cette optique il faut absolument que la nouvelle API client qui remplacera BMA signe toutes ses réponses.

1 Like

Je pensais typiquement à une attaque Sybil qui serait passée inaperçue, et on ne se rendrait même pas compte qu’ils ont des nœuds qui tournent.