La création d'identité dans Duniter-v2s

:arrow_lower_right:
Ce sujet précise comment fonctionne la création d’identité dans Duniter-v2s.

Comme déjà expliqué ici et , dans duniter-v2s toute action utilisateur entrera directement en blockchain (si la transaction est valide et qu’il y a de la place dans le bloc).

Ce qui signifie qu’une identité créée se trouvera en blockchain dès sa création, même si elle n’est pas encore « validée ».

Une identité a trois états possibles :

  • Created
  • ConfirmedByOwner
  • Validated

Seul le 3ᵉ état donne droit à créer ses DU et émettre des certifications.

1. Le 1ᵉʳ certificateur crée l’identité

Pour créer son identité, il faut d’abord trouver son 1ᵉʳ certificateur, et lui fournir une clé publique.

Le 1ᵉʳ certificateur va alors soumettre l’extrinsic identity.create_identity(owner_key).
Le paramètre owner_key est de type AccountId et doit correspondre à la clé publique du propriétaire de l’identité.

Cet extrinsic va créer une nouvelle identité et la certifier, l’émetteur de la certification étant le signataire de cet extrinsic.

2. Le propriétaire confirme

Ensuite, le propriétaire de l’identité doit confirmer son identité en soumettant l’extrinsic identity.confirm_identity(name), où name est une chaine de caractère qui représentera le nom de l’identité (ce que l’on nommait UserID dans duniter v1).
L’identité passe alors à l’état ConfirmedByOwner.

La signature de cet extrinsic par le propriétaire de l’identité vaut acte d’engagement à respecter la licence Ğ1 et est considéré comme une demande d’adhésion à la toile de confiance Ğ1.

3. L’identité reçoit ses autres certifications

C’est seulement une fois que l’identité est confirmée par son propriétaire qu’elle peut recevoir d’autres certifications, via l’extrinsic cert.add_cert(receiver). Dès que l’identité a reçu au moins cinq certifications elle est envoyée dans la queue des identités dont il faut évaluer la distance.

4. La règle de distance est évaluée

Lors du prochain « round » d’évaluation de la distance, deux possibilités :

  1. L’identité respecte la règle de distance, elle passe à l’état Validated
  2. L’identité ne respecte pas la règle de distance, elle sera réévaluée au prochain round.

Je n’ai pas encore implémenté la distance, donc je ne peux pas encore vous dire quelle sera la durée entre deux rounds, certaines contraintes techniques peuvent nécessiter une durée assez longue, de l’ordre de 6h à 12h je pense).

5. L’identité est validée

Une fois que l’identité est à l’état Validated, elle obtient le droit de co-créer le DU et de certifier où créer d’autres identités. Elle obtient également le droit de demander l’adhésion à la sous-toile forgeron.

Aparté : Ce qui fait quatre droits obtenus en même temps, ça fait beaucoup, je proposerai dans un autre sujet que certains de ces droits requièrent plus de certifications, mais comme ce n’est pas structurant pour le code, on peut voir ça bien plus tard.

6. Nouveaux paramètres

Ce nouveau mécanisme implique l’ajout de deux nouveaux paramètres à la wot :

ConfirmPeriod

La durée pendant laquelle le propriétaire peut confirmer son identité après sa création. Passé cette durée, si l’identité n’est toujours pas confirmée elle est supprimée et la 1er certification est supprimée également (le certificateur récupère alors cette certification dans son stock).
Cette durée doit être courte, de l’ordre de la semaine.

IdtyCreationPeriod

La durée minimale entre deux créations d’identité par un même « créateur ». Ce paramètre est essentiel pour se protéger du spam, sa durée doit être supérieure où égale à ConfirmPeriod afin qu’il ne soit pas possible de créer une nouvelle identité alors que la précédente n’a pas encore été confirmée. Cette durée doit être courte, de l’ordre de la semaine.

7. Expiration de l’identité dans l’état ConfirmedByOwner

Pour ce cas on réutilise le paramètre msWindow, qui est PendingMembershipPeriod dans le code pour plus de clarté : c’est la durée maximale ou une demande d’adhésion peut rester en attente.

La demande d’adhésion correspond à la confirmation de l’identité par son propriétaire, ce paramètre PendingMembershipPeriod fixe donc la durée maximale ou une identité peut rester à l’état ConfirmedByOwner.

