Problèmes de la sanction possible en cas d'évaluation de la distance et alternatives

Bonjour à tous,

Depuis quelques jours, je me documente sur les changements qui ont été faits dans Duniter v2 pendant ces 2 ans où j’étais absent.

Je découvre qu’il a été décidé de sanctionner monétairement le compte qui demande l’évaluation de la règle de distance pour une identité si le résultat de l’évaluation est négatif.

J’imagine que l’intention est de protéger du spam, mais cela me semble impliquer trop de défauts pour les wallets et pour les utilisateurs. Je vais expliquer les défauts puis proposer une alternative.

1. Implique au wallet de vérifier la distance offchain au préalable (ou de créer un intermédiaire pour le faire)

Si chaque wallet vérifie la distance localement :

  • Développements complexes pour les wallets
  • Risques de bugs, car les implémentations arrondissent différemment (on avait eu le problème sur la v1 entre le module C++ et le module Rust qui arrondissent les flottants différemment).
  • Demande au wallet de télécharger l’intégralité du graphe de la TdC, ce qui n’est pas envisageable en cas de faible connexion
  • Demande beaucoup de calculs en local, ce qui n’est pas envisageable pour des ordiphones avec une configuration matérielle modeste

Si des intermédiaires vérifient la distance offchain et font la demande :

  • Rajoute un logiciel dans un écosystème technique déjà très complexe. Et même si c’est intégré à un logiciel existant, cela ajoute encore un autre type d’acteur alors qu’on en a déjà beaucoup (forgerons, indexeurs, nœuds miroirs RPC, etc.)
  • Ces acteurs intermédiaires prennent des risques (voir partie 2) sans rémunération ; il faudrait les rémunérer pour leur travail. Cela complexifie encore le modèle d’incitations économiques à mettre en place pour pérenniser l’écosystème sur le long terme.
  • Ces acteurs ont un pouvoir de censure. Ils peuvent blacklister des membres, les empêchant de renouveler leur adhésion. C’est aussi le cas pour les nœuds miroirs RPC, c’est pourquoi il faut décentraliser le réseau RPC, ce qui est déjà complexe. Ces acteurs pourraient être des nœuds RPC avec une option de configuration particulière, mais cela complexifie la compréhension du réseau. Il faudrait ajouter un flag dans les fiches de peer, etc.

2. La distance peut passer sous le seuil entre la pré-évaluation offchain et l’évaluation onchain

Imaginons qu’un membre atteigne tout juste 80 % des référents. Il suffit qu’un autre membre devienne référent en émettant une certification à l’autre bout de la toile pour que, d’un coup, le membre évalué passe à 79,9 % des référents, alors que rien n’a changé concernant ses certifications à lui.

Le relayeur qui signe la demande d’évaluation prend donc un risque : celui d’être sanctionné monétairement même si la pré-évaluation était correcte.

Il faudrait pré-évaluer contre un état correspondant au bloc sur lequel vont se baser les oracles pour le prochain “round”, ce qui n’est faisable que si les rounds sont suffisamment longs et annoncés à l’avance.

3. Si l’identité ne respecte pas la distance, quelqu’un doit redemander régulièrement pour elle

Aujourd’hui, dans la v1, l’utilisateur demande l’adhésion une fois, et son adhésion est inscrite automatiquement dans le futur quand les conditions sont réunies. Dans la v2, en l’état actuel, il faut qu’un acteur redemande l’évaluation de la distance, sinon l’identité ne (re)deviendra pas membre même si elle respecte les critères. C’est une perte de fonctionnalité pour les utilisateurs.


J’avais déjà ces potentiels problèmes en partie en tête il y a 4 ans. C’est pour cela que mon idée de départ était de mesurer la distance dans l’intégralité de la toile toutes les 4h (à chaque session/epoch). Cela avait aussi le bénéfice de permettre à une identité qui n’atteint pas le seuil d’être réévaluée automatiquement jusqu’à ce qu’elle atteigne le seuil ou que la demande expire.
À l’époque, cette approche faisait d’autant plus sens que quelqu’un travaillait sur un algorithme permettant d’évaluer l’intégralité de la toile en un temps raisonnable par rapport au nombre de membres.

