From f97f5c9620ca1aa9283cabf566972dd975af97ca Mon Sep 17 00:00:00 2001
From: Hugo Trentesaux <hugo.trentesaux@lilo.org>
Date: Tue, 28 Feb 2023 16:15:31 +0100
Subject: [PATCH] Runtime documentation (nodes/rust/duniter-v2s!133)

* fix renaming RuntimeCall

* cargo xtask gen-calls-doc

and update metadata

* doc storage

* more doc

* doc identity

* doc calls
---
 docs/api/runtime-calls.md              | 253 +++++++++++++------------
 end2end-tests/tests/common/balances.rs |   2 +-
 pallets/authority-members/README.md    |  12 +-
 pallets/authority-members/src/lib.rs   |  31 ++-
 pallets/authority-members/src/types.rs |   3 +
 pallets/certification/src/lib.rs       |   7 +
 pallets/certification/src/types.rs     |   4 +
 pallets/duniter-wot/src/lib.rs         |   1 +
 pallets/identity/src/lib.rs            |  21 +-
 pallets/identity/src/types.rs          |  26 +++
 pallets/membership/src/lib.rs          |  35 +++-
 pallets/universal-dividend/src/lib.rs  |  21 +-
 resources/metadata.scale               | Bin 127710 -> 131886 bytes
 xtask/src/gen_calls_doc.rs             |   5 +-
 14 files changed, 290 insertions(+), 131 deletions(-)

diff --git a/docs/api/runtime-calls.md b/docs/api/runtime-calls.md
index ad32cf07e..42672b72f 100644
--- a/docs/api/runtime-calls.md
+++ b/docs/api/runtime-calls.md
@@ -25,7 +25,7 @@ There are **68** user calls from **21** pallets.
 when: T::BlockNumber
 maybe_periodic: Option<schedule::Period<T::BlockNumber>>
 priority: schedule::Priority
-call: Box<CallOrHashOf<T>>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -50,11 +50,11 @@ Cancel an anonymously scheduled task.
 <details><summary><code>schedule_named(id, when, maybe_periodic, priority, call)</code></summary>
 
 ```rust
-id: Vec<u8>
+id: TaskName
 when: T::BlockNumber
 maybe_periodic: Option<schedule::Period<T::BlockNumber>>
 priority: schedule::Priority
-call: Box<CallOrHashOf<T>>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -66,7 +66,7 @@ Schedule a named task.
 <details><summary><code>cancel_named(id)</code></summary>
 
 ```rust
-id: Vec<u8>
+id: TaskName
 ```
 </details>
 
@@ -81,7 +81,7 @@ Cancel a named scheduled task.
 after: T::BlockNumber
 maybe_periodic: Option<schedule::Period<T::BlockNumber>>
 priority: schedule::Priority
-call: Box<CallOrHashOf<T>>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -94,11 +94,11 @@ Anonymously schedule a task after a delay.
 <details><summary><code>schedule_named_after(id, after, maybe_periodic, priority, call)</code></summary>
 
 ```rust
-id: Vec<u8>
+id: TaskName
 after: T::BlockNumber
 maybe_periodic: Option<schedule::Period<T::BlockNumber>>
 priority: schedule::Priority
-call: Box<CallOrHashOf<T>>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -131,7 +131,7 @@ be reported.
 <details><summary><code>transfer(dest, value)</code></summary>
 
 ```rust
-dest: <T::Lookup as StaticLookup>::Source
+dest: AccountIdLookupOf<T>
 value: T::Balance
 ```
 </details>
@@ -151,7 +151,7 @@ The dispatch origin for this call must be `Signed` by the transactor.
 <details><summary><code>transfer_keep_alive(dest, value)</code></summary>
 
 ```rust
-dest: <T::Lookup as StaticLookup>::Source
+dest: AccountIdLookupOf<T>
 value: T::Balance
 ```
 </details>
@@ -169,7 +169,7 @@ origin account.
 <details><summary><code>transfer_all(dest, keep_alive)</code></summary>
 
 ```rust
-dest: <T::Lookup as StaticLookup>::Source
+dest: AccountIdLookupOf<T>
 keep_alive: bool
 ```
 </details>
@@ -265,7 +265,7 @@ and the remaining amount to another account.
 </details>
 
 
-
+ask to leave the set of validators two sessions after
 
 #### go_online - 1
 
@@ -276,7 +276,7 @@ and the remaining amount to another account.
 </details>
 
 
-
+ask to join the set of validators two sessions after
 
 #### set_session_keys - 2
 
@@ -288,7 +288,7 @@ keys: T::KeysWrapper
 </details>
 
 
-
+declare new session keys to replace current ones
 
 ### Grandpa - 15
 
@@ -356,6 +356,11 @@ hash: T::Hash
 
 Clear an unrequested preimage from the runtime storage.
 
+If `len` is provided, then it will be a much cheaper operation.
+
+- `hash`: The hash of the preimage to be removed from the store.
+- `len`: The length of the preimage of `hash`.
+
 #### request_preimage - 2
 
 <details><summary><code>request_preimage(hash)</code></summary>
@@ -443,7 +448,39 @@ Transaction fees will be waived if the member is voting on any particular propos
 for the first time and the call is successful. Subsequent vote changes will charge a
 fee.
 
-#### close - 4
+#### close_old_weight - 4
+
+<details><summary><code>close_old_weight(proposal_hash, index, proposal_weight_bound, length_bound)</code></summary>
+
+```rust
+proposal_hash: T::Hash
+index: ProposalIndex
+proposal_weight_bound: OldWeight
+length_bound: u32
+```
+</details>
+
+
+Close a vote that is either approved, disapproved or whose voting period has ended.
+
+May be called by any signed account in order to finish voting and close the proposal.
+
+If called before the end of the voting period it will only close the vote if it is
+has enough votes to be approved or disapproved.
+
+If called after the end of the voting period abstentions are counted as rejections
+unless there is a prime member set and the prime member cast an approval.
+
+If the close operation completes successfully with disapproval, the transaction fee will
+be waived. Otherwise execution of the approved operation will be charged to the caller.
+
++ `proposal_weight_bound`: The maximum amount of weight consumed by executing the closed
+proposal.
++ `length_bound`: The upper bound for the length of the proposal in storage. Checked via
+`storage::read` so it is `size_of::<u32>() == 4` larger than the pure length.
+
+
+#### close - 6
 
 <details><summary><code>close(proposal_hash, index, proposal_weight_bound, length_bound)</code></summary>
 
@@ -514,19 +551,6 @@ value: BalanceOf<T>
 
 Transfer some liquid free balance to another account, in milliUD.
 
-#### force_set_first_eligible_ud - 3
-
-<details><summary><code>force_set_first_eligible_ud(who, first_eligible_ud)</code></summary>
-
-```rust
-who: T::AccountId
-first_eligible_ud: FirstEligibleUd
-```
-</details>
-
-
-
-
 ### Identity - 41
 
 #### create_identity - 0
@@ -571,7 +595,7 @@ idty_index: T::IdtyIndex
 </details>
 
 
-
+validate the owned identity (must meet the main wot requirements)
 
 #### change_owner_key - 3
 
