Sujet technique, similaire à Production du DU.
Dans ma rédaction du protocole, je passe actuellement sur les traitements événementiels internes, c’est-à-dire des traitements qui doivent intervenir à un instant donné et qui ne sont pas déclenchés par une action utilisateur mais par la blockchain elle-même, dont voici la liste :
- Expiration de certification (au bout de 2 ans) [sigValidity]
- Expiration d’adhésion (au bout de 1 an) [msValidity]
- Révocation implicite (1 an après la parte de statut de membre) [msValidity x 2]
Il y a également l’événement de DU, mais celui-ci ne pose pas problème car sa complexité d’implémentation est en O(1) vu qu’il n’y a au plus qu’un seul DU par bloc. Ce qui n’est pas le cas des certifications, adhésions et révocations qui sont en O(N) si l’on doit toutes les parcourir à chaque fois, N étant le nombre de membres.
Il y avait aussi les événements de péremption des documents en piscine, mais comme celle-ci va être retirée je les mets juste pour mémoire.
Anciens événements de péremption en piscine.
- Péremption de l’identité (pas devenue membre au bout de 2 mois) [idtyWindow]
- Péremption de la certification (non consommée au bout de 2 mois) [sigWindow]
- Péremption de l’adhésion (au bout de 2 mois) [msWindow]
La recherche par intervalle est coûteuse
Le gros problème de ces événements internes, c’est la difficulté de les retrouver en base de données : il faut faire une recherche par intervalle de valeurs, par exemple trouver toutes les certifications qui ont expiré entre le 06/01/2021 12h (bloc(t - 1)) et 12h10 (bloc(t)).
Ce genre de traitements est coûteux car il faut “scanner” les données (d’où le O(N)). De plus l’API du Storage n’offre pas de fonctions de recherches par intervalle de valeur pour des raisons structurelles.
Créer un index applicatif
Le seul moyen dont nous disposons est de créer nous-même un index mais de niveau applicatif. C’est-à-dire des entrées dans la base de données qui référencent d’autres données.
Par exemple avoir une entrée Storage["cert_expiry"]["2022-01-01 02:34:00"] = [id_cert_1, id_cert2]
qui liste les certifications 1 et 2 qui sont censées expirer à 02h34 le 01/01/2022.
Ainsi on n’a pas à parcourir la liste entière des certifications, mais simplement une petite sous-partie puis lire les certifications elles-mêmes.
Le choix de l’index
Mettre une date-heure me semble correct, dans la mesure où l’on a un bloc toutes les 6 secondes, ça veut dire qu’entre deux bloc affichant l’intervalle [t-1, t] on doit en moyenne aller faire 6 lectures pour Storage["cert_expiry"]
à chaque bloc pour les expirations de certifications, 6 autres pour les adhésions et 6 autres pour les révocations.
A mettre en perspective des 14516 transactions monétaires maximales théoriques par bloc, soit donc le double en nombre de lectures (l’émetteur, le bénéficiaire) donc environ 29000 lectures/bloc : 18 lectures ne sont rien.
On pourrait toutefois choisir de mettre en index un n° de bloc, arguant qu’un bloc se produit théoriquement toutes les 6" alors on peut calculer le n° du bloc auquel l’expiration se produit. C’est aussi très direct. Néanmoins c’est moins exact, le temps inter-bloc n’étant pas garanti avec Substrate.
Je préfère donc l’index avec date-heure d’expiration, plus précisément un timestamp en UTC+0.
C’est ce que je compte indiquer dans le protocole comme changement pour Duniter V2S.