Question : comment fonctionne l’algorithme de l’oracle de distance maintenant ? Est-ce qu’il parcourt toute la toile ?


Solution alternative :

Ajouter un paramètre DistanceRetryPeriod dans la palette distance (en nombre d’EstimationPeriod).
Stocker tout les index d’identités en échec dans un set IdtyToRetry: [idty_indexes].
Stocker tous les index d’identités en échec dans une map IdtyToRetryPerPeriod: (EstimationPeriodIndex, [idty_indexes]).
Rejeter toute nouvelle demande d’estimation pour une identité dans le set IdtyToRetry.
À chaque début d’estimation, prendre (take) le tableau [idty_indexes] correspondant dans la map IdtyToRetryPerPeriod et filtrer pour enlever toutes les identités dont le statut est IdtyStatus::Revoked (les retirer aussi du set). Pousser toutes les autres dans la prochaine pool d’estimation.
Au résultat d’estimation: Supprimer du set et de la map les identités qui respectent la règle. Ajouter dans le set et la map “retry” toutes les identités en échec avec period index: CurrentPeriodIndex + T::DistanceRetryPeriod


Pour la migration vers la v2, je suggère de simplement supprimer la sanction pour le moment.

Il y a déjà plusieurs checks qui protègent du spam, notamment le fait de devoir recevoir 5 certifications valides pour que la distance soit évaluée. Cela est déjà aussi sécurisé contre le spam que la v1 en production depuis 8 ans.

Qu’en pensez-vous ? :slight_smile:

5 Likes

Pour l’instant la solution envisagée était de faire appel à un serveur pour évaluer la distance avant de soumettre l’extrinsic. @HugoTrentesaux

À quoi fais-tu référence ? S’il s’agit de la méthode que j’avais trouvée avec la matrice d’adjacence, le coût en mémoire est impraticable.

Pour chaque identité candidate, on explore ses certificateurs récursivement. C’est assez efficace (le plus coûteux est le chargement des données).

Il y aurait sûrement des optimisations non-triviales à faire si on voulait évaluer un grand nombre d’identités d’un coup, mais pour l’instant les vagues d’évaluations devraient être réduites (surtout depuis que la période d’évaluation est passée à quelques minutes).

Si je me souviens bien, je pouvais évaluer toute la toile en quelques secondes à peine sur mon laptop à 4 cœurs. Donc une réévaluation fréquente de toute la toile devrait être scalable si la période est assez grande pour que les quelques forgerons qui ont une machine supérieure au RPi4 puissent y dédier quelques cœurs et avoir une proba assez élevée d’écrire un bloc avec le résultat.

Si on veut évaluer beaucoup d’identités il faut quand même découper en petites fournées, car chaque publication de résultats doit contenir le score de chaque identité, et au changement de période il faut tout traiter en un seul bloc.

Ça me semble bien.

1 Like