@@ -624,22 +648,10 @@ inc: bool
 </details>
 
 
-
+change sufficient ref count for given key
 
 ### Membership - 42
 
-#### request_membership - 1
-
-<details><summary><code>request_membership(metadata)</code></summary>
-
-```rust
-metadata: T::MetaData
-```
-</details>
-
-
-
-
 #### renew_membership - 3
 
 <details><summary><code>renew_membership(maybe_idty_id)</code></summary>
@@ -650,7 +662,7 @@ maybe_idty_id: Option<T::IdtyId>
 </details>
 
 
-
+extend the validity period of an active membership
 
 ### Cert - 43
 
@@ -683,7 +695,21 @@ metadata: T::MetaData
 </details>
 
 
+submit a membership request (must have a declared identity)
+(only available for sub wot, automatic for main wot)
+
+#### claim_membership - 2
 
+<details><summary><code>claim_membership(maybe_idty_id)</code></summary>
+
+```rust
+maybe_idty_id: Option<T::IdtyId>
+```
+</details>
+
+
+claim that the previously requested membership fullfills the requirements
+(only available for sub wot, automatic for main wot)
 
 #### renew_membership - 3
 
@@ -695,7 +721,7 @@ maybe_idty_id: Option<T::IdtyId>
 </details>
 
 
-
+extend the validity period of an active membership
 
 #### revoke_membership - 4
 
@@ -707,7 +733,8 @@ maybe_idty_id: Option<T::IdtyId>
 </details>
 
 
-
+revoke an active membership
+(only available for sub wot, automatic for main wot)
 
 ### SmithsCert - 53
 
@@ -801,7 +828,7 @@ The dispatch origin for this call must be _Signed_.
 
 ```rust
 other_signatories: Vec<T::AccountId>
-call: Box<<T as Config>::Call>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -819,14 +846,13 @@ Result is equivalent to the dispatched result.
 
 #### as_multi - 1
 
-<details><summary><code>as_multi(threshold, other_signatories, maybe_timepoint, call, store_call, max_weight)</code></summary>
+<details><summary><code>as_multi(threshold, other_signatories, maybe_timepoint, call, max_weight)</code></summary>
 
 ```rust
 threshold: u16
 other_signatories: Vec<T::AccountId>
 maybe_timepoint: Option<Timepoint<T::BlockNumber>>
-call: OpaqueCall<T>
-store_call: bool
+call: Box<<T as Config>::RuntimeCall>
 max_weight: Weight
 ```
 </details>
@@ -941,9 +967,9 @@ Request a randomness
 <details><summary><code>proxy(real, force_proxy_type, call)</code></summary>
 
 ```rust
-real: T::AccountId
+real: AccountIdLookupOf<T>
 force_proxy_type: Option<T::ProxyType>
-call: Box<<T as Config>::Call>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -960,13 +986,12 @@ Parameters:
 - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call.
 - `call`: The call to be made by the `real` account.
 
-
 #### add_proxy - 1
 
 <details><summary><code>add_proxy(delegate, proxy_type, delay)</code></summary>
 
 ```rust
-delegate: T::AccountId
+delegate: AccountIdLookupOf<T>
 proxy_type: T::ProxyType
 delay: T::BlockNumber
 ```
@@ -983,13 +1008,12 @@ Parameters:
 - `delay`: The announcement period required of the initial proxy. Will generally be
 zero.
 
-
 #### remove_proxy - 2
 
 <details><summary><code>remove_proxy(delegate, proxy_type, delay)</code></summary>
 
 ```rust
-delegate: T::AccountId
+delegate: AccountIdLookupOf<T>
 proxy_type: T::ProxyType
 delay: T::BlockNumber
 ```
@@ -1004,7 +1028,6 @@ Parameters:
 - `proxy`: The account that the `caller` would like to remove as a proxy.
 - `proxy_type`: The permissions currently enabled for the removed proxy account.
 
-
 #### remove_proxies - 3
 
 <details><summary><code>remove_proxies()</code></summary>
@@ -1018,13 +1041,12 @@ Unregister all proxy accounts for the sender.
 
 The dispatch origin for this call must be _Signed_.
 
-WARNING: This may be called on accounts created by `anonymous`, however if done, then
+WARNING: This may be called on accounts created by `pure`, however if done, then
 the unreserved fees will be inaccessible. **All access to this account will be lost.**
 
+#### create_pure - 4
 
-#### anonymous - 4
-
-<details><summary><code>anonymous(proxy_type, delay, index)</code></summary>
+<details><summary><code>create_pure(proxy_type, delay, index)</code></summary>
 
 ```rust
 proxy_type: T::ProxyType
@@ -1053,13 +1075,12 @@ same sender, with the same parameters.
 
 Fails if there are insufficient funds to pay for deposit.
 
+#### kill_pure - 5
 
-#### kill_anonymous - 5
-
-<details><summary><code>kill_anonymous(spawner, proxy_type, index, height, ext_index)</code></summary>
+<details><summary><code>kill_pure(spawner, proxy_type, index, height, ext_index)</code></summary>
 
 ```rust
-spawner: T::AccountId
+spawner: AccountIdLookupOf<T>
 proxy_type: T::ProxyType
 index: u16
 height: T::BlockNumber
@@ -1068,30 +1089,29 @@ ext_index: u32
 </details>
 
 
-Removes a previously spawned anonymous proxy.
+Removes a previously spawned pure proxy.
 
 WARNING: **All access to this account will be lost.** Any funds held in it will be
 inaccessible.
 
 Requires a `Signed` origin, and the sender account must have been created by a call to
-`anonymous` with corresponding parameters.
-
-- `spawner`: The account that originally called `anonymous` to create this account.
-- `index`: The disambiguation index originally passed to `anonymous`. Probably `0`.
-- `proxy_type`: The proxy type originally passed to `anonymous`.
-- `height`: The height of the chain when the call to `anonymous` was processed.
-- `ext_index`: The extrinsic index in which the call to `anonymous` was processed.
+`pure` with corresponding parameters.
 
-Fails with `NoPermission` in case the caller is not a previously created anonymous
-account whose `anonymous` call has corresponding parameters.
+- `spawner`: The account that originally called `pure` to create this account.
+- `index`: The disambiguation index originally passed to `pure`. Probably `0`.
+- `proxy_type`: The proxy type originally passed to `pure`.
+- `height`: The height of the chain when the call to `pure` was processed.
+- `ext_index`: The extrinsic index in which the call to `pure` was processed.
 
+Fails with `NoPermission` in case the caller is not a previously created pure
+account whose `pure` call has corresponding parameters.
 
 #### announce - 6
 
 <details><summary><code>announce(real, call_hash)</code></summary>
 
 ```rust
-real: T::AccountId
+real: AccountIdLookupOf<T>
 call_hash: CallHashOf<T>
 ```
 </details>
@@ -1113,13 +1133,12 @@ Parameters:
 - `real`: The account that the proxy will make a call on behalf of.
 - `call_hash`: The hash of the call to be made by the `real` account.
 
-
 #### remove_announcement - 7
 
 <details><summary><code>remove_announcement(real, call_hash)</code></summary>
 
 ```rust
-real: T::AccountId
+real: AccountIdLookupOf<T>
 call_hash: CallHashOf<T>
 ```
 </details>