Si passé cette durée, l’identité est toujours dans l’état ConfirmedByOwner, alors l’identité est supprimée et toutes les certifications qu’elle avait reçues sont supprimées également. Les certificateurs récupèrent ces certifications dans leurs stocks.
Il n’y a alors plus aucune trace de l’identité ni de ces certifications dans le storage onchain, c’est comme si elle n’avait jamais existé.
La valeur de ce paramètre est maintenue à deux mois comme dans Duniter v1.

8. Maintien du paramètre sigPeriod

Ce paramètre est actuellement nommé CertPeriod dans le code, mais ce nom ne me satisfait pas pleinement, si quelqu’un à une idée d’un nom qui désigne mieux son rôle je suis preneur :slight_smile:

Pour rappel, ce paramètre fixe la durée minimale entre deux certifications.
Étant donné que la création d’une identité implique sa certification par le créateur, le paramètre certPeriod s’applique, donc si le créateur à déjà émis une certification il y a moins de cinq jours, la création de l’identité échouera.

9. Certifications et règle de distance

Les certifications reçues par une identité non validée (et ayant reçu moins de cinq certifications) ne sont pas prises en comptes dans l’évaluation de la règle de distance des autres identités, ce qui n’a d’impact que dans le fait d’être considéré comme membre référent où non, puisque l’identité non-validée ne peut pas apporter de chemin à d’autres identités du fait qu’elle n’a pas pu émettre de certifications.

Actuellement, la notion de membre référent n’existe que relativement à l’évaluation de la règle de distance d’une identité, ce qui signifie que selon l’identité dont on évalue la distance, un même membre sera considéré comme référent où non.

Exemple :

Disons qu’il faut six certifications émises et reçues pour être membre référent, et que Kevin en a reçue dix et émise cinq (dont une envers Vincent).

Si Kevin créer une nouvelle identité pour Olivia, il la certifie en même temps, il a alors émis six certifications.

Cependant, lors de l’évaluation de la règle de distance de Vincent, si la règle de distance d’Olivia n’est pas évaluée lors du même round (car elle n’a pas encore obtenue cinq certifications), alors Kevin ne sera pas considéré comme référent, car sa certification envers Olivia ne se trouve pas dans les données de la wot transmises au code qui calcule la distance.
En revanche, lors de l’évaluation de la règle de distance pour Olivia (quand elle aura obtenu quatre autres certifications), Kevin sera considéré comme référent, et donc compté dans les 80 % de référents à atteindre.

Notez que j’ai précisé « si la règle de distance d’Olivia n’est pas évaluée lors du même round ». Cela est dû au fait que la règle de distance sera désormais évaluée par groupes, alors qu’elle est évaluée individuellement dans Duniter v1.
L’évaluation par groupe va permettre de fortement optimiser le calcul, car tous les chemins communs ne seront parcourus qu’une seule fois, contre N fois dans Duniter v1 pour l’évaluation de N identités.

Dans certains cas, le nombre de membre référents sera plus élevé que si l’évaluation avait été individuelle, donc ça devrait compliquer le respect de la règle de distance, on pourrait compenser cet effet en diminuant légèrement xpercent. Si quelqu’un veut faire des simulations pour évaluer cet effet ce serait ure super contribution, d’autant que je ne le ferai pas moi-même, j’ai déjà tellement à faire !



Résumé

  • Les documents Identity et Membership n’existent plus ils sont remplacés par deux extrinsics de la pallet identity: create_identity(owner_key) et confirm_identity(name).
  • Le délai de deux mois est conservé, si l’identité n’est pas pleinement validée dans les deux mois (confirmation par le propriétaire, obtention de cinq certifications, et validation de la distance), elle est supprimée et toutes ses certifications reçues aussi.
  • Deux nouveaux délais sont introduits : le délai laissé au propriétaire de l’identité pour confirmer sa demande, et le délai entre deux créations d’identité.
  • Les certifications reçues par une identité non-validée ne comptent dans la règle de distance que lorsque l’identité a obtenu cinq certifications.
4 « J'aime »

Il faudra que les wallets signale cette impossibilité avant d’envoyer la création d’identité.

Comment ça se passe pour les personnes qui n’ont plus que 4 certifs, puis en récupère une nouvelle, et que la règle de distance n’est pas respecté, et qu’il récupère ensuite une 6e certif pour être bon.
Par quels états va passer cette identité ?

Un détail ambigu : Que se passe-t-il si ConfirmPeriod < CertPeriod et que l’identité n’est pas confirmée, le créateur peut-il certifier tout de suite parce que la certification est oubliée, ou faut-il attendre ? (même si le problème ne se posera pas avec les paramètres choisis)

Il doit me rester quelque part une simulation sur les référents, je peux tenter.