Oui, c’est ce que reflète le ticket Use distance pre-computation (#36) · Issues · clients / Cesium-grp / cesium2s · GitLab il me semble. C’est effectivement lourd.

Oui le coût actuel d’un calcul de distance avec moins de 10k membre est négligeable, c’est plutôt le chargement initial des données qui prend du temps, et là encore à mes yeux c’est négligeable pour l’instant.

Oui ce serait très bien, il n’y a aucun risque pour l’instant, on a largement le temps de gérer le problème.

2 Likes

Supprimer le slash en cal d’échec (qui est en fait le slash du montant réservé lors de la demande d’évaluation) peut se faire en modifiant un paramètre, sans toucher au code.

1 Like

Oui Hugo évoquait l’idée d’un calcul côté wallet, mais nous ne sommes pas partis la dessus. Dorian est en train d’implémenter la récupération du fichier JSON pré calculé toutes les 5 minutes.
Cette solution a un bon côté, niveau fonctionnel : elle permet l’affiche du pourcentage du nombre de référents joignables, dans la page des details d’un compte.
Mais l’inconvénient est de devoir (encore) être dépendant d’un autre serveur tier. Cela en fait déjà beaucoup : le noeud duniter, l’indexeur squid, le datapod, et maintenant le serveur de precalcul…

La solution proposée par Éloïs, si je comprends bien, résoud le problème de dépendance pour la demande d’adhésion. Mais quid que l’accès en lecture pour l’affichage ? Garde ton le service tiers ? Si oui, comment s’assurer que le serveur est bien synchro ?

1 Like

Si c’est juste pour l’affichage il n’y a pas de raison de mettre en blockchain, donc mieux vaut que ça reste un service tiers.

Ce qui n’empêche pas que ce service tiers soit un appel RPC fourni par les nœuds miroirs (en option), afin de ne pas ajouter de nouvelle dépendance ni de nouvelle stack réseau, et de savoir qu’il est synchro avant de demander l’évaluation.

4 Likes

Oui c’était ça. A l’époque on ne savais pas encore que le coût en mémoire serait impraticable.

En effet avec l’information qu’on utilise toujours l’ancien algo, ça fait sens d’avoir des rounds plus petit car on évalue pas toute la toile.

Même en supprimant la sanction monétaire et en traitant le problème du spam plus tard, il y a quand même en l’état une perte de fonctionnalité par rapport à la Ğ1v1:


En spécifiant le montant de la réserve à zéro?

Je suis pour minimiser le nombre de services/réseaux différents dont un wallet dépend pour que son interface soit pleinement fonctionnelle.

Pour l’estimation en lecture, l’idéal serait d’ajouter une méthode RPC duniter_wot_distance(at, idtyIndex) qui retourne un objet avec trois champs: le nombre de référents atteints, le nombre total de référent, et le seuil à atteindre (actuellement 80%).

Le noeud RPC calculerai à la volée la distance pour l’identité demandée si la valeur n’es pas en cache.

On propose la même chose, mais l’appelé “service tiers” me semble confusant. Ce n’est certes pas on-chain, mais ça resterait intégrer dans le logiciel duniter-v2s, donc de mon point de vue l’appellation “service tier” n’est pas appropriée.

1 Like

Pourquoi pas mais cela fait potentiellement beaucoup d’appel, car en naviguant dans Césium nous pourrions a chaque page de détail avoir un appel RPC + calcul, pour une info qui n’a pas besoin d’être en temps réel (5 min suffisent) alors qu’aujourd’hui un seul appel au precalcul renvoit toutes les identités d’un seul coup. Donc la navigation dans l’App n’induit qu’un seul accès réseau/ 5 min.

A réfléchir…

1 Like

Il me semble que l’usage de Cesium c’est plutôt de gérer ses comptes que de chercher des métriques de distance sur tout les utilisateurs, on à pas besoin d’avoir les métriques de distance pour tout le monde dans un wallet qui sert d’abord à gérer ses comptes. L’utilisateur va chercher à savoir ce qu’il en est pour lui-même et ses certifiés, pas plus.

Il me semble préférable d’avoir un site web dédié pour tout ce qui est explorations plus globale de toutes les données.

Aussi c’est mieux pour la maintenabilité long-terme, si Cesium v2 cherche à être à la fois wallet et explorateur comme l’est un peu Cesium v1, ça fait un logiciel plus gros et plus dur à maintenir.

A mon humble avis, Cesium v2 gagnerait à se concentrer sur la gestion de ses comptes et à être plus minimaliste que Cesium v1 :slight_smile:

1 Like

La discussion est super intéressante, il y a plein de points de vue différents tous valables et difficiles à concilier ! Je vais essayer de donner le mien rapidement :

  • frais en cas d’évaluation négative → Je suis pour le mettre à zéro car on n’a pas encore de solution technique permettant d’être certain que cela n’arrivera pas.
  • distance qui passe sous le seuil entre pré-évaluation offchain et évaluation par l’oracle → L’évaluation par l’oracle se fait sur le premier bloc de la période courante. Dans l’idéal il faudrait aligner la pré-évaluation sur ces blocs et s’assurer que le hash du bloc est le même. Si ce n’est pas le cas, elle peut être en avance ou en retard.
    • si la pré-évaluation est en avance → elle pourrait intégrer l’expiration de certifications qui n’avaient pas encore eu lieu, mais dans ce cas ça ne me paraît pas problématique.
    • si la pré-évaluation est en retard → elle pourrait :
      • traîner à donner son “feu vert” parce qu’elle ne tient pas compte de nouvelles certifications
      • donner un “feu vert” alors que l’expiration de certifications va avoir lieu, dans ce cas c’est un problème.
  • perte de fonctionnalité sur l’évaluation automatique
    • dans le cas d’une nouvelle identité → Ça me semble suffisant que la ré-évaluation se fasse uniquement à chaque nouvelle certification reçue par l’identité (par batch lancé automatiquement par le client du certificateur). Les cas où la distance devient positive grâce à une modification plus éloignée sur la toile sont extrêmement rares.
    • dans le cas d’un renouvellement d’adhésion → Si quelqu’un renouvelle son adhésion sans respecter la règle de distance, je trouve ça mieux qu’il soit prévenu par son client au moment où il effectue l’action plutôt que l’évaluation soit relancée pendant une période donnée (combien) jusqu’à ce que le critère soit hypothétiquement réalisé, par exemple suite à une certification. On peut discuter davantage de ce point.
  • responsabilité de Cesium → Ma vision n’est pas un Cesium minimaliste, mais un Cesium complet, cf le post "Tout" avoir directement dans Cesium v2 - Mise à jour V2 - Forum Monnaie Libre. Je préfère pouvoir répondre aux besoins de la communauté et en particulier des animateurs de groupes locaux en concentrant les efforts de développement et de maintenance (incluant financement spécifique) sur un logiciel unique que dépendre de services non maintenus comme wotwizard et g1-monit. J’adore la diversité quand il s’agit d’explorer de nouvelles approches, mais quand les besoins sont clairs et bien identifiés, ça me semble une bonne idée de les implémenter dans le client principal.

À mon avis le plus gros problème est la multiplication des serveurs tiers. Je compte bien utiliser les capacités de Hasura à fusionner plusieurs API et servir le résultat du calcul de distance sur squid, et même éventuellement les données indexées par les datapods. Dans mon esprit la solution temporaire actuelle a pour seul but d’avoir quelque chose de concret compatible avec la migration.

Au sujet de la discussion précalcul / calcul à la volée, j’aimerais prendre un peu de recul. L’idée d’un système p2p est de permettre à participant au réseau de pouvoir soi-même répondre ses besoins. Mais il y a plein de cas où ce n’est pas pratique (volume de données à récupérer, implémentation complexe, consommation de ressources…). Dans ces cas on accepte de déléguer le calcul à un tiers de confiance, mais cela a un coût pour le tiers. À mon avis il faut minimiser le coût pour ces tiers. Dans l’exemple du calcul de la règle de distance, ça me semble bien plus économe de calculer pour tout le monde toutes les cinq minutes plutôt que de calculer à la volée pour chaque requête, potentiellement sur chaque page d’une application, et sans gestion de cache.

1 Like

On est d’accord pour montant du dépôt à zéro mais pas pour les mêmes raisons. Tu semble vouloir toujours qu’on trouve à l’avenir des moyens d’avoir une pré-évaluation suffisamment fiable pour rétablir la sanction monétaire un jour.

De mon point de vue, l’objectif est de trouver d’autres protections anti-spam qui n’impliques pas d’avoir une pré-évaluation. La pré-évaluation ne devrais être qu’un bonus indicatif pour l’affichage.

Dit autrement, on doit pouvoir développer un wallet 100% fonctionnel pour gérer se comptes Ğ1 sans aucun pré-évalation de la distance.

Je suis d’accord, ça reste techniquement une perte de fonctionnalité dans certains cas à la marge, mais dans la pratique l’utilisateur bloqué ira de toute façon chercher une certification de plus.

À l’inverse, je suis pour une simplification de l’expérience utilisateur ; j’estime que ce n’est pas à l’utilisateur de porter la charge mentale : “Ah oui, je dois renouveler.”

Grâce aux batchs, les wallets pourraient automatiquement demander le renouvellement de manière transparente lors d’une transaction de l’utilisateur. Ainsi, on aurait juste à dire aux utilisateurs : “Votre compte doit être actif au moins une fois par an.”

L’alternative que je propose peut s’adapter sans réévaluation automatique coté runtime. Il suffit d’interdire deux réévaluations trop rapprochées (par exemple, à moins d’une semaine), avec un paramètre, nommé par exemple DistanceRetryMinPeriod, qui préciserait la durée minimale à attendre pour pouvoir redemander une évaluation.

Je suggère l’algo suivant:

Pour toute transaction d’un utilisateur membre ou anciennement membre, si le dernier renouvellement d’adhésion réussi de l’utilisateur remonte à plus de 6 mois et que la dernière demande d’évaluation de distance est plus ancienne que DistanceRetryMinPeriod, alors inclure dans la transaction une demande d’évaluation de distance.

En plus de cela, effectuer cette demande pour chaque certification reçue au-delà de 5 si l’identité réceptrice n’est pas encore ou plus membre.

Je suis d’accord en théorie, mais en pratique, il n’y a pas de contributeurs bénévoles à Cesium, à part Benoît, qui n’a pas le temps. À tel point que la communauté a dû payer 6 000 euros pour que Cesium v2 avance et qu’on puisse migrer la Ğ1.

Du coup, faire reposer un maximum de choses sur un logiciel qui n’a pas de forces bénévoles pour le maintenir me semble risqué !

Ne pas avoir de pré-évaluation signifie faire faire la pré-évaluation à tous les oracles et de manière répétée, plutôt qu’à un seul, avec les coûts associés en blockchain. Certes pour la migration c’est faisable et ça réduit (peut-être ?) la quantité de travail pour les clients, mais ça risque de coûter cher à l’avenir.

Je ne comprends pas ce que tu veux dire. Si c’est un résultat publié en blockchain par un oracle, alors par définition ce n’est pas une pré-évaluation, c’est une évaluation.

Et dans tous les cas, on ne peut pas faire confiance à un seul oracle, il en faut plusieurs pour s’assurer qu’ils ne trichent pas.

D’ailleurs, ce qu’il manque, c’est la sanction des oracles qui donnent un résultat différent de la médiane. C’est le principe même des oracles normalement : ils sont incités économiquement à donner la bonne mesure, car ils sont sanctionnés s’ils ne donnent pas la même que les autres.

En tous cas, ce n’est pas à l’utilisateur d’être sanctionné. Le système d’oracle doit être transparent pour l’utilisateur. :slight_smile:

Par nature, la décentralisation coûte plus cher que la centralisation, car plusieurs acteurs refont le même calcul. C’est le principe même de la blockchain : tous les nœuds exécutent l’intégralité de tous les blocs.

Le but des oracles n’est pas de réduire le coût de calcul, mais de contourner la contrainte de temps d’exécution d’un bloc limité à 2 secondes.

Je voulais dire que généraliser la demande d’évaluation sans vérification préalable fait faire à la blockchain le travail des pré-évaluateurs. La blockchain sert à vérifier, mais là on s’en servirait pour faire le calcul sans même savoir si on s’attend à un résultat positif.

Un résultat négatif en blockchain devrait rester exceptionnel (signe d’une attaque, d’une erreur ou d’une malchance de timing avec la pré-évaluation).

La pré-évaluation ne servant pas de vérification, elle sert à éviter d’appeler les oracles pour rien, et de minimiser le risque de résultat négatif, donc de minimiser le coût global de la règle de distance.

On peut faire ça, mais il y a plein de cas où ce n’est pas clair. Par exemple, si on a 2 résultats différents : faut-il sanctionner les 2 ?

L’idée était plutôt de gérer ça humainement entre forgerons. Un résultat différent est probablement soit un bug de l’oracle qui doit être rapporté plutôt que sanctionné, soit une attaque qui doit mener à une enquête et éventuellement à l’éviction de la toile forgeron. Il faudra d’ailleurs un système d’alerte pour ça. (faut-il créer un événement en cas de résultats différents, afin de permettre aux indexeurs de détecter le problème ?)

1 Like

La blockchain est un outil commun qui sert à ce à quoi on décide collectivement.

Je suis favorable à déporter off-chain autant que possible quand le rapport coûts/bénéfices est raisonnable, mais je pense qu’on doit rester pragmatiques et considérer l’impact global.

La blockchain ne sert déjà pas qu’à vérifier, ente les remark, les events, le username, etc, on met déjà on-chain des éléments qui ne sont pas nécessaire à la vérification des règles du protocole.

Déporter la pré-évaluation de la distance off-chain entraîne un rapport coûts/bénéfices qui me semble trop mauvais au global pour être acceptable.

1 Like

Ce sera aux devs de clients de le dire. Les deux solutions ont chacune des conséquences sur l’UI, dont on n’a pas encore discuté.

Si on n’est pas prêt à sanctionner les membres forgerons, alors on peut encore moins sanctionner les utilisateurs finaux.

J’imagine que tu veux parler des wallets/applications comme CesiumV2 ou Gecko ?

S’il vous plaît, arrêtez d’utiliser le terme “client”. Dans tous les autres projets blockchain, le terme “client” désigne le client du protocole blockchain, soit Duniter dans le cas de la Ğ1.

Bah si, on en a déjà discuté. J’en parle dans mon premier post, et on en a parlé en vocal vendredi avec kimamila, qui a confirmé que c’était important que la pré-évaluation de la distance ne soit que de l’affichage.

Niveau UX (et pas juste UI ; UI, c’est l’apparence, UX, c’est l’expérience utilisateur), il me semble évident qu’il n’est pas souhaitable de dépendre d’encore un autre service tiers pour savoir si l’on a le droit de proposer à l’utilisateur de renouveler son adhésion.

CesiumV2 dépend déjà de beaucoup de services. Regarde donc ce fichier : src/environments/environment.prod.ts · master · clients / Cesium-grp / cesium2s · GitLab

Chaque service supplémentaire implique une expérience utilisateur dégradée (voire non fonctionnelle) chaque fois que l’un de ces services n’est pas disponible.

Perdre les indexeurs ne fait perdre qu’en affichage, par exemple : cela dégrade l’expérience utilisateur, mais on ne perd pas en fonctionnalités essentielles. L’utilisateur peut toujours réaliser ses opérations essentielles (transferts, certifications, renouvellement).

Si la pré-évaluation de la distance n’est que de l’affichage, alors l’utilisateur peut quand même renouveler son adhésion, même quand le service qui fournit cette pré-évaluation ne répond pas.

Si la pré-évaluation de la distance est un prérequis (ce qu’implique de fait la sanction > 0), alors toute indisponibilité du service devient une perte de fonctionnalité. Soit l’interface ne permet pas à l’utilisateur de renouveler son adhésion (va donc expliquer pourquoi dans l’interface), soit l’interface doit afficher un avertissement expliquant à l’utilisateur qu’il pourrait être sanctionné s’il renouvelle son adhésion. Va expliquer ça aux utilisateurs… C’est un cauchemar à développer.

Sauf que ça ne sera pas possible : dans tous les cas il faudra gérer le moment entre le clic sur le bouton qui lance la procédure, et le moment où le membership est validé/renouvelé.

Avec pré-évaluation offchain, il faut faire des requêtes et pouvoir afficher une erreur ou griser le bouton.

Avec répétition automatique onchain, il faut afficher l’état en attente, empêcher de relancer une demande, peut-être ajouter une estimation de temps, vérifier périodiquement l’état.

Je parlais de ces aspects d’UI, pas d’un simple champ informatif.

Les sanctions dans les deux cas ont des buts complètement différents donc je ne vois pas le rapport.

1 Like