@@ -1136,13 +1155,12 @@ Parameters:
 - `real`: The account that the proxy will make a call on behalf of.
 - `call_hash`: The hash of the call to be made by the `real` account.
 
-
 #### reject_announcement - 8
 
 <details><summary><code>reject_announcement(delegate, call_hash)</code></summary>
 
 ```rust
-delegate: T::AccountId
+delegate: AccountIdLookupOf<T>
 call_hash: CallHashOf<T>
 ```
 </details>
@@ -1159,16 +1177,15 @@ Parameters:
 - `delegate`: The account that previously announced the call.
 - `call_hash`: The hash of the call to be made.
 
-
 #### proxy_announced - 9
 
 <details><summary><code>proxy_announced(delegate, real, force_proxy_type, call)</code></summary>
 
 ```rust
-delegate: T::AccountId
-real: T::AccountId
+delegate: AccountIdLookupOf<T>
+real: AccountIdLookupOf<T>
 force_proxy_type: Option<T::ProxyType>
-call: Box<<T as Config>::Call>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -1185,7 +1202,6 @@ Parameters:
 - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call.
 - `call`: The call to be made by the `real` account.
 
-
 ### Utility - 64
 
 #### batch - 0
@@ -1193,7 +1209,7 @@ Parameters:
 <details><summary><code>batch(calls)</code></summary>
 
 ```rust
-calls: Vec<<T as Config>::Call>
+calls: Vec<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -1215,7 +1231,7 @@ bypassing `frame_system::Config::BaseCallFilter`).
 
 ```rust
 index: u16
-call: Box<<T as Config>::Call>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -1239,7 +1255,7 @@ The dispatch origin for this call must be _Signed_.
 <details><summary><code>batch_all(calls)</code></summary>
 
 ```rust
-calls: Vec<<T as Config>::Call>
+calls: Vec<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -1261,7 +1277,7 @@ bypassing `frame_system::Config::BaseCallFilter`).
 <details><summary><code>force_batch(calls)</code></summary>
 
 ```rust
-calls: Vec<<T as Config>::Call>
+calls: Vec<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -1286,7 +1302,7 @@ bypassing `frame_system::Config::BaseCallFilter`).
 
 ```rust
 value: BalanceOf<T, I>
-beneficiary: <T::Lookup as StaticLookup>::Source
+beneficiary: AccountIdLookupOf<T>
 ```
 </details>
 
@@ -1302,7 +1318,7 @@ proposal is awarded.
 
 ```rust
 amount: BalanceOf<T, I>
-beneficiary: <T::Lookup as StaticLookup>::Source
+beneficiary: AccountIdLookupOf<T>
 ```
 </details>
 
@@ -1455,7 +1471,7 @@ not been enacted yet.
 <details><summary><code>set_balance(who, new_free, new_reserved)</code></summary>
 
 ```rust
-who: <T::Lookup as StaticLookup>::Source
+who: AccountIdLookupOf<T>
 new_free: T::Balance
 new_reserved: T::Balance
 ```
@@ -1476,8 +1492,8 @@ The dispatch origin for this call is `root`.
 <details><summary><code>force_transfer(source, dest, value)</code></summary>
 
 ```rust
-source: <T::Lookup as StaticLookup>::Source
-dest: <T::Lookup as StaticLookup>::Source
+source: AccountIdLookupOf<T>
+dest: AccountIdLookupOf<T>
 value: T::Balance
 ```
 </details>
@@ -1491,7 +1507,7 @@ specified.
 <details><summary><code>force_unreserve(who, amount)</code></summary>
 
 ```rust
-who: <T::Lookup as StaticLookup>::Source
+who: AccountIdLookupOf<T>
 amount: T::Balance
 ```
 </details>
@@ -1513,7 +1529,7 @@ member_id: T::MemberId
 </details>
 
 
-
+remove an identity from the set of authorities
 
 ### Grandpa - 15
 
@@ -1607,7 +1623,7 @@ idty_name: Option<IdtyName>
 </details>
 
 
-
+remove an identity from storage
 
 #### prune_item_identities_names - 6
 
@@ -1619,7 +1635,7 @@ names: Vec<IdtyName>
 </details>
 
 
-
+remove identity names from storage
 
 ### Membership - 42
 
@@ -1634,7 +1650,7 @@ metadata: T::MetaData
 </details>
 
 
-
+request membership without checks
 
 ### Cert - 43
 
@@ -1650,7 +1666,7 @@ verify_rules: bool
 </details>
 
 
-
+add a certification without checks (only root)
 
 #### del_cert - 2
 
@@ -1663,7 +1679,7 @@ receiver: T::IdtyIndex
 </details>
 
 
-
+remove a certification (only root)
 
 #### remove_all_certs_received_by - 3
 
@@ -1675,7 +1691,7 @@ idty_index: T::IdtyIndex
 </details>
 
 
-
+remove all certifications received by an identity (only root)
 
 ### SmithsMembership - 52
 
@@ -1690,7 +1706,7 @@ metadata: T::MetaData
 </details>
 
 
-
+request membership without checks
 
 ### SmithsCert - 53
 
@@ -1706,7 +1722,7 @@ verify_rules: bool
 </details>
 
 
-
+add a certification without checks (only root)
 
 #### del_cert - 2
 
@@ -1719,7 +1735,7 @@ receiver: T::IdtyIndex
 </details>
 
 
-
+remove a certification (only root)
 
 #### remove_all_certs_received_by - 3
 
@@ -1731,7 +1747,7 @@ idty_index: T::IdtyIndex
 </details>
 
 
-
+remove all certifications received by an identity (only root)
 
 ### Utility - 64
 
@@ -1741,7 +1757,7 @@ idty_index: T::IdtyIndex
 
 ```rust
 as_origin: Box<T::PalletsOrigin>
-call: Box<<T as Config>::Call>
+call: Box<<T as Config>::RuntimeCall>
 ```
 </details>
 
@@ -1758,7 +1774,7 @@ The dispatch origin for this call must be _Root_.
 
 ## Disabled calls
 
-There are **7** disabled calls from **4** pallets.
+There are **7** disabled calls from **3** pallets.
 
 ### System - 0
 
@@ -1828,21 +1844,22 @@ usually means being a stash account).
 
 ### Membership - 42
 
-#### claim_membership - 2
+#### request_membership - 1
 
-<details><summary><code>claim_membership(maybe_idty_id)</code></summary>
+<details><summary><code>request_membership(metadata)</code></summary>
 
 ```rust
-maybe_idty_id: Option<T::IdtyId>
+metadata: T::MetaData
 ```
 </details>
 
 
+submit a membership request (must have a declared identity)
+(only available for sub wot, automatic for main wot)
 
+#### claim_membership - 2
 
-#### revoke_membership - 4
-
-<details><summary><code>revoke_membership(maybe_idty_id)</code></summary>
+<details><summary><code>claim_membership(maybe_idty_id)</code></summary>
 
 ```rust
 maybe_idty_id: Option<T::IdtyId>
@@ -1850,13 +1867,12 @@ maybe_idty_id: Option<T::IdtyId>
 </details>
 
 