Pour moi il manque Min ou Minimal, et j’aurais tendance à utiliser Interval à la place de Period mais c’est peutêtre de la francisation plutôt que le terme adéquoit.
Après, l’ordre CertMinInterval ou MinCertPeriod… ça dépend des autres noms pour être cohérent.

Ne serait-il pas plus simple de ne considérer les certifications que des identités validées ?

3 état concernant la création.
Il y a aussi l’état Revoked non ?

Vu que ce n’est pas le destinataire de l’identité qui créer l’identité, parler à ce moment-là de propriétaire de l’identité me semble ambiguë.

Mais là il me semble que owner-key signifie propriétaire de la clé pas de l’identité.

Je ne penses pas, pour moi c’est plutôt claire que ça correspond à la clé du propriétaire de l’identité.

Il ne me semble pas, la création est déléguée à un membre, mais l’identité appartient au destinataire. C’est plutôt clair à mon avis

1 « J'aime »

Si l’identité était déjà Validée, elle sera révoquée.
Si l’identité était non-validée, elle ne peut pas perdre de certification avant expiration de sa demande, car duniter v2s force ConfirmPeriod < PendingMembershipPeriod < CertValidityPeriod

CertPeriod s’applique lors de la création de l’identité, donc il n’y a pas d’interférence possible avec ConfirmPeriod, qui s’applique au propriétaire de l’identité et non à son créateur.

C’est impossible, si tu fais ça aucune identité en attente ne peut respecter la règle de distance.

Il n’ y a pas d’état Revoked dans le storage onchain, car une identité révoquée n’existe plus dans ce dernier.

Quel terme propose tu à la place ? Le terme destinataire ne me convient pas, car c’est mon identité, je n’en suis pas le destinataire, mais le propriétaire, je délègue juste à mon 1er certificateur l’acte de déclaration.

Oui exactement :slight_smile:

Oui :slight_smile:

Pour moi ce serait plutôt le terme « créateur » qui est ambigü, il faudrait coller à « premier certificateur » ou autre.

2 « J'aime »

S’agissant d’une forme de certification ça ne me choquerait pas que ce paramètre soit le même que sigPeriod (ou certPeriod, ou le nom que vous aurez trouvé).

Je ne vois aucune raison d’interdire la création d’une nouvelle identité si la précédente n’a pas encore été confirmée, dans la mesure où de toute façon on ne peut pas spammer le système grâce au paramètre sigPeriod d’une part, et la quantité limité des droits à certifier par membre.

Ce serait effectivement plus simple pour l’utilisateur que la valeur soit là même, mais ça restera un paramètre différent dans le code, pour garder de la souplesse dans les évolutions que l’on souhaitera dans le futur.

Notamment, j’ai peur que l’on décide un jour de réduire la durée de CertPeriod, car j’ai besoin que la durée de IdtyCreationPeriod reste élevée pour une autre raison: le IdtyIndex.

Le IdtyIndex est un nombre entier signé sur 4 octets (u32), un IdtyIndex unique est associé à chaque identité créée dès sa création, ça à 3 avantages:

  1. L’identité est identifiée de manière unique par quelque chose qui ne dépend pas de la clé publique, cette dernière pourra donc être modifiée, une fonctionnalité à laquelle je tiens pour l’avenir. Et je ne veux pas que l’on se base sur le IdtyName (anciennement UserID) pour cela, car ce dernier doit aussi pouvoir changer, et sera peut-être totalement supprimé de la blockchain à l’avenir.
  2. Ça permet de référencer une identitié en seulement 4 octets, or j’ai plein d’item dans le onchain storage qui références des identités, notamment les certifications, l’impact sur la taille du onchain storage est titanesque.
  3. Ça permet de le fournir directement au bout de code qui calcule la distance, car ce dernier représente chaque identité par un nombre entier.

Aparté: En réalité c’est principalement pour les raisons 2 et 3, car pour 1. j’ai une autre solution en tête, dont je n’ai pas encore parlé car j’ai beaucoup trop de choses en tête et pas le temps de les expliquer bien, il me faudra des mois (voir des années), pour expliquer correctement tout ce que j’ai en tête, et entre-temps j’aurais de nouvelles idées donc ça ne finira jamais :stuck_out_tongue:

Le problème, c’est que l’on peut faire une attaque qui consiste à créer plein d’identités sans réel propriétaire derrière, juste pour incrémenter trop vite le compteur IdtyIndex pour lui faire atteindre u32::MAX (environ 4 milliards).
C’est pour empêcher cette attaque précise que je souhaite que la valeur de IdtyCreationPeriod reste élevée. 5 jours me semble suffisants, ça fait qu’un attaquant ne peut incrémenter le compteur que de +7300 dans sa vie, mais on devra se rappeler qu’il ne faut pas descendre trop en dessous de 5 jours.

1 « J'aime »

OK, je comprends mieux le principe. Mais même en admettant qu’une identité soit créée toutes les secondes, il faut quand même plus de 120 ans pour épuiser le compteur. Sachant que ces identités bidons vont disparaître au bout de quelques jours faute de confirmation, en rendant l’allocation de IdtyIndex circulaire, le problème est éliminé.

Ce qui serait en O(NlogN) : si on ne reboucle pas, il suffit de faire +1 à chaque fois. Si on reboucle, il faut faire +1, vérifier si le numéro est en usage (donc un accès à la base de données, en O(logN)), si oui recommencer (au pire N fois). (imagine qu’on reboucle mais que le numéro 10 est encore utilisé, jusqu’au 9 pas de problème, mais il faut savoir que le prochain disponible est le 11)

Donc le jour où on arrive aux milliards il faudrait plutôt augmenter la taille du nombre j’imagine.

Mathématiquement c’est probablement vrai. In real life ça l’est moins, car une attaque va allouer tout un lot d"index contigus, ou quasi contigus. Ce ne sera pas une fragmentation type disque dur de Windows 3.11.

De toute façon sigPeriod ne descendra pas à l’échelle d’une seconde; ni même d’une heure. Il va donc se passer des centaines d’années avant que l’overflow ne puisse se produire. Substrate / Duniter aura été ré-écrit from scratch un paquet de fois… J’incline à penser que c’est un faux problème.

Après, si cette variable en plus IdtyCreationPeriod évite de se poser la question sans coûter spécialement cher, go !

1 « J'aime »

On ne peut pas c’est trop couteux. @tuxmain a bien répondu :slight_smile:

Ce jour n’arrivera jamais, la Ğ1 n’a pas vocation à devenir la monnaie de toute l’humanité, on cible 1 million d’utilisateurs, on peut sans doute monter à 10 millions, mais pas beaucoup au-delà en mono-blockchain.
Si un jour on arrive jusque la, il faudra soit splitter en plusieurs monnaies-libres (ce que je recommande), soit faire du sharding multi-chain (très complexe et ne résout pas tout), soit compter sur une nouvelle technologie qui n’existe pas encore et dont on a aucune certitude qu’elle existe un jour.
Je parle souvent des layer 2, mais on ne peut pas tout faire en layer 2 , et notamment la couche d’identification me semble nécessiter d’être ancrée au moins en partie en layer 1, et notamment la partie qui attribue un IdtyIndex.

Ce n’est pas une bonne approche. Plus le onchain storage est gros, plus le temps pour y accéder en lecture/écriture est long, et donc plus le poids d’une même opération augmente, et donc la capacité de la blockchain diminue.
Alors heureusement le temps d’accès au storage est en O(ln n), mais il faut être prudent quand même.

Je pense aussi, sauf si des centaines de milliers de membres se mettent à spammer à mort la création d’identité, mais c’est un extrinsic qui fait beaucoup de contrôles donc qui consomme beaucoup de poids, donc il coûtera cher, donc le spammer sera coûteux.
Bref, oui tant que IdtyCreationPeriod n’est pas trop faible, c’est un faux problème.

Elle est déjà dans le code, et je suis d’accord pour que sa valeur soit égale à celle de CertPeriod pour la Ğ1 :slight_smile:

C’est aussi parce que je code en suivant le principe de découplage, je préfère avoir plusieurs paramètres différents qui pourraient être fusionnés en un seul dans le métier actuel, mais qui techniquement sont appliqués à des endroits différents.

Alors en réalité c’est le nombre de clés qui est important, quand je parle du temps d’accès au storage O(ln n), n représente le nombre de clés.

Aussi, pour que ce temps d’accès reste en O(ln n), la répartition des préfixes des clés doit être relativement homogène, c’est pour cela que substrate préfixe toutes les clés par leur hash.

Si la taille des clés où des valeurs augmente, ça impacte le temps de sérialisation/dé-sérialisation de l’entrée, mais je ne sais pas si c’est non-négligeable. À noter également, que le runtime est compilé en wasm32, donc les mots font 4 octets, donc il traite plus rapidement les u32 que les u64.

Bref ce n’est pas juste une question de « taille globale du storage », c’est plus subtil :slight_smile: