@tuxmain ce ticket est en réalité plus dur qu'il ny parait.
Car il faut également stocker l'historique des obtentions et retrait du droit au DU pour chaque identité.
Une possibilité est de stocker un Vec<BlockNumber>, ou chaque numéro de bloc correspond à un evenement d'optention ou de perte du droit au DU.
L'extrinsic claim_uds devrait alors consommer ce vecteur (le vider).
Ça implique également de stoker la liste des comptes qui ont eu droit au DU par le passé et qui n'ont pas encore claim tout leurs DUs.
Enfin il faut vérifier si un cas vicieux est possible ou non: obtenir et perdre le droit au DU (ou l'inverse), au soin d'un même bloc.
Bref, c'est beaucoup de complexité pour une optimisation qui ne me semble pas nécessaire à la migration, à mon humble avis il faut le déprioriser, je doit d'ailleurs ajouter des label pour la priorisation!
J'avais commencé en stockant pour chaque membre un Option<BlockNumber> du dernier DU réclamé. Ça me semble plus simple comme ça, lors du claim il faut juste compter et mettre à jour le BlockNumber. (et en ajoutant un historique des réévaluations du DU)
S'il y a un ticket plus prioritaire et à ma portée je veux bien changer, mais sinon ça me fait quand même un exercice assez complet.
Nouvelle idée de design, plus simple et qui ne demande aucune création auto du DU:
Ajouter 2 champs dans une nouvelle entité IdtyUdData à stocker dans une map dans la pallet UD (par IdtyIndex):
last_claimed_ud_or_in_at: BlockNumber: Contiens le numéro de bloc du dernier DU réclamé ou le numéro de bloc de la dernière entrée dans la WoT si aucun DU n'a été réclamé depuis.
out_at: Option<BlockNumber>: Contiens le numéro de bloc auquel l'identité à perdue son droit au DU, où None si l'identité à toujours droit au DU.
Le point clé: Lorsque qu'une identité veut acquérir le membership, il faut retourner une erreur si out_at.is_some. D'un point de vue métier, cela signifie qu'un menbre dont l'adhésion a expiré ne peut pas redemander l'adhésion avant d'avoir réclamé ses DU. Ça me semble être le meilleur des compromis, car on évite de devoir mémoriser plusieurs entrées/sorties du membre, et on évite également toute livraison automatique du DU.
@tuxmain tu peut prendre ce ticket si tu veut, je l'ai repriorisé car il est nécessaire pour pouvoir compter correctement le poids de pallet_universal_divident.on_initialize.
Plusieurs remargues importantes avant de commencer:
Il faut ajouter une StorageValue UdIndex qui compte c'est le combientième DU, zéro correspondant au 1er DU qui n'est pas versé automatiquement, et c'est ce nombre qu'il faut stocker dans un nouveau champ last_claimed_ud: u32 dans Idtyvalue. Ainsi quand un utilisateur réclame ses DU, on à juste à faire la différence en nombre "d'index du DU" pour savoir combien de DU ont doit créer. last_claimed_ud ne doit pas être une option, initialize le à zéro quand l'identité est créée, pour l'update quand elle est validée.
Quand l'identité est supprimée, quel qu'en soit la raison, il faut lui verser tout ses DU non réclamés, afin de pourvoir supprimer intégralemet l'identité et ne pas garder de trace dans le storage. C'est pourquoi la suppression d'identité devra devenir manuelle, je vais ouvrir une autre issue pour ça.
Il faut stocker les montant des N dernières Réévaluations dans une seule StorageValue qui doit être un Vec<(u32, BalanceOf<T>)>. Ce Vec doit constamment être ordonné, voir comment faire ici: https://substrate.recipes/vec-set.html. N doit être un type associé (nom à trouver), avec le marqueur pallet::constant. Il faut bien comprendre que si un membre ne réclame pas ses DU pendant plus de N réévaluations, ses DU sont perdus à jamais. Ce nombre de réévaluation doit donc couvrir une période suffisamment large (au moins 2 ans).
Cela requiert également une migration pour translate toutes les IdentityValue, où alors une lazy migration est possible, avec une implémentation custom de Decode, c'est peut-être plus simple, à discuter.
Sans doute d'autres difficultés importante que j’oublie, au moindre doute dans la conception propose moi une visio