+claim that the previously requested membership fullfills the requirements
+(only available for sub wot, automatic for main wot)
 
+#### revoke_membership - 4
 
-### SmithsMembership - 52
-
-#### claim_membership - 2
-
-<details><summary><code>claim_membership(maybe_idty_id)</code></summary>
+<details><summary><code>revoke_membership(maybe_idty_id)</code></summary>
 
 ```rust
 maybe_idty_id: Option<T::IdtyId>
@@ -1864,5 +1880,6 @@ maybe_idty_id: Option<T::IdtyId>
 </details>
 
 
-
+revoke an active membership
+(only available for sub wot, automatic for main wot)
 
diff --git a/end2end-tests/tests/common/balances.rs b/end2end-tests/tests/common/balances.rs
index 8149199de..47be32477 100644
--- a/end2end-tests/tests/common/balances.rs
+++ b/end2end-tests/tests/common/balances.rs
@@ -28,7 +28,7 @@ pub async fn set_balance(client: &Client, who: AccountKeyring, amount: u64) -> R
             .create_signed(
                 &gdev::tx()
                     .sudo()
-                    .sudo(gdev::runtime_types::gdev_runtime::Call::Balances(
+                    .sudo(gdev::runtime_types::gdev_runtime::RuntimeCall::Balances(
                         pallet_balances::pallet::Call::set_balance {
                             who: MultiAddress::Id(who.to_account_id()),
                             new_free: amount,
diff --git a/pallets/authority-members/README.md b/pallets/authority-members/README.md
index c99560fb5..133701b9c 100644
--- a/pallets/authority-members/README.md
+++ b/pallets/authority-members/README.md
@@ -1,6 +1,6 @@
 # Duniter authority members pallet
 
-In a permissioned network, we have to define the set of authorities, and among these authorities, the ones taking part in the next session. That's what authority members pallet does. In practice:
+In a permissioned network, we have to define the set of authorities, and among these authorities, the ones validators in the next session. That's what authority members pallet does. In practice:
 
 - it manages a `Members` set with some custom rules
 - it implements the `SessionManager` trait from the session frame pallet
@@ -18,4 +18,12 @@ Then one can "go online" and "go offline" to enter or leave two sessions after.
 
 ## Staying in the set of authorities
 
-If a smith is offline more than `MaxOfflineSessions`, he leaves the set of authorities.
\ No newline at end of file
+If a smith is offline more than `MaxOfflineSessions`, he leaves the set of authorities.
+
+## Some vocabulary
+
+*Smiths* are people allowed to forge blocks, but in details this is:
+
+- **smith** status required to become an authority
+- **authority** status required to become validator
+- **validator** status required to add blocks
\ No newline at end of file
diff --git a/pallets/authority-members/src/lib.rs b/pallets/authority-members/src/lib.rs
index 3767ba1dd..21b23b64d 100644
--- a/pallets/authority-members/src/lib.rs
+++ b/pallets/authority-members/src/lib.rs
@@ -128,37 +128,45 @@ pub mod pallet {
 
     // STORAGE //
 
+    /// maps member id to account id
     #[pallet::storage]
     #[pallet::getter(fn account_id_of)]
     pub type AccountIdOf<T: Config> =
         StorageMap<_, Twox64Concat, T::MemberId, T::AccountId, OptionQuery>;
 
+    /// count the number of authorities
     #[pallet::storage]
     #[pallet::getter(fn authorities_counter)]
     pub type AuthoritiesCounter<T: Config> = StorageValue<_, u32, ValueQuery>;
 
+    /// list incoming authorities
     #[pallet::storage]
     #[pallet::getter(fn incoming)]
     pub type IncomingAuthorities<T: Config> = StorageValue<_, Vec<T::MemberId>, ValueQuery>;
 
+    /// list online authorities
     #[pallet::storage]
     #[pallet::getter(fn online)]
     pub type OnlineAuthorities<T: Config> = StorageValue<_, Vec<T::MemberId>, ValueQuery>;
 
+    /// list outgoing authorities
     #[pallet::storage]
     #[pallet::getter(fn outgoing)]
     pub type OutgoingAuthorities<T: Config> = StorageValue<_, Vec<T::MemberId>, ValueQuery>;
 
+    /// maps member id to member data
     #[pallet::storage]
     #[pallet::getter(fn member)]
     pub type Members<T: Config> =
         StorageMap<_, Twox64Concat, T::MemberId, MemberData<T::AccountId>, OptionQuery>;
 
+    /// maps session index to the list of member id set to expire at this session
     #[pallet::storage]
     #[pallet::getter(fn members_expire_on)]
     pub type MembersExpireOn<T: Config> =
         StorageMap<_, Twox64Concat, SessionIndex, Vec<T::MemberId>, ValueQuery>;
 
+    /// maps session index to the list of member id forced to rotate keys before this session
     #[pallet::storage]
     #[pallet::getter(fn must_rotate_keys_before)]
     pub type MustRotateKeysBefore<T: Config> =
@@ -220,6 +228,7 @@ pub mod pallet {
     #[pallet::call]
     impl<T: Config> Pallet<T> {
         #[pallet::weight(1_000_000_000)]
+        /// ask to leave the set of validators two sessions after
         pub fn go_offline(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
             // Verification phase //
             let who = ensure_signed(origin)?;
@@ -246,6 +255,7 @@ pub mod pallet {
             Ok(().into())
         }
         #[pallet::weight(1_000_000_000)]
+        /// ask to join the set of validators two sessions after
         pub fn go_online(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
             // Verification phase //
             let who = ensure_signed(origin)?;
@@ -282,6 +292,7 @@ pub mod pallet {
         }
 
         #[pallet::weight(1_000_000_000)]
+        /// declare new session keys to replace current ones
         pub fn set_session_keys(
             origin: OriginFor<T>,
             keys: T::KeysWrapper,
@@ -314,6 +325,7 @@ pub mod pallet {
             Ok(().into())
         }
         #[pallet::weight(1_000_000_000)]
+        /// remove an identity from the set of authorities
         pub fn remove_member(
             origin: OriginFor<T>,
             member_id: T::MemberId,
@@ -330,8 +342,12 @@ pub mod pallet {
     // PUBLIC FUNCTIONS //
 
     impl<T: Config> Pallet<T> {
-        /// Should be transactional
+        // Should be transactional (if an error occurs, storage should not be modified at all)
+        //  Execute the annotated function in a new storage transaction.
+        //  The return type of the annotated function must be `Result`. All changes to storage performed
+        //  by the annotated function are discarded if it returns `Err`, or committed if `Ok`.
         #[frame_support::transactional]
+        /// change owner key of an authority member
         pub fn change_owner_key(
             member_id: T::MemberId,
             new_owner_key: T::AccountId,
@@ -370,6 +386,7 @@ pub mod pallet {
     // INTERNAL FUNCTIONS //
 
     impl<T: Config> Pallet<T> {
+        /// perform authority member removal
         fn do_remove_member(member_id: T::MemberId, owner_key: T::AccountId) -> Weight {
             if Self::is_online(member_id) {
                 // Trigger the member deletion for next session
@@ -398,6 +415,7 @@ pub mod pallet {
 
             Weight::zero()
         }
+        /// perform planned expiration of authority member for the given session
         pub(super) fn expire_memberships(current_session_index: SessionIndex) {
             for member_id in MembersExpireOn::<T>::take(current_session_index) {
                 if let Some(member_data) = Members::<T>::get(member_id) {
@@ -414,6 +432,7 @@ pub mod pallet {
                 }
             }
         }
+        /// perform incoming authorities insertion
         fn insert_in(member_id: T::MemberId) -> bool {
             let not_already_inserted = IncomingAuthorities::<T>::mutate(|members_ids| {
                 if let Err(index) = members_ids.binary_search(&member_id) {
@@ -429,6 +448,7 @@ pub mod pallet {
             }
             not_already_inserted
         }
+        /// perform outgoing authority insertion
         fn insert_out(member_id: T::MemberId) -> bool {
             let not_already_inserted = OutgoingAuthorities::<T>::mutate(|members_ids| {
                 if let Err(index) = members_ids.binary_search(&member_id) {
@@ -448,21 +468,25 @@ pub mod pallet {
             }
             not_already_inserted
         }
+        /// check if member is incoming
         fn is_incoming(member_id: T::MemberId) -> bool {
             IncomingAuthorities::<T>::get()
                 .binary_search(&member_id)
                 .is_ok()
         }
+        /// check if member is online
         fn is_online(member_id: T::MemberId) -> bool {
             OnlineAuthorities::<T>::get()
                 .binary_search(&member_id)
                 .is_ok()
         }
+        /// check if member is outgoing
         fn is_outgoing(member_id: T::MemberId) -> bool {
             OutgoingAuthorities::<T>::get()
                 .binary_search(&member_id)
                 .is_ok()
         }
+        /// perform removal from incoming authorities
         fn remove_in(member_id: T::MemberId) {
             AuthoritiesCounter::<T>::mutate(|counter| counter.saturating_sub(1));
             IncomingAuthorities::<T>::mutate(|members_ids| {
@@ -471,6 +495,7 @@ pub mod pallet {
                 }
             })
         }
+        /// perform removal from online authorities
         fn remove_online(member_id: T::MemberId) {
             AuthoritiesCounter::<T>::mutate(|counter| counter.saturating_add(1));
             OnlineAuthorities::<T>::mutate(|members_ids| {
@@ -479,6 +504,7 @@ pub mod pallet {
                 }
             });
         }
+        /// perform removal from outgoing authorities
         fn remove_out(member_id: T::MemberId) {
             OutgoingAuthorities::<T>::mutate(|members_ids| {
                 if let Ok(index) = members_ids.binary_search(&member_id) {
@@ -486,6 +512,7 @@ pub mod pallet {
                 }
             });
         }
+        /// check that accountid is member
         fn verify_ownership_and_membership(
             who: &T::AccountId,
         ) -> Result<T::MemberId, DispatchError> {
@@ -596,6 +623,7 @@ impl<T: Config> pallet_session::SessionManager<T::ValidatorId> for Pallet<T> {
     }
 }
 
+// see substrate FullIdentification
 fn add_full_identification<T: Config>(
     validator_id: T::ValidatorId,
 ) -> Option<(T::ValidatorId, T::FullIdentification)> {
@@ -604,6 +632,7 @@ fn add_full_identification<T: Config>(
         .map(|full_ident| (validator_id, full_ident))
 }
 
+// implement SessionManager with FullIdentification
 impl<T: Config> pallet_session::historical::SessionManager<T::ValidatorId, T::FullIdentification>
     for Pallet<T>
 {
diff --git a/pallets/authority-members/src/types.rs b/pallets/authority-members/src/types.rs
index 594cbc36c..f77996d6d 100644
--- a/pallets/authority-members/src/types.rs
+++ b/pallets/authority-members/src/types.rs
@@ -25,8 +25,11 @@ use sp_staking::SessionIndex;
 #[cfg_attr(feature = "std", derive(Debug, Deserialize, Serialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo)]
 pub struct MemberData<AccountId> {
+    /// session at which the membership expires
     pub expire_on_session: SessionIndex,
+    /// session before which the member must have rotated keys
     pub must_rotate_keys_before: SessionIndex,
+    /// pubkey of the member
     pub owner_key: AccountId,
 }
 
diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs
index 57a1d7e3c..7099ab19a 100644
--- a/pallets/certification/src/lib.rs
+++ b/pallets/certification/src/lib.rs
@@ -269,6 +269,7 @@ pub mod pallet {
 
     #[pallet::call]
     impl<T: Config<I>, I: 'static> Pallet<T, I> {
+        /// add a certification without checks (only root)
         #[pallet::weight(1_000_000_000)]
         pub fn force_add_cert(
             origin: OriginFor<T>,
@@ -355,6 +356,7 @@ pub mod pallet {
             Self::do_add_cert(block_number, issuer, receiver)
         }
 
+        /// remove a certification (only root)
         #[pallet::weight(1_000_000_000)]
         pub fn del_cert(
             origin: OriginFor<T>,
@@ -366,6 +368,7 @@ pub mod pallet {
             Ok(().into())
         }
 
+        /// remove all certifications received by an identity (only root)
         #[pallet::weight(1_000_000_000)]
         pub fn remove_all_certs_received_by(
             origin: OriginFor<T>,
@@ -382,6 +385,7 @@ pub mod pallet {
     // INTERNAL FUNCTIONS //
 
     impl<T: Config<I>, I: 'static> Pallet<T, I> {
+        /// perform cert add
         fn do_add_cert(
             block_number: T::BlockNumber,
             issuer: T::IdtyIndex,
@@ -438,6 +442,7 @@ pub mod pallet {
 
             Ok(().into())
         }
+        /// remove the certifications due to expire on the given block
         fn prune_certifications(block_number: T::BlockNumber) -> Weight {
             let mut total_weight = Weight::zero();
 
@@ -449,6 +454,7 @@ pub mod pallet {
 
             total_weight
         }
+        /// perform the certification removal
         fn remove_cert_inner(
             issuer: T::IdtyIndex,
             receiver: T::IdtyIndex,
@@ -505,6 +511,7 @@ pub mod pallet {
     }
 }
 
+// implement setting next_issuable_on for certification period
 impl<T: Config<I>, I: 'static> SetNextIssuableOn<T::BlockNumber, T::IdtyIndex> for Pallet<T, I> {
     fn set_next_issuable_on(idty_index: T::IdtyIndex, next_issuable_on: T::BlockNumber) -> Weight {
         <StorageIdtyCertMeta<T, I>>::mutate_exists(idty_index, |cert_meta_opt| {
diff --git a/pallets/certification/src/types.rs b/pallets/certification/src/types.rs
index 4ab2c51cd..7eadcabc5 100644
--- a/pallets/certification/src/types.rs
+++ b/pallets/certification/src/types.rs
@@ -20,10 +20,14 @@ use codec::{Decode, Encode};
 use frame_support::pallet_prelude::*;
 use scale_info::TypeInfo;
 
+/// certification metadata attached to an identity
 #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub struct IdtyCertMeta<BlockNumber: Default> {
+    /// count issued certifications
     pub issued_count: u32,
+    /// block before which identity not allowed to issue a new certification
     pub next_issuable_on: BlockNumber,
+    /// number of certifications received
     pub received_count: u32,
 }
 
diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs
index 9c717b731..e285dde5d 100644
--- a/pallets/duniter-wot/src/lib.rs
+++ b/pallets/duniter-wot/src/lib.rs
@@ -162,6 +162,7 @@ where
             // TODO replace this code by the commented one for distance feature
             /*let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index);
             idty_cert_meta.received_count >= T::MinCertForMembership::get() as u32*/
+            // in the main wot, automatically claim membership when the identity is validated
             pallet_membership::Pallet::<T, I>::claim_membership(
                 RawOrigin::Root.into(),
                 Some(idty_index),
diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs
index fc2dfe4e5..ab95a439d 100644
--- a/pallets/identity/src/lib.rs
+++ b/pallets/identity/src/lib.rs
@@ -169,6 +169,7 @@ pub mod pallet {
 
     // STORAGE //
 
+    /// maps identity index to identity value
     #[pallet::storage]
     #[pallet::getter(fn identity)]
     pub type Identities<T: Config> = CountedStorageMap<
@@ -179,19 +180,22 @@ pub mod pallet {
         OptionQuery,
     >;
 
+    /// maps account id to identity index
     #[pallet::storage]
     #[pallet::getter(fn identity_index_of)]
     pub type IdentityIndexOf<T: Config> =
         StorageMap<_, Blake2_128, T::AccountId, T::IdtyIndex, OptionQuery>;
 
+    /// maps identity name to null type (simply a set)
     #[pallet::storage]
     #[pallet::getter(fn identity_by_did)]
     pub type IdentitiesNames<T: Config> = StorageMap<_, Blake2_128, IdtyName, (), OptionQuery>;
 
+    /// counter of the identity index to give to the next identity
     #[pallet::storage]
     pub(super) type NextIdtyIndex<T: Config> = StorageValue<_, T::IdtyIndex, ValueQuery>;
 
-    /// Identities by removed block
+    /// maps block number to the list of identities set to be removed at this bloc
     #[pallet::storage]
     #[pallet::getter(fn removable_on)]
     pub type IdentitiesRemovableOn<T: Config> =
@@ -312,6 +316,7 @@ pub mod pallet {
             T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Created { creator });
             Ok(().into())
         }
+
         /// Confirm the creation of an identity and give it a name
         ///
         /// - `idty_name`: the name uniquely associated to this identity. Must match the validation rules defined by the runtime.
@@ -355,7 +360,9 @@ pub mod pallet {
             T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Confirmed);
             Ok(().into())
         }
+
         #[pallet::weight(1_000_000_000)]
+        /// validate the owned identity (must meet the main wot requirements)
         pub fn validate_identity(
             origin: OriginFor<T>,
             idty_index: T::IdtyIndex,
@@ -517,6 +524,7 @@ pub mod pallet {
         }
 
         #[pallet::weight(1_000_000_000)]
+        /// remove an identity from storage
         pub fn remove_identity(
             origin: OriginFor<T>,
             idty_index: T::IdtyIndex,
@@ -533,6 +541,7 @@ pub mod pallet {
         }
 
         #[pallet::weight(1_000_000_000)]
+        /// remove identity names from storage
         pub fn prune_item_identities_names(
             origin: OriginFor<T>,
             names: Vec<IdtyName>,
@@ -547,6 +556,7 @@ pub mod pallet {
         }
 
         #[pallet::weight(1_000_000_000)]
+        /// change sufficient ref count for given key
         pub fn fix_sufficients(
             origin: OriginFor<T>,
             owner_key: T::AccountId,
@@ -625,6 +635,7 @@ pub mod pallet {
     // INTERNAL FUNCTIONS //
 
     impl<T: Config> Pallet<T> {
+        /// perform identity removal
         pub(super) fn do_remove_identity(idty_index: T::IdtyIndex) -> Weight {
             if let Some(idty_val) = Identities::<T>::get(idty_index) {
                 let _ = T::RemoveIdentityConsumers::remove_idty_consumers(idty_index);
@@ -645,6 +656,7 @@ pub mod pallet {
             }
             Weight::zero()
         }
+        /// incremental counter for identity index
         fn get_next_idty_index() -> T::IdtyIndex {
             if let Ok(next_index) = <NextIdtyIndex<T>>::try_get() {
                 <NextIdtyIndex<T>>::put(next_index.saturating_add(T::IdtyIndex::one()));
@@ -654,6 +666,7 @@ pub mod pallet {
                 T::IdtyIndex::one()
             }
         }
+        /// remove identities planned for removal at the given block if their status did not change
         fn prune_identities(block_number: T::BlockNumber) -> Weight {
             let mut total_weight = Weight::zero();
 
@@ -670,16 +683,21 @@ pub mod pallet {
     }
 }
 
+// implement getting owner key of identity index
+
 impl<T: Config> sp_runtime::traits::Convert<T::IdtyIndex, Option<T::AccountId>> for Pallet<T> {
     fn convert(idty_index: T::IdtyIndex) -> Option<T::AccountId> {
         Identities::<T>::get(idty_index).map(|idty_val| idty_val.owner_key)
     }
 }
 
+// implement StoredMap trait for this pallet
+
 impl<T> frame_support::traits::StoredMap<T::AccountId, T::IdtyData> for Pallet<T>
 where
     T: Config,
 {
+    /// get identity data for an account id
     fn get(key: &T::AccountId) -> T::IdtyData {
         if let Some(idty_index) = Self::identity_index_of(key) {
             if let Some(idty_val) = Identities::<T>::get(idty_index) {
@@ -691,6 +709,7 @@ where
             Default::default()
         }
     }
+    /// mutate an account fiven a function of its data
     fn try_mutate_exists<R, E: From<sp_runtime::DispatchError>>(
         key: &T::AccountId,
         f: impl FnOnce(&mut Option<T::IdtyData>) -> Result<R, E>,
diff --git a/pallets/identity/src/types.rs b/pallets/identity/src/types.rs
index ba1cdf8d0..58efc4d0f 100644
--- a/pallets/identity/src/types.rs
+++ b/pallets/identity/src/types.rs
@@ -23,17 +23,25 @@ use scale_info::TypeInfo;
 use serde::{Deserialize, Serialize};
 use sp_std::vec::Vec;
 
+/// events related to identity
 pub enum IdtyEvent<T: crate::Config> {
+    /// creation of a new identity by an other
     Created { creator: T::IdtyIndex },
+    /// confirmation of an identity (with a given name)
     Confirmed,
+    /// validation of an identity
     Validated,
+    /// changing the owner key of the identity
     ChangedOwnerKey { new_owner_key: T::AccountId },
+    /// removing an identity
     Removed { status: IdtyStatus },
 }
 
+/// name of the identity, ascii encoded
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)]
 pub struct IdtyName(pub Vec<u8>);
 
+/// implement scale string typeinfo for encoding
 impl scale_info::TypeInfo for IdtyName {
     type Identity = str;
 
@@ -65,6 +73,8 @@ impl<'de> serde::Deserialize<'de> for IdtyName {
     }
 }
 
+/// status of the identity
+/// used for temporary period before validation
 #[cfg_attr(feature = "std", derive(Deserialize, Serialize))]
 #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub enum IdtyStatus {
@@ -78,28 +88,44 @@ impl Default for IdtyStatus {
     }
 }
 
+/// identity value (as in key/value)
 #[cfg_attr(feature = "std", derive(Debug, Deserialize, Serialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo)]
 pub struct IdtyValue<BlockNumber, AccountId, IdtyData> {
+    /// data shared between pallets defined by runtime
+    /// only contains first_eligible_ud in our case
     pub data: IdtyData,
+    /// block before which creating a new identity is not allowed
     pub next_creatable_identity_on: BlockNumber,
+    /// previous owner key of this identity (optional)
     pub old_owner_key: Option<(AccountId, BlockNumber)>,
+    /// current owner key of this identity
     pub owner_key: AccountId,
+    /// block before which this identity can not be removed
+    /// used only for temporary period before validation
+    /// equals 0 for a validated identity
     pub removable_on: BlockNumber,
+    /// current status of the identity (until validation)
     pub status: IdtyStatus,
 }
 
+/// payload to define a new owner key
 #[derive(Clone, Copy, Encode, RuntimeDebug)]
 pub struct NewOwnerKeyPayload<'a, AccountId, IdtyIndex, Hash> {
+    /// hash of the genesis block
     // Avoid replay attack between networks
     pub genesis_hash: &'a Hash,
+    /// identity index
     pub idty_index: IdtyIndex,
+    /// old owner key of the identity
     pub old_owner_key: &'a AccountId,
 }
 
 #[derive(Clone, Copy, Encode, Decode, PartialEq, Eq, TypeInfo, RuntimeDebug)]
 pub struct RevocationPayload<IdtyIndex, Hash> {
+    /// hash of the genesis block
     // Avoid replay attack between networks
     pub genesis_hash: Hash,
+    /// identity index
     pub idty_index: IdtyIndex,
 }
diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs
index 154acb372..475287c40 100644
--- a/pallets/membership/src/lib.rs
+++ b/pallets/membership/src/lib.rs
@@ -108,21 +108,26 @@ pub mod pallet {
 
     // STORAGE //
 
+    /// maps identity id to membership data
+    // (expiration block for instance)
     #[pallet::storage]
     #[pallet::getter(fn membership)]
     pub type Membership<T: Config<I>, I: 'static = ()> =
         CountedStorageMap<_, Twox64Concat, T::IdtyId, MembershipData<T::BlockNumber>, OptionQuery>;
 
+    /// maps block number to the list of identity id set to expire at this block
     #[pallet::storage]
     #[pallet::getter(fn memberships_expire_on)]
     pub type MembershipsExpireOn<T: Config<I>, I: 'static = ()> =
         StorageMap<_, Twox64Concat, T::BlockNumber, Vec<T::IdtyId>, ValueQuery>;
 
+    /// maps identity id to pending membership metadata
     #[pallet::storage]
     #[pallet::getter(fn pending_membership)]
     pub type PendingMembership<T: Config<I>, I: 'static = ()> =
         StorageMap<_, Twox64Concat, T::IdtyId, T::MetaData, OptionQuery>;
 
+    /// maps block number to the list of memberships set to expire at this block
     #[pallet::storage]
     #[pallet::getter(fn pending_memberships_expire_on)]
     pub type PendingMembershipsExpireOn<T: Config<I>, I: 'static = ()> =
@@ -133,19 +138,19 @@ pub mod pallet {
     #[pallet::event]
     #[pallet::generate_deposit(pub(super) fn deposit_event)]
     pub enum Event<T: Config<I>, I: 'static = ()> {
-        /// A membership has acquired
+        /// A membership was acquired
         /// [idty_id]
         MembershipAcquired(T::IdtyId),
-        /// A membership has expired
+        /// A membership expired
         /// [idty_id]
         MembershipExpired(T::IdtyId),
-        /// A membership has renewed
+        /// A membership was renewed
         /// [idty_id]
         MembershipRenewed(T::IdtyId),
-        /// An identity requested membership
+        /// An membership was requested
         /// [idty_id]
         MembershipRequested(T::IdtyId),
-        /// A membership has revoked
+        /// A membership was revoked
         /// [idty_id]
         MembershipRevoked(T::IdtyId),
         /// A pending membership request has expired
@@ -191,6 +196,7 @@ pub mod pallet {
     #[pallet::call]
     impl<T: Config<I>, I: 'static> Pallet<T, I> {
         #[pallet::weight(1_000_000_000)]
+        /// request membership without checks
         pub fn force_request_membership(
             origin: OriginFor<T>,
             idty_id: T::IdtyId,
@@ -202,6 +208,8 @@ pub mod pallet {
         }
 
         #[pallet::weight(1_000_000_000)]
+        /// submit a membership request (must have a declared identity)
+        /// (only available for sub wot, automatic for main wot)
         pub fn request_membership(
             origin: OriginFor<T>,
             metadata: T::MetaData,
@@ -218,6 +226,8 @@ pub mod pallet {
         }
 
         #[pallet::weight(1_000_000_000)]
+        /// claim that the previously requested membership fullfills the requirements
+        /// (only available for sub wot, automatic for main wot)
         pub fn claim_membership(
             origin: OriginFor<T>,
             maybe_idty_id: Option<T::IdtyId>,
@@ -244,6 +254,7 @@ pub mod pallet {
         }
 
         #[pallet::weight(1_000_000_000)]
+        /// extend the validity period of an active membership
         pub fn renew_membership(
             origin: OriginFor<T>,
             maybe_idty_id: Option<T::IdtyId>,
@@ -264,6 +275,8 @@ pub mod pallet {
         }
 
         #[pallet::weight(1_000_000_000)]
+        /// revoke an active membership
+        /// (only available for sub wot, automatic for main wot)
         pub fn revoke_membership(
             origin: OriginFor<T>,
             maybe_idty_id: Option<T::IdtyId>,
@@ -284,12 +297,14 @@ pub mod pallet {
     // INTERNAL FUNCTIONS //
 
     impl<T: Config<I>, I: 'static> Pallet<T, I> {
+        /// perform the membership renewal and emit events
         pub(super) fn do_renew_membership(idty_id: T::IdtyId) -> Weight {
             let total_weight = Self::do_renew_membership_inner(idty_id);
             Self::deposit_event(Event::MembershipRenewed(idty_id));
             T::OnEvent::on_event(&sp_membership::Event::MembershipRenewed(idty_id));
             total_weight
         }
+        /// perform the membership renewal
         fn do_renew_membership_inner(idty_id: T::IdtyId) -> Weight {
             let block_number = frame_system::pallet::Pallet::<T>::block_number();
             let expire_on = block_number + T::MembershipPeriod::get();
@@ -298,6 +313,7 @@ pub mod pallet {
             MembershipsExpireOn::<T, I>::append(expire_on, idty_id);
             Weight::zero()
         }
+        /// perform the membership request
         fn do_request_membership(
             idty_id: T::IdtyId,
             metadata: T::MetaData,
@@ -319,6 +335,7 @@ pub mod pallet {
 
             Ok(().into())
         }
+        /// check the origin and get identity id if valid
         fn ensure_origin_and_get_idty_id(
             origin: OriginFor<T>,
             maybe_idty_id: Option<T::IdtyId>,
@@ -332,6 +349,7 @@ pub mod pallet {
                 _ => Err(BadOrigin.into()),
             }
         }
+        /// perform the membership expiration if it has not been renewed meanwhile
         fn expire_memberships(block_number: T::BlockNumber) -> Weight {
             let mut total_weight: Weight = Weight::zero();
 
@@ -348,6 +366,7 @@ pub mod pallet {
 
             total_weight
         }
+        /// perform the expiration of pending membership planned at given block
         fn expire_pending_memberships(block_number: T::BlockNumber) -> Weight {
             let mut total_weight: Weight = Weight::zero();
 
@@ -363,21 +382,27 @@ pub mod pallet {
             total_weight
         }
 
+        /// check if identity is member
         pub(super) fn is_member_inner(idty_id: &T::IdtyId) -> bool {
             Membership::<T, I>::contains_key(idty_id)
         }
+        /// insert membership in storage
         fn insert_membership(idty_id: T::IdtyId, membership_data: MembershipData<T::BlockNumber>) {
             Membership::<T, I>::insert(idty_id, membership_data);
         }
+        /// retreive membership from storage
         fn get_membership(idty_id: &T::IdtyId) -> Option<MembershipData<T::BlockNumber>> {
             Membership::<T, I>::try_get(idty_id).ok()
         }
+        /// remove membership from storage
         fn remove_membership(idty_id: &T::IdtyId) -> bool {
             Membership::<T, I>::take(idty_id).is_some()
         }
     }
 }
 
+// implement traits
+
 impl<T: Config<I>, I: 'static> IsInPendingMemberships<T::IdtyId> for Pallet<T, I> {
     fn is_in_pending_memberships(idty_id: T::IdtyId) -> bool {
         PendingMembership::<T, I>::contains_key(idty_id)
diff --git a/pallets/universal-dividend/src/lib.rs b/pallets/universal-dividend/src/lib.rs
index 41992650d..73d5af1eb 100644
--- a/pallets/universal-dividend/src/lib.rs
+++ b/pallets/universal-dividend/src/lib.rs
@@ -254,7 +254,9 @@ pub mod pallet {
 
     // INTERNAL FUNCTIONS //
     impl<T: Config> Pallet<T> {
+        /// create universal dividend
         fn create_ud(members_count: BalanceOf<T>) {
+            // get current value of UD and monetary mass
             let ud_amount = <CurrentUd<T>>::get();
             let monetary_mass = <MonetaryMass<T>>::get();
 
@@ -263,9 +265,14 @@ pub mod pallet {
                 core::mem::replace(next_ud_index, next_ud_index.saturating_add(1))
             });
 
+            // compute the new monetary mass
             let new_monetary_mass =
                 monetary_mass.saturating_add(ud_amount.saturating_mul(members_count));
+
+            // update the storage value of the monetary mass
             MonetaryMass::<T>::put(new_monetary_mass);
+
+            // emit an event to inform blockchain users that the holy UNIVERSAL DIVIDEND was created
             Self::deposit_event(Event::NewUdCreated {
                 amount: ud_amount,
                 index: ud_index,
@@ -273,6 +280,8 @@ pub mod pallet {
                 monetary_mass: new_monetary_mass,
             });
         }
+
+        /// claim all due universal dividend at a time
         fn do_claim_uds(who: &T::AccountId) -> DispatchResultWithPostInfo {
             T::MembersStorage::try_mutate_exists(who, |maybe_first_eligible_ud| {
                 if let Some(FirstEligibleUd(Some(ref mut first_ud_index))) = maybe_first_eligible_ud
@@ -304,6 +313,8 @@ pub mod pallet {
                 }
             })
         }
+
+        /// like balance.transfer, but give an amount in UD
         fn do_transfer_ud(
             origin: OriginFor<T>,
             dest: <T::Lookup as StaticLookup>::Source,
@@ -321,11 +332,14 @@ pub mod pallet {
             )?;
             Ok(().into())
         }
+
+        /// reevaluate the value of the universal dividend
         fn reeval_ud(members_count: BalanceOf<T>) {
+            // get current value and monetary mass
             let ud_amount = <CurrentUd<T>>::get();
-
             let monetary_mass = <MonetaryMass<T>>::get();
 
+            // compute new value
             let new_ud_amount = Self::reeval_ud_formula(
                 ud_amount,
                 T::SquareMoneyGrowthRate::get(),
@@ -336,6 +350,7 @@ pub mod pallet {
                 ),
             );
 
+            // update the storage value and the history of past reevals
             CurrentUd::<T>::put(new_ud_amount);
             PastReevals::<T>::mutate(|past_reevals| {
                 if past_reevals.len() == T::MaxPastReeval::get() as usize {
@@ -352,6 +367,8 @@ pub mod pallet {
                 members_count,
             });
         }
+
+        /// formula for Universal Dividend reevaluation
         fn reeval_ud_formula(
             ud_t: BalanceOf<T>,
             c_square: Perbill,
@@ -406,6 +423,8 @@ pub mod pallet {
         pub fn init_first_eligible_ud() -> FirstEligibleUd {
             CurrentUdIndex::<T>::get().into()
         }
+        /// function to call when removing a member
+        /// auto-claims UDs
         pub fn on_removed_member(first_ud_index: UdIndex, who: &T::AccountId) -> Weight {
             let current_ud_index = CurrentUdIndex::<T>::get();
             if first_ud_index < current_ud_index {
diff --git a/resources/metadata.scale b/resources/metadata.scale
index ff4c1c40a4d58bf8b3d8dc74373830583ef1ddbb..06d4f6891828dfade5738b4d106249ba753edd96 100644
GIT binary patch
delta 17461
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

delta 14231
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
ZknhZp-+Xpjag^_rz*DU97~gq_|94fu*46+3

diff --git a/xtask/src/gen_calls_doc.rs b/xtask/src/gen_calls_doc.rs
index d60bd2b6a..3307e8c20 100644
--- a/xtask/src/gen_calls_doc.rs
+++ b/xtask/src/gen_calls_doc.rs
@@ -129,10 +129,11 @@ impl CallCategory {
                 "remove_identity" | "prune_item_identities_names" | "prune_item_identity_index_of",
             ) => Self::Root,
             ("Membership", "force_request_membership") => Self::Root,
-            ("Membership", "claim_membership" | "revoke_membership") => Self::Disabled,
+            ("Membership", "request_membership" | "claim_membership" | "revoke_membership") => {
+                Self::Disabled
+            }
             ("Cert", "force_add_cert" | "del_cert" | "remove_all_certs_received_by") => Self::Root,
             ("SmithsMembership", "force_request_membership") => Self::Root,
-            ("SmithsMembership", "claim_membership") => Self::Disabled,
             ("SmithsCert", "force_add_cert" | "del_cert" | "remove_all_certs_received_by") => {
                 Self::Root
             }
-- 
GitLab