# Implémentation des quotas

**URL:** https://forum.duniter.org/t/implementation-des-quotas/11543
**Category:** R&D
**Tags:** fees
**Created:** [8 September 2023 14:59 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543 "2023-09-08T14:59:48Z")
**Posts on this page:** 13
**Page:** 2

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [13 October 2023 10:53 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/21 "2023-10-13T10:53:03Z")

</div>

> [@HugoTrentesaux](#):
>
> `IdtyValue` n’est pas forcément le bon endroit pour ranger une information de quotas. Ce serait mieux de le mettre dans `IdtyData`.

J’ai pas mal avancé dans l’implémentation, même si je me heurte à la difficulté des types paramétriques partagés entre des pallets et un type du runtime. Je ne sais toujours pas si c’est une bonne idée d’être parti sur un champ `quotas` dans `IdtyData`.

En gros pour l’instant :

- dans `correct_and_deposit_fee` on vérifie seulement si `account_data.linked_idty` est défini pour ajouter à la queue
- dans `on_idle` on appelle `process_refund_queue`
- on y appelle `spend_quotas` qui cherche l’identité dans le storage et _vérifie son statut_ avant d’appeler `update_quotas` et `do_spend_quotas` sur les `IdtyData`
- ensuite, tout le traitement “quotas” est fait dans `IdtyData` qui est un type du runtime fourni à la pallet identity comme type paramétrique car il partage des informations avec la pallet universal dividend
- c’est ensuite `try_refund` appelé dans `process_refund_queue` qui retirera les sous à la trésorerie et les mettra sur le compte (non implémenté)

Et la difficulté, c’est de faire en sorte que _tout le monde_ utilise le même type `Balance` sans mettre des dépendances dans tous les sens avec le trait `Currency` :

- `IdtyData` (type du runtime) dans son champ `quotas`
- le trait `IdtyQuotasLinker` de la pallet identity qui permet à la pallet account de déléguer `spend_quotas`
- le trait `Quotas` de la pallet identity implémenté par `IdtyData` qui gère `update_quotas` et `do_spend_quotas`

Comme `IdtyData` est un type du runtime, il connaît les types concrets et ne peut pas utiliser des types paramétriques (sinon il y a un cycle de dépendance entre le type runtime et le type idtydata), mais comme il prend des arguments venant de fonctions des pallets, il y a une incompatibilité.

Donc soit on fait une conversion à un moment donné (Balance / BlockNumber → u64 / u32) puis (u64 / u32 → Balance / BlockNumber), soit on déplace le champs `quotas` vers `IdtyValue`, mais ça implique quand même d’ajouter une dépendance de la pallet identity à la pallet balance ou un type paramétrique qui implémente le trait `Currency`.

Bref, voilà les réflexions que je dois avoir en ce moment 😶

* * *

[edit] je pars sur la conversion, c’est ce qui me paraît le plus naturel et ça ne devrait pas poser de problèmes (à tester)

---

<div class="post-metadata">

### Author: ![cgeek](https://forum.duniter.org/user_avatar/forum.duniter.org/cgeek/32/279_2.png) [@cgeek](https://forum.duniter.org/u/cgeek)
#### Post date: [14 October 2023 09:22 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/22 "2023-10-14T09:22:43Z")

</div>

> [@HugoTrentesaux](#):
>
> Comme `IdtyData` est un type du runtime, il connaît les types concrets et ne peut pas utiliser des types paramétriques (sinon il y a un cycle de dépendance entre le type runtime et le type idtydata)

Je ne sais pas si ça peut t’aider, mais dans une vidéo de l’équipe Substrate que j’ai vu il y a quelques temps, il y avait une partie sur “[Share functionality between pallets](https://youtu.be/VVU3Io2dACY?si=u_5lxVthDKXN9aIw&t=4390)” où l’intervenant revient sur les 2 principaux modes selon lui :

- couplage fort (par héritage = dépendance direct du trait Config d’une autre pallet)
- couplage souple (ajout d’un type qui sera implémenté à la définition du Runtime)

Le fait qu’IdtyData soit un type du Runtime (je comprends : pas un type d’une palette) ça signifie que c’est encore autre chose, n’est-ce pas ? Y a-t-il une contrainte qui explique qu’il soit défini comme ça ?

---

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [17 October 2023 10:46 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/23 "2023-10-17T10:46:59Z")

</div>

Je suis moins à l’aise avec les explications par vidéo qu’avec la documentation écrite et celle-ci : [https://docs.substrate.io/build/pallet-coupling/](https://docs.substrate.io/build/pallet-coupling/) me convient bien.

On y retrouve bien les deux types de couplage sous le nom “Tightly coupled pallets” / “Loosely coupled pallets”.

Il faudrait que j’illustre le schéma de couplage des pallets dans Duniter-v2s qui m’a l’air cohérent. Pour l’instant `duniter-account` et fortement couplé avec `balances` `provide_randomness` et `pallet_treasury` ([pallets/duniter-account/src/lib.rs#L52-L56](https://git.duniter.org/nodes/rust/duniter-v2s/-/blob/f78c17f902fbe0bf477bc1ab3a1c704b4591ce44/pallets/duniter-account/src/lib.rs#L52-L56)). Je propose d’ajouter des couplages faibles par l’intermédiaire des types `IdtyId`, `InnerOnChargeTransaction`, `Currency`, `IdtyLinker`. Le type `IdtyLinker` implémente le trait `IdtyQuotasLinker` (noms à revoir) qui permet de demander un traitement externe des quotas.

Pour l’instant j’ai fait en sorte que ce soit la pallet `identity` qui implémente la gestion des quotas parce que notre notion de quotas est fortement liée à la notion d’identité. Et cette pallet n’a pas besoin d’être liée fortement à la pallet `universal-dividend` parce que la seule donnée qu’elle partage avec elle est dans `IdtyData` : le `first_eligible_ud`, d’où le couplage faible à ce type ([pallets/identity/src/lib.rs#L79](https://git.duniter.org/nodes/rust/duniter-v2s/-/blob/f78c17f902fbe0bf477bc1ab3a1c704b4591ce44/pallets/identity/src/lib.rs#L79)).

Maintenant la question : « _pourquoi `IdtyData` est un type du runtime (et donc pas un type d’une pallet) ?_ ». Ça rentre dans “couplage souple”, mais au lieu d’utiliser un type implémenté par une pallet (par exemple le type `AccountData` ([runtime/common/src/pallets\_config.rs#L70](https://git.duniter.org/nodes/rust/duniter-v2s/-/blob/f78c17f902fbe0bf477bc1ab3a1c704b4591ce44/runtime/common/src/pallets_config.rs#L70)), on utilise un type implémenté par le runtime (configuré [runtime/common/src/pallets\_config.rs#L445](https://git.duniter.org/nodes/rust/duniter-v2s/-/blob/f78c17f902fbe0bf477bc1ab3a1c704b4591ce44/runtime/common/src/pallets_config.rs#L445), défini [runtime/common/src/entities.rs#L75-L79](https://git.duniter.org/nodes/rust/duniter-v2s/-/blob/f78c17f902fbe0bf477bc1ab3a1c704b4591ce44/runtime/common/src/entities.rs#L75-L79)).

J’imagine que l’idée est de permettre à plusieurs pallets d’ajouter des données liées à une identité dans les `IdtyData` sans avoir à modifier la pallet `identity` elle-même (les `IdtyValue`). Et ça tombe bien parce que c’est ce dont j’ai besoin pour les quotas. Est-ce qu’on a d’autre exemples de ça dans le runtime polkadot ? Il faudrait que je l’étudie plus en détail.

> [@cgeek](#):
>
> Y a-t-il une contrainte qui explique qu’il soit défini comme ça ?

Je pense que c’est un reste du travail d’elois pour avoir beaucoup de modularité, et ça aide pas mal au niveau des tests. Est-ce que c’est un peu “sur-ingéniéré” ? Je n’ai pas encore assez de recul là dessus, je verrai en avançant dans l’implémentation, mais pour l’instant le code que j’écris m’a l’air lisible et à sa place, on verra à la relecture 🙂

---

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [18 October 2023 09:14 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/24 "2023-10-18T09:14:15Z")

</div>

En écrivant les tests, je me rends compte que ce serait effectivement plus simple de regrouper les fonctionnalités des quotas dans une pallet.

> [@tuxmain](#):
>
> Je pensais plutôt faire une crate `quota` avec une map `AccountId -> (last_use, amount)`. Ainsi on fait une seule lecture db.

Du coup la solution que je retiens est de conserver le `linked_idty` dans `duniter-account` (c’est bien sa place) et de partir sur une pallet quotas avec une map `IdtyId` → `(last_use, amount)`.

Je laisse ma branche actuelle `hugo-quotas-2` de la MR [!183](https://git.duniter.org/nodes/rust/duniter-v2s/-/merge_requests/183) en l’état, et je repars sur une branche `hugo-quotas` avec une pallet quotas. C’est un peu de travail de réécriture sur quelque chose qui pourrait marcher en l’état, mais c’est plus propre et ça m’embêterait de partir sur une solution trop crade.

---

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [20 October 2023 12:38 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/25 "2023-10-20T12:38:59Z")

</div>

C’est bon, les quotas ont leur pallet ! Maintenant que c’est fait, il m’apparaît évident que c’est la bonne approche. J’ai pu développer facilement des tests unitaires, ce qui était trop compliqué avant, et les tests d’intégration fonctionnent toujours. Et en bonus, ça va m’aider à comprendre le point toujours mystérieux ([Comportement actuel des frais](https://forum.duniter.org/t/comportement-actuel-des-frais/11561)) puisque dans l’opération, le montant des frais est resté de 2, mais le montant du remboursement est passé à 1 🤔

> **bonus**
>
> J’aurais pu implémenter ça plus rapidement si je n’avais pas posé quelques demies journées de congés pour cause de grasse matinée car couché tard et tonne de boulot militant pour la BASE et la lutte contre l’A69.

---

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [6 November 2023 10:01 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/26 "2023-11-06T10:01:50Z")

</div>

Une question intéressante de spécifications liée aux quotas a été soulevée dans les [discussions sur la MR](https://git.duniter.org/nodes/rust/duniter-v2s/-/merge_requests/183#note_38514).

À partir de quand a-t-on droit aux quotas ? Quand l’identité est :

- créée ?
- confirmée ?
- validée ?

Est-ce qu’une identité qui perd le statut de membre perd aussi le droit au quotas (= remboursement des frais de transaction) ?

---

<div class="post-metadata">

### Author: ![tuxmain](https://forum.duniter.org/user_avatar/forum.duniter.org/tuxmain/32/6423_2.png) [@tuxmain](https://forum.duniter.org/u/tuxmain)
#### Post date: [6 November 2023 11:01 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/27 "2023-11-06T11:01:22Z")

</div>

La seule chose dont on veut s’assurer est que seules les personnes physiques puissent avoir un quota, et qu’elles puissent en avoir un seul.

Seul l’état de membre permet de satisfaire cette contrainte, donc je dirais que seuls les membres ont droit au quota.

À partir d’une identité membre je peux créer plusieurs identités factices qui ne doivent pas être éligibles. Si je perds mon statut de membre pour cause de mort ou de suspicion de multicompte, mes comptes ne doivent plus être éligibles.

Si un jour les identités membres faibles (reçoit le DU mais n’a pas de part de gouvernance et ne certifie pas) sont implémentées, elles pourraient tout de même avoir un quota.

---

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [6 November 2023 12:26 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/28 "2023-11-06T12:26:35Z")

</div>

Pour moi, le droit au DU et le droit à l’utilisation gratuite de la blockchain ne sont pas aussi sensibles. Si quelqu’un essaye de profiter plusieurs fois des quotas gratuits en créant plusieurs identités il est hors licence et s’expose à perdre le droit au DU. Il faudra voir les ordres de grandeur des quotas et des frais, mais la menace d’accaparement des ressources blockchain n’est _a priori_ pas présente, les quotas sont juste là pour que les identités n’aient pas à payer de frais de transaction.

#### Scénario “normal”

En émettant une première certification vers un compte, un membre s’engage à ce que ce compte corresponde à une personne physique, et lui attribue un numéro d’identité. Il me semble logique que dans ce cas, la personne ait droit à l’utilisation gratuite de la blockchain par cooptation.

#### Scénario d’attaque

Un utilisateur membre souhaitant nuire à la Ğ1 en utilisant des ressources blockchain utilise ses 100 certifications pour créer 100 nouvelles identités sybil, au rythme de une tous les cinq jours. Ces comptes peuvent soumettre des transactions sur le réseau et se faire rembourser les frais correspondant dans la limite des quotas (par exemple l’équivalent de 1 Ğ1 par semaine). Les identités sybil expirent au bout de 2 mois car elles n’ont pas eu d’autres certifications et perdent le droit au quota.  
Au total, en 500 jours, 100 identités ont bénéficié de 8 semaines de quotas, soit un équivalent de 800 Ğ1 d’économie de frais de transactions pour l’attaquant. Quelqu’un qui souhaiterait investir 800 Ğ1 dans une attaque aurait le même pouvoir de nuisance, mais sans risquer de perdre le droit au DU.

Je rappelle que les frais de transaction sont un ajout par rapport à la Ğ1v1. Moins l’utilisateur légitime les ressent, mieux ce sera. Ils sont vraiment là pour des raisons techniques, pour que monopoliser les ressources blockchain coûte cher. Et “cher” peut se compter en Ğ1 mais également en certifications hors licence.

---

<div class="post-metadata">

### Author: ![Maaltir](https://forum.duniter.org/user_avatar/forum.duniter.org/maaltir/32/5039_2.png) [@Maaltir](https://forum.duniter.org/u/Maaltir)
#### Post date: [6 November 2023 13:24 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/29 "2023-11-06T13:24:53Z")

</div>

Je pense qu’une identité confirmée peut bénéficier de quotas.  
Peut-on imaginer que cette identité pas encore membre ait un quota inférieur ?  
Peut-on imaginer que chaque certificateur d’une identité non membre transmette une partie de ses quotas jusqu’à ce que l’identité certifiée devienne membre ?

---

<div class="post-metadata">

### Author: ![tuxmain](https://forum.duniter.org/user_avatar/forum.duniter.org/tuxmain/32/6423_2.png) [@tuxmain](https://forum.duniter.org/u/tuxmain)
#### Post date: [6 November 2023 18:20 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/30 "2023-11-06T18:20:17Z")

</div>

Ok en effet le risque de sécurité est assez faible.

Si on crée un moyen de tricher facilement il faut en revanche vérifier que ça n’augmente pas trop le flicage inter-membres&nbsp;: tout le monde sera invité à se demander quels sont les critères pour déterminer le seuil de bizarreries dans les historiques de certifications et de transactions des gens, pour savoir s’il y a usage illégitime du quota. Une chose de plus que la licence devra imposer.

Cette interdiction pourrait ne pas être dans la licence parce que c’est marginal et qu’il faudrait être tordu pour exploiter ça, mais alors certains pourraient le faire en pensant que c’est légitime.

---

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [6 November 2023 18:47 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/31 "2023-11-06T18:47:07Z")

</div>

_A priori_ quand un utilisateur émet une certification (_a fortiori_ la première), on lui demande de s’assurer qu’il a en face de lui une personne physique qui respecte la licence et des règles de sécurité. Donc c’est à voir côté client. Évidemment on peut toujours tricher, mais ce sera difficile d’affirmer ne pas savoir si c’est clair dans les clients grand public.

---

<div class="post-metadata">

### Author: ![tuxmain](https://forum.duniter.org/user_avatar/forum.duniter.org/tuxmain/32/6423_2.png) [@tuxmain](https://forum.duniter.org/u/tuxmain)
#### Post date: [6 November 2023 21:56 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/32 "2023-11-06T21:56:17Z")

</div>

Il ne faut pas non plus se fier aux développeurs de clients pour respecter des “bonnes pratiques” floues. Si on veut imposer aux clients de décourager cette pratique il faut que ce soit précisé dans la licence, qui est le seul document devant faire consensus et autorité même parmi les non-devs.

Il existe déjà des clients Gchange non-libres faits par des gens n’ayant jamais mis les pieds sur ce forum… il y aura forcément des clients G1 qui feront n’importe quoi, et les membres devront être capables de détecter qu’ils ne respectent pas la licence ou incitent à l’enfreindre.

---

<div class="post-metadata">

### Author: ![cgeek](https://forum.duniter.org/user_avatar/forum.duniter.org/cgeek/32/279_2.png) [@cgeek](https://forum.duniter.org/u/cgeek)
#### Post date: [7 November 2023 12:34 UTC](https://forum.duniter.org/t/implementation-des-quotas/11543/33 "2023-11-07T12:34:55Z")

</div>

Ce que l’on peut faire : comme le suggère Hugo présumer légitime une identité confirmée, et donc lui accorder le droit aux quotas.

Puis, si l’on se rend compte à l’analyse de la blockchain qu’il existe un abus manifeste sur cette fonctionnalité, on pourrait rajouter des pénalités aux créateurs d’identités qui expirent (ou ne reçoivent qu’une seule certification, etc.) de sorte à rendre la pratique inintéressante.

Il ne faudrait pas non plus inciter à la création de fausses identités, au-delà de la ressource blockchain, cette action doit rester non-banale et engager la responsabilité morale de son auteur.

[Previous page](https://forum.duniter.org/t/implementation-des-quotas/11543.md?page=1)
