From 6b59808405d169642921d0ced479cf7643fbdb9d Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux <hugo.trentesaux@lilo.org> Date: Fri, 15 Dec 2023 15:06:14 +0100 Subject: [PATCH] refac membership (nodes/rust/duniter-v2s!215) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * delete notes.txt file * update notes with links to issues * update comment according to #159 * doc idtystatus in readme * update weightinfo and benchmarks accordingly * add benchmark * remove remove_identity_consumers * remove force_remove_identity call * fix todo in test * update doc - remove request_membership - remove validate_identity * fix tests according to new MembershipRemovalReason * add membership removal reasons and clean up membership internal functions * remove check_remove_identity * build live tests (but no current network to check them against) * clippy 🤦â€â™‚ * add wot tests related to issue #136 * refac certification creation checks * refac identity creation checks * test benchmark ok * more precise error messages * check benchmarks ok * cargo cucumber ok * cargo test workspace ok * cargo test workspace quasi ok * cargo check all tests * cargo check all * remove IdtyEvent change owner key * remove removal other reason * refac revocation and removal reason * wip * refac * refac scheduling (tests ok) * add *Period * cargo test identity ok * remove IdtyEvent::Validated * cargo test wot ok * cargo test wot ok (one fails but fot the good reason) * cargo test membership ok * cargo check wot tests * cargo check identity tests * cargo check membership tests * also remove validate trait * remove validate_identity * refac identity status to allow more fine-grain control * remove unused trait * cargo check ok * remove indentity confirmation constraints * remove request from membership primitives * remove request_membership from lib.rs --- Cargo.lock | 1 + docs/api/runtime-calls.md | 82 +--- docs/api/runtime-errors.md | 180 ++++++--- docs/api/runtime-events.md | 101 ++--- docs/dev/pallet_conventions.md | 2 +- .../identity_creation.feature | 8 +- end2end-tests/tests/common/identity.rs | 21 - end2end-tests/tests/common/membership.rs | 40 ++ end2end-tests/tests/common/mod.rs | 1 + end2end-tests/tests/cucumber_tests.rs | 18 +- live-tests/tests/sanity_gdev.rs | 25 +- node/src/chain_spec/gdev.rs | 4 +- node/src/chain_spec/gtest.rs | 4 +- pallets/certification/src/lib.rs | 80 ++-- pallets/distance/src/mock.rs | 14 +- pallets/duniter-account/src/lib.rs | 5 +- pallets/duniter-wot/src/lib.rs | 220 ++++------- pallets/duniter-wot/src/mock.rs | 19 +- pallets/duniter-wot/src/tests.rs | 291 ++++++++------ pallets/duniter-wot/src/types.rs | 25 -- pallets/identity/README.md | 14 +- pallets/identity/src/benchmarking.rs | 125 +++--- pallets/identity/src/lib.rs | 373 +++++++++++------- pallets/identity/src/mock.rs | 10 +- pallets/identity/src/tests.rs | 81 ++-- pallets/identity/src/traits.rs | 30 +- pallets/identity/src/types.rs | 67 ++-- pallets/identity/src/weights.rs | 257 ++++++------ pallets/membership/README.md | 16 +- pallets/membership/src/benchmarking.rs | 42 +- pallets/membership/src/lib.rs | 172 +------- pallets/membership/src/mock.rs | 1 - pallets/membership/src/tests.rs | 83 +--- pallets/membership/src/weights.rs | 96 ++--- pallets/quota/src/lib.rs | 1 - pallets/quota/src/mock.rs | 10 +- .../universal-dividend/src/benchmarking.rs | 2 +- pallets/universal-dividend/src/lib.rs | 4 +- primitives/membership/Cargo.toml | 3 + primitives/membership/src/lib.rs | 17 +- primitives/membership/src/traits.rs | 24 +- resources/metadata.scale | Bin 132945 -> 132039 bytes runtime/common/src/handlers.rs | 67 +--- runtime/common/src/pallets_config.rs | 16 +- runtime/common/src/providers.rs | 9 +- runtime/common/src/weights/pallet_identity.rs | 344 ++++++++-------- .../weights/pallet_membership_membership.rs | 185 +++------ .../pallet_membership_smith_membership.rs | 158 ++++---- runtime/gdev/src/lib.rs | 12 +- runtime/gdev/src/migrations_v400.rs | 45 --- runtime/gdev/tests/common/mod.rs | 4 +- runtime/gdev/tests/fixme_tests.rs | 52 ++- runtime/gdev/tests/integration_tests.rs | 199 +++++----- runtime/gtest/src/lib.rs | 11 +- runtime/gtest/src/parameters.rs | 4 +- xtask/src/gen_doc.rs | 1 - 56 files changed, 1616 insertions(+), 2060 deletions(-) create mode 100644 end2end-tests/tests/common/membership.rs delete mode 100644 pallets/duniter-wot/src/types.rs delete mode 100644 runtime/gdev/src/migrations_v400.rs diff --git a/Cargo.lock b/Cargo.lock index 728e25021..2e3ce8e0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9790,6 +9790,7 @@ name = "sp-membership" version = "3.0.0" dependencies = [ "frame-support", + "impl-trait-for-tuples", "parity-scale-codec", "scale-info", "serde", diff --git a/docs/api/runtime-calls.md b/docs/api/runtime-calls.md index f6b99dfcd..e15a49ff9 100644 --- a/docs/api/runtime-calls.md +++ b/docs/api/runtime-calls.md @@ -13,7 +13,7 @@ through on-chain governance mechanisms. ## User calls -There are **80** user calls from **23** pallets. +There are **78** user calls from **23** pallets. ### Account - 1 @@ -642,18 +642,6 @@ Confirm the creation of an identity and give it a name The identity must have been created using `create_identity` before it can be confirmed. -#### validate_identity - 2 - -<details><summary><code>validate_identity(idty_index)</code></summary> - -```rust -idty_index: T::IdtyIndex -``` -</details> - - -validate the owned identity (must meet the main wot requirements) - #### change_owner_key - 3 <details><summary><code>change_owner_key(new_key, new_key_sig)</code></summary> @@ -694,20 +682,6 @@ Revoke an identity using a revocation signature Any signed origin can execute this call. -#### force_remove_identity - 5 - -<details><summary><code>force_remove_identity(idty_index, idty_name, reason)</code></summary> - -```rust -idty_index: T::IdtyIndex -idty_name: Option<IdtyName> -reason: IdtyRemovalReason<T::IdtyRemovalOtherReason> -``` -</details> - - -remove an identity from storage - #### fix_sufficients - 7 <details><summary><code>fix_sufficients(owner_key, inc)</code></summary> @@ -746,7 +720,6 @@ Link an account to an identity claim membership -a pending membership should exist it must fullfill the requirements (certs, distance) for main wot claim_membership is called automatically when validating identity for smith wot, it means joining the authority members @@ -762,6 +735,18 @@ for smith wot, it means joining the authority members extend the validity period of an active membership +#### revoke_membership - 3 + +<details><summary><code>revoke_membership()</code></summary> + +```rust +``` +</details> + + +revoke an active membership +(only available for sub wot, automatic for main wot) + ### Cert - 43 #### add_cert - 0 @@ -840,18 +825,6 @@ Removes the status if `status` is `None`. ### SmithMembership - 52 -#### request_membership - 0 - -<details><summary><code>request_membership()</code></summary> - -```rust -``` -</details> - - -submit a membership request (must have a declared identity) -(only available for sub wot, automatic for main wot) - #### claim_membership - 1 <details><summary><code>claim_membership()</code></summary> @@ -862,7 +835,6 @@ submit a membership request (must have a declared identity) claim membership -a pending membership should exist it must fullfill the requirements (certs, distance) for main wot claim_membership is called automatically when validating identity for smith wot, it means joining the authority members @@ -1909,7 +1881,7 @@ The dispatch origin for this call must be _Root_. ## Disabled calls -There are **6** disabled calls from **3** pallets. +There are **4** disabled calls from **2** pallets. ### System - 0 @@ -1985,29 +1957,3 @@ usually means being a stash account). - `O(1)` in number of key types. Actual cost depends on the number of length of `T::Keys::key_ids()` which is fixed. -### Membership - 42 - -#### request_membership - 0 - -<details><summary><code>request_membership()</code></summary> - -```rust -``` -</details> - - -submit a membership request (must have a declared identity) -(only available for sub wot, automatic for main wot) - -#### revoke_membership - 3 - -<details><summary><code>revoke_membership()</code></summary> - -```rust -``` -</details> - - -revoke an active membership -(only available for sub wot, automatic for main wot) - diff --git a/docs/api/runtime-errors.md b/docs/api/runtime-errors.md index 1bb46f090..5feb1cf03 100644 --- a/docs/api/runtime-errors.md +++ b/docs/api/runtime-errors.md @@ -1,6 +1,6 @@ # Runtime errors -There are **178** errors from **37** pallets. +There are **186** errors from **37** pallets. <ul> <li>System - 0 @@ -638,77 +638,105 @@ Insufficient certifications received to claim membership. <li> <details> <summary> -<code>DistanceNotOk</code> - 1</summary> -Distance has not received a positive evaluation. +<code>DistanceIsInvalid</code> - 1</summary> +Distance is invalid. </details> </li> <li> <details> <summary> -<code>IdtyNotAllowedToRequestMembership</code> - 2</summary> +<code>DistanceNotEvaluated</code> - 2</summary> +Distance is not evaluated. +</details> +</li> +<li> +<details> +<summary> +<code>DistanceEvaluationPending</code> - 3</summary> +Distance evaluation has been requested but is still pending +</details> +</li> +<li> +<details> +<summary> +<code>DistanceEvaluationNotRequested</code> - 4</summary> +Distance evaluation has not been requested +</details> +</li> +<li> +<details> +<summary> +<code>IdtyNotAllowedToRequestMembership</code> - 5</summary> Identity is not allowed to request membership. </details> </li> <li> <details> <summary> -<code>IdtyNotAllowedToRenewMembership</code> - 3</summary> +<code>IdtyNotAllowedToRenewMembership</code> - 6</summary> Identity not allowed to renew membership. </details> </li> <li> <details> <summary> -<code>IdtyCreationPeriodNotRespected</code> - 4</summary> +<code>IdtyCreationPeriodNotRespected</code> - 7</summary> Identity creation period not respected. </details> </li> <li> <details> <summary> -<code>NotEnoughReceivedCertsToCreateIdty</code> - 5</summary> +<code>NotEnoughReceivedCertsToCreateIdty</code> - 8</summary> Insufficient received certifications to create identity. </details> </li> <li> <details> <summary> -<code>MaxEmittedCertsReached</code> - 6</summary> +<code>MaxEmittedCertsReached</code> - 9</summary> Maximum number of emitted certifications reached. </details> </li> <li> <details> <summary> -<code>NotAllowedToChangeIdtyAddress</code> - 7</summary> +<code>NotAllowedToChangeIdtyAddress</code> - 10</summary> Not allowed to change identity address. </details> </li> <li> <details> <summary> -<code>NotAllowedToRemoveIdty</code> - 8</summary> +<code>NotAllowedToRemoveIdty</code> - 11</summary> Not allowed to remove identity. </details> </li> <li> <details> <summary> -<code>IssuerCanNotEmitCert</code> - 9</summary> -Issuer cannot emit a certification because it is not validated. +<code>IssuerNotMember</code> - 12</summary> +Issuer cannot emit a certification because it is not member. +</details> +</li> +<li> +<details> +<summary> +<code>CertToUnconfirmed</code> - 13</summary> +Cannot issue a certification to an unconfirmed identity </details> </li> <li> <details> <summary> -<code>CertToUndefined</code> - 10</summary> -Cannot issue a certification to an identity without membership or pending membership. +<code>CertToRevoked</code> - 14</summary> +Cannot issue a certification to a revoked identity </details> </li> <li> <details> <summary> -<code>IdtyNotFound</code> - 11</summary> +<code>IdtyNotFound</code> - 15</summary> Issuer or receiver not found. </details> </li> @@ -761,7 +789,7 @@ Invalid identity name. <li> <details> <summary> -<code>IdtyNotConfirmedByOwner</code> - 6</summary> +<code>IdtyNotConfirmed</code> - 6</summary> Identity not confirmed by its owner. </details> </li> @@ -789,68 +817,82 @@ Invalid revocation key. <li> <details> <summary> -<code>NotRespectIdtyCreationPeriod</code> - 10</summary> +<code>IssuerNotMember</code> - 10</summary> +Issuer is not member and can not perform this action +</details> +</li> +<li> +<details> +<summary> +<code>NotRespectIdtyCreationPeriod</code> - 11</summary> Identity creation period is not respected. </details> </li> <li> <details> <summary> -<code>OwnerKeyAlreadyRecentlyChanged</code> - 11</summary> +<code>OwnerKeyAlreadyRecentlyChanged</code> - 12</summary> Owner key already changed recently. </details> </li> <li> <details> <summary> -<code>OwnerKeyAlreadyUsed</code> - 12</summary> +<code>OwnerKeyAlreadyUsed</code> - 13</summary> Owner key already used. </details> </li> <li> <details> <summary> -<code>ProhibitedToRevertToAnOldKey</code> - 13</summary> +<code>ProhibitedToRevertToAnOldKey</code> - 14</summary> Reverting to an old key is prohibited. </details> </li> -</ul> +<li> +<details> +<summary> +<code>AlreadyRevoked</code> - 15</summary> +Already revoked +</details> </li> -<li>Membership - 42 -<ul> <li> <details> <summary> -<code>IdtyIdNotFound</code> - 0</summary> -Identity ID not found. +<code>CanNotRevokeUnconfirmed</code> - 16</summary> +Can not revoke identity that never was member </details> </li> <li> <details> <summary> -<code>MembershipAlreadyAcquired</code> - 1</summary> -Membership already acquired. +<code>CanNotRevokeUnvalidated</code> - 17</summary> +Can not revoke identity that never was member </details> </li> +</ul> +</li> +<li>Membership - 42 +<ul> <li> <details> <summary> -<code>MembershipAlreadyRequested</code> - 2</summary> -Membership already requested. +<code>IdtyIdNotFound</code> - 0</summary> +Identity ID not found. </details> </li> <li> <details> <summary> -<code>MembershipNotFound</code> - 3</summary> -Membership not found. +<code>MembershipAlreadyAcquired</code> - 1</summary> +Membership already acquired. </details> </li> <li> <details> <summary> -<code>MembershipRequestNotFound</code> - 4</summary> -Membership request not found. +<code>MembershipNotFound</code> - 2</summary> +Membership not found. </details> </li> </ul> @@ -966,77 +1008,105 @@ Insufficient certifications received to claim membership. <li> <details> <summary> -<code>DistanceNotOk</code> - 1</summary> -Distance has not received a positive evaluation. +<code>DistanceIsInvalid</code> - 1</summary> +Distance is invalid. +</details> +</li> +<li> +<details> +<summary> +<code>DistanceNotEvaluated</code> - 2</summary> +Distance is not evaluated. +</details> +</li> +<li> +<details> +<summary> +<code>DistanceEvaluationPending</code> - 3</summary> +Distance evaluation has been requested but is still pending +</details> +</li> +<li> +<details> +<summary> +<code>DistanceEvaluationNotRequested</code> - 4</summary> +Distance evaluation has not been requested </details> </li> <li> <details> <summary> -<code>IdtyNotAllowedToRequestMembership</code> - 2</summary> +<code>IdtyNotAllowedToRequestMembership</code> - 5</summary> Identity is not allowed to request membership. </details> </li> <li> <details> <summary> -<code>IdtyNotAllowedToRenewMembership</code> - 3</summary> +<code>IdtyNotAllowedToRenewMembership</code> - 6</summary> Identity not allowed to renew membership. </details> </li> <li> <details> <summary> -<code>IdtyCreationPeriodNotRespected</code> - 4</summary> +<code>IdtyCreationPeriodNotRespected</code> - 7</summary> Identity creation period not respected. </details> </li> <li> <details> <summary> -<code>NotEnoughReceivedCertsToCreateIdty</code> - 5</summary> +<code>NotEnoughReceivedCertsToCreateIdty</code> - 8</summary> Insufficient received certifications to create identity. </details> </li> <li> <details> <summary> -<code>MaxEmittedCertsReached</code> - 6</summary> +<code>MaxEmittedCertsReached</code> - 9</summary> Maximum number of emitted certifications reached. </details> </li> <li> <details> <summary> -<code>NotAllowedToChangeIdtyAddress</code> - 7</summary> +<code>NotAllowedToChangeIdtyAddress</code> - 10</summary> Not allowed to change identity address. </details> </li> <li> <details> <summary> -<code>NotAllowedToRemoveIdty</code> - 8</summary> +<code>NotAllowedToRemoveIdty</code> - 11</summary> Not allowed to remove identity. </details> </li> <li> <details> <summary> -<code>IssuerCanNotEmitCert</code> - 9</summary> -Issuer cannot emit a certification because it is not validated. +<code>IssuerNotMember</code> - 12</summary> +Issuer cannot emit a certification because it is not member. +</details> +</li> +<li> +<details> +<summary> +<code>CertToUnconfirmed</code> - 13</summary> +Cannot issue a certification to an unconfirmed identity </details> </li> <li> <details> <summary> -<code>CertToUndefined</code> - 10</summary> -Cannot issue a certification to an identity without membership or pending membership. +<code>CertToRevoked</code> - 14</summary> +Cannot issue a certification to a revoked identity </details> </li> <li> <details> <summary> -<code>IdtyNotFound</code> - 11</summary> +<code>IdtyNotFound</code> - 15</summary> Issuer or receiver not found. </details> </li> @@ -1061,24 +1131,10 @@ Membership already acquired. <li> <details> <summary> -<code>MembershipAlreadyRequested</code> - 2</summary> -Membership already requested. -</details> -</li> -<li> -<details> -<summary> -<code>MembershipNotFound</code> - 3</summary> +<code>MembershipNotFound</code> - 2</summary> Membership not found. </details> </li> -<li> -<details> -<summary> -<code>MembershipRequestNotFound</code> - 4</summary> -Membership request not found. -</details> -</li> </ul> </li> <li>SmithCert - 53 diff --git a/docs/api/runtime-events.md b/docs/api/runtime-events.md index ab06c6d7a..cd058e2b4 100644 --- a/docs/api/runtime-events.md +++ b/docs/api/runtime-events.md @@ -1,6 +1,6 @@ # Runtime events -There are **129** events from **37** pallets. +There are **126** events from **37** pallets. <ul> <li>System - 0 @@ -1077,7 +1077,7 @@ members_count: BalanceOf<T> <li> <details> <summary> -<code>UdsAutoPaidAtRemoval(count, total, who)</code> - 2</summary> +<code>UdsAutoPaid(count, total, who)</code> - 2</summary> DUs were automatically transferred as part of a member removal. ```rust @@ -1165,51 +1165,38 @@ new_owner_key: T::AccountId <li> <details> <summary> -<code>IdtyRemoved(idty_index, reason)</code> - 4</summary> -An identity has been removed. +<code>IdtyRevoked(idty_index, reason)</code> - 4</summary> +An identity has been revoked. ```rust idty_index: T::IdtyIndex -reason: IdtyRemovalReason<T::IdtyRemovalOtherReason> +reason: RevocationReason ``` </details> </li> -</ul> -</li> -<li>Membership - 42 -<ul> <li> <details> <summary> -<code>MembershipAcquired(member, expire_on)</code> - 0</summary> -A membership was acquired. +<code>IdtyRemoved(idty_index, reason)</code> - 5</summary> +An identity has been removed. ```rust -member: T::IdtyId -expire_on: BlockNumberFor<T> +idty_index: T::IdtyIndex +reason: RemovalReason ``` </details> </li> -<li> -<details> -<summary> -<code>MembershipTerminated(member, reason)</code> - 1</summary> -A membership was terminated. - -```rust -member: T::IdtyId -reason: MembershipTerminationReason -``` - -</details> +</ul> </li> +<li>Membership - 42 +<ul> <li> <details> <summary> -<code>PendingMembershipAdded(member, expire_on)</code> - 2</summary> -A pending membership was added. +<code>MembershipAdded(member, expire_on)</code> - 0</summary> +A membership was added. ```rust member: T::IdtyId @@ -1221,11 +1208,12 @@ expire_on: BlockNumberFor<T> <li> <details> <summary> -<code>PendingMembershipExpired(member)</code> - 3</summary> -A pending membership has expired. +<code>MembershipRemoved(member, reason)</code> - 1</summary> +A membership was removed. ```rust member: T::IdtyId +reason: MembershipRemovalReason ``` </details> @@ -1237,14 +1225,12 @@ member: T::IdtyId <li> <details> <summary> -<code>NewCert(issuer, issuer_issued_count, receiver, receiver_received_count)</code> - 0</summary> +<code>CertAdded(issuer, receiver)</code> - 0</summary> A new certification was added. ```rust issuer: T::IdtyIndex -issuer_issued_count: u32 receiver: T::IdtyIndex -receiver_received_count: u32 ``` </details> @@ -1252,14 +1238,12 @@ receiver_received_count: u32 <li> <details> <summary> -<code>RemovedCert(issuer, issuer_issued_count, receiver, receiver_received_count, expiration)</code> - 1</summary> +<code>CertRemoved(issuer, receiver, expiration)</code> - 1</summary> A certification was removed. ```rust issuer: T::IdtyIndex -issuer_issued_count: u32 receiver: T::IdtyIndex -receiver_received_count: u32 expiration: bool ``` @@ -1268,7 +1252,7 @@ expiration: bool <li> <details> <summary> -<code>RenewedCert(issuer, receiver)</code> - 2</summary> +<code>CertRenewed(issuer, receiver)</code> - 2</summary> A certification was renewed. ```rust @@ -1331,34 +1315,8 @@ status: Option<(<T as frame_system::Config>::AccountId, DistanceStatus)> <li> <details> <summary> -<code>MembershipAcquired(member, expire_on)</code> - 0</summary> -A membership was acquired. - -```rust -member: T::IdtyId -expire_on: BlockNumberFor<T> -``` - -</details> -</li> -<li> -<details> -<summary> -<code>MembershipTerminated(member, reason)</code> - 1</summary> -A membership was terminated. - -```rust -member: T::IdtyId -reason: MembershipTerminationReason -``` - -</details> -</li> -<li> -<details> -<summary> -<code>PendingMembershipAdded(member, expire_on)</code> - 2</summary> -A pending membership was added. +<code>MembershipAdded(member, expire_on)</code> - 0</summary> +A membership was added. ```rust member: T::IdtyId @@ -1370,11 +1328,12 @@ expire_on: BlockNumberFor<T> <li> <details> <summary> -<code>PendingMembershipExpired(member)</code> - 3</summary> -A pending membership has expired. +<code>MembershipRemoved(member, reason)</code> - 1</summary> +A membership was removed. ```rust member: T::IdtyId +reason: MembershipRemovalReason ``` </details> @@ -1386,14 +1345,12 @@ member: T::IdtyId <li> <details> <summary> -<code>NewCert(issuer, issuer_issued_count, receiver, receiver_received_count)</code> - 0</summary> +<code>CertAdded(issuer, receiver)</code> - 0</summary> A new certification was added. ```rust issuer: T::IdtyIndex -issuer_issued_count: u32 receiver: T::IdtyIndex -receiver_received_count: u32 ``` </details> @@ -1401,14 +1358,12 @@ receiver_received_count: u32 <li> <details> <summary> -<code>RemovedCert(issuer, issuer_issued_count, receiver, receiver_received_count, expiration)</code> - 1</summary> +<code>CertRemoved(issuer, receiver, expiration)</code> - 1</summary> A certification was removed. ```rust issuer: T::IdtyIndex -issuer_issued_count: u32 receiver: T::IdtyIndex -receiver_received_count: u32 expiration: bool ``` @@ -1417,7 +1372,7 @@ expiration: bool <li> <details> <summary> -<code>RenewedCert(issuer, receiver)</code> - 2</summary> +<code>CertRenewed(issuer, receiver)</code> - 2</summary> A certification was renewed. ```rust diff --git a/docs/dev/pallet_conventions.md b/docs/dev/pallet_conventions.md index d7b9d7829..d84d6f232 100644 --- a/docs/dev/pallet_conventions.md +++ b/docs/dev/pallet_conventions.md @@ -5,7 +5,7 @@ Custom Duniter pallet calls should adhere to the standard Substrate naming convention: - `action_` for regular calls (e.g., `create_identity`). -- `force_action_` for calls with a privileged origin (e.g., `force_remove_identity`). +- `force_action_` for calls with a privileged origin (e.g., `force_set_distance_status`). ## Error diff --git a/end2end-tests/cucumber-features/identity_creation.feature b/end2end-tests/cucumber-features/identity_creation.feature index ce660e1ae..0e7a8a10a 100644 --- a/end2end-tests/cucumber-features/identity_creation.feature +++ b/end2end-tests/cucumber-features/identity_creation.feature @@ -14,10 +14,10 @@ Feature: Identity creation # then next cert can be done after cert_period, which is 15 When 15 block later When alice creates identity for dave - Then dave identity should be created + Then dave identity should be unconfirmed Then dave should be certified by alice When dave confirms his identity with pseudo "dave" - Then dave identity should be confirmed + Then dave identity should be unvalidated When 3 block later When bob certifies dave When charlie certifies dave @@ -30,5 +30,5 @@ Feature: Identity creation When alice runs distance oracle When 30 blocks later Then dave should have distance ok - When eve validates dave identity - Then dave identity should be validated + When dave claims membership + Then dave identity should be member diff --git a/end2end-tests/tests/common/identity.rs b/end2end-tests/tests/common/identity.rs index 0aa26bf91..57707e5b0 100644 --- a/end2end-tests/tests/common/identity.rs +++ b/end2end-tests/tests/common/identity.rs @@ -72,27 +72,6 @@ pub async fn confirm_identity(client: &Client, from: AccountKeyring, pseudo: Str Ok(()) } -pub async fn validate_identity(client: &Client, from: AccountKeyring, to: u32) -> Result<()> { - let from = PairSigner::new(from.pair()); - - let _events = create_block_with_extrinsic( - client, - client - .tx() - .create_signed( - &gdev::tx().identity().validate_identity(to), - &from, - BaseExtrinsicParamsBuilder::new(), - ) - .await - .unwrap(), - ) - .await - .unwrap(); - - Ok(()) -} - // get identity index from account keyring name pub async fn get_identity_index(world: &DuniterWorld, account: String) -> Result<u32> { let account: AccountId = AccountKeyring::from_str(&account) diff --git a/end2end-tests/tests/common/membership.rs b/end2end-tests/tests/common/membership.rs new file mode 100644 index 000000000..d800f3387 --- /dev/null +++ b/end2end-tests/tests/common/membership.rs @@ -0,0 +1,40 @@ +// Copyright 2021 Axiom-Team +// +// This file is part of Substrate-Libre-Currency. +// +// Substrate-Libre-Currency is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// Substrate-Libre-Currency is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>. + +use super::*; +use sp_keyring::AccountKeyring; +use subxt::tx::PairSigner; + +pub async fn claim_membership(client: &Client, from: AccountKeyring) -> Result<()> { + let from = PairSigner::new(from.pair()); + + let _events = create_block_with_extrinsic( + client, + client + .tx() + .create_signed( + &gdev::tx().membership().claim_membership(), + &from, + BaseExtrinsicParamsBuilder::new(), + ) + .await + .unwrap(), + ) + .await + .unwrap(); + + Ok(()) +} diff --git a/end2end-tests/tests/common/mod.rs b/end2end-tests/tests/common/mod.rs index b147b9783..6dbbbda5b 100644 --- a/end2end-tests/tests/common/mod.rs +++ b/end2end-tests/tests/common/mod.rs @@ -20,6 +20,7 @@ pub mod balances; pub mod cert; pub mod distance; pub mod identity; +pub mod membership; pub mod oneshot; #[subxt::subxt( diff --git a/end2end-tests/tests/cucumber_tests.rs b/end2end-tests/tests/cucumber_tests.rs index 92f1f36ee..db7e64171 100644 --- a/end2end-tests/tests/cucumber_tests.rs +++ b/end2end-tests/tests/cucumber_tests.rs @@ -334,15 +334,11 @@ async fn confirm_identity(world: &mut DuniterWorld, from: String, pseudo: String } #[allow(clippy::needless_pass_by_ref_mut)] -#[when(regex = r#"([a-zA-Z]+) validates ([a-zA-Z]+) identity"#)] -async fn validate_identity(world: &mut DuniterWorld, from: String, to: String) -> Result<()> { +#[when(regex = r#"([a-zA-Z]+) claims membership"#)] +async fn claim_membership(world: &mut DuniterWorld, from: String) -> Result<()> { // input names to keyrings let from = AccountKeyring::from_str(&from).expect("unknown from"); - let to: u32 = common::identity::get_identity_index(world, to) - .await - .unwrap(); - - common::identity::validate_identity(world.client(), from, to).await + common::membership::claim_membership(world.client(), from).await } #[allow(clippy::needless_pass_by_ref_mut)] @@ -576,9 +572,11 @@ impl FromStr for IdtyStatus { fn from_str(input: &str) -> std::result::Result<IdtyStatus, String> { match input { - "created" => Ok(IdtyStatus::Created), - "confirmed" => Ok(IdtyStatus::ConfirmedByOwner), - "validated" => Ok(IdtyStatus::Validated), + "unconfirmed" => Ok(IdtyStatus::Unconfirmed), + "unvalidated" => Ok(IdtyStatus::Unvalidated), + "member" => Ok(IdtyStatus::Member), + "notmember" => Ok(IdtyStatus::NotMember), + "revoked" => Ok(IdtyStatus::Revoked), _ => Err(format!("'{input}' does not match a status")), } } diff --git a/live-tests/tests/sanity_gdev.rs b/live-tests/tests/sanity_gdev.rs index e16979c77..d0ae6434c 100644 --- a/live-tests/tests/sanity_gdev.rs +++ b/live-tests/tests/sanity_gdev.rs @@ -46,7 +46,7 @@ type IdtyData = gdev::runtime_types::common_runtime::entities::IdtyData; type IdtyIndex = u32; type IdtyValue = gdev::runtime_types::pallet_identity::types::IdtyValue<BlockNumber, AccountId32, IdtyData>; -use gdev::runtime_types::pallet_identity::types::IdtyStatus; +// use gdev::runtime_types::pallet_identity::types::IdtyStatus; struct Storage { accounts: HashMap<AccountId32, AccountInfo>, @@ -110,7 +110,7 @@ async fn sanity_tests_at(client: Client, _maybe_block_hash: Option<H256>) -> any next_creatable_identity_on: idty_value.next_creatable_identity_on, old_owner_key: None, // Not used in the live test, skip the conversion owner_key: AccountId32::from(idty_value.owner_key.0), - removable_on: idty_value.removable_on, + next_scheduled: idty_value.next_scheduled, status: idty_value.status, }; identities.insert(IdtyIndex::from_le_bytes(idty_index_bytes), idty_val); @@ -275,27 +275,6 @@ mod verifier { ), ); } - - match idty_value.status { - IdtyStatus::Validated => { - // Rule 3: If the identity is validated, removable_on should be zero - self.assert( - idty_value.removable_on == 0, - format!( - "Identity {} is corrupted: removable_on > 0 on validated idty", - idty_index - ), - ); - } - _ => { - // Rule 4: If the identity is not validated, next_creatable_identity_on should be zero - self.assert( - idty_value.next_creatable_identity_on == 0, - format!("Identity {} is corrupted: next_creatable_identity_on > 0 on non-validated idty", - idty_index) - ); - } - } } for (idty_index, idty_value) in identities { diff --git a/node/src/chain_spec/gdev.rs b/node/src/chain_spec/gdev.rs index 3b64a884c..0639cbfed 100644 --- a/node/src/chain_spec/gdev.rs +++ b/node/src/chain_spec/gdev.rs @@ -354,8 +354,8 @@ fn genesis_data_to_gdev_genesis_conf( next_creatable_identity_on: 0, old_owner_key: old_owner_key.map(|address| (address, 0)), owner_key, - removable_on: if active { 0 } else { 2 }, - status: IdtyStatus::Validated, + next_scheduled: if active { 0 } else { 2 }, + status: IdtyStatus::Member, }, }, ) diff --git a/node/src/chain_spec/gtest.rs b/node/src/chain_spec/gtest.rs index 3b845e478..796b2c7de 100644 --- a/node/src/chain_spec/gtest.rs +++ b/node/src/chain_spec/gtest.rs @@ -301,8 +301,8 @@ fn genesis_data_to_gtest_genesis_conf( next_creatable_identity_on: 0, old_owner_key: old_owner_key.clone().map(|address| (address, 0)), owner_key, - removable_on: if active { 0 } else { 2 }, - status: IdtyStatus::Validated, + next_scheduled: if active { 0 } else { 2 }, + status: IdtyStatus::Member, }, }, ) diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs index 6074908e2..fd60d814e 100644 --- a/pallets/certification/src/lib.rs +++ b/pallets/certification/src/lib.rs @@ -283,38 +283,8 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - // Forbid self cert - ensure!(issuer != receiver, Error::<T, I>::CannotCertifySelf); - - // Verify caller ownership - let issuer_owner_key = - T::OwnerKeyOf::convert(issuer).ok_or(Error::<T, I>::IssuerNotFound)?; - ensure!(issuer_owner_key == who, DispatchError::BadOrigin); - - // Verify compatibility with other pallets state - T::CheckCertAllowed::check_cert_allowed(issuer, receiver)?; - - // Verify rule MinReceivedCertToBeAbleToIssueCert - let issuer_idty_cert_meta = <StorageIdtyCertMeta<T, I>>::get(issuer); - ensure!( - issuer_idty_cert_meta.received_count - >= T::MinReceivedCertToBeAbleToIssueCert::get(), - Error::<T, I>::NotEnoughCertReceived - ); - - // Verify rule MaxByIssuer - ensure!( - issuer_idty_cert_meta.issued_count < T::MaxByIssuer::get(), - Error::<T, I>::IssuedTooManyCert - ); - - // Verify rule CertPeriod let block_number = frame_system::pallet::Pallet::<T>::block_number(); - ensure!( - block_number >= issuer_idty_cert_meta.next_issuable_on, - Error::<T, I>::NotRespectCertPeriod - ); - + Self::check_cert_allowed(who, issuer, receiver, block_number)?; Self::do_add_cert(block_number, issuer, receiver) } @@ -524,6 +494,54 @@ pub mod pallet { } total_weight } + + /// check cert allowed + // first internal checks + // then external checks + fn check_cert_allowed( + caller_key: T::AccountId, + issuer: T::IdtyIndex, + receiver: T::IdtyIndex, + block_number: T::BlockNumber, + ) -> DispatchResult { + // --- first internal checks + // 1. Forbid self cert + ensure!(issuer != receiver, Error::<T, I>::CannotCertifySelf); + + // 2. Verify caller ownership + let issuer_owner_key = + T::OwnerKeyOf::convert(issuer).ok_or(Error::<T, I>::IssuerNotFound)?; + ensure!(issuer_owner_key == caller_key, DispatchError::BadOrigin); + + // 3. Verify rule MinReceivedCertToBeAbleToIssueCert + // (this number can differ from the one necessary to be member) + let issuer_idty_cert_meta = <StorageIdtyCertMeta<T, I>>::get(issuer); + ensure!( + issuer_idty_cert_meta.received_count + >= T::MinReceivedCertToBeAbleToIssueCert::get(), + Error::<T, I>::NotEnoughCertReceived + ); + + // 4. Verify rule MaxByIssuer + ensure!( + issuer_idty_cert_meta.issued_count < T::MaxByIssuer::get(), + Error::<T, I>::IssuedTooManyCert + ); + + // 5. Verify rule CertPeriod + ensure!( + block_number >= issuer_idty_cert_meta.next_issuable_on, + Error::<T, I>::NotRespectCertPeriod + ); + + // --- then external checks + // - issuer is member + // - receiver is confirmed + // - receiver is not revoked + T::CheckCertAllowed::check_cert_allowed(issuer, receiver)?; + + Ok(()) + } } } diff --git a/pallets/distance/src/mock.rs b/pallets/distance/src/mock.rs index 17071e729..988c9b43f 100644 --- a/pallets/distance/src/mock.rs +++ b/pallets/distance/src/mock.rs @@ -215,9 +215,10 @@ impl pallet_balances::Config for Test { parameter_types! { pub const ChangeOwnerKeyPeriod: u64 = 10; pub const ConfirmPeriod: u64 = 2; + pub const ValidationPeriod: u64 = 3; + pub const AutorevocationPeriod: u64 = 5; + pub const DeletionPeriod: u64 = 7; pub const IdtyCreationPeriod: u64 = 3; - pub const MaxInactivityPeriod: u64 = 5; - pub const ValidationPeriod: u64 = 2; } pub struct IdtyNameValidatorTestImpl; @@ -230,17 +231,18 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { impl pallet_identity::Config for Test { type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; type ConfirmPeriod = ConfirmPeriod; + type ValidationPeriod = ValidationPeriod; + type AutorevocationPeriod = AutorevocationPeriod; + type DeletionPeriod = DeletionPeriod; type CheckIdtyCallAllowed = (); type IdtyCreationPeriod = IdtyCreationPeriod; type IdtyData = (); type IdtyNameValidator = IdtyNameValidatorTestImpl; type IdtyIndex = u32; type AccountLinker = (); - type IdtyRemovalOtherReason = (); type Signer = UintAuthorityId; type Signature = TestSignature; type OnIdtyChange = (); - type RemoveIdentityConsumers = (); type RuntimeEvent = RuntimeEvent; type WeightInfo = (); #[cfg(feature = "runtime-benchmarks")] @@ -277,8 +279,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities { next_creatable_identity_on: 0, owner_key: i as u64, old_owner_key: None, - removable_on: 0, - status: pallet_identity::IdtyStatus::Validated, + next_scheduled: 0, + status: pallet_identity::IdtyStatus::Member, }, }) .collect(), diff --git a/pallets/duniter-account/src/lib.rs b/pallets/duniter-account/src/lib.rs index 93964997e..836220376 100644 --- a/pallets/duniter-account/src/lib.rs +++ b/pallets/duniter-account/src/lib.rs @@ -487,10 +487,7 @@ impl<T: Config> pallet_identity::traits::OnIdtyChange<T> for Pallet<T> { IdtyEvent::Created { owner_key, .. } => { Self::do_link_identity(owner_key.clone(), idty_id); } - IdtyEvent::Confirmed - | IdtyEvent::Validated - | IdtyEvent::ChangedOwnerKey { .. } - | IdtyEvent::Removed { .. } => {} + IdtyEvent::Removed { .. } => {} } } } diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs index 7f017280c..41ad8db13 100644 --- a/pallets/duniter-wot/src/lib.rs +++ b/pallets/duniter-wot/src/lib.rs @@ -17,8 +17,6 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::type_complexity)] -mod types; - #[cfg(test)] mod mock; @@ -31,15 +29,13 @@ pub mod traits; mod benchmarking;*/ pub use pallet::*; -pub use types::*; use traits::*; -use frame_support::dispatch::UnfilteredDispatchable; use frame_support::pallet_prelude::*; -use frame_system::RawOrigin; use pallet_certification::traits::SetNextIssuableOn; use pallet_identity::{IdtyEvent, IdtyStatus}; +use pallet_membership::MembershipRemovalReason; use sp_runtime::traits::IsMember; type IdtyIndex = u32; @@ -63,10 +59,8 @@ pub mod pallet { pub trait Config<I: 'static = ()>: frame_system::Config + pallet_certification::Config<I, IdtyIndex = IdtyIndex> - + pallet_identity::Config< - IdtyIndex = IdtyIndex, - IdtyRemovalOtherReason = IdtyRemovalWotReason, - > + pallet_membership::Config<I, IdtyId = IdtyIndex> + + pallet_identity::Config<IdtyIndex = IdtyIndex> + + pallet_membership::Config<I, IdtyId = IdtyIndex> { /// Distance evaluation provider type IsDistanceOk: IsDistanceOk<IdtyIndex>; @@ -90,17 +84,6 @@ pub mod pallet { block_number + T::FirstIssuableOn::get(), ); } - pub(super) fn dispatch_idty_call(idty_call: pallet_identity::Call<T>) -> bool { - if !T::IsSubWot::get() { - if let Err(e) = idty_call.dispatch_bypass_filter(RawOrigin::Root.into()) { - sp_std::if_std! { - println!("fail to dispatch idty call: {:?}", e) - } - return false; - } - } - true - } } // ERRORS // @@ -113,6 +96,10 @@ pub mod pallet { DistanceIsInvalid, /// Distance is not evaluated. DistanceNotEvaluated, + /// Distance evaluation has been requested but is still pending + DistanceEvaluationPending, + /// Distance evaluation has not been requested + DistanceEvaluationNotRequested, /// Identity is not allowed to request membership. IdtyNotAllowedToRequestMembership, /// Identity not allowed to renew membership. @@ -127,10 +114,12 @@ pub mod pallet { NotAllowedToChangeIdtyAddress, /// Not allowed to remove identity. NotAllowedToRemoveIdty, - /// Issuer cannot emit a certification because it is not validated. - IssuerCanNotEmitCert, - /// Cannot issue a certification to an identity without membership or pending membership. - CertToUndefined, + /// Issuer cannot emit a certification because it is not member. + IssuerNotMember, + /// Cannot issue a certification to an unconfirmed identity + CertToUnconfirmed, + /// Cannot issue a certification to a revoked identity + CertToRevoked, /// Issuer or receiver not found. IdtyNotFound, } @@ -142,48 +131,37 @@ impl<AccountId, T: Config<I>, I: 'static> pallet_identity::traits::CheckIdtyCall where T: frame_system::Config<AccountId = AccountId> + pallet_membership::Config<I>, { + // identity creation checks fn check_create_identity(creator: IdtyIndex) -> Result<(), DispatchError> { // main WoT constraints if !T::IsSubWot::get() { let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator); // perform all checks + // 1. check that identity has the right to create an identity + // identity can be member with 5 certifications and still not reach identity creation threshold which could be higher (6, 7...) ensure!( cert_meta.received_count >= T::MinCertForCreateIdtyRight::get(), Error::<T, I>::NotEnoughReceivedCertsToCreateIdty ); + // 2. check that issuer can emit one more certification + // (this is only a partial check) ensure!( cert_meta.issued_count < T::MaxByIssuer::get(), Error::<T, I>::MaxEmittedCertsReached ); + // 3. check that issuer respects certification creation period ensure!( cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number(), Error::<T, I>::IdtyCreationPeriodNotRespected ); } - // no constraints for subwot + // TODO (#136) make these trait implementation work on instances rather than static to avoid checking IsSubWot + // smith subwot can never prevent from creating identity Ok(()) } - fn check_confirm_identity(idty_index: IdtyIndex) -> Result<(), DispatchError> { - // main WoT automatic action - if !T::IsSubWot::get() { - // force add a membership request to the main WoT - pallet_membership::Pallet::<T, I>::force_request_membership(idty_index) - .map_err(|e| e.error)?; - } - // no constraints for subwot - Ok(()) - } - fn check_validate_identity(idty_index: IdtyIndex) -> Result<(), DispatchError> { - // main WoT constraints - if !T::IsSubWot::get() { - // check if identity is allowed to claim membership to the main wot - // (will be called automatically after) - pallet_membership::Pallet::<T, I>::check_allowed_to_claim(idty_index)?; - } - // no constraints for subwot - Ok(()) - } - fn check_change_identity_address(idty_index: IdtyIndex) -> Result<(), DispatchError> { + + // identity change owner key cheks + fn change_owner_key(idty_index: IdtyIndex) -> Result<(), DispatchError> { // sub WoT prevents from changing identity if T::IsSubWot::get() { ensure!( @@ -194,80 +172,44 @@ where // no constraints for main wot Ok(()) } - fn check_remove_identity(idty_index: IdtyIndex) -> Result<(), DispatchError> { - // identity can not be removed when member of a subwot (smith in this case) - if T::IsSubWot::get() { - ensure!( - !pallet_membership::Pallet::<T, I>::is_member(&idty_index), - Error::<T, I>::NotAllowedToRemoveIdty - ); - } - Ok(()) - } } // implement cert call checks impl<T: Config<I>, I: 'static> pallet_certification::traits::CheckCertAllowed<IdtyIndex> for Pallet<T, I> -// TODO add the following where clause once checks can be done on pallet instance +// TODO (#136) add the following where clause once checks can be done on pallet instance // where // T: pallet_membership::Config<I>, { // check the following: // - issuer has identity - // - issuer identity is validated + // - issuer identity is member // - receiver has identity - // - receiver identity is confirmed or validated - // - receiver has membership - // - // /!\ do not check the following: - // - receiver has membership - // - issuer has membership - // this has the following consequences: - // - receiver can receive smith certification without having requested membership - // - issuer can issue cert even if he lost his membership - // (not renewed or passed below cert threshold and above again without claiming membership) - // this is counterintuitive behavior but not a big problem - // - // TODO to fix this strange behavior, we will have to make the tests - // (CheckCertAllowed and CheckMembershipCallAllowed) run on the relevant instance - // i.e. Cert for Wot, SmithCert for SmithWot... - // → see issue #136 + // - receiver identity is confirmed and not revoked fn check_cert_allowed(issuer: IdtyIndex, receiver: IdtyIndex) -> Result<(), DispatchError> { // issuer checks - // ensure issuer has validated identity + // ensure issuer is member if let Some(issuer_data) = pallet_identity::Pallet::<T>::identity(issuer) { ensure!( - issuer_data.status == IdtyStatus::Validated, - Error::<T, I>::IssuerCanNotEmitCert + issuer_data.status == IdtyStatus::Member, + Error::<T, I>::IssuerNotMember ); } else { return Err(Error::<T, I>::IdtyNotFound.into()); } - // issue #136 this has to be done on the correct instance of membership pallet - // // ensure issuer has membership - // if pallet_membership::Pallet::<T, I>::membership(issuer).is_none() { - // // improvement: give reason why issuer can not emit cert (not member) - // return Err(Error::<T, I>::IssuerCanNotEmitCert.into()); - // } // receiver checks - // ensure receiver has confirmed or validated identity + // ensure receiver identity is confirmed and not revoked if let Some(receiver_data) = pallet_identity::Pallet::<T>::identity(receiver) { match receiver_data.status { - IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => {} // able to receive cert - IdtyStatus::Created => return Err(Error::<T, I>::CertToUndefined.into()), + // able to receive cert + IdtyStatus::Unvalidated | IdtyStatus::Member | IdtyStatus::NotMember => {} + IdtyStatus::Unconfirmed => return Err(Error::<T, I>::CertToUnconfirmed.into()), + IdtyStatus::Revoked => return Err(Error::<T, I>::CertToRevoked.into()), }; } else { return Err(Error::<T, I>::IdtyNotFound.into()); } - // issue #136 this has to be done on the correct instance of membership pallet - // // ensure receiver has a membership or a pending membership - // if pallet_membership::Pallet::<T, I>::pending_membership(issuer).is_none() - // && pallet_membership::Pallet::<T, I>::membership(issuer).is_none() - // { - // return Err(Error::<T, I>::CertToUndefined.into()); - // } Ok(()) } } @@ -276,22 +218,7 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::CheckCertAllowed<Id impl<T: Config<I>, I: 'static> sp_membership::traits::CheckMembershipCallAllowed<IdtyIndex> for Pallet<T, I> { - // membership request is only possible for subwot and when identity is validated - fn check_idty_allowed_to_request_membership( - idty_index: &IdtyIndex, - ) -> Result<(), DispatchError> { - if let Some(idty_value) = pallet_identity::Pallet::<T>::identity(idty_index) { - ensure!( - T::IsSubWot::get() && idty_value.status == IdtyStatus::Validated, - Error::<T, I>::IdtyNotAllowedToRequestMembership - ); - } else { - return Err(Error::<T, I>::IdtyNotFound.into()); - } - Ok(()) - } - - // membership claim is only possible when enough certs are received (both wots) + // membership claim is only possible when enough certs are received (both wots) and distance is ok fn check_idty_allowed_to_claim_membership(idty_index: &IdtyIndex) -> Result<(), DispatchError> { let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index); ensure!( @@ -302,11 +229,11 @@ impl<T: Config<I>, I: 'static> sp_membership::traits::CheckMembershipCallAllowed Ok(()) } - // membership renewal is only possible when identity is validated + // membership renewal is only possible when identity is member (otherwise it should claim again) fn check_idty_allowed_to_renew_membership(idty_index: &IdtyIndex) -> Result<(), DispatchError> { if let Some(idty_value) = pallet_identity::Pallet::<T>::identity(idty_index) { ensure!( - idty_value.status == IdtyStatus::Validated, + idty_value.status == IdtyStatus::Member, Error::<T, I>::IdtyNotAllowedToRenewMembership ); T::IsDistanceOk::is_distance_ok(idty_index)?; @@ -326,23 +253,18 @@ where match membership_event { sp_membership::Event::<IdtyIndex>::MembershipAdded(idty_index) => { if !T::IsSubWot::get() { - // when membership is acquired, validate identity + // when main membership is acquired, tell identity // (only used on first membership acquiry) - pallet_identity::Pallet::<T>::try_validate_identity(*idty_index); + pallet_identity::Pallet::<T>::membership_added(*idty_index); } } - sp_membership::Event::<IdtyIndex>::MembershipRemoved(_) => {} - sp_membership::Event::<IdtyIndex>::MembershipRenewed(_) => {} - sp_membership::Event::<IdtyIndex>::PendingMembershipAdded(_) => {} - sp_membership::Event::<IdtyIndex>::PendingMembershipExpired(idty_index) => { - Self::dispatch_idty_call(pallet_identity::Call::force_remove_identity { - idty_index: *idty_index, - idty_name: None, - reason: pallet_identity::IdtyRemovalReason::Other( - IdtyRemovalWotReason::MembershipExpired, - ), - }); + sp_membership::Event::<IdtyIndex>::MembershipRemoved(idty_index) => { + if !T::IsSubWot::get() { + // when main membership is lost, tell identity + pallet_identity::Pallet::<T>::membership_removed(*idty_index); + } } + sp_membership::Event::<IdtyIndex>::MembershipRenewed(_) => {} } } } @@ -351,6 +273,7 @@ where impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pallet<T, I> { fn on_idty_change(idty_index: IdtyIndex, idty_event: &IdtyEvent<T>) { match idty_event { + // identity just has been created, a cert must be added IdtyEvent::Created { creator, .. } => { if let Err(e) = <pallet_certification::Pallet<T, I>>::do_add_cert_checked( *creator, idty_index, true, @@ -360,25 +283,38 @@ impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pall } } } - IdtyEvent::Validated => { - // auto claim membership on main wot - <pallet_membership::Pallet<T, I>>::try_claim_membership(idty_index); - } + // TODO split in removed / revoked in two events: + // if identity is revoked keep it + // if identity is removed also remove certs IdtyEvent::Removed { status } => { - if *status != IdtyStatus::Validated { - if let Err(e) = - <pallet_certification::Pallet<T, I>>::remove_all_certs_received_by( - frame_system::Origin::<T>::Root.into(), - idty_index, - ) - { + // try remove membership in any case + <pallet_membership::Pallet<T, I>>::do_remove_membership( + idty_index, + MembershipRemovalReason::Revoked, + ); + + // only remove certs if identity is unvalidated + match status { + IdtyStatus::Unconfirmed | IdtyStatus::Unvalidated => { + if let Err(e) = + <pallet_certification::Pallet<T, I>>::remove_all_certs_received_by( + frame_system::Origin::<T>::Root.into(), + idty_index, + ) + { + sp_std::if_std! { + println!("fail to remove certs received by some idty: {:?}", e) + } + } + } + IdtyStatus::Revoked => {} + IdtyStatus::Member | IdtyStatus::NotMember => { sp_std::if_std! { - println!("fail to remove certs received by some idty: {:?}", e) + println!("removed non-revoked identity: {:?}", idty_index); } } } } - IdtyEvent::Confirmed | IdtyEvent::ChangedOwnerKey { .. } => {} } } } @@ -413,12 +349,10 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::OnRemovedCert<IdtyI && pallet_membership::Pallet::<T, I>::is_member(&receiver) { // expire receiver membership - // it gives them a bit of time to get back enough certs - if let Err(e) = <pallet_membership::Pallet<T, I>>::force_expire_membership(receiver) { - sp_std::if_std! { - println!("fail to expire membership: {:?}", e) - } - } + <pallet_membership::Pallet<T, I>>::do_remove_membership( + receiver, + MembershipRemovalReason::NotEnoughCerts, + ) } } } diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs index 29454df22..9420b482f 100644 --- a/pallets/duniter-wot/src/mock.rs +++ b/pallets/duniter-wot/src/mock.rs @@ -108,8 +108,10 @@ impl pallet_duniter_wot::Config<Instance1> for Test { parameter_types! { pub const ChangeOwnerKeyPeriod: u64 = 10; pub const ConfirmPeriod: u64 = 2; + pub const ValidationPeriod: u64 = 5; + pub const AutorevocationPeriod: u64 = 6; + pub const DeletionPeriod: u64 = 7; pub const IdtyCreationPeriod: u64 = 3; - pub const ValidationPeriod: u64 = 2; } pub struct IdtyNameValidatorTestImpl; @@ -124,15 +126,16 @@ impl pallet_identity::Config for Test { type ConfirmPeriod = ConfirmPeriod; type CheckIdtyCallAllowed = (DuniterWot, SmithSubWot); type IdtyCreationPeriod = IdtyCreationPeriod; + type ValidationPeriod = ValidationPeriod; + type AutorevocationPeriod = AutorevocationPeriod; + type DeletionPeriod = DeletionPeriod; type IdtyData = (); type IdtyNameValidator = IdtyNameValidatorTestImpl; type IdtyIndex = IdtyIndex; type AccountLinker = (); - type IdtyRemovalOtherReason = IdtyRemovalWotReason; type Signer = UintAuthorityId; type Signature = TestSignature; - type OnIdtyChange = DuniterWot; - type RemoveIdentityConsumers = (); + type OnIdtyChange = (DuniterWot, SmithSubWot); type RuntimeEvent = RuntimeEvent; type WeightInfo = (); #[cfg(feature = "runtime-benchmarks")] @@ -142,7 +145,6 @@ impl pallet_identity::Config for Test { // Membership parameter_types! { pub const MembershipPeriod: u64 = 8; - pub const PendingMembershipPeriod: u64 = 3; } impl pallet_membership::Config<Instance1> for Test { @@ -154,7 +156,6 @@ impl pallet_membership::Config<Instance1> for Test { type OnEvent = DuniterWot; type RuntimeEvent = RuntimeEvent; type WeightInfo = (); - type PendingMembershipPeriod = PendingMembershipPeriod; #[cfg(feature = "runtime-benchmarks")] type BenchmarkSetupHandler = (); } @@ -199,7 +200,6 @@ impl pallet_duniter_wot::Config<Instance2> for Test { // SmithMembership parameter_types! { pub const SmithMembershipPeriod: u64 = 20; - pub const SmithPendingMembershipPeriod: u64 = 3; } impl pallet_membership::Config<Instance2> for Test { @@ -209,7 +209,6 @@ impl pallet_membership::Config<Instance2> for Test { type AccountIdOf = (); type MembershipPeriod = SmithMembershipPeriod; type OnEvent = SmithSubWot; - type PendingMembershipPeriod = SmithPendingMembershipPeriod; type WeightInfo = (); type RuntimeEvent = RuntimeEvent; #[cfg(feature = "runtime-benchmarks")] @@ -259,8 +258,8 @@ pub fn new_test_ext( next_creatable_identity_on: 0, owner_key: i as u64, old_owner_key: None, - removable_on: 0, - status: pallet_identity::IdtyStatus::Validated, + next_scheduled: 0, + status: pallet_identity::IdtyStatus::Member, }, }) .collect(), diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs index 71a58f5e4..3645f1979 100644 --- a/pallets/duniter-wot/src/tests.rs +++ b/pallets/duniter-wot/src/tests.rs @@ -14,14 +14,13 @@ // You should have received a copy of the GNU Affero General Public License // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. -use crate::mock::{Identity, System}; +use crate::mock::*; use crate::pallet as pallet_duniter_wot; -use crate::{mock::*, IdtyRemovalWotReason}; use codec::Encode; use frame_support::instances::{Instance1, Instance2}; use frame_support::{assert_noop, assert_ok}; use pallet_identity::{ - IdtyIndexAccountIdPayload, IdtyName, IdtyStatus, RevocationPayload, + IdtyIndexAccountIdPayload, IdtyName, IdtyStatus, RevocationPayload, RevocationReason, NEW_OWNER_KEY_PAYLOAD_PREFIX, REVOCATION_PAYLOAD_PREFIX, }; use pallet_membership::MembershipRemovalReason; @@ -79,28 +78,15 @@ fn test_join_smiths() { new_test_ext(5, 3).execute_with(|| { run_to_block(2); - // Dave shoud be able to request smith membership - assert_ok!(SmithMembership::request_membership(RuntimeOrigin::signed( - 4 - ),)); - System::assert_has_event(RuntimeEvent::SmithMembership( - pallet_membership::Event::PendingMembershipAdded { - member: 4, - expire_on: 2 - + <Test as pallet_membership::Config<Instance2>>::PendingMembershipPeriod::get( - ), - }, - )); - - // Then, Alice should be able to send a smith cert to Dave + // Alice should be able to send a smith cert to Dave run_to_block(3); assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(1), 1, 4)); - // Then, Bob should be able to send a smith cert to Dave + // Bob should be able to send a smith cert to Dave run_to_block(4); assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(2), 2, 4)); - // Then, Dave should be able to claim his membership + // Dave should be able to claim his membership run_to_block(4); assert_ok!(SmithMembership::claim_membership(RuntimeOrigin::signed(4),)); System::assert_has_event(RuntimeEvent::SmithMembership( @@ -122,7 +108,7 @@ fn test_smith_certs_expirations_should_expire_smith_membership() { System::assert_has_event(RuntimeEvent::SmithMembership( pallet_membership::Event::MembershipRemoved { member: 1, - reason: MembershipRemovalReason::Expired, + reason: MembershipRemovalReason::NotEnoughCerts, }, )); }); @@ -153,9 +139,9 @@ fn test_smith_member_cant_change_its_idty_address() { }); } -/// members of the smith subwot can not remove their identity +/// members of the smith subwot can revoke their identity #[test] -fn test_smith_member_cant_revoke_its_idty() { +fn test_smith_member_can_revoke_its_idty() { new_test_ext(5, 3).execute_with(|| { run_to_block(2); @@ -165,15 +151,26 @@ fn test_smith_member_cant_revoke_its_idty() { }; // Identity 3 can't change it's address - assert_noop!( - Identity::revoke_identity( - RuntimeOrigin::signed(3), - 3, - 3, - TestSignature(3, (REVOCATION_PAYLOAD_PREFIX, revocation_payload).encode()) - ), - pallet_duniter_wot::Error::<Test, Instance2>::NotAllowedToRemoveIdty - ); + assert_ok!(Identity::revoke_identity( + RuntimeOrigin::signed(3), + 3, + 3, + TestSignature(3, (REVOCATION_PAYLOAD_PREFIX, revocation_payload).encode()) + )); + // membership should be removed + System::assert_has_event(RuntimeEvent::Membership( + pallet_membership::Event::MembershipRemoved { + member: 3, + reason: pallet_membership::MembershipRemovalReason::Revoked, + }, + )); + // smith membership should be removed as well + System::assert_has_event(RuntimeEvent::SmithMembership( + pallet_membership::Event::MembershipRemoved { + member: 3, + reason: pallet_membership::MembershipRemovalReason::Revoked, + }, + )); }); } @@ -197,8 +194,11 @@ fn test_create_idty_ok() { receiver: 6, })); - assert_eq!(Identity::identity(6).unwrap().status, IdtyStatus::Created); - assert_eq!(Identity::identity(6).unwrap().removable_on, 4); + assert_eq!( + Identity::identity(6).unwrap().status, + IdtyStatus::Unconfirmed + ); + assert_eq!(Identity::identity(6).unwrap().next_scheduled, 2 + 2); }); } @@ -225,15 +225,9 @@ fn test_new_idty_validation() { receiver: 6, })); - // Ferdie should not be able to claim membership - // assert_noop!( - // Membership::claim_membership(RuntimeOrigin::signed(6)), - // pallet_membership::Error::<Test, Instance1>::xxx - // ); - - // Anyone should be able to validate Ferdie identity + // Ferdie should be able to claim membership run_to_block(5); - assert_ok!(Identity::validate_identity(RuntimeOrigin::signed(42), 6)); + assert_ok!(Membership::claim_membership(RuntimeOrigin::signed(6)),); System::assert_has_event(RuntimeEvent::Membership( pallet_membership::Event::MembershipAdded { member: 6, @@ -254,8 +248,8 @@ fn test_new_idty_validation() { next_creatable_identity_on: 0, old_owner_key: None, owner_key: 6, - removable_on: 0, - status: IdtyStatus::Validated, + next_scheduled: 0, + status: IdtyStatus::Member, }) ); }); @@ -277,14 +271,6 @@ fn test_confirm_idty_ok() { RuntimeOrigin::signed(6), IdtyName::from("Ferdie"), )); - System::assert_has_event(RuntimeEvent::Membership( - pallet_membership::Event::PendingMembershipAdded { - member: 6, - expire_on: 3 - + <Test as pallet_membership::Config<Instance1>>::PendingMembershipPeriod::get( - ), - }, - )); System::assert_has_event(RuntimeEvent::Identity( pallet_identity::Event::IdtyConfirmed { idty_index: 6, @@ -303,26 +289,37 @@ fn test_revoke_idty() { new_test_ext(5, 1).execute_with(|| { run_to_block(2); - // Alice identity can not be revoked because she's smith - assert_noop!( - Identity::revoke_identity( - RuntimeOrigin::signed(1), - 1, + // Alice identity can be revoked + assert_ok!(Identity::revoke_identity( + RuntimeOrigin::signed(1), + 1, + 1, + TestSignature( 1, - TestSignature( - 1, - ( - REVOCATION_PAYLOAD_PREFIX, - RevocationPayload { - idty_index: 1u32, - genesis_hash: System::block_hash(0), - } - ) - .encode() + ( + REVOCATION_PAYLOAD_PREFIX, + RevocationPayload { + idty_index: 1u32, + genesis_hash: System::block_hash(0), + } ) - ), - pallet_duniter_wot::Error::<Test, Instance2>::NotAllowedToRemoveIdty - ); + .encode() + ) + )); + // her membership should be removed + System::assert_has_event(RuntimeEvent::Membership( + pallet_membership::Event::MembershipRemoved { + member: 1, + reason: pallet_membership::MembershipRemovalReason::Revoked, + }, + )); + // and her smith membership should be removed as well + System::assert_has_event(RuntimeEvent::SmithMembership( + pallet_membership::Event::MembershipRemoved { + member: 1, + reason: pallet_membership::MembershipRemovalReason::Revoked, + }, + )); // Anyone should be able to submit Bob revocation certificate assert_ok!(Identity::revoke_identity( @@ -343,9 +340,9 @@ fn test_revoke_idty() { )); System::assert_has_event(RuntimeEvent::Identity( - pallet_identity::Event::IdtyRemoved { + pallet_identity::Event::IdtyRevoked { idty_index: 2, - reason: pallet_identity::IdtyRemovalReason::<IdtyRemovalWotReason>::Revoked, + reason: pallet_identity::RevocationReason::User, }, )); }); @@ -362,8 +359,14 @@ fn test_idty_membership_expire() { // Bob renews his membership assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(2))); + run_to_block(5); + // renew certifications so that Alice can still issue cert at block 22 + assert_ok!(Cert::add_cert(RuntimeOrigin::signed(2), 2, 1)); + assert_ok!(Cert::add_cert(RuntimeOrigin::signed(3), 3, 1)); + // Charlie's membership should expire at block #8 run_to_block(8); + assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(1))); assert!(Membership::membership(3).is_none()); System::assert_has_event(RuntimeEvent::Membership( @@ -372,35 +375,53 @@ fn test_idty_membership_expire() { reason: MembershipRemovalReason::Expired, }, )); - // membership expiry should not trigger identity removal - assert!(!System::events().iter().any(|record| record.event - == RuntimeEvent::Identity(pallet_identity::Event::IdtyRemoved { + assert_eq!( + Identity::identity(3), + Some(pallet_identity::IdtyValue { + data: (), + next_creatable_identity_on: 0, + old_owner_key: None, + owner_key: 3, + next_scheduled: 14, // = 8 (membership removal block) + 6 (auto revocation period) + status: IdtyStatus::NotMember, + }) + ); + // check that identity is added to auto-revoke list (currently IdentityChangeSchedule) + assert_eq!(Identity::next_scheduled(14), vec!(3)); + run_to_block(14); + assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(1))); + // Charlie's identity should be auto-revoked at block #11 (8 + 3) + System::assert_has_event(RuntimeEvent::Identity( + pallet_identity::Event::IdtyRevoked { idty_index: 3, - reason: pallet_identity::IdtyRemovalReason::Other( - IdtyRemovalWotReason::MembershipExpired - ) - }))); - // it should be moved to pending membership instead - assert!(Membership::pending_membership(3).is_some()); - - // then pending membership should expire and identity should finally be removed - run_to_block(11); - System::assert_has_event(RuntimeEvent::Membership( - pallet_membership::Event::PendingMembershipExpired { member: 3 }, + reason: pallet_identity::RevocationReason::Expired, + }, )); + assert_eq!( + Identity::identity(3), + Some(pallet_identity::IdtyValue { + data: (), + next_creatable_identity_on: 0, + old_owner_key: None, + owner_key: 3, + next_scheduled: 21, // = 14 (revocation block) + 7 (deletion period) + status: IdtyStatus::Revoked, + }) + ); + // Alice can't certify revoked identity + assert_noop!( + Cert::add_cert(RuntimeOrigin::signed(1), 1, 3), + pallet_duniter_wot::Error::<Test, Instance1>::CertToRevoked + ); + + run_to_block(21); System::assert_has_event(RuntimeEvent::Identity( pallet_identity::Event::IdtyRemoved { idty_index: 3, - reason: pallet_identity::IdtyRemovalReason::Other( - IdtyRemovalWotReason::MembershipExpired, - ), + reason: pallet_identity::RemovalReason::Revoked, }, )); - - // Charlie's identity should be removed at block #11 - assert!(Identity::identity(3).is_none()); - - // Alice can't renew her cert to Charlie + // Alice can't certify removed identity assert_noop!( Cert::add_cert(RuntimeOrigin::signed(1), 1, 3), pallet_duniter_wot::Error::<Test, Instance1>::IdtyNotFound @@ -423,10 +444,10 @@ fn test_unvalidated_idty_certs_removal() { IdtyName::from("Ferdie"), )); - // After PendingMembershipPeriod, Ferdie identity should expire - // and his received certifications should be removed assert_eq!(Cert::certs_by_receiver(6).len(), 1); - run_to_block(6); + // After ValidationPeriod, Ferdie identity should be automatically removed + // and his received certifications should be removed + run_to_block(8); assert_eq!(Cert::certs_by_receiver(6).len(), 0); }); } @@ -474,7 +495,7 @@ fn test_certification_expire() { System::assert_has_event(RuntimeEvent::SmithMembership( pallet_membership::Event::MembershipRemoved { member: 1, - reason: MembershipRemovalReason::Expired, + reason: MembershipRemovalReason::NotEnoughCerts, }, )); @@ -498,7 +519,7 @@ fn test_certification_expire() { System::assert_has_event(RuntimeEvent::Membership( pallet_membership::Event::MembershipRemoved { member: 1, - reason: MembershipRemovalReason::Expired, + reason: MembershipRemovalReason::NotEnoughCerts, }, )); @@ -508,7 +529,7 @@ fn test_certification_expire() { assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(2))); assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(3))); - // Alice can not renew her membership which does not exist because it is pending + // Alice can not renew her membership which does not exist assert_noop!( Membership::renew_membership(RuntimeOrigin::signed(1)), pallet_membership::Error::<Test, Instance1>::MembershipNotFound @@ -521,19 +542,13 @@ fn test_certification_expire() { ); // --- BLOCK 23 --- - run_to_block(23); + run_to_block(26); // println!("{:?}", System::events()); - // after a delay (3 blocks), the pending membership finally expires - System::assert_has_event(RuntimeEvent::Membership( - pallet_membership::Event::PendingMembershipExpired { member: 1 }, - )); - // and the identity is removed + // after a delay, the non member identity is automatically revoked System::assert_has_event(RuntimeEvent::Identity( - pallet_identity::Event::IdtyRemoved { + pallet_identity::Event::IdtyRevoked { idty_index: 1, - reason: pallet_identity::IdtyRemovalReason::Other( - IdtyRemovalWotReason::MembershipExpired, - ), + reason: RevocationReason::Expired, }, )); }) @@ -588,13 +603,12 @@ fn test_cert_can_not_be_issued() { System::assert_has_event(RuntimeEvent::SmithMembership( pallet_membership::Event::MembershipRemoved { member: 1, - reason: MembershipRemovalReason::Expired, + reason: MembershipRemovalReason::NotEnoughCerts, }, )); run_to_block(11); - // /!\ COUNTERINTUITIVE BEHAVIOR - // Dave should not be able to receive a smith cert since he did not request smith membership + // Dave should be able to receive a smith cert since assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(3), 3, 4)); // Bob renews his smith certification towards Alice assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(2), 2, 1)); @@ -637,7 +651,7 @@ fn test_cert_can_not_be_issued() { System::assert_has_event(RuntimeEvent::Membership( pallet_membership::Event::MembershipRemoved { member: 1, - reason: MembershipRemovalReason::Expired, + reason: MembershipRemovalReason::NotEnoughCerts, }, // pending membership expires at 23 )); @@ -655,3 +669,54 @@ fn test_cert_can_not_be_issued() { // she would have been able to emit a cert without being member }) } + +/// test non smith identity can not emit smith cert +#[test] +fn test_non_smith_can_not_issue_smith_cert() { + new_test_ext(4, 3).execute_with(|| { + assert_noop!( + SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1), + pallet_certification::Error::<Test, Instance2>::NotEnoughCertReceived + ); + }) +} + +/// FIXME this test should not fail with NotRespectCertPeriod but NotSmith or somthing like that +/// test non smith identity can not emit smith cert +#[test] +fn test_non_smith_with_certs_can_not_issue_smith_cert() { + new_test_ext(4, 3).execute_with(|| { + run_to_block(2); + assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(1), 1, 4)); + assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(2), 2, 4)); + assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(3), 3, 4)); + assert_noop!( + SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1), + pallet_certification::Error::<Test, Instance2>::NotRespectCertPeriod + ); + }) +} + +/// FIXME this test should not succeed because Dave should not be able to issue cert +/// after revocation of his smith membership +/// test non smith identity can not emit smith cert +#[test] +fn test_revoked_smith_with_certs_can_not_issue_smith_cert() { + new_test_ext(4, 3).execute_with(|| { + run_to_block(2); + assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(1), 1, 4)); + assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(2), 2, 4)); + assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(3), 3, 4)); + assert_ok!(SmithMembership::claim_membership(RuntimeOrigin::signed(4))); + assert_noop!( + SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1), + pallet_certification::Error::<Test, Instance2>::NotRespectCertPeriod + ); + run_to_block(4); + assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1),); + run_to_block(5); + assert_ok!(SmithMembership::revoke_membership(RuntimeOrigin::signed(4))); + run_to_block(6); + assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1),); + }) +} diff --git a/pallets/duniter-wot/src/types.rs b/pallets/duniter-wot/src/types.rs deleted file mode 100644 index 2a049f86d..000000000 --- a/pallets/duniter-wot/src/types.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2023 Axiom-Team -// -// This file is part of Duniter-v2S. -// -// Duniter-v2S is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, version 3 of the License. -// -// Duniter-v2S is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. - -use codec::{Decode, Encode}; -use frame_support::pallet_prelude::*; -use scale_info::TypeInfo; - -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] -pub enum IdtyRemovalWotReason { - MembershipExpired, - Other, -} diff --git a/pallets/identity/README.md b/pallets/identity/README.md index 1d728ed92..e8da9f126 100644 --- a/pallets/identity/README.md +++ b/pallets/identity/README.md @@ -9,13 +9,15 @@ A Duniter identity contains: - its **owner key** (that can change) - an optional **old owner key** with the date of the key change - a **status** that can be - - created (by an existing identity) - - confirmed (by owner, comes with a name) - - validated (that has become member in the allowed timeframe) + - unconfirmed (created by a member identity) + - unvalidated (confirmed by owner = given a name) + - member (of the main wot) + - notmember (of the main wot) + - revoked (automatically of manually) It also contains: -- the block number at which it can emit its **next certification** +- the block number at which it can emit its **next certification** (TODO distinguish next certification and next identity creation) - the block number at which it can be **removed from storage** It also contains attached data defined by the runtime that can be for example @@ -24,7 +26,7 @@ It also contains attached data defined by the runtime that can be for example ### Name -Each identity is declared with a name emited on confirmation event. Duniter keeps a list of identity names hash to ensure unicity. +Each identity is declared with a name emited on confirmation event. Duniter keeps a list of identity names hash to ensure unicity. ### Owner key @@ -40,4 +42,4 @@ The next certification is a rate limit to the emission of certification (and the ### Revokation -Revoking an identity basically means deleting it. \ No newline at end of file +Revoking an identity basically means deleting it. diff --git a/pallets/identity/src/benchmarking.rs b/pallets/identity/src/benchmarking.rs index 2ec4a1352..fea88edfd 100644 --- a/pallets/identity/src/benchmarking.rs +++ b/pallets/identity/src/benchmarking.rs @@ -40,7 +40,7 @@ struct Account<T: Config> { key: T::AccountId, index: T::IdtyIndex, origin: <T as frame_system::Config>::RuntimeOrigin, - name: IdtyName, + // name: IdtyName, } // Create and confirm one account using Alice authorized account. @@ -48,7 +48,10 @@ struct Account<T: Config> { // Alice next_creatable_identity_on is reinitialized at the end so several account can be // created in a row. fn create_one_identity<T: Config>(owner_key: T::AccountId) -> Result<Account<T>, &'static str> { - let caller: T::AccountId = Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key; + // get Alice account to create identity + let caller: T::AccountId = Identities::<T>::get(T::IdtyIndex::from(1u32)) + .unwrap() + .owner_key; let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); let owner_key_origin: <T as frame_system::Config>::RuntimeOrigin = @@ -57,17 +60,23 @@ fn create_one_identity<T: Config>(owner_key: T::AccountId) -> Result<Account<T>, let name = IdtyName("new_identity".into()); Pallet::<T>::confirm_identity(owner_key_origin.clone(), name.clone())?; let idty_index = IdentityIndexOf::<T>::get(&owner_key).unwrap(); + // make identity member + <Identities<T>>::mutate_exists(T::IdtyIndex::from(idty_index), |idty_val_opt| { + if let Some(ref mut idty_val) = idty_val_opt { + idty_val.status = IdtyStatus::Member; + } + }); // Reset next_creatable_identity_on to add more identities with Alice - <Identities<T>>::mutate_exists(T::IdtyIndex::one(), |idty_val_opt| { + <Identities<T>>::mutate_exists(T::IdtyIndex::from(1u32), |idty_val_opt| { if let Some(ref mut idty_val) = idty_val_opt { idty_val.next_creatable_identity_on = T::BlockNumber::zero(); } }); Ok(Account { key: owner_key, - origin: owner_key_origin, - name: name, index: idty_index, + origin: owner_key_origin, + // name: name, }) } @@ -75,19 +84,19 @@ fn create_one_identity<T: Config>(owner_key: T::AccountId) -> Result<Account<T>, fn create_dummy_identity<T: Config>(i: u32) -> Result<(), &'static str> { let idty_index: T::IdtyIndex = i.into(); let owner_key: T::AccountId = account("Bob", i, SEED); - let removable_on = T::BlockNumber::zero(); + let next_scheduled = T::BlockNumber::zero(); let value = IdtyValue { data: Default::default(), next_creatable_identity_on: T::BlockNumber::zero(), old_owner_key: None, owner_key: owner_key.clone(), - removable_on, - status: IdtyStatus::ConfirmedByOwner, + next_scheduled, + status: IdtyStatus::Unvalidated, }; let name = i.to_le_bytes(); let idty_name = IdtyName(name.into()); <Identities<T>>::insert(idty_index, value); - IdentitiesRemovableOn::<T>::append(removable_on, (idty_index, IdtyStatus::Created)); + IdentityChangeSchedule::<T>::append(next_scheduled, idty_index); IdentityIndexOf::<T>::insert(owner_key.clone(), idty_index); <IdentitiesNames<T>>::insert(idty_name.clone(), idty_index); Ok(()) @@ -114,6 +123,8 @@ benchmarks! { T::AccountId: From<AccountId32>, T::IdtyIndex: From<u32>, } + + // create identity create_identity { let caller: T::AccountId = Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key; // Alice let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); @@ -125,6 +136,7 @@ benchmarks! { assert_has_event::<T>(Event::<T>::IdtyCreated { idty_index: idty_index.unwrap(), owner_key: owner_key }.into()); } + // confirm identity confirm_identity { let caller: T::AccountId = Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key; let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); @@ -137,26 +149,7 @@ benchmarks! { assert_has_event::<T>(Event::<T>::IdtyConfirmed { idty_index: idty_index.unwrap(), owner_key: owner_key, name: IdtyName("new_identity".into()) }.into()); } - validate_identity { - let index = NextIdtyIndex::<T>::get(); - let caller: T::AccountId = Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key; - let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); - let owner_key: T::AccountId = account("new_identity", 2, SEED); - let owner_key_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(owner_key.clone()).into(); - let name = IdtyName("new_identity".into()); - Pallet::<T>::create_identity(caller_origin.clone(), owner_key.clone())?; - Pallet::<T>::confirm_identity(owner_key_origin.clone(), name.clone())?; - // Should be superior to the minimal number of certificates to gain membership. - for j in 0..100 { - let issuer: T::IdtyIndex = j.into(); - T::BenchmarkSetupHandler::add_cert(&issuer, &index); - } - T::BenchmarkSetupHandler::force_status_ok(&index, &owner_key); - }: _<T::RuntimeOrigin>(caller_origin, index.into()) - verify { - assert_has_event::<T>(Event::<T>::IdtyValidated { idty_index: index.into() }.into()); - } - + // change owner key change_owner_key { let old_key: T::AccountId = account("new_identity", 2, SEED); let account: Account<T> = create_one_identity(old_key.clone())?; @@ -194,12 +187,13 @@ benchmarks! { assert!(IdentityIndexOf::<T>::get(&caller).unwrap() == account.index, "Owner key not changed"); } + // revoke identity revoke_identity { let old_key: T::AccountId = account("new_identity", 2, SEED); let account: Account<T> = create_one_identity(old_key.clone())?; // Change key - // The sufficients for the old key will drop to 0 during benchmark + // The sufficients for the old key will drop to 0 during benchmark (not for revoke, only for remove) let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero()); let new_key_payload = IdtyIndexAccountIdPayload { genesis_hash: &genesis_hash, @@ -221,22 +215,9 @@ benchmarks! { let signature = sr25519_sign(0.into(), &caller_public, &message).unwrap().into(); }: _<T::RuntimeOrigin>(account.origin.clone(), account.index.clone().into(), caller.clone(), signature) verify { - assert_has_event::<T>(Event::<T>::IdtyRemoved { idty_index: account.index, reason: IdtyRemovalReason::Revoked }.into()); - assert!(IdentityIndexOf::<T>::get(&account.key).is_none(), "Identity not revoked"); - } - - force_remove_identity { - let new_identity: T::AccountId = account("new_identity", 2, SEED); - let account: Account<T> = create_one_identity(new_identity)?; - let identities = Pallet::<T>::identities_count(); - }: _<T::RuntimeOrigin>(RawOrigin::Root.into(), account.index.clone(), Some(account.name.clone()), IdtyRemovalReason::Manual) - verify { - assert!( - Pallet::<T>::identities_count() == identities - 1, - "Identities not removed" - ); - assert_has_event::<T>(Event::<T>::IdtyRemoved { idty_index: account.index, reason: IdtyRemovalReason::Manual }.into()); - assert!(IdentityIndexOf::<T>::get(&account.key).is_none(), "Identity not removed"); + assert_has_event::<T>(Event::<T>::IdtyRevoked { idty_index: account.index, reason: RevocationReason::User }.into()); + // revocation does not mean deletion anymore + // assert!(IdentityIndexOf::<T>::get(&account.key).is_none(), "Identity not revoked"); } // The complexity depends on the number of identities to prune @@ -258,6 +239,7 @@ benchmarks! { } } + // fix sufficients identity fix_sufficients { let new_identity: T::AccountId = account("Bob", 2, SEED); let account: Account<T> = create_one_identity(new_identity)?; @@ -267,6 +249,7 @@ benchmarks! { assert!(sufficient < frame_system::Pallet::<T>::sufficients(&account.key), "Sufficient not incremented"); } + // link account link_account { let alice_origin = RawOrigin::Signed(Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key); let bob_public = sr25519_generate(0.into(), None); @@ -277,13 +260,36 @@ benchmarks! { ).encode(); let signature = sr25519_sign(0.into(), &bob_public, &payload).unwrap().into(); }: _<T::RuntimeOrigin>(alice_origin.into(), bob, signature) + // Base weight of an empty initialize on_initialize { }: {Pallet::<T>::on_initialize(BlockNumberFor::<T>::zero());} + + // --- do revoke identity + do_revoke_identity_noop { + let idty_index: T::IdtyIndex = 0u32.into(); + assert!(Identities::<T>::get(idty_index).is_none()); + }: {Pallet::<T>::do_revoke_identity(idty_index, RevocationReason::Root);} + do_revoke_identity { + let idty_index: T::IdtyIndex = 1u32.into(); + let new_identity: T::AccountId = account("Bob", 2, SEED); + assert!(Identities::<T>::get(idty_index).is_some()); + Identities::<T>::mutate( idty_index, |id| { + if let Some(id) = id { + id.old_owner_key = Some((new_identity, BlockNumberFor::<T>::zero())); + } + }); + assert!(Identities::<T>::get(idty_index).unwrap().old_owner_key.is_some()); + }: {Pallet::<T>::do_revoke_identity(idty_index, RevocationReason::Root);} + verify { + assert_has_event::<T>(Event::<T>::IdtyRevoked { idty_index, reason: RevocationReason::Root }.into()); + } + + // --- do remove identity do_remove_identity_noop { let idty_index: T::IdtyIndex = 0u32.into(); assert!(Identities::<T>::get(idty_index).is_none()); - }: {Pallet::<T>::do_remove_identity(idty_index, IdtyRemovalReason::Revoked);} + }: {Pallet::<T>::do_remove_identity(idty_index, RemovalReason::Revoked);} do_remove_identity { let idty_index: T::IdtyIndex = 1u32.into(); let new_identity: T::AccountId = account("Bob", 2, SEED); @@ -294,24 +300,27 @@ benchmarks! { } }); assert!(Identities::<T>::get(idty_index).unwrap().old_owner_key.is_some()); - }: {Pallet::<T>::do_remove_identity(idty_index, IdtyRemovalReason::Revoked);} + }: {Pallet::<T>::do_remove_identity(idty_index, RemovalReason::Revoked);} verify { - assert_has_event::<T>(Event::<T>::IdtyRemoved { idty_index, reason: IdtyRemovalReason::Revoked }.into()); + assert_has_event::<T>(Event::<T>::IdtyRemoved { idty_index, reason: RemovalReason::Revoked }.into()); } + + // --- prune identities prune_identities_noop { - assert!(IdentitiesRemovableOn::<T>::try_get(T::BlockNumber::zero()).is_err()); + assert!(IdentityChangeSchedule::<T>::try_get(T::BlockNumber::zero()).is_err()); }: {Pallet::<T>::prune_identities(T::BlockNumber::zero());} + prune_identities_none { let idty_index: T::IdtyIndex = 100u32.into(); - IdentitiesRemovableOn::<T>::append(T::BlockNumber::zero(), (idty_index, IdtyStatus::Created)); - assert!(IdentitiesRemovableOn::<T>::try_get(T::BlockNumber::zero()).is_ok()); + IdentityChangeSchedule::<T>::append(T::BlockNumber::zero(), idty_index); + assert!(IdentityChangeSchedule::<T>::try_get(T::BlockNumber::zero()).is_ok()); assert!(<Identities<T>>::try_get(idty_index).is_err()); }: {Pallet::<T>::prune_identities(T::BlockNumber::zero());} + prune_identities_err { let idty_index: T::IdtyIndex = 100u32.into(); create_dummy_identity::<T>(100u32)?; - IdentitiesRemovableOn::<T>::append(T::BlockNumber::zero(), (idty_index, IdtyStatus::Created)); - assert!(<Identities<T>>::get(idty_index).unwrap().status != IdentitiesRemovableOn::<T>::get(T::BlockNumber::zero())[0].1); + IdentityChangeSchedule::<T>::append(T::BlockNumber::zero(), idty_index); }: {Pallet::<T>::prune_identities(T::BlockNumber::zero());} impl_benchmark_test_suite!( @@ -326,8 +335,8 @@ benchmarks! { next_creatable_identity_on: 0, old_owner_key: None, owner_key: account("Alice", 1, SEED), - removable_on: 0, - status: crate::IdtyStatus::Validated, + next_scheduled: 0, + status: crate::IdtyStatus::Member, }, }, GenesisIdty { @@ -338,8 +347,8 @@ benchmarks! { next_creatable_identity_on: 0, old_owner_key: None, owner_key: account("Bob", 1, SEED), - removable_on: 0, - status: crate::IdtyStatus::Created, + next_scheduled: 0, + status: crate::IdtyStatus::Unconfirmed, }, }, ]}), diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs index e60ab74ac..dcbf64d3b 100644 --- a/pallets/identity/src/lib.rs +++ b/pallets/identity/src/lib.rs @@ -67,18 +67,32 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { - #[pallet::constant] /// Period during which the owner can confirm the new identity. + // something like 2 days but this should be done quickly as the first certifier is helping + #[pallet::constant] type ConfirmPeriod: Get<Self::BlockNumber>; + /// Period before which the identity has to be validated (become member). + // this is the 2 month period in v1 + #[pallet::constant] + type ValidationPeriod: Get<Self::BlockNumber>; + /// Period before which an identity who lost membership is automatically revoked. + // this is the 1 year period in v1 + #[pallet::constant] + type AutorevocationPeriod: Get<Self::BlockNumber>; + /// Period after which a revoked identity is removed and the keys are freed. #[pallet::constant] + type DeletionPeriod: Get<Self::BlockNumber>; /// Minimum duration between two owner key changes + // to avoid stealing the identity without means to revoke + #[pallet::constant] type ChangeOwnerKeyPeriod: Get<Self::BlockNumber>; + /// Minimum duration between the creation of 2 identities by the same creator + // it should be greater or equal than the certification period in certification pallet + #[pallet::constant] + type IdtyCreationPeriod: Get<Self::BlockNumber>; /// Management of the authorizations of the different calls. /// The default implementation allows everything. type CheckIdtyCallAllowed: CheckIdtyCallAllowed<Self>; - #[pallet::constant] - /// Minimum duration between the creation of 2 identities by the same creator - type IdtyCreationPeriod: Get<Self::BlockNumber>; /// Custom data to store in each identity type IdtyData: Clone + Codec @@ -101,17 +115,12 @@ pub mod pallet { type AccountLinker: LinkIdty<Self::AccountId, Self::IdtyIndex>; /// Handle logic to validate an identity name type IdtyNameValidator: IdtyNameValidator; - /// Additional reasons for identity removal - type IdtyRemovalOtherReason: Clone + Codec + Debug + Eq + TypeInfo; /// On identity confirmed by its owner type OnIdtyChange: OnIdtyChange<Self>; /// Signing key of a payload type Signer: IdentifyAccount<AccountId = Self::AccountId>; /// Signature of a payload type Signature: Parameter + Verify<Signer = Self::Signer>; - /// Handle the logic that removes all identity consumers. - /// "identity consumers" meaning all things that rely on the existence of the identity. - type RemoveIdentityConsumers: RemoveIdentityConsumers<Self::IdtyIndex>; /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>; /// Type representing the weight of this pallet @@ -167,11 +176,8 @@ pub mod pallet { let _ = Pallet::<T>::get_next_idty_index(); // use instead custom provided index let idty_index = idty.index; - if idty.value.removable_on > T::BlockNumber::zero() { - <IdentitiesRemovableOn<T>>::append( - idty.value.removable_on, - (idty_index, idty.value.status), - ) + if idty.value.next_scheduled > T::BlockNumber::zero() { + <IdentityChangeSchedule<T>>::append(idty.value.next_scheduled, idty_index) } <Identities<T>>::insert(idty_index, idty.value.clone()); IdentitiesNames::<T>::insert(idty.name.clone(), idty_index); @@ -215,9 +221,9 @@ pub mod pallet { /// 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> = - StorageMap<_, Twox64Concat, T::BlockNumber, Vec<(T::IdtyIndex, IdtyStatus)>, ValueQuery>; + #[pallet::getter(fn next_scheduled)] + pub type IdentityChangeSchedule<T: Config> = + StorageMap<_, Twox64Concat, T::BlockNumber, Vec<T::IdtyIndex>, ValueQuery>; // HOOKS // @@ -256,10 +262,15 @@ pub mod pallet { idty_index: T::IdtyIndex, new_owner_key: T::AccountId, }, + /// An identity has been revoked. + IdtyRevoked { + idty_index: T::IdtyIndex, + reason: RevocationReason, + }, /// An identity has been removed. IdtyRemoved { idty_index: T::IdtyIndex, - reason: IdtyRemovalReason<T::IdtyRemovalOtherReason>, + reason: RemovalReason, }, } @@ -284,35 +295,18 @@ pub mod pallet { // Verification phase // let who = ensure_signed(origin)?; - let creator = - IdentityIndexOf::<T>::try_get(&who).map_err(|_| Error::<T>::IdtyIndexNotFound)?; - let creator_idty_val = - Identities::<T>::try_get(creator).map_err(|_| Error::<T>::IdtyNotFound)?; - - if IdentityIndexOf::<T>::contains_key(&owner_key) { - return Err(Error::<T>::IdtyAlreadyCreated.into()); - } - - // run checks for identity creation - T::CheckIdtyCallAllowed::check_create_identity(creator)?; - let block_number = frame_system::pallet::Pallet::<T>::block_number(); - - if creator_idty_val.next_creatable_identity_on > block_number { - return Err(Error::<T>::NotRespectIdtyCreationPeriod.into()); - } + let creator_index = Self::check_create_identity(&who, &owner_key, block_number)?; // Apply phase // frame_system::Pallet::<T>::inc_sufficients(&owner_key); - <Identities<T>>::mutate_exists(creator, |idty_val_opt| { + <Identities<T>>::mutate_exists(creator_index, |idty_val_opt| { if let Some(ref mut idty_val) = idty_val_opt { idty_val.next_creatable_identity_on = block_number + T::IdtyCreationPeriod::get(); } }); - let removable_on = block_number + T::ConfirmPeriod::get(); - let idty_index = Self::get_next_idty_index(); <Identities<T>>::insert( idty_index, @@ -321,17 +315,26 @@ pub mod pallet { next_creatable_identity_on: T::BlockNumber::zero(), old_owner_key: None, owner_key: owner_key.clone(), - removable_on, - status: IdtyStatus::Created, + next_scheduled: Self::schedule_identity_change( + idty_index, + T::ConfirmPeriod::get(), + ), + status: IdtyStatus::Unconfirmed, }, ); - IdentitiesRemovableOn::<T>::append(removable_on, (idty_index, IdtyStatus::Created)); + IdentityIndexOf::<T>::insert(owner_key.clone(), idty_index); Self::deposit_event(Event::IdtyCreated { idty_index, owner_key: owner_key.clone(), }); - T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Created { creator, owner_key }); + T::OnIdtyChange::on_idty_change( + idty_index, + &IdtyEvent::Created { + creator: creator_index, + owner_key, + }, + ); Ok(().into()) } @@ -352,10 +355,10 @@ pub mod pallet { let idty_index = IdentityIndexOf::<T>::try_get(&who).map_err(|_| Error::<T>::IdtyIndexNotFound)?; - let mut idty_value = + let idty_value = Identities::<T>::try_get(idty_index).map_err(|_| Error::<T>::IdtyNotFound)?; - if idty_value.status != IdtyStatus::Created { + if idty_value.status != IdtyStatus::Unconfirmed { return Err(Error::<T>::IdtyAlreadyConfirmed.into()); } if !T::IdtyNameValidator::validate(&idty_name) { @@ -364,52 +367,21 @@ pub mod pallet { if <IdentitiesNames<T>>::contains_key(&idty_name) { return Err(Error::<T>::IdtyNameAlreadyExist.into()); } - T::CheckIdtyCallAllowed::check_confirm_identity(idty_index)?; // Apply phase // - idty_value.status = IdtyStatus::ConfirmedByOwner; + Self::update_identity_status( + idty_index, + idty_value, + IdtyStatus::Unvalidated, + T::ValidationPeriod::get(), + ); - <Identities<T>>::insert(idty_index, idty_value); <IdentitiesNames<T>>::insert(idty_name.clone(), idty_index); Self::deposit_event(Event::IdtyConfirmed { idty_index, owner_key: who, name: idty_name, }); - T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Confirmed); - Ok(().into()) - } - - #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::validate_identity())] - /// validate the owned identity (must meet the main wot requirements) - // automatically claim membership if not done - pub fn validate_identity( - origin: OriginFor<T>, - idty_index: T::IdtyIndex, - ) -> DispatchResultWithPostInfo { - // Verification phase // - let _ = ensure_signed(origin)?; - - let mut idty_value = - Identities::<T>::try_get(idty_index).map_err(|_| Error::<T>::IdtyNotFound)?; - - match idty_value.status { - IdtyStatus::Created => return Err(Error::<T>::IdtyNotConfirmedByOwner.into()), - IdtyStatus::ConfirmedByOwner => { - T::CheckIdtyCallAllowed::check_validate_identity(idty_index)?; - } - IdtyStatus::Validated => return Err(Error::<T>::IdtyAlreadyValidated.into()), - } - - // Apply phase // - idty_value.removable_on = T::BlockNumber::zero(); - idty_value.status = IdtyStatus::Validated; - - <Identities<T>>::insert(idty_index, idty_value); - Self::deposit_event(Event::IdtyValidated { idty_index }); - T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Validated); - Ok(().into()) } @@ -440,7 +412,7 @@ pub mod pallet { Error::<T>::OwnerKeyAlreadyUsed ); - T::CheckIdtyCallAllowed::check_change_identity_address(idty_index)?; + T::CheckIdtyCallAllowed::change_owner_key(idty_index)?; let block_number = frame_system::Pallet::<T>::block_number(); let maybe_old_old_owner_key = @@ -486,12 +458,6 @@ pub mod pallet { idty_index, new_owner_key: new_key.clone(), }); - T::OnIdtyChange::on_idty_change( - idty_index, - &IdtyEvent::ChangedOwnerKey { - new_owner_key: new_key, - }, - ); Ok(().into()) } @@ -516,6 +482,14 @@ pub mod pallet { let idty_value = Identities::<T>::get(idty_index).ok_or(Error::<T>::IdtyNotFound)?; + match idty_value.status { + IdtyStatus::Unconfirmed => return Err(Error::<T>::CanNotRevokeUnconfirmed.into()), + IdtyStatus::Unvalidated => return Err(Error::<T>::CanNotRevokeUnvalidated.into()), + IdtyStatus::Member => (), + IdtyStatus::NotMember => (), + IdtyStatus::Revoked => return Err(Error::<T>::AlreadyRevoked.into()), + }; + ensure!( if let Some((ref old_owner_key, last_change)) = idty_value.old_owner_key { // old owner key can also revoke the identity until the period expired @@ -529,9 +503,6 @@ pub mod pallet { Error::<T>::InvalidRevocationKey ); - // make sure that no wot prevents identity removal - T::CheckIdtyCallAllowed::check_remove_identity(idty_index)?; - // then check payload signature let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero()); let revocation_payload = RevocationPayload { @@ -546,26 +517,7 @@ pub mod pallet { ); // finally if all checks pass, remove identity - Self::do_remove_identity(idty_index, IdtyRemovalReason::Revoked); - Ok(().into()) - } - - #[pallet::call_index(5)] - #[pallet::weight(T::WeightInfo::force_remove_identity())] - /// remove an identity from storage - pub fn force_remove_identity( - origin: OriginFor<T>, - idty_index: T::IdtyIndex, - idty_name: Option<IdtyName>, - reason: IdtyRemovalReason<T::IdtyRemovalOtherReason>, - ) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - - Self::do_remove_identity(idty_index, reason); - if let Some(idty_name) = idty_name { - <IdentitiesNames<T>>::remove(idty_name); - } - + Self::do_revoke_identity(idty_index, RevocationReason::User); Ok(().into()) } @@ -655,13 +607,15 @@ pub mod pallet { /// Invalid identity name. IdtyNameInvalid, /// Identity not confirmed by its owner. - IdtyNotConfirmedByOwner, + IdtyNotConfirmed, /// Identity not found. IdtyNotFound, /// Invalid payload signature. InvalidSignature, /// Invalid revocation key. InvalidRevocationKey, + /// Issuer is not member and can not perform this action + IssuerNotMember, /// Identity creation period is not respected. NotRespectIdtyCreationPeriod, /// Owner key already changed recently. @@ -670,60 +624,103 @@ pub mod pallet { OwnerKeyAlreadyUsed, /// Reverting to an old key is prohibited. ProhibitedToRevertToAnOldKey, + /// Already revoked + AlreadyRevoked, + /// Can not revoke identity that never was member + CanNotRevokeUnconfirmed, + /// Can not revoke identity that never was member + CanNotRevokeUnvalidated, } - // PUBLIC FUNCTIONS // + // INTERNAL FUNCTIONS // impl<T: Config> Pallet<T> { + /// get identity count pub fn identities_count() -> u32 { Identities::<T>::count() } - } - // INTERNAL FUNCTIONS // - - impl<T: Config> Pallet<T> { - /// try to validate identity - // (used when membership is claimed first) - pub fn try_validate_identity(idty_index: T::IdtyIndex) { + /// membership added + // when an identity becomes member, update its status + // unschedule identity action, this falls back to membership scheduling + // no identity schedule while membership is active + pub fn membership_added(idty_index: T::IdtyIndex) { if let Some(mut idty_value) = Identities::<T>::get(idty_index) { - // only does something if identity is not yet validated - if idty_value.status != IdtyStatus::Validated { - idty_value.removable_on = T::BlockNumber::zero(); - idty_value.status = IdtyStatus::Validated; + Self::unschedule_identity_change(idty_index, idty_value.next_scheduled); + idty_value.next_scheduled = T::BlockNumber::zero(); + idty_value.status = IdtyStatus::Member; + <Identities<T>>::insert(idty_index, idty_value); + Self::deposit_event(Event::IdtyValidated { idty_index }); + } + // else should not happen + } - <Identities<T>>::insert(idty_index, idty_value); - Self::deposit_event(Event::IdtyValidated { idty_index }); + /// membership removed + // only does something if identity is actually member + // a membership can be removed when the identity is revoked + // in this case, this does nothing + pub fn membership_removed(idty_index: T::IdtyIndex) { + if let Some(idty_value) = Identities::<T>::get(idty_index) { + if idty_value.status == IdtyStatus::Member { + Self::update_identity_status( + idty_index, + idty_value, + IdtyStatus::NotMember, + T::AutorevocationPeriod::get(), + ); } - // already validated, no need to re-validate } + // else should not happen } /// perform identity removal - pub(super) fn do_remove_identity( - idty_index: T::IdtyIndex, - reason: IdtyRemovalReason<T::IdtyRemovalOtherReason>, - ) -> Weight { - if let Some(idty_val) = Identities::<T>::get(idty_index) { - let _ = T::RemoveIdentityConsumers::remove_idty_consumers(idty_index); - IdentityIndexOf::<T>::remove(&idty_val.owner_key); + // (kind of garbage collector) + // this should not be called while the identity is still member + // otherwise there will still be a membership in storage, but no more identity + pub fn do_remove_identity(idty_index: T::IdtyIndex, reason: RemovalReason) -> Weight { + if let Some(idty_value) = Identities::<T>::get(idty_index) { + // this line allows the owner key to be used after that + IdentityIndexOf::<T>::remove(&idty_value.owner_key); // Identity should be removed after the consumers of the identity Identities::<T>::remove(idty_index); - frame_system::Pallet::<T>::dec_sufficients(&idty_val.owner_key); - if let Some((old_owner_key, _last_change)) = idty_val.old_owner_key { + frame_system::Pallet::<T>::dec_sufficients(&idty_value.owner_key); + if let Some((old_owner_key, _last_change)) = idty_value.old_owner_key { frame_system::Pallet::<T>::dec_sufficients(&old_owner_key); } Self::deposit_event(Event::IdtyRemoved { idty_index, reason }); T::OnIdtyChange::on_idty_change( idty_index, &IdtyEvent::Removed { - status: idty_val.status, + status: idty_value.status, }, ); return T::WeightInfo::do_remove_identity(); } T::WeightInfo::do_remove_identity_noop() } + + /// revoke identity + pub fn do_revoke_identity(idty_index: T::IdtyIndex, reason: RevocationReason) -> Weight { + if let Some(idty_value) = Identities::<T>::get(idty_index) { + Self::update_identity_status( + idty_index, + idty_value, + IdtyStatus::Revoked, + T::DeletionPeriod::get(), + ); + + Self::deposit_event(Event::IdtyRevoked { idty_index, reason }); + T::OnIdtyChange::on_idty_change( + idty_index, + &IdtyEvent::Removed { + status: IdtyStatus::Revoked, + }, + ); + return T::WeightInfo::do_revoke_identity(); + } + T::WeightInfo::do_revoke_identity_noop() + } + /// incremental counter for identity index fn get_next_idty_index() -> T::IdtyIndex { if let Ok(next_index) = <NextIdtyIndex<T>>::try_get() { @@ -734,15 +731,35 @@ pub mod pallet { T::IdtyIndex::one() } } - /// remove identities planned for removal at the given block if their status did not change + + /// remove identities planned for removal at the given block pub fn prune_identities(block_number: T::BlockNumber) -> Weight { let mut total_weight = Weight::zero(); - for (idty_index, idty_status) in IdentitiesRemovableOn::<T>::take(block_number) { + for idty_index in IdentityChangeSchedule::<T>::take(block_number) { if let Ok(idty_val) = <Identities<T>>::try_get(idty_index) { - if idty_val.removable_on == block_number && idty_val.status == idty_status { - total_weight += - Self::do_remove_identity(idty_index, IdtyRemovalReason::Expired) + if idty_val.next_scheduled == block_number { + match idty_val.status { + IdtyStatus::Unconfirmed => { + total_weight += + Self::do_remove_identity(idty_index, RemovalReason::Unconfirmed) + } + IdtyStatus::Unvalidated => { + total_weight += + Self::do_remove_identity(idty_index, RemovalReason::Unvalidated) + } + IdtyStatus::Revoked => { + total_weight += + Self::do_remove_identity(idty_index, RemovalReason::Revoked) + } + IdtyStatus::NotMember => { + total_weight += + Self::do_revoke_identity(idty_index, RevocationReason::Expired) + } + IdtyStatus::Member => { // do not touch identities of member accounts + // this should not happen + } + } } else { total_weight += T::WeightInfo::prune_identities_err() .saturating_sub(T::WeightInfo::prune_identities_none()) @@ -761,11 +778,82 @@ pub mod pallet { // call account linker T::AccountLinker::link_identity(account_id, idty_index); } + + /// change identity status and reschedule next action + fn update_identity_status( + idty_index: T::IdtyIndex, + mut idty_value: IdtyValue<T::BlockNumber, T::AccountId, T::IdtyData>, + new_status: IdtyStatus, + period: T::BlockNumber, + ) { + Self::unschedule_identity_change(idty_index, idty_value.next_scheduled); + idty_value.next_scheduled = Self::schedule_identity_change(idty_index, period); + idty_value.status = new_status; + <Identities<T>>::insert(idty_index, idty_value); + } + + /// unschedule identity change + fn unschedule_identity_change(idty_id: T::IdtyIndex, block_number: T::BlockNumber) { + let mut scheduled = IdentityChangeSchedule::<T>::get(block_number); + if let Some(pos) = scheduled.iter().position(|x| *x == idty_id) { + scheduled.swap_remove(pos); + IdentityChangeSchedule::<T>::set(block_number, scheduled); + } + } + /// schedule identity change after given period + fn schedule_identity_change( + idty_id: T::IdtyIndex, + period: T::BlockNumber, + ) -> T::BlockNumber { + let block_number = frame_system::pallet::Pallet::<T>::block_number(); + let next_scheduled = block_number + period; + IdentityChangeSchedule::<T>::append(next_scheduled, idty_id); + next_scheduled + } + + /// check create identity + // first internal checks + // then other pallet checks trough trait + fn check_create_identity( + issuer_key: &T::AccountId, + receiver_key: &T::AccountId, + block_number: T::BlockNumber, + ) -> Result<T::IdtyIndex, DispatchError> { + // first get issuer details + let creator_index = IdentityIndexOf::<T>::try_get(issuer_key) + .map_err(|_| Error::<T>::IdtyIndexNotFound)?; + let creator_idty_val = + Identities::<T>::try_get(creator_index).map_err(|_| Error::<T>::IdtyNotFound)?; + + // --- some checks can be done internally + // 1. issuer is member + ensure!( + creator_idty_val.status == IdtyStatus::Member, + Error::<T>::IssuerNotMember + ); + + // 2. issuer respects identity creation period + ensure!( + creator_idty_val.next_creatable_identity_on <= block_number, + Error::<T>::NotRespectIdtyCreationPeriod + ); + + // 3. receiver key is not already used by another identity + ensure!( + !IdentityIndexOf::<T>::contains_key(receiver_key), + Error::<T>::IdtyAlreadyCreated + ); + + // --- other checks depend on other pallets + // run checks for identity creation + T::CheckIdtyCallAllowed::check_create_identity(creator_index)?; + + Ok(creator_index) + } } } // 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) @@ -773,7 +861,6 @@ impl<T: Config> sp_runtime::traits::Convert<T::IdtyIndex, Option<T::AccountId>> } // implement StoredMap trait for this pallet - impl<T> frame_support::traits::StoredMap<T::AccountId, T::IdtyData> for Pallet<T> where T: Config, diff --git a/pallets/identity/src/mock.rs b/pallets/identity/src/mock.rs index 8311e4aa6..9421a70f0 100644 --- a/pallets/identity/src/mock.rs +++ b/pallets/identity/src/mock.rs @@ -88,9 +88,10 @@ impl system::Config for Test { parameter_types! { pub const ChangeOwnerKeyPeriod: u64 = 10; pub const ConfirmPeriod: u64 = 2; + pub const ValidationPeriod: u64 = 3; + pub const AutorevocationPeriod: u64 = 5; + pub const DeletionPeriod: u64 = 7; pub const IdtyCreationPeriod: u64 = 3; - pub const MaxInactivityPeriod: u64 = 5; - pub const ValidationPeriod: u64 = 2; } pub struct IdtyNameValidatorTestImpl; @@ -103,17 +104,18 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { impl pallet_identity::Config for Test { type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; type ConfirmPeriod = ConfirmPeriod; + type ValidationPeriod = ValidationPeriod; + type AutorevocationPeriod = AutorevocationPeriod; + type DeletionPeriod = DeletionPeriod; type CheckIdtyCallAllowed = (); type IdtyCreationPeriod = IdtyCreationPeriod; type IdtyData = (); type IdtyNameValidator = IdtyNameValidatorTestImpl; type IdtyIndex = u64; type AccountLinker = (); - type IdtyRemovalOtherReason = (); type Signer = AccountPublic; type Signature = Signature; type OnIdtyChange = (); - type RemoveIdentityConsumers = (); type RuntimeEvent = RuntimeEvent; type WeightInfo = (); #[cfg(feature = "runtime-benchmarks")] diff --git a/pallets/identity/src/tests.rs b/pallets/identity/src/tests.rs index f112fa173..7d8c3abc6 100644 --- a/pallets/identity/src/tests.rs +++ b/pallets/identity/src/tests.rs @@ -15,11 +15,7 @@ // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. use crate::mock::*; -use crate::{ - pallet, Error, GenesisIdty, IdtyIndexAccountIdPayload, IdtyName, IdtyRemovalReason, IdtyValue, - RevocationPayload, LINK_IDTY_PAYLOAD_PREFIX, NEW_OWNER_KEY_PAYLOAD_PREFIX, - REVOCATION_PAYLOAD_PREFIX, -}; +use crate::*; use codec::Encode; use frame_support::dispatch::DispatchResultWithPostInfo; use frame_support::{assert_noop, assert_ok}; @@ -58,8 +54,8 @@ fn alice() -> GenesisIdty<Test> { next_creatable_identity_on: 0, old_owner_key: None, owner_key: account(1).id, - removable_on: 0, - status: crate::IdtyStatus::Validated, + next_scheduled: 0, + status: crate::IdtyStatus::Member, }, } } @@ -73,8 +69,8 @@ fn bob() -> GenesisIdty<Test> { next_creatable_identity_on: 0, old_owner_key: None, owner_key: account(2).id, - removable_on: 0, - status: crate::IdtyStatus::Validated, + next_scheduled: 0, + status: crate::IdtyStatus::Member, }, } } @@ -88,8 +84,8 @@ fn inactive_bob() -> GenesisIdty<Test> { next_creatable_identity_on: 0, old_owner_key: None, owner_key: account(2).id, - removable_on: 2, - status: crate::IdtyStatus::Validated, + next_scheduled: 2, + status: crate::IdtyStatus::NotMember, }, } } @@ -112,8 +108,8 @@ fn test_identity_index() { }) .execute_with(|| { assert_eq!(Identity::identities_count(), 2); - // assert_eq!(NextIdtyIndex, 3); // TODO see if we can debug that - // TODO create identity and check it was incremented + // assert_eq!(NextIdtyIndex, 3); // TODO check how to test that + // ... create identity and check it was incremented }); } @@ -154,12 +150,12 @@ fn test_create_identity_but_not_confirm_it() { account(2).id )); - // The identity shoud expire in blocs #3 + // The identity should expire in blocs #3 run_to_block(3); System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved { idty_index: 2, - reason: IdtyRemovalReason::<()>::Expired, + reason: RemovalReason::Unconfirmed, })); // We shoud be able to recreate the identity @@ -304,8 +300,8 @@ fn test_change_owner_key() { next_creatable_identity_on: 0, old_owner_key: Some((account(1).id, 1)), owner_key: account(10).id, - removable_on: 0, - status: crate::IdtyStatus::Validated, + next_scheduled: 0, + status: crate::IdtyStatus::Member, }) ); // Alice still sufficient @@ -364,10 +360,10 @@ fn test_change_owner_key() { .encode() ) )); - // Old owner key should not be sufficient anymore - assert_eq!(System::sufficients(&account(10).id), 0); - // Last owner key should not be sufficient anymore - assert_eq!(System::sufficients(&account(100).id), 0); + // Old owner key is still sufficient (identity is revoked but not removed) + assert_eq!(System::sufficients(&account(10).id), 1); + // Last owner key should still be sufficient (identity is revoked but not removed) + assert_eq!(System::sufficients(&account(100).id), 1); }); } @@ -586,17 +582,23 @@ fn test_idty_revocation() { ) )); - System::assert_has_event(RuntimeEvent::System(frame_system::Event::KilledAccount { - account: account(1).id, - })); - System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved { + // // account is not killed anymore for revoked identity + // System::assert_has_event(RuntimeEvent::System(frame_system::Event::KilledAccount { + // account: account(1).id, + // })); + // // identity is not removed immediately after revocation + // System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved { + // idty_index: 1, + // reason: RemovalReason::Revoked, + // })); + System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRevoked { idty_index: 1, - reason: IdtyRemovalReason::<()>::Revoked, + reason: RevocationReason::User, })); run_to_block(2); - // The identity no longer exists + // The identity can not be revoked multiple times assert_eq!( Identity::revoke_identity( RuntimeOrigin::signed(account(1).id), @@ -607,7 +609,7 @@ fn test_idty_revocation() { (REVOCATION_PAYLOAD_PREFIX, revocation_payload).encode() ) ), - Err(Error::<Test>::IdtyNotFound.into()) + Err(Error::<Test>::AlreadyRevoked.into()) ); }); } @@ -629,16 +631,17 @@ fn test_inactive_genesis_members() { // alice identity remains untouched assert!(pallet::Identities::<Test>::get(alice.index).is_some()); assert!(pallet::IdentityIndexOf::<Test>::get(&alice.value.owner_key).is_some()); - // but bob identity has been removed - assert!(pallet::Identities::<Test>::get(bob.index).is_none()); - assert!(pallet::IdentityIndexOf::<Test>::get(&bob.value.owner_key).is_none()); + // but bob identity has been revoked + assert!(pallet::Identities::<Test>::get(bob.index).is_some()); + assert!(pallet::IdentityIndexOf::<Test>::get(&bob.value.owner_key).is_some()); - System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved { + System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRevoked { idty_index: bob.index, - reason: IdtyRemovalReason::Expired, + reason: RevocationReason::Expired, })); }); } + #[test] fn test_revocation_of_genesis_member() { let alice = alice(); @@ -660,13 +663,13 @@ fn test_revocation_of_genesis_member() { // alice identity remains untouched assert!(pallet::Identities::<Test>::get(alice.index).is_some()); assert!(pallet::IdentityIndexOf::<Test>::get(&alice.value.owner_key).is_some()); - // but bob identity has been removed - assert!(pallet::Identities::<Test>::get(bob.index).is_none()); - assert!(pallet::IdentityIndexOf::<Test>::get(&bob.value.owner_key).is_none()); + // but bob identity has been revoked + assert!(pallet::Identities::<Test>::get(bob.index).is_some()); + assert!(pallet::IdentityIndexOf::<Test>::get(&bob.value.owner_key).is_some()); - System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved { + System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRevoked { idty_index: bob.index, - reason: IdtyRemovalReason::Revoked, + reason: RevocationReason::User, // because called manually by revoke_self_identity })); }); } @@ -689,3 +692,5 @@ fn revoke_self_identity(idty: GenesisIdty<Test>) -> DispatchResultWithPostInfo { ), ) } + +// TODO add tests for all periods (confirmation, validation, autorevocation, deletion) diff --git a/pallets/identity/src/traits.rs b/pallets/identity/src/traits.rs index 536208cd0..a152bd39c 100644 --- a/pallets/identity/src/traits.rs +++ b/pallets/identity/src/traits.rs @@ -20,10 +20,7 @@ use impl_trait_for_tuples::impl_for_tuples; pub trait CheckIdtyCallAllowed<T: Config> { fn check_create_identity(creator: T::IdtyIndex) -> Result<(), DispatchError>; - fn check_confirm_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError>; - fn check_validate_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError>; - fn check_change_identity_address(idty_index: T::IdtyIndex) -> Result<(), DispatchError>; - fn check_remove_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError>; + fn change_owner_key(idty_index: T::IdtyIndex) -> Result<(), DispatchError>; } #[impl_for_tuples(5)] @@ -32,20 +29,8 @@ impl<T: Config> CheckIdtyCallAllowed<T> for Tuple { for_tuples!( #( Tuple::check_create_identity(creator)?; )* ); Ok(()) } - fn check_confirm_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError> { - for_tuples!( #( Tuple::check_confirm_identity(idty_index)?; )* ); - Ok(()) - } - fn check_validate_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError> { - for_tuples!( #( Tuple::check_validate_identity(idty_index)?; )* ); - Ok(()) - } - fn check_change_identity_address(idty_index: T::IdtyIndex) -> Result<(), DispatchError> { - for_tuples!( #( Tuple::check_change_identity_address(idty_index)?; )* ); - Ok(()) - } - fn check_remove_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError> { - for_tuples!( #( Tuple::check_remove_identity(idty_index)?; )* ); + fn change_owner_key(idty_index: T::IdtyIndex) -> Result<(), DispatchError> { + for_tuples!( #( Tuple::change_owner_key(idty_index)?; )* ); Ok(()) } } @@ -66,15 +51,6 @@ impl<T: Config> OnIdtyChange<T> for Tuple { } } -pub trait RemoveIdentityConsumers<IndtyIndex> { - fn remove_idty_consumers(idty_index: IndtyIndex) -> Weight; -} -impl<IndtyIndex> RemoveIdentityConsumers<IndtyIndex> for () { - fn remove_idty_consumers(_: IndtyIndex) -> Weight { - Weight::zero() - } -} - /// trait used to link an account to an identity pub trait LinkIdty<AccountId, IdtyIndex> { fn link_identity(account_id: AccountId, idty_index: IdtyIndex); diff --git a/pallets/identity/src/types.rs b/pallets/identity/src/types.rs index f497ac34d..20120f25c 100644 --- a/pallets/identity/src/types.rs +++ b/pallets/identity/src/types.rs @@ -23,28 +23,44 @@ use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_std::vec::Vec; -/// events related to identity +/// internal events related to identity pub enum IdtyEvent<T: crate::Config> { + /// IdtyEvent::Created /// creation of a new identity by an other + // pallet account links account to identity + // pallet wot adds certification + // pallet quota adds storage item for this identity Created { creator: T::IdtyIndex, owner_key: T::AccountId, }, - /// 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 + /// IdtyEvent::Removed + /// removing an identity (unvalidated or revoked) + // pallet wot removes associated certifications if status is not revoked + // pallet quota removes associated quota Removed { status: IdtyStatus }, + // TODO add a way to unlink accounts corresponding to revoked or removed identities } #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] -pub enum IdtyRemovalReason<OtherReason: TypeInfo + Decode + Encode + Eq + Clone> { +pub enum RevocationReason { + /// revoked by root (e.g. governance or migration) + Root, + /// revoked by user action (revocation document) + User, + /// revoked due to inactive period Expired, - Manual, - Other(OtherReason), +} + +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub enum RemovalReason { + /// removed by root + Root, + /// removed because unconfirmed + Unconfirmed, + /// removed because unvalidated + Unvalidated, + /// removed automatically after revocation buffer Revoked, } @@ -85,20 +101,22 @@ impl<'de> serde::Deserialize<'de> for IdtyName { } /// status of the identity -/// used for temporary period before validation -/// also used for buffer when losing membership before being deleted +// this is a kind of index to tell the state of the identity #[cfg_attr(feature = "std", derive(Deserialize, Serialize))] #[derive(Encode, Decode, Default, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)] pub enum IdtyStatus { - /// created through a first certification + /// created through a first certification but unconfirmed #[default] - Created, - /// confirmed by owner with a name published - ConfirmedByOwner, - /// validated by the main web of trust - Validated, - // disabled by the main web of trust, deletion planned - // Disabled, + Unconfirmed, + /// confirmed by key owner with a name published but unvalidated + Unvalidated, + /// member of the main web of trust + // (there must be a membership in membership pallet storage) + Member, + /// not member of the main web of trust, auto-revocation planned + NotMember, + /// revoked manually or automatically, deletion possible + Revoked, } /// identity value (as in key/value) @@ -114,10 +132,9 @@ pub struct IdtyValue<BlockNumber, AccountId, IdtyData> { 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, + /// next action scheduled on identity + // 0 if no action scheduled + pub next_scheduled: BlockNumber, /// current status of the identity (until validation) pub status: IdtyStatus, } diff --git a/pallets/identity/src/weights.rs b/pallets/identity/src/weights.rs index 729d3a8ef..ee07fdec9 100644 --- a/pallets/identity/src/weights.rs +++ b/pallets/identity/src/weights.rs @@ -18,18 +18,17 @@ use frame_support::weights::{constants::RocksDbWeight, Weight}; -/// Weight functions needed for pallet_universal_dividend. pub trait WeightInfo { fn create_identity() -> Weight; fn confirm_identity() -> Weight; - fn validate_identity() -> Weight; fn change_owner_key() -> Weight; fn revoke_identity() -> Weight; - fn force_remove_identity() -> Weight; fn prune_item_identities_names(i: u32) -> Weight; fn fix_sufficients() -> Weight; fn link_account() -> Weight; fn on_initialize() -> Weight; + fn do_revoke_identity_noop() -> Weight; + fn do_revoke_identity() -> Weight; fn do_remove_identity_noop() -> Weight; fn do_remove_identity() -> Weight; fn prune_identities_noop() -> Weight; @@ -39,183 +38,149 @@ pub trait WeightInfo { // Insecure weights implementation, use it for tests only! impl WeightInfo for () { - // Storage: Identity IdentityIndexOf (r:2 w:1) - // Storage: Identity Identities (r:2 w:2) - // Storage: Cert StorageIdtyCertMeta (r:2 w:2) - // Storage: Parameters ParametersStorage (r:1 w:0) - // Storage: System Account (r:1 w:1) - // Storage: Identity NextIdtyIndex (r:1 w:1) - // Storage: Identity CounterForIdentities (r:1 w:1) - // Storage: Identity IdentitiesRemovableOn (r:1 w:1) - // Storage: Cert StorageCertsRemovableOn (r:1 w:1) - // Storage: Cert CertsByReceiver (r:1 w:1) fn create_identity() -> Weight { - // Minimum execution time: 440_987 nanoseconds. - Weight::from_parts(462_747_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(13 as u64)) - .saturating_add(RocksDbWeight::get().writes(11 as u64)) + // Proof Size summary in bytes: + // Measured: `1165` + // Estimated: `7105` + // Minimum execution time: 1_643_969_000 picoseconds. + Weight::from_parts(1_781_521_000, 0) + .saturating_add(Weight::from_parts(0, 7105)) + .saturating_add(RocksDbWeight::get().reads(14)) + .saturating_add(RocksDbWeight::get().writes(12)) } - // Storage: Identity IdentityIndexOf (r:1 w:0) - // Storage: Identity Identities (r:1 w:1) - // Storage: Identity IdentitiesNames (r:1 w:1) - // Storage: Membership PendingMembership (r:1 w:1) - // Storage: Membership Membership (r:1 w:0) - // Storage: Parameters ParametersStorage (r:1 w:0) - // Storage: Membership PendingMembershipsExpireOn (r:1 w:1) fn confirm_identity() -> Weight { - // Minimum execution time: 186_617 nanoseconds. - Weight::from_parts(309_527_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(7 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) - } - // Storage: Identity Identities (r:1 w:1) - // Storage: Membership Membership (r:1 w:1) - // Storage: Cert StorageIdtyCertMeta (r:1 w:0) - // Storage: Parameters ParametersStorage (r:1 w:0) - // Storage: Membership PendingMembership (r:1 w:1) - // Storage: Membership CounterForMembership (r:1 w:1) - // Storage: Membership MembershipsExpireOn (r:1 w:1) - // Storage: UniversalDividend CurrentUdIndex (r:1 w:0) - fn validate_identity() -> Weight { - // Minimum execution time: 299_920 nanoseconds. - Weight::from_parts(320_025_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(8 as u64)) - .saturating_add(RocksDbWeight::get().writes(5 as u64)) + // Proof Size summary in bytes: + // Measured: `661` + // Estimated: `6601` + // Minimum execution time: 564_892_000 picoseconds. + Weight::from_parts(588_761_000, 0) + .saturating_add(Weight::from_parts(0, 6601)) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(4)) } - // Storage: Identity IdentityIndexOf (r:2 w:2) - // Storage: Identity Identities (r:1 w:1) - // Storage: SmithMembership Membership (r:1 w:0) - // Storage: System BlockHash (r:1 w:0) - // Storage: System Account (r:1 w:1) - // Storage: AuthorityMembers Members (r:1 w:0) fn change_owner_key() -> Weight { - // Minimum execution time: 442_260 nanoseconds. - Weight::from_parts(728_714_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(7 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) + // Proof Size summary in bytes: + // Measured: `837` + // Estimated: `6777` + // Minimum execution time: 991_641_000 picoseconds. + Weight::from_parts(1_071_332_000, 0) + .saturating_add(Weight::from_parts(0, 6777)) + .saturating_add(RocksDbWeight::get().reads(7)) + .saturating_add(RocksDbWeight::get().writes(5)) } - // Storage: Identity Identities (r:1 w:1) - // Storage: SmithMembership Membership (r:1 w:0) - // Storage: System BlockHash (r:1 w:0) - // Storage: Membership Membership (r:1 w:1) - // Storage: Identity CounterForIdentities (r:1 w:1) - // Storage: System Account (r:1 w:1) - // Storage: Cert CertsByReceiver (r:1 w:1) - // Storage: Cert StorageIdtyCertMeta (r:2 w:2) - // Storage: Parameters ParametersStorage (r:1 w:0) - // Storage: Identity IdentityIndexOf (r:0 w:1) fn revoke_identity() -> Weight { - // Minimum execution time: 494_407 nanoseconds. - Weight::from_parts(800_824_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(10 as u64)) - .saturating_add(RocksDbWeight::get().writes(8 as u64)) - } - // Storage: Identity Identities (r:1 w:1) - // Storage: SmithMembership Membership (r:1 w:0) - // Storage: Membership Membership (r:1 w:1) - // Storage: Identity CounterForIdentities (r:1 w:1) - // Storage: System Account (r:1 w:1) - // Storage: Cert CertsByReceiver (r:1 w:1) - // Storage: Cert StorageIdtyCertMeta (r:2 w:2) - // Storage: Parameters ParametersStorage (r:1 w:0) - // Storage: Identity IdentityIndexOf (r:0 w:1) - // Storage: Identity IdentitiesNames (r:0 w:1) - fn force_remove_identity() -> Weight { - // Minimum execution time: 302_574 nanoseconds. - Weight::from_parts(504_132_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(9 as u64)) - .saturating_add(RocksDbWeight::get().writes(9 as u64)) + // Proof Size summary in bytes: + // Measured: `778` + // Estimated: `6718` + // Minimum execution time: 829_174_000 picoseconds. + Weight::from_parts(869_308_000, 0) + .saturating_add(Weight::from_parts(0, 6718)) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(6)) } - // Storage: Identity IdentitiesNames (r:0 w:20) - /// The range of component `i` is `[1, 1000]`. fn prune_item_identities_names(i: u32) -> Weight { - // Minimum execution time: 22_533 nanoseconds. - Weight::from_parts(282_674_421 as u64, 0) - // Standard Error: 170_391 - .saturating_add(Weight::from_parts(5_660_460 as u64, 0).saturating_mul(i as u64)) - .saturating_add(RocksDbWeight::get().writes((1 as u64).saturating_mul(i as u64))) + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 51_362_000 picoseconds. + Weight::from_parts(80_389_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 75_232 + .saturating_add(Weight::from_parts(30_016_649, 0).saturating_mul(i.into())) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - // Storage: System Account (r:1 w:1) fn fix_sufficients() -> Weight { - // Minimum execution time: 112_793 nanoseconds. - Weight::from_parts(122_192_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + // Proof Size summary in bytes: + // Measured: `67` + // Estimated: `3591` + // Minimum execution time: 154_343_000 picoseconds. + Weight::from_parts(156_117_000, 0) + .saturating_add(Weight::from_parts(0, 3591)) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) } - /// Storage: Identity IdentityIndexOf (r:1 w:0) - /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) - /// Storage: System BlockHash (r:1 w:0) - /// Proof: System BlockHash (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) fn link_account() -> Weight { // Proof Size summary in bytes: - // Measured: `359` - // Estimated: `3824` - // Minimum execution time: 543_046_000 picoseconds. - Weight::from_parts(544_513_000, 0) - .saturating_add(Weight::from_parts(0, 3824)) + // Measured: `307` + // Estimated: `3772` + // Minimum execution time: 538_773_000 picoseconds. + Weight::from_parts(591_354_000, 0) + .saturating_add(Weight::from_parts(0, 3772)) .saturating_add(RocksDbWeight::get().reads(3)) .saturating_add(RocksDbWeight::get().writes(1)) } fn on_initialize() -> Weight { // Proof Size summary in bytes: - // Measured: `359` - // Estimated: `3824` - // Minimum execution time: 543_046_000 picoseconds. - Weight::from_parts(544_513_000, 0) - .saturating_add(Weight::from_parts(0, 3824)) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_529_000 picoseconds. + Weight::from_parts(7_360_000, 0).saturating_add(Weight::from_parts(0, 0)) + } + fn do_revoke_identity_noop() -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `3734` + // Minimum execution time: 103_668_000 picoseconds. + Weight::from_parts(107_679_000, 0) + .saturating_add(Weight::from_parts(0, 3734)) + .saturating_add(RocksDbWeight::get().reads(1)) + } + fn do_revoke_identity() -> Weight { + // Proof Size summary in bytes: + // Measured: `1525` + // Estimated: `7465` + // Minimum execution time: 2_204_911_000 picoseconds. + Weight::from_parts(2_225_493_000, 0) + .saturating_add(Weight::from_parts(0, 7465)) + .saturating_add(RocksDbWeight::get().reads(17)) + .saturating_add(RocksDbWeight::get().writes(20)) } fn do_remove_identity_noop() -> Weight { // Proof Size summary in bytes: - // Measured: `359` - // Estimated: `3824` - // Minimum execution time: 543_046_000 picoseconds. - Weight::from_parts(544_513_000, 0) - .saturating_add(Weight::from_parts(0, 3824)) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `269` + // Estimated: `3734` + // Minimum execution time: 104_296_000 picoseconds. + Weight::from_parts(115_316_000, 0) + .saturating_add(Weight::from_parts(0, 3734)) + .saturating_add(RocksDbWeight::get().reads(1)) } fn do_remove_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `359` - // Estimated: `3824` - // Minimum execution time: 543_046_000 picoseconds. - Weight::from_parts(544_513_000, 0) - .saturating_add(Weight::from_parts(0, 3824)) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `1432` + // Estimated: `6192` + // Minimum execution time: 2_870_497_000 picoseconds. + Weight::from_parts(4_159_994_000, 0) + .saturating_add(Weight::from_parts(0, 6192)) + .saturating_add(RocksDbWeight::get().reads(16)) + .saturating_add(RocksDbWeight::get().writes(22)) } fn prune_identities_noop() -> Weight { // Proof Size summary in bytes: - // Measured: `359` - // Estimated: `3824` - // Minimum execution time: 543_046_000 picoseconds. - Weight::from_parts(544_513_000, 0) - .saturating_add(Weight::from_parts(0, 3824)) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `108` + // Estimated: `3573` + // Minimum execution time: 68_859_000 picoseconds. + Weight::from_parts(71_836_000, 0) + .saturating_add(Weight::from_parts(0, 3573)) + .saturating_add(RocksDbWeight::get().reads(1)) } fn prune_identities_none() -> Weight { // Proof Size summary in bytes: - // Measured: `359` - // Estimated: `3824` - // Minimum execution time: 543_046_000 picoseconds. - Weight::from_parts(544_513_000, 0) - .saturating_add(Weight::from_parts(0, 3824)) - .saturating_add(RocksDbWeight::get().reads(3)) + // Measured: `292` + // Estimated: `3757` + // Minimum execution time: 178_332_000 picoseconds. + Weight::from_parts(186_982_000, 0) + .saturating_add(Weight::from_parts(0, 3757)) + .saturating_add(RocksDbWeight::get().reads(2)) .saturating_add(RocksDbWeight::get().writes(1)) } fn prune_identities_err() -> Weight { // Proof Size summary in bytes: - // Measured: `359` - // Estimated: `3824` - // Minimum execution time: 543_046_000 picoseconds. - Weight::from_parts(544_513_000, 0) - .saturating_add(Weight::from_parts(0, 3824)) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `1177` + // Estimated: `4642` + // Minimum execution time: 1_427_848_000 picoseconds. + Weight::from_parts(2_637_229_000, 0) + .saturating_add(Weight::from_parts(0, 4642)) + .saturating_add(RocksDbWeight::get().reads(8)) + .saturating_add(RocksDbWeight::get().writes(8)) } } diff --git a/pallets/membership/README.md b/pallets/membership/README.md index 116b2addd..4bcd6020f 100644 --- a/pallets/membership/README.md +++ b/pallets/membership/README.md @@ -1,25 +1,23 @@ # Duniter membership pallet -Duniter membership is related to duniter Web of Trust and more specific than [parity membership pallet](https://github.com/paritytech/substrate/tree/master/frame/membership). It is used only internally by the identity, WoT, and distance pallets. In particular, it is adding the concept of "pending membership" which is an intermediate state where the identity is waiting to become member. +Duniter membership is related to duniter Web of Trust and more specific than [parity membership pallet](https://github.com/paritytech/substrate/tree/master/frame/membership). It is used only internally by the identity, WoT, and distance pallets. ## Main Web of Trust When used in conjunction with the main Web of Trust, the membership pallet is combined with the Duniter-WoT pallet and the identity pallet, resulting in the following functionality: -- `request_membership` is automatically invoked when confirming identity and should not be called manually. It will add the identity to the pending membership. -- `claim_membership` is automatically triggered during identity validation and should not be manually invoked. This process requires a pending membership, sufficient membership certificates, and a valid distance. Membership is granted upon successful completion of these requirements. +- `claim_membership` requires enough certifications, and a valid distance - `renew_membership` requires a valid membership and a valid distance status to extend the validity period of a membership. -- `revoke_membership` is automatically executed when a membership expires and should not be called manually. +- `revoke_membership` (to be removed?) -In practice, a new user creates an account, confirms identity using the `confirm_identity` call from the identity pallet, and is added to the pending membership. The user then validates it identity using the `validate_identity` call from the identity pallet, triggering a membership claim. If the certification and distance requirements are met, the identity is granted membership. +In practice, a new user creates an account, confirms identity using the `confirm_identity` call from the identity pallet. The user then validates its identity using `claim_membership`. If the certification and distance requirements are met, the identity is granted membership. ## Sub Web of Trust Smith Functionality related to the Smith Web of Trust involves the following: -- `request_membership` requires a validated identity for the member to be added to the pending membership. -- `claim_membership` requires a pending membership, sufficient smith certificates, and a valid distance status for the identity to be included among the authority members. -- `renew_membership` needs a valid membership and a valid distance status to extend the membership's validity period. +- `claim_membership` requires to be member of the main wot and have enough smith certifications +- `renew_membership` needs a valid membership to extend the membership's validity period. - `revoke_membership` requires a valid origin to revoke the membership. -In practice, a user must complete all steps to gain membership in the main Web Of Trust. They can then manually request smith membership using the `request_membership` call of the membership pallet. The membership can be claimed using the `claim_membership` call from the membership pallet, and if the identity meets smith certificate and distance requirements, it will be added to the authority members. \ No newline at end of file +In practice, a user must complete all steps to gain membership in the main Web Of Trust. They can call `claim_membership` to be added to the authority members. diff --git a/pallets/membership/src/benchmarking.rs b/pallets/membership/src/benchmarking.rs index f389dd596..48849bd51 100644 --- a/pallets/membership/src/benchmarking.rs +++ b/pallets/membership/src/benchmarking.rs @@ -19,7 +19,6 @@ use super::*; use frame_benchmarking::benchmarks_instance_pallet; -use frame_support::dispatch::UnfilteredDispatchable; use frame_system::pallet_prelude::BlockNumberFor; use frame_system::RawOrigin; use sp_runtime::traits::{Convert, One}; @@ -38,28 +37,11 @@ benchmarks_instance_pallet! { where T::IdtyId: From<u32>, } - request_membership { - // Dave identity (4) - // for main wot, no constraints - // for smith subwot, his pubkey is hardcoded in default metadata - let idty: T::IdtyId = 4.into(); - Membership::<T, I>::take(idty); - let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap(); - let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); - // Lazily prepare call as this extrinsic will always return an errror when in subwot - let call = Call::<T, I>::request_membership { }; - }: { - call.dispatch_bypass_filter(caller_origin).ok(); - } - verify { - if T::CheckMembershipCallAllowed::check_idty_allowed_to_request_membership(&idty).is_ok() { - assert_has_event::<T, I>(Event::<T, I>::PendingMembershipAdded{member: idty, expire_on: BlockNumberFor::<T>::one() + T::PendingMembershipPeriod::get()}.into()); - } - } + + // claim membership claim_membership { let idty: T::IdtyId = 3.into(); Membership::<T, I>::take(idty); - PendingMembership::<T, I>::insert(idty.clone(), ()); let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap(); let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); T::BenchmarkSetupHandler::force_status_ok(&idty, &caller); @@ -67,6 +49,8 @@ benchmarks_instance_pallet! { verify { assert_has_event::<T, I>(Event::<T, I>::MembershipAdded{member: idty, expire_on: BlockNumberFor::<T>::one() + T::MembershipPeriod::get()}.into()); } + + // renew membership renew_membership { let idty: T::IdtyId = 3.into(); let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap(); @@ -76,6 +60,8 @@ benchmarks_instance_pallet! { verify { assert_has_event::<T, I>(Event::<T, I>::MembershipAdded{member: idty, expire_on: BlockNumberFor::<T>::one() + T::MembershipPeriod::get()}.into()); } + + // revoke membership revoke_membership { let idty: T::IdtyId = 3.into(); let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap(); @@ -84,23 +70,11 @@ benchmarks_instance_pallet! { verify { assert_has_event::<T, I>(Event::<T, I>::MembershipRemoved{member: idty, reason: MembershipRemovalReason::Revoked}.into()); } + // Base weight of an empty initialize on_initialize { }: {Pallet::<T, I>::on_initialize(BlockNumberFor::<T>::zero());} - expire_pending_memberships { - let i in 0..1024; - let mut idties: Vec<T::IdtyId> = Vec::new(); - for j in 0..i { - let j: T::IdtyId = j.into(); - PendingMembership::<T, I>::insert(j, ()); - idties.push(j); - } - PendingMembershipsExpireOn::<T, I>::insert(BlockNumberFor::<T>::zero(), idties); - assert_eq!(PendingMembershipsExpireOn::<T, I>::get(BlockNumberFor::<T>::zero()).len(), i as usize); - }: {Pallet::<T, I>::expire_pending_memberships(BlockNumberFor::<T>::zero());} - verify { - assert_eq!(PendingMembershipsExpireOn::<T, I>::get(BlockNumberFor::<T>::zero()).len(), 0 as usize); - } + expire_memberships { let i in 0..1024; let mut idties: Vec<T::IdtyId> = Vec::new(); diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs index d58257699..4f44e11dc 100644 --- a/pallets/membership/src/lib.rs +++ b/pallets/membership/src/lib.rs @@ -56,8 +56,14 @@ impl<IdtyId, AccountId> SetupBenchmark<IdtyId, AccountId> for () { #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] pub enum MembershipRemovalReason { + // reach end of life Expired, + // was explicitly revoked Revoked, + // received certs count passed below threshold + NotEnoughCerts, + // system reasons (consumers, authority members, or root) + System, } #[frame_support::pallet] @@ -92,9 +98,6 @@ pub mod pallet { type MembershipPeriod: Get<Self::BlockNumber>; /// On event handler type OnEvent: OnEvent<Self::IdtyId>; - #[pallet::constant] - /// Maximum period (in number of blocks), where an identity can remain pending subscription. - type PendingMembershipPeriod: Get<Self::BlockNumber>; /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::RuntimeEvent>; @@ -144,18 +147,6 @@ pub mod pallet { pub type MembershipsExpireOn<T: Config<I>, I: 'static = ()> = StorageMap<_, Twox64Concat, T::BlockNumber, Vec<T::IdtyId>, ValueQuery>; - /// identities with pending membership request - #[pallet::storage] - #[pallet::getter(fn pending_membership)] - pub type PendingMembership<T: Config<I>, I: 'static = ()> = - StorageMap<_, Twox64Concat, T::IdtyId, (), 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 = ()> = - StorageMap<_, Twox64Concat, T::BlockNumber, Vec<T::IdtyId>, ValueQuery>; - // EVENTS // #[pallet::event] @@ -171,13 +162,6 @@ pub mod pallet { member: T::IdtyId, reason: MembershipRemovalReason, }, - /// A pending membership was added. - PendingMembershipAdded { - member: T::IdtyId, - expire_on: BlockNumberFor<T>, - }, - /// A pending membership has expired. - PendingMembershipExpired { member: T::IdtyId }, } // ERRORS// @@ -188,12 +172,8 @@ pub mod pallet { IdtyIdNotFound, /// Membership already acquired. MembershipAlreadyAcquired, - /// Membership already requested. - MembershipAlreadyRequested, /// Membership not found. MembershipNotFound, - /// Membership request not found. - MembershipRequestNotFound, } // HOOKS // @@ -202,9 +182,7 @@ pub mod pallet { impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> { fn on_initialize(n: T::BlockNumber) -> Weight { if n > T::BlockNumber::zero() { - Self::expire_pending_memberships(n) - .saturating_add(Self::expire_memberships(n)) - .saturating_add(T::WeightInfo::on_initialize()) + T::WeightInfo::on_initialize().saturating_add(Self::expire_memberships(n)) } else { T::WeightInfo::on_initialize() } @@ -215,24 +193,9 @@ pub mod pallet { #[pallet::call] impl<T: Config<I>, I: 'static> Pallet<T, I> { - /// submit a membership request (must have a declared identity) - /// (only available for sub wot, automatic for main wot) - #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::request_membership())] - pub fn request_membership(origin: OriginFor<T>) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin)?; - - let idty_id = T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T, I>::IdtyIdNotFound)?; - - T::CheckMembershipCallAllowed::check_idty_allowed_to_request_membership(&idty_id)?; - - Self::do_request_membership(idty_id) - } - /// claim membership - /// a pending membership should exist /// it must fullfill the requirements (certs, distance) - /// for main wot claim_membership is called automatically when validating identity + /// TODO #159 for main wot claim_membership is called automatically when distance is evaluated positively /// for smith wot, it means joining the authority members #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::claim_membership())] @@ -241,7 +204,7 @@ pub mod pallet { let idty_id = Self::get_idty_id(origin)?; Self::check_allowed_to_claim(idty_id)?; - Self::do_claim_membership(idty_id); + Self::do_add_membership(idty_id); Ok(().into()) } @@ -273,7 +236,7 @@ pub mod pallet { let idty_id = Self::get_idty_id(origin)?; // Apply phase - Self::do_revoke_membership(idty_id); + Self::do_remove_membership(idty_id, MembershipRemovalReason::Revoked); Ok(().into()) } @@ -282,33 +245,6 @@ pub mod pallet { // INTERNAL FUNCTIONS // impl<T: Config<I>, I: 'static> Pallet<T, I> { - /// force request membership - pub fn force_request_membership(idty_id: T::IdtyId) -> DispatchResultWithPostInfo { - Self::do_request_membership(idty_id) - } - - /// force expire membership - pub fn force_expire_membership(idty_id: T::IdtyId) -> DispatchResultWithPostInfo { - let new_expire_on = frame_system::pallet::Pallet::<T>::block_number() - + T::PendingMembershipPeriod::get(); - Self::do_expire_membership(idty_id, new_expire_on); - - Ok(().into()) - } - - /// try to claim membership if not already done - pub fn try_claim_membership(idty_id: T::IdtyId) { - if Self::check_allowed_to_claim(idty_id).is_ok() { - Self::do_claim_membership(idty_id); - } - // else { should not try to claim membership if not allowed} - } - - /// force revoke membership - pub fn force_revoke_membership(idty_id: T::IdtyId) { - Self::do_revoke_membership(idty_id); - } - /// unschedule membership expiry fn unschedule_membership_expiry(idty_id: T::IdtyId, block_number: T::BlockNumber) { let mut scheduled = MembershipsExpireOn::<T, I>::get(block_number); @@ -331,76 +267,31 @@ pub mod pallet { }); } - /// perform the membership request - fn do_request_membership(idty_id: T::IdtyId) -> DispatchResultWithPostInfo { - // checks - if PendingMembership::<T, I>::contains_key(idty_id) { - return Err(Error::<T, I>::MembershipAlreadyRequested.into()); - } - if Membership::<T, I>::contains_key(idty_id) { - return Err(Error::<T, I>::MembershipAlreadyAcquired.into()); - } - - let block_number = frame_system::pallet::Pallet::<T>::block_number(); - let expire_on = block_number + T::PendingMembershipPeriod::get(); - - // apply membership request - PendingMembership::<T, I>::insert(idty_id, ()); - PendingMembershipsExpireOn::<T, I>::append(expire_on, idty_id); - Self::deposit_event(Event::PendingMembershipAdded { - member: idty_id, - expire_on, - }); - T::OnEvent::on_event(&sp_membership::Event::PendingMembershipAdded(idty_id)); - - Ok(().into()) - } - /// check that membership can be claimed pub fn check_allowed_to_claim(idty_id: T::IdtyId) -> Result<(), DispatchError> { - PendingMembership::<T, I>::get(idty_id) - .ok_or(Error::<T, I>::MembershipRequestNotFound)?; // enough certifications and distance rule for example T::CheckMembershipCallAllowed::check_idty_allowed_to_claim_membership(&idty_id)?; Ok(()) } - /// perform membership claim - fn do_claim_membership(idty_id: T::IdtyId) { - if PendingMembership::<T, I>::take(idty_id).is_some() { - Self::insert_membership_and_schedule_expiry(idty_id); - T::OnEvent::on_event(&sp_membership::Event::MembershipAdded(idty_id)); - } - // else { unreachable if check_allowed_to_claim called before } + /// perform membership addition + fn do_add_membership(idty_id: T::IdtyId) { + Self::insert_membership_and_schedule_expiry(idty_id); + T::OnEvent::on_event(&sp_membership::Event::MembershipAdded(idty_id)); } - /// perform membership revokation - fn do_revoke_membership(idty_id: T::IdtyId) { + /// perform membership removal + pub fn do_remove_membership(idty_id: T::IdtyId, reason: MembershipRemovalReason) { if let Some(membership_data) = Membership::<T, I>::take(idty_id) { Self::unschedule_membership_expiry(idty_id, membership_data.expire_on); Self::deposit_event(Event::MembershipRemoved { member: idty_id, - reason: MembershipRemovalReason::Revoked, + reason, }); T::OnEvent::on_event(&sp_membership::Event::MembershipRemoved(idty_id)); } } - /// perform membership expiration - // add pending membership and schedule expiry of pending membership - fn do_expire_membership(idty_id: T::IdtyId, expire_on: T::BlockNumber) { - if Membership::<T, I>::take(idty_id).is_some() { - PendingMembership::<T, I>::insert(idty_id, ()); - PendingMembershipsExpireOn::<T, I>::append(expire_on, idty_id); - } // else should not happen - - Self::deposit_event(Event::MembershipRemoved { - member: idty_id, - reason: MembershipRemovalReason::Expired, - }); - T::OnEvent::on_event(&sp_membership::Event::MembershipRemoved(idty_id)); - } - /// check the origin and get identity id if valid fn get_idty_id(origin: OriginFor<T>) -> Result<T::IdtyId, DispatchError> { if let Ok(RawOrigin::Signed(account_id)) = origin.into() { @@ -409,36 +300,21 @@ pub mod pallet { Err(BadOrigin.into()) } } + /// perform the membership expiry scheduled at given block - // MembershipExpired events should be handeled by main wot and delete identity - // expired membership get back to pending membership pub fn expire_memberships(block_number: T::BlockNumber) -> Weight { let mut expired_idty_count = 0u32; - let new_expire_on = block_number + T::PendingMembershipPeriod::get(); for idty_id in MembershipsExpireOn::<T, I>::take(block_number) { // remove membership (take) - Self::do_expire_membership(idty_id, new_expire_on); + Self::do_remove_membership(idty_id, MembershipRemovalReason::Expired); expired_idty_count = 0; } T::WeightInfo::expire_memberships(expired_idty_count) } - /// perform the expiration of pending membership planned at given block - // only expire pending membership if still pending - pub fn expire_pending_memberships(block_number: T::BlockNumber) -> Weight { - let mut expired_idty_count = 0u32; - for idty_id in PendingMembershipsExpireOn::<T, I>::take(block_number) { - if PendingMembership::<T, I>::take(idty_id).is_some() { - Self::deposit_event(Event::PendingMembershipExpired { member: idty_id }); - T::OnEvent::on_event(&sp_membership::Event::PendingMembershipExpired(idty_id)); - expired_idty_count = 0; - } - } - T::WeightInfo::expire_pending_memberships(expired_idty_count) - } /// check if identity is member - pub(super) fn do_is_member(idty_id: &T::IdtyId) -> bool { + pub(super) fn is_member(idty_id: &T::IdtyId) -> bool { Membership::<T, I>::contains_key(idty_id) } } @@ -446,15 +322,9 @@ pub mod pallet { // 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) - } -} - impl<T: Config<I>, I: 'static> sp_runtime::traits::IsMember<T::IdtyId> for Pallet<T, I> { fn is_member(idty_id: &T::IdtyId) -> bool { - Self::do_is_member(idty_id) + Self::is_member(idty_id) } } diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs index 74f44e85b..5173ff716 100644 --- a/pallets/membership/src/mock.rs +++ b/pallets/membership/src/mock.rs @@ -89,7 +89,6 @@ impl pallet_membership::Config for Test { type AccountIdOf = ConvertInto; type MembershipPeriod = MembershipPeriod; type OnEvent = (); - type PendingMembershipPeriod = PendingMembershipPeriod; type RuntimeEvent = RuntimeEvent; type WeightInfo = (); #[cfg(feature = "runtime-benchmarks")] diff --git a/pallets/membership/src/tests.rs b/pallets/membership/src/tests.rs index dfdd12bc3..d3ea56167 100644 --- a/pallets/membership/src/tests.rs +++ b/pallets/membership/src/tests.rs @@ -21,7 +21,6 @@ use frame_support::{assert_noop, assert_ok}; use maplit::btreemap; use sp_membership::traits::*; use sp_membership::MembershipData; -use sp_runtime::traits::IsMember; // alias type RtEvent = RuntimeEvent; @@ -49,32 +48,8 @@ fn test_genesis_build() { }); } -#[test] -fn test_membership_already_acquired() { - new_test_ext(default_gen_conf()).execute_with(|| { - run_to_block(1); - // Membership 0 cannot be reclaimed because there is no membership request - assert_noop!( - DefaultMembership::claim_membership(RuntimeOrigin::signed(0)), - Error::<Test, _>::MembershipRequestNotFound - ); - }); -} - -#[test] -fn test_membership_request_not_found() { - new_test_ext(default_gen_conf()).execute_with(|| { - run_to_block(1); - // Membership 0 cannot be reclaimed - assert_noop!( - DefaultMembership::claim_membership(RuntimeOrigin::signed(1)), - Error::<Test, _>::MembershipRequestNotFound - ); - }); -} - /// test membership expiration -// membership should be moved to pending membership and expire after +// membership should expire #[test] fn test_membership_expiration() { new_test_ext(default_gen_conf()).execute_with(|| { @@ -88,11 +63,6 @@ fn test_membership_expiration() { member: 0, reason: MembershipRemovalReason::Expired, })); - // it should be added to pending membership and expire on block #6 - run_to_block(6); - System::assert_has_event(RtEvent::DefaultMembership( - Event::PendingMembershipExpired { member: 0 }, - )); }); } @@ -156,64 +126,27 @@ fn test_membership_revocation() { member: 0, reason: MembershipRemovalReason::Revoked, })); + assert_eq!(DefaultMembership::membership(0), None); - // Membership 0 can re-request membership + // Membership 0 can re-claim membership run_to_block(5); - assert_ok!(DefaultMembership::request_membership( - RuntimeOrigin::signed(0), - )); - System::assert_has_event(RtEvent::DefaultMembership(Event::PendingMembershipAdded { + assert_ok!(DefaultMembership::claim_membership(RuntimeOrigin::signed( + 0 + ),)); + System::assert_has_event(RtEvent::DefaultMembership(Event::MembershipAdded { member: 0, - expire_on: 5 + <Test as crate::Config>::PendingMembershipPeriod::get(), + expire_on: 5 + <Test as crate::Config>::MembershipPeriod::get(), })); }); } -/// test pending membership expiration -#[test] -fn test_pending_membership_expiration() { - new_test_ext(Default::default()).execute_with(|| { - // Idty 0 request membership - run_to_block(1); - assert_ok!(DefaultMembership::request_membership( - RuntimeOrigin::signed(0), - )); - System::assert_has_event(RtEvent::DefaultMembership(Event::PendingMembershipAdded { - member: 0, - expire_on: 1 + <Test as crate::Config>::PendingMembershipPeriod::get(), - })); - - // Then, idty 0 shold still in pending memberships until PendingMembershipPeriod ended - run_to_block(PendingMembershipPeriod::get()); - assert!(DefaultMembership::is_in_pending_memberships(0)); - - // Then, idty 0 request should expire after PendingMembershipPeriod - run_to_block(1 + PendingMembershipPeriod::get()); - assert!(!DefaultMembership::is_in_pending_memberships(0)); - System::assert_has_event(RtEvent::DefaultMembership( - Event::PendingMembershipExpired { member: 0 }, - )); - }) -} - /// test membership workflow -// - request membership // - claim membership // - renew membership // - membership expiry #[test] fn test_membership_workflow() { new_test_ext(Default::default()).execute_with(|| { - // - Idty 0 request membership - run_to_block(1); - assert_ok!(DefaultMembership::request_membership( - RuntimeOrigin::signed(0), - )); - System::assert_has_event(RtEvent::DefaultMembership(Event::PendingMembershipAdded { - member: 0, - expire_on: 1 + <Test as crate::Config>::PendingMembershipPeriod::get(), - })); - // - Then, idty 0 claim membership run_to_block(2); assert_ok!(DefaultMembership::claim_membership(RuntimeOrigin::signed( diff --git a/pallets/membership/src/weights.rs b/pallets/membership/src/weights.rs index 253c1fc92..e244e83b7 100644 --- a/pallets/membership/src/weights.rs +++ b/pallets/membership/src/weights.rs @@ -20,75 +20,65 @@ use frame_support::weights::{constants::RocksDbWeight, Weight}; /// Weight functions needed for pallet_universal_dividend. pub trait WeightInfo { - fn request_membership() -> Weight; fn claim_membership() -> Weight; fn renew_membership() -> Weight; fn revoke_membership() -> Weight; fn on_initialize() -> Weight; - fn expire_pending_memberships(_i: u32) -> Weight; fn expire_memberships(_i: u32) -> Weight; } // Insecure weights implementation, use it for tests only! impl WeightInfo for () { - // Storage: Identity IdentityIndexOf (r:1 w:0) - // Storage: Identity Identities (r:1 w:0) - fn request_membership() -> Weight { - // Minimum execution time: 48_477 nanoseconds. - Weight::from_parts(50_689_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(2 as u64)) - } - // Storage: Identity IdentityIndexOf (r:1 w:0) - // Storage: Membership Membership (r:1 w:1) - // Storage: Cert StorageIdtyCertMeta (r:1 w:0) - // Storage: Parameters ParametersStorage (r:1 w:0) - // Storage: Membership PendingMembership (r:1 w:1) - // Storage: Membership CounterForMembership (r:1 w:1) - // Storage: Membership MembershipsExpireOn (r:1 w:1) fn claim_membership() -> Weight { - // Minimum execution time: 144_079 nanoseconds. - Weight::from_parts(146_565_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(7 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) + // Proof Size summary in bytes: + // Measured: `1272` + // Estimated: `4737` + // Minimum execution time: 1_213_348_000 picoseconds. + Weight::from_parts(1_439_442_000, 0) + .saturating_add(Weight::from_parts(0, 4737)) + .saturating_add(RocksDbWeight::get().reads(10)) + .saturating_add(RocksDbWeight::get().writes(4)) } - // Storage: Identity IdentityIndexOf (r:1 w:0) - // Storage: Membership Membership (r:1 w:1) - // Storage: Identity Identities (r:1 w:0) - // Storage: Parameters ParametersStorage (r:1 w:0) - // Storage: Membership MembershipsExpireOn (r:1 w:1) fn renew_membership() -> Weight { - // Minimum execution time: 120_859 nanoseconds. - Weight::from_parts(124_222_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(2 as u64)) + // Proof Size summary in bytes: + // Measured: `988` + // Estimated: `6928` + // Minimum execution time: 714_537_000 picoseconds. + Weight::from_parts(862_085_000, 0) + .saturating_add(Weight::from_parts(0, 6928)) + .saturating_add(RocksDbWeight::get().reads(7)) + .saturating_add(RocksDbWeight::get().writes(3)) } - // Storage: Identity IdentityIndexOf (r:1 w:0) - // Storage: Membership Membership (r:1 w:1) - // Storage: Membership CounterForMembership (r:1 w:1) - // Storage: Identity Identities (r:1 w:0) - // Storage: UniversalDividend CurrentUdIndex (r:1 w:0) fn revoke_membership() -> Weight { - // Minimum execution time: 109_486 nanoseconds. - Weight::from_parts(113_303_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(2 as u64)) + // Proof Size summary in bytes: + // Measured: `703` + // Estimated: `6643` + // Minimum execution time: 847_926_000 picoseconds. + Weight::from_parts(1_282_028_000, 0) + .saturating_add(Weight::from_parts(0, 6643)) + .saturating_add(RocksDbWeight::get().reads(8)) + .saturating_add(RocksDbWeight::get().writes(5)) } fn on_initialize() -> Weight { - // Minimum execution time: 109_486 nanoseconds. - Weight::from_parts(113_303_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(2 as u64)) - } - fn expire_pending_memberships(_i: u32) -> Weight { - // Minimum execution time: 109_486 nanoseconds. - Weight::from_parts(113_303_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(2 as u64)) + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_012_000 picoseconds. + Weight::from_parts(4_629_000, 0).saturating_add(Weight::from_parts(0, 0)) } - fn expire_memberships(_i: u32) -> Weight { - // Minimum execution time: 109_486 nanoseconds. - Weight::from_parts(113_303_000 as u64, 0) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(2 as u64)) + fn expire_memberships(i: u32) -> Weight { + // Proof Size summary in bytes: + // Measured: `567 + i * (23 ±0)` + // Estimated: `6583 + i * (2499 ±0)` + // Minimum execution time: 86_925_000 picoseconds. + Weight::from_parts(89_056_000, 0) + .saturating_add(Weight::from_parts(0, 6583)) + // Standard Error: 2_429_589 + .saturating_add(Weight::from_parts(295_368_241, 0).saturating_mul(i.into())) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(i.into()))) + .saturating_add(RocksDbWeight::get().writes(5)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into()))) + .saturating_add(Weight::from_parts(0, 2499).saturating_mul(i.into())) } } diff --git a/pallets/quota/src/lib.rs b/pallets/quota/src/lib.rs index f3a579cb2..e618281ea 100644 --- a/pallets/quota/src/lib.rs +++ b/pallets/quota/src/lib.rs @@ -354,7 +354,6 @@ impl<T: Config> pallet_identity::traits::OnIdtyChange<T> for Pallet<T> { IdtyEvent::Removed { .. } => { IdtyQuota::<T>::remove(idty_id); } - IdtyEvent::Confirmed | IdtyEvent::Validated | IdtyEvent::ChangedOwnerKey { .. } => {} } } } diff --git a/pallets/quota/src/mock.rs b/pallets/quota/src/mock.rs index 266f31a08..d023eebee 100644 --- a/pallets/quota/src/mock.rs +++ b/pallets/quota/src/mock.rs @@ -136,9 +136,10 @@ impl pallet_balances::Config for Test { parameter_types! { pub const ChangeOwnerKeyPeriod: u64 = 10; pub const ConfirmPeriod: u64 = 2; + pub const ValidationPeriod: u64 = 3; + pub const AutorevocationPeriod: u64 = 5; + pub const DeletionPeriod: u64 = 7; pub const IdtyCreationPeriod: u64 = 3; - pub const MaxInactivityPeriod: u64 = 5; - pub const ValidationPeriod: u64 = 2; } pub struct IdtyNameValidatorTestImpl; impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { @@ -149,17 +150,18 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { impl pallet_identity::Config for Test { type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; type ConfirmPeriod = ConfirmPeriod; + type ValidationPeriod = ValidationPeriod; + type AutorevocationPeriod = AutorevocationPeriod; + type DeletionPeriod = DeletionPeriod; type CheckIdtyCallAllowed = (); type IdtyCreationPeriod = IdtyCreationPeriod; type IdtyData = (); type IdtyNameValidator = IdtyNameValidatorTestImpl; type IdtyIndex = u64; type AccountLinker = (); - type IdtyRemovalOtherReason = (); type Signer = AccountPublic; type Signature = Signature; type OnIdtyChange = (); - type RemoveIdentityConsumers = (); type RuntimeEvent = RuntimeEvent; type WeightInfo = (); #[cfg(feature = "runtime-benchmarks")] diff --git a/pallets/universal-dividend/src/benchmarking.rs b/pallets/universal-dividend/src/benchmarking.rs index 99a392937..5786d2ee0 100644 --- a/pallets/universal-dividend/src/benchmarking.rs +++ b/pallets/universal-dividend/src/benchmarking.rs @@ -111,7 +111,7 @@ benchmarks! { }: {Pallet::<T>::on_removed_member(CurrentUdIndex::<T>::get() - i as u16, &caller);} verify { if i != 0 { - assert_has_event::<T>(Event::<T>::UdsAutoPaidAtRemoval {count: i as u16, total: uds_total, who: caller}.into()); + assert_has_event::<T>(Event::<T>::UdsAutoPaid {count: i as u16, total: uds_total, who: caller}.into()); } } diff --git a/pallets/universal-dividend/src/lib.rs b/pallets/universal-dividend/src/lib.rs index 09ba8511d..b41e4b245 100644 --- a/pallets/universal-dividend/src/lib.rs +++ b/pallets/universal-dividend/src/lib.rs @@ -236,7 +236,7 @@ pub mod pallet { members_count: BalanceOf<T>, }, /// DUs were automatically transferred as part of a member removal. - UdsAutoPaidAtRemoval { + UdsAutoPaid { count: UdIndex, total: BalanceOf<T>, who: T::AccountId, @@ -442,7 +442,7 @@ pub mod pallet { PastReevals::<T>::get().into_iter(), ); T::Currency::deposit_creating(who, uds_total); - Self::deposit_event(Event::UdsAutoPaidAtRemoval { + Self::deposit_event(Event::UdsAutoPaid { count: uds_count, total: uds_total, who: who.clone(), diff --git a/primitives/membership/Cargo.toml b/primitives/membership/Cargo.toml index f1142e3df..d0f391814 100644 --- a/primitives/membership/Cargo.toml +++ b/primitives/membership/Cargo.toml @@ -22,6 +22,9 @@ try-runtime = ['frame-support/try-runtime'] [dependencies] +# crates.io +impl-trait-for-tuples = "0.2.1" + # substrate scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } diff --git a/primitives/membership/src/lib.rs b/primitives/membership/src/lib.rs index fa5b992f9..897bf64ff 100644 --- a/primitives/membership/src/lib.rs +++ b/primitives/membership/src/lib.rs @@ -27,6 +27,7 @@ use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; +/// membership events pub enum Event<IdtyId> { /// A membership was acquired. MembershipAdded(IdtyId), @@ -34,10 +35,6 @@ pub enum Event<IdtyId> { MembershipRemoved(IdtyId), /// A membership was renewed. MembershipRenewed(IdtyId), - /// A pending membership request was added. - PendingMembershipAdded(IdtyId), - /// A pending membership request has expired. - PendingMembershipExpired(IdtyId), } #[cfg_attr(feature = "std", derive(Deserialize, Serialize))] @@ -45,3 +42,15 @@ pub enum Event<IdtyId> { pub struct MembershipData<BlockNumber: Decode + Encode + TypeInfo> { pub expire_on: BlockNumber, } + +use impl_trait_for_tuples::impl_for_tuples; +// use sp_std::prelude::*; +// use frame_support::pallet_prelude::*; +// use frame_system::pallet_prelude::*; + +#[impl_for_tuples(5)] +impl<IdtyId> traits::OnEvent<IdtyId> for Tuple { + fn on_event(event: &Event<IdtyId>) { + for_tuples!( #( Tuple::on_event(event); )* ); + } +} diff --git a/primitives/membership/src/traits.rs b/primitives/membership/src/traits.rs index 28d0c52de..abb5961cd 100644 --- a/primitives/membership/src/traits.rs +++ b/primitives/membership/src/traits.rs @@ -19,7 +19,6 @@ use frame_support::pallet_prelude::*; pub trait CheckMembershipCallAllowed<IdtyId> { fn check_idty_allowed_to_claim_membership(idty_id: &IdtyId) -> Result<(), DispatchError>; fn check_idty_allowed_to_renew_membership(idty_id: &IdtyId) -> Result<(), DispatchError>; - fn check_idty_allowed_to_request_membership(idty_id: &IdtyId) -> Result<(), DispatchError>; } impl<IdtyId> CheckMembershipCallAllowed<IdtyId> for () { @@ -29,33 +28,16 @@ impl<IdtyId> CheckMembershipCallAllowed<IdtyId> for () { fn check_idty_allowed_to_renew_membership(_: &IdtyId) -> Result<(), DispatchError> { Ok(()) } - fn check_idty_allowed_to_request_membership(_: &IdtyId) -> Result<(), DispatchError> { - Ok(()) - } -} - -pub trait IsInPendingMemberships<IdtyId> { - fn is_in_pending_memberships(idty_id: IdtyId) -> bool; } pub trait OnEvent<IdtyId> { fn on_event(event: &crate::Event<IdtyId>); } -impl<IdtyId> OnEvent<IdtyId> for () { - fn on_event(_: &crate::Event<IdtyId>) {} -} +// impl<IdtyId> OnEvent<IdtyId> for () { +// fn on_event(_: &crate::Event<IdtyId>) {} +// } pub trait MembersCount { fn members_count() -> u32; } - -pub trait Validate<AccountId> { - fn validate(&self, account_id: &AccountId) -> bool; -} - -impl<AccountId> Validate<AccountId> for () { - fn validate(&self, _account_id: &AccountId) -> bool { - true - } -} diff --git a/resources/metadata.scale b/resources/metadata.scale index fb9903cdcd8ab7a3f169487e4becee25afdc7d8c..60cf370fe64aecd0dc9bbdd157c56e90b5653228 100644 GIT binary patch delta 5469 zcmeHLe^gZ0oxh*^?kFhWpb|kq2O|h7L<|}+sGwrBiXw>7R>jB6LnbmaFh7W-QA2mF zF>0fI$K0A|T6@->*wjSM#6H~<H+qa4*_Je%=vJC&8oMMlDG|@cv$~1h{k}IdKyCX+ z{@Q=`91e5u_kMrfd%r(E_jUas?wy@+Lp)kgO)6|3a&vaV)EZZyEEM!rs%}?!*rU$? zso~uv2cWe0HtX{iI?_}9ni}wVQ-IPct;Oe5gKnR<%A)B{%}pOde4493Pn%mfDh(*A z(mcKvwK2lLZ2Hr4e_r@kf(!}vDxWXN7_-*|G(Q8&DBsfL_G>Q28B5cX=B1Y3rwaC% z$kZCI)90;s`#r=CMpH8AcBw&2I>YpmTw)4inb7;LkJW!!l!Q24DZQv~t=X*KDSK$T zz26*T{Q_XKmivO`USDWa!vf7843ICW)vbY`=3z>B&U}{`&=Qu5pUXm`KH-UNxUC;~ z;zjyjvROlX_@|r4#*332XY{g`b$Ui<98T-cH`nSfhBCw%j*}MoftE?=)aSPB<Xv2c zr&iB-a)P)V6MBUv-7(h5Tk^!m9Nm^&cuS7x;W%bZid!>yFW1`|H|Qr@#|xVhQ64UO zs^M{Dgb#Nm^6<Dzaf*KFw-eDGzWdu`K9n(@40ck#c|A8Lq14%^x;?cX%~PlO0}bvb z2783&7@&oxeGmpe&GoYRnc-7CBRN0A<whS;^@5K=IH#}peTshiqXRe>Uh(@JPK1{0 z1?d+!rmfbTC6$`L&fVBJm$3_Uue^h^4*jj`57FMgsRMLQ{SI8_y85m3@TZ@S8G`Qc z|Mb4jaW(vUpDPYm_1F7y!n5!08HTI!9R-u{vAn6^*XWUN3arHqIWG<KjWsrWG72{g zniO#&2GcRgJj#`;$H+I*k%n8wyXhD)gnqAOA;584R!zje<CY}ygT}IKY**rMnLFwR zyDcx}A{Te%y<E)V_qco{4;2CmlIfPphOPFwt)RZk^>I8^ex8T<CezBb7$xUVMq>(; zxQswkt<&e%>=rW^vl-_nqkJgh<-SrB%GuK~a#$h-H17mUR`hct(~aio_&JbbGCUy9 zR%7C%G(}W1CRnC|RP*px(XpqIkchjDRHBkNO|v2@Un|1UlI%g8+2*=nd5TC~(PZYh z5UY@{AkMzr=he(it@e2|!SacZJj|E3itsS`mOX<`xmZ@rz*J?90*Oa328#Tm2;*gV z2G)(5p-?RN>#N<HylODyCsi}#gqf%$AySbcpPz{u>7R*AQ&jyM>}4`U3n;f7&sh@P zWyK)hmsq<@wX+Iy6Es_C6wCtWs4)s><3j~&<-WN{l{s^<HhH~*-103!zq+VV-4tMK zy}34Nq^iIkDx5xxF_o0qhB9s7Xj9x#qs@bix+6NL&BL-Jj{+(qW}PI3p2)&a=V3y8 zv+0mqVIj-;l-8)8t%LNmM%bs6VqN@Jlf6}8Z4vezQTAPf*mp$OzbHj<{4SGyhr;$6 z)5?&bV85KR5R(%IwsJs`<6bt;cp)4(Xq;FG7sp|F_A!c?DUV?}jzkO{jT$;O$k0)f zZEO57)5cMS9hWaHM!HlNqZsW5jki&Sl4F;mIp;L7h`3Wl?2O5KPGR&%1eVX)1#8ry z6tNE3z7$h<r=pimNi+UyDV6|TvaA9x;Ih0@0T;UEoaLB7Km8#sk1xkaTs6)v$5Mq- zxql)3N+i^K2Kn1#8o$DBNVN(DBYPDV$F@?SvR(yZ75&H~RcN6UPOZi~O6WD!SV^;( z%9%upjVDgJ6+Mr;gY@4u_1{w1J!?yL$^xP16{O3+D!e<wCK9GLsf~?Vur?5K`D9lc zrMI&N-=Y+Ltp@K7PZZ{nIP5H0$o-|5X5}<ejDK5=QqI$g6sln9k;aRONezK!=e z&yK9+=84Fj^Tj}V=UH0gDZTS)#A#Y6^yiBw%HOqNm|V9Wr!hl5umO`%D$6$DpSQaf zx&uMg>(t7rXNIg^Ua5IqZto_hh(E;^9a{gYqd^Tg>NL&k@N3N>jhdm$Q5On2+yO@* zNTuD;6cOJNlO0e@&9o{e!-RN+I3`)P?^o~j1@AK<zuJHYVUy!)>5_)X=32V{q2iEi zuSc4^Qj6(`lfyTnicWWf`7=zmZ$ue}%Y8v)jV@Ud2!u30*{`r#8%q#<GGE1v%t%`+ zSZKEQRldPEB2j!O+f+Q56B+;)4!2A52HnBdq6mKsStN;zCU2I5&cwnR{fyI=xPq-@ zcabmTb+Hk$N5%8JSm-0>jgfon@X+u%f~CSvSVf&9->JhQl*uF~<~%aXt8JmsaW-hK zP^0FuW9s}ypL6r_klC6UQt8ryp}-P>T+>3eHDhd!e8vg)!)0P{%`PXHa$n6Zr{JJe zFn=g5?QDtVQRQG=82uNpiv1<50!xh^C1(={&Q%!zPo%m+wz)77i;bVTs3jzqM$ckF z46Df=4X-Z#tIHWC-izFq8B=B`L@vppdR-2u>a|Esn!n!X_c($L#G^XR_9XY!V;tT1 z>-AWM1o?G6W+PEPvWc2VlJspt?)F(_jf7oYt+8txAxff@*uAY=pn7RH5r)ChU>9%D zl4Uw_#r-!-E~r6=S8LJyjwdNKBF^5Y$ikyDEI^w44K>NGRcOLW8P|ZNyhfP#Rr(r` zL|fd}0B6eL$UT^7tv}AV>}$aoDeBO~*9yW(56FZk;OFbj@p$9MPv8x3Rp<qaQl+O6 zGoi_UYQ!^Wli40D;##D@jCV&1%+^5##%+a+-6N>0z3IWEB!X}W$Ox#OrbaE$EN^-6 z9o`(RUWYx1%WWMb9kQf5xSh4qh|_ed`AbUMERhs>-i!RHI|POMD!-;xYe5UO>=42c zBbYFR!j>H*xW#rwEiLm=U)XEZ`cTcO>-~R)`@gMl2flfn9vl>#!wy?<LYI8R*xw3p z9F_Wa@d}Q~lBbc&k410&g{Lu!9~VFTBGowmG;|T)Zbs8d!A{EBHq`LbLiQ<`Ag{FH z)r2#a&T}G_or{R4T!_YZ$DjzkATNCn`$u<}iY^G&X$f_aP*+swa#W~$kkDoMFaLmT z@!h7-Wx=i*<^KrD`Nx7D5NYy|3-K@P#6fy<ytos)_>Dm^%X@`>_WC%v^I6yleEjHH zWb@lXzV$5f_+4Rq_AG6h-xGQlA1z;b4lA-?qf;rO$fp4l4x26BmS{`1rPwlUdA58T zv&qkQW2~IM8`G#4TH~#|F@-9jH9o)Fti<NHMAq#l_%?qJa)zhbkWlVd>2+W;Eg3ua z;E<hX+GP7e0?Bg@BYjAgX*XMLI83-POKv9;vgJ#MsbS?sG=FWb<QthU<Ln5saP2rj zofISQHN2|O@8x#91QKix)1xcT_*EEV1+}_Q3_L|Y>M0yTx$);ys1#UftT=;sE^3th zkm_4-$)CJTo&UmH_*Z4E@)MIZ$vAly4=Yr*Zk)#+gk;Ox1VY>7iMNrDHsjjcIIdu? z+;b6gsTlm~A~m4{M&CscdOIjT`!&WB<Q>*YCv?Pkv=hGoj>|v3ivZf?y5C?Eq1d;7 zgCI^D#qVJoaK<>*g-+mt{Qmo>9M`ENWjyAmX4Ir2Hb@<9c3=&xOMdx2xpLVkxP;+0 zLaMX7(ZUI-wtqmV<c1U<;st(BF%Er*#{tMMuM(!S$raa7Lf5tD8j43Giey27g#8?M z7`^8%U84e>CWn7SzGNEDeFU8j(irzKHiE8T`*rL>hY|k=905JPUi}Yv2;rsmAP2=p zX%DKAxn@ZewJc~*y_>Y^D5d~}&3;0j_ynuzl81hZs_mt#Bi~J^o6<ww?Q_}fvo<C& zkp@R(PN<C9uI6~M!R>6I&ZiBuK@%1ReZ=6fnw{C}9JzIxlirBYo|soqX?|ET`)A~% zQOrhVStS$2aBTluMyTt?P#2l?IU0R|7$Puxo{14u(&{1T>Lk3~8f)bRvleQEz6Wi^ zv3G(ZvirB9)(6d&ZS6$0qzdRO(SR{h>^Hw%5zRy%=4Ll*tz?b%Ur)WsCD(jPeY8R* z{t;;-6LJUoFg*lp_LVZ}7CsmX`tp+rA>X@!jr9DKzxa$2aIL)b8Gc3q_TA6vy0Bi} z_!E6FQ00$$@u=L_3n2=@2Bt%y8npBduuE>diB_DEzq?6!)FF%dP(Xq1>_dnGy}J(& z{(VO}IR$3SkpuF3|B1qwBVERKzBC;<C_8RrYW!hQ4l@ET8-KoyM>)L-XWv1#a#$Rd zb$6(ibQ?dogU2~#%_skjCn;+-d_~BsU2gpf8io2FzA}?XuKAiaenz%@jW^LLAHGM{ zdkoJ#>=a2?#k`CfdMpr<X6U6#$(NDb3eM}PM*foX?^CACQTW2q^a;z2jA@mAUz0DO zHqQ5XUA@Kug--z$%X5N0mG#OR8(&Q|(>QM90^9G3vU>y;7B6Vf2rc`(-`4!TYI>1q zew%GisYR`B(wwX5`xb>pyv;t#qOIBzr6k(y(=5tknpX?B1Iac=grmae4^nmnTT^U~ g+?aN!mTB8F)tWu7xi>WgsTvjz<>^$3_hi}r7f-piiU0rr delta 5961 zcmds5eNa?amVdwZA&sJG6tGdyCIJKo6pR>AQCc7dCrBfpaYn@_{eX`B0o|`vvhiyt zYM9cbn77U?N8RY8++C75>hw5olO3iOt2FEEkOa4kA!;TXT|-vPm<=^Lo5Vfub%R}F z{@H(acDAak@4e@qbI-l!{?5m{Z|}DBy<{2XRaALg$;nZl&r5dJyMm68>UYX+mqT5y zc>Nn?PZ;yJV{}qprAuuu3n;R7qAVl)#)1tHXj(g2X4eicjGLVdoG>_|Ldz97==UwC zn>R0pSgp1wfym54P83z`m6BwwZ=trWJccPUFXqKCBNecwRcvl`2NV~_akeVi7m__3 zxFnNH<cJ|wfaAHe<;q6?24WXDnoW4BRrYukwZRqgxm6|5u*t6`sqL*w&`GKbhj+cw zPlq-(&cRY%rFhpXfnbZf^?~MyJ`URLMR~AllS}`_@{CjQx!k^HEv>X7fft{5*juB7 zwNIuv*F|R^T1<q^YbvlJGis$u+N}7(h`c>AZ*0KcA_wh?aenQ{Q$B5(V<s%xR!2(s zgriaXv+X0iWXTURkf@z+*@}Bwjr%9`f6J|4Y<T&zlj6lUd30-c)YaN=gHx!tsI@^` zs-}rOJWiS9v+6YTX}8tg`~_Y+xuHROKlG^BKP>dj#z(~~!>k`}%oT6&=r`pWH)V?h zJi5%mz@{|*4zCq%SgR?Ur;71HWbyFz%`GdD8LoP7EI+=SK<swOs?y+gDL&P$wrkr; zrj|(<rrQaZcK;@y;<68O*mJz0ph{PusOGF!cKhrE8hb!#3lR*xv`{cN{JrxQA)&6x zA81q>h)Di$;NNn-pXnw?Xz<Bi<s^^N>Q>cFu3$iX8Icxpumwzz{f}Kn5}(($9kRs* zRewNkR<!jOGI1)r`$8f=Q?y0Yh+-WQ0gH8+-=~nPSZn=WMdT8}k+*QCc#h+#|EBiJ z#hhB}Q^sMGpxW>NX&h&{6%4KSx>dUz3&1F6)GRIXMup~GN~1?6mmINLt~Ry5Xh|ti z-QL(mkrbiDtoVXF>?biqd$7eH^0)}<?w}eTych<$!$<lHc=TxJFTI2_ntb^+^FKM9 zaV3$b?&H6kG5H*if)z^R0;dvK@Ah~Wa@;xNpuIfTt3Cg_nS`>xnB!hBkIVP-T4Lqo z@PB<WaTKnECwz9C$5kz7C_6lGYoP^K!#P7gA5D}?_owkUc-F8DkM7Gx7Y6pdhgBHV zrvo`j7-ZBg*7qgj3((-jiI|2v?8HPAVu+Pw;4xjY;g&Q!NS*>Gk9(}ij`uO76T?r1 z_#wlP{owAgPcxB&uUTRi=1LF%u(m8rU~(3o5G8@az#Y}Wu4KW&f6Z%CcpJN)g~dDs zR+f!z$&z463$`{i`U8q}h2QNm&={{@%tl2V#<I==6tZPAFn)9*g=@YST(Y3`jGwIU zoPpPXRD&Uf9a@UaY3YJk%W)!?A;4zbc^%z$IthuEA=rpY;xx=MB<7an#xUg?QzDly z#JWnM@Q|w%5+7}@P|)l<C$o$~OhgeYE+pHPFu4$UaIlvOk;WHA7~U?#>IuaH0Wi>1 z>u&bRYA8UCSIp+jB6F5Rm|mTQdfpM~CqEAPTLdat2Th>Tv_*DR^prI*2dFYnX|r-Q z#z|;YuP>erp2sS^Vh%0~?A3W>sd@9TDp3}YQ?XeM$WMCY<{-z(>~H78#(p&qkBnCY zSVM)g=5m}u>qv2&`+;@Gd!u?oBYN3^`IyYg=i}*dZ2~B(8tIXiY%`Xe7aubA;uW}d zbKl8ZqVhXN<T-9jMERlxSRKE^VBaEeJ0t8JQTDwt>>Uwyz68ai_ZsXS0@o>M(^Dqt z4JEk4V;`$2#q@Cx&aq#xv}kLjN$k~9*!e?(_R#^G_RoJ4r(Z8cInN&vw1&(SR$7KC z95wZ(bVc<Zi_zO<uqCt4%FrBl%+T8<uw&&&XQ6Tw<CK2999wz3$!07;TXr`wh?akx z&Gi_ZX9SLZMBwsy?wr}{6=rk2?938;2YvdTC1?aLu=+~;82#*4C0w||YL=pinqg?q z;jao>TVASudnpK(H%2Bh(>{nmejsMI1BTuYxIy7Z&!(_F%P?{L9f7lOTL`(_9RXq; zHSE+fY$Wf_tHvVoYfm+5Xf&)Z({wnZj}WqlqGtIzM$y-Xq9K8UXdKW=h+!L?_zdxE zMGZEP@1Cx~JEIfLS-X`>W*Ix8zKm4;qva^&$%H1&S&s?GV6J+c;Il;S;OsQ^$7Uqx z3s>MZ9=Rsdw0tpg)<UX}hTS{gTs)rKyO4T34U3p#6+T5V8|TM#%x1-Yyv6pn;xP(0 z-K}&?kv-Ce?+TK5kiFYTUa_$avoMNvwP88p*jGklVbuXR=p3B^WTZMPgTaszD3g85 z{AvZIzcMADa-+qs*x3MzrVdvMt{DrAi8_D1&!sfEsbb*9i1lD{5E*5@kvwSM<W?z@ z8TG?(4QclWz9r$!C@{+czxt#<<a2Qe?AL4YG6kAt4OlY9A#yfYsc?}U>~I5~L<PIq zfRa%KW~IT77h__oEvQn&308^7F;=QIM;zx6HMt;_h1Q{ZR)rWF@hZiKB3>m~m2hJ; z1Ys*zWvI8YaWcj_64H#4Up33_(lWoV$sO=2uEp)uR4oNaDsx4&wsKL;&D9w9Q!jG# zGr&?Ma;w-{8JU=?|3Ib)YFiyW?w_v2{%Jj4XFqGi6pUuQjd&Vk*d!O`A%WGq@C3nZ zuM0Ws{0nHs8up=r@A9&!9lkh;RjC+<B<5^FV{uE>h`Aje+O~`8db7Zx?en7gVAd{2 zrp;=O3Lti(2@}T(V%-B4=4(PqR#cua5xF4xXnDXgBK@(7zk<S?&FFyJXeMe6OXBtC zL-+;YWyjs9MjN~D#&+yw+n=SIY%|e5H55gAM-19S5!<zk6jLW|z_f8x#v~vuD0^Ey zN^lE%dIP?XEvEd;9Z~t6G4eZ1`Ci`2?KEzKh8;#r%kDLVQrHv^^2c|I$Xi?&P?TCl zHFIbuTjPO^f~)DP-|WPA?APD&pq9s>|DSHgANfCqprd~RoiSbJRZ_8YOr&x!U4Ld1 zJ^@a$1?~6;oMJcHsUkZSxv)jgQE+`zuYC@0i1FRVh4+YD4_mtpX)JRaC9pF_|D7@C z%q4q88)YZsrjz@k5V{Zpp+2@{J31#^FqY{PxqegT3dvlF$Xt!e+=!96%9?jz>*yPX z%vF&a5cl;VSr`8rJ9vIj)KH(w4!?k(QUO}FliXw|250wJ;x5dj+S0KLSv(}xvJ1Jq zB<b2NIwv15X?=VWt9cRC8Dk}~#%#)Q)Zs*XqLeJ9O6gLDlq(fU#S)judS1j*Bpb~n zmfb<=H#O4tbWr?BkMw`mfk!D5^>v_hOqPU%ih#^<S*9Aj;D<P9rEJvu6U-i!Z>TF| zaR*>e&zCF(%`RnQLm))okX|Kid8DPy5R0jA?Exweiz5A_BqJ6}k;+8><N#iMgtoQ& zb=qC3e*Sg5E>OGmI1T_=Y|=?8+w*nxBqoUz<zGI9=cpO|OB_U{{`bFxQ$)Rf_btTp z;wqsNEU}xSpz|O_M_)J23TuSJ25FkU_Sbk^pb+$<9_&Fon|hiqekWUX8u{3%?>-Hx zcRE?oSu7+!SI<&h-mmXJi+e)$At5fQCgfLTL>fz`5vWZHWq!$eL=ZVqWw)<UUU=^} z1hu33_21wP1B{)&MUYS^^`e=oBX2KMbnDl8u@&gi<#*8woMSWl;6xwW-iI`*gAVo4 zzWVixeHbI*s{YCQ*vOB%VW@bIwZ22qJlIbRgX~y8e#}GED?Y?Z5H1c~!uKd)-@Swd zlo5(9qxg|TF<B(Yp_9j5j_!KPWz3;#{>5d|pP@f~1sd5`fBPe>16^v)#{|7z{pTO! z2<W2fuE9%1#OZ6uMu|Rf4YkOqtBkx6xRqe!DQmq)srJDzLJesW^VusmF`ezcPQI7G zPF%-wHuK*R&RZqs<~&FZi0LQA^i5-~VdHM%Qg!)5PebPH9#Znga3w*zFl&i#DIJEh zPfK(emh(Bm**lT}gRJ)^(nrxNOghy%zrTrf1*;#@NMFouzsqX<lJdW(z+NS9c6&o! zQfJWF$Dbo*PM&=eJ=@XueoTGSNCT=uj7O2y$ZMCKUJZhc0k`?sF#|GN{wX<}!k+sS ze@B4G7$8#<GGG3T?B-<){{!<aPQTw%2rgzci$*%ly$u5Bs6n)&hixAu-{@r@4q^uO zv-sNxQ9{~w8;_0u^BT5~Cyf5@8}<mh`#F8UM-6*H@B6)B*rROG7s!k65-VVML%*(m zf%!a+u@he+OXw0$vJbwbSa?Mjhp^K4idp>!Y_fM7uH%f>I0Sbpm>g<FtG}_uz`L!R z{pTN`(3i-nyX4eo*gJO#O6S<EyZ9A-#dO_6aRR-=t%0r78SrmzXYYQ66kYryn#6Gf z;-a*A)$O6THjYC6=5MH?8)Rp`K@*Mg?qe4vfbe~kC((nQ8)*f!K&w9}dlvhBu6w7( z@ZSNYgD1di^nLQL;8##q&>!P@5pj~_h?hh=yYnI@Y)h2(l$Nz9jT>rPmBtnHSW6FW z$&z)hNvqo&rKC#M0+X^t@hL%fFkP}oII8>smC9GOJwvkRm>l$K)~Mu4d-BZDO2ysW kq83Se)|Iu$fo7#HAp3%Hqw$>Ql-s>ZoKG#5_T)?d4ZK!rM*si- diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs index a0a084988..8cb679c66 100644 --- a/runtime/common/src/handlers.rs +++ b/runtime/common/src/handlers.rs @@ -20,8 +20,6 @@ use frame_support::dispatch::UnfilteredDispatchable; use frame_support::instances::{Instance1, Instance2}; use frame_support::pallet_prelude::Weight; use frame_support::Parameter; -use pallet_identity::IdtyEvent; -use sp_runtime::traits::IsMember; // new session handler pub struct OnNewSessionHandler<Runtime>(core::marker::PhantomData<Runtime>); @@ -35,37 +33,6 @@ where } } -// identity change runtime handler -pub struct OnIdtyChangeHandler<Runtime>(core::marker::PhantomData<Runtime>); -impl<T> pallet_identity::traits::OnIdtyChange<T> for OnIdtyChangeHandler<T> -where - T: frame_system::Config<AccountId = AccountId>, - T: pallet_authority_members::Config<MemberId = IdtyIndex>, - T: pallet_identity::Config<IdtyIndex = IdtyIndex, IdtyData = IdtyData>, - T: pallet_universal_dividend::Config, -{ - fn on_idty_change(idty_index: IdtyIndex, idty_event: &IdtyEvent<T>) { - match idty_event { - IdtyEvent::Validated => { - // when identity is validated, it starts getting right to UD - // but this is handeled by membership event handler (MembershipAdded) - } - IdtyEvent::ChangedOwnerKey { new_owner_key } => { - if let Err(e) = pallet_authority_members::Pallet::<T>::change_owner_key( - idty_index, - new_owner_key.clone(), - ) { - log::error!( - "on_idty_change: pallet_authority_members.change_owner_key(): {:?}", - e - ); - } - } - IdtyEvent::Created { .. } | IdtyEvent::Confirmed | IdtyEvent::Removed { .. } => {} - } - } -} - // membership event runtime handler pub struct OnMembershipEventHandler<Inner, Runtime>(core::marker::PhantomData<(Inner, Runtime)>); impl< @@ -102,9 +69,7 @@ impl< }); } // in other case, ther is nothing to do - sp_membership::Event::MembershipRenewed(_) - | sp_membership::Event::PendingMembershipAdded(_) - | sp_membership::Event::PendingMembershipExpired(_) => (), + sp_membership::Event::MembershipRenewed(_) => (), }); Inner::on_event(membership_event) } @@ -148,6 +113,8 @@ impl< } // authority member removal handler +// TODO refac smith wot +// or document the link between smith membership and authority member pub struct OnRemovedAuthorityMemberHandler<Runtime>(core::marker::PhantomData<Runtime>); impl<Runtime> pallet_authority_members::traits::OnRemovedMember<IdtyIndex> for OnRemovedAuthorityMemberHandler<Runtime> @@ -155,30 +122,10 @@ where Runtime: frame_system::Config + pallet_membership::Config<Instance2, IdtyId = IdtyIndex>, { fn on_removed_member(idty_index: IdtyIndex) { - // TODO investigate why we should remove smith membership when removing authority member - pallet_membership::Pallet::<Runtime, Instance2>::force_revoke_membership(idty_index); - } -} - -// identity removal handler -pub struct RemoveIdentityConsumersImpl<Runtime>(core::marker::PhantomData<Runtime>); -impl<Runtime> pallet_identity::traits::RemoveIdentityConsumers<IdtyIndex> - for RemoveIdentityConsumersImpl<Runtime> -where - Runtime: pallet_identity::Config<IdtyIndex = IdtyIndex> - + pallet_authority_members::Config<MemberId = IdtyIndex> - + pallet_membership::Config<Instance1, IdtyId = IdtyIndex> - + pallet_membership::Config<Instance2, IdtyId = IdtyIndex>, -{ - fn remove_idty_consumers(idty_index: IdtyIndex) -> Weight { - // Remove smith member - if pallet_membership::Pallet::<Runtime, Instance2>::is_member(&idty_index) { - pallet_membership::Pallet::<Runtime, Instance2>::force_revoke_membership(idty_index); - } - // Remove "classic" member - pallet_membership::Pallet::<Runtime, Instance1>::force_revoke_membership(idty_index); - - Weight::zero() + pallet_membership::Pallet::<Runtime, Instance2>::do_remove_membership( + idty_index, + pallet_membership::MembershipRemovalReason::System, + ); } } diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs index 31bae949b..471c97672 100644 --- a/runtime/common/src/pallets_config.rs +++ b/runtime/common/src/pallets_config.rs @@ -460,20 +460,26 @@ macro_rules! pallets_config { type MinCertForCreateIdtyRight = WotMinCertForCreateIdtyRight; } + parameter_types! { + pub const ValidationPeriod: BlockNumber = 2 * MONTHS; + pub const AutorevocationPeriod: BlockNumber = 1 * YEARS; + pub const DeletionPeriod: BlockNumber = 10 * YEARS; + } impl pallet_identity::Config for Runtime { type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod; type ConfirmPeriod = ConfirmPeriod; + type ValidationPeriod = ValidationPeriod; + type AutorevocationPeriod = AutorevocationPeriod; + type DeletionPeriod = DeletionPeriod; type CheckIdtyCallAllowed = (Wot, SmithSubWot); type IdtyCreationPeriod = IdtyCreationPeriod; type IdtyData = IdtyData; type IdtyIndex = IdtyIndex; type AccountLinker = Account; type IdtyNameValidator = IdtyNameValidatorImpl; - type IdtyRemovalOtherReason = pallet_duniter_wot::IdtyRemovalWotReason; type Signer = <Signature as sp_runtime::traits::Verify>::Signer; type Signature = Signature; - type OnIdtyChange = (common_runtime::handlers::OnIdtyChangeHandler<Runtime>, Wot, Quota, Account); - type RemoveIdentityConsumers = RemoveIdentityConsumersImpl<Self>; + type OnIdtyChange = (Wot, SmithSubWot, Quota, Account); type RuntimeEvent = RuntimeEvent; type WeightInfo = common_runtime::weights::pallet_identity::WeightInfo<Runtime>; #[cfg(feature = "runtime-benchmarks")] @@ -486,8 +492,7 @@ macro_rules! pallets_config { type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>; type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>; type MembershipPeriod = MembershipPeriod; - type OnEvent = OnMembershipEventHandler<Wot, Runtime>; - type PendingMembershipPeriod = PendingMembershipPeriod; + type OnEvent = (OnMembershipEventHandler<Wot, Runtime>, Wot); type RuntimeEvent = RuntimeEvent; type WeightInfo = common_runtime::weights::pallet_membership_membership::WeightInfo<Runtime>; #[cfg(feature = "runtime-benchmarks")] @@ -537,7 +542,6 @@ macro_rules! pallets_config { type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>; type MembershipPeriod = SmithMembershipPeriod; type OnEvent = OnSmithMembershipEventHandler<SmithSubWot, Runtime>; - type PendingMembershipPeriod = SmithPendingMembershipPeriod; type RuntimeEvent = RuntimeEvent; type WeightInfo = common_runtime::weights::pallet_membership_smith_membership::WeightInfo<Runtime>; #[cfg(feature = "runtime-benchmarks")] diff --git a/runtime/common/src/providers.rs b/runtime/common/src/providers.rs index 141714062..b9d235720 100644 --- a/runtime/common/src/providers.rs +++ b/runtime/common/src/providers.rs @@ -119,9 +119,12 @@ where idty_id: &<T as pallet_identity::Config>::IdtyIndex, ) -> Result<(), DispatchError> { match pallet_distance::Pallet::<T>::identity_distance_status(idty_id) { - Some((_, pallet_distance::DistanceStatus::Valid)) => Ok(()), - Some((_, pallet_distance::DistanceStatus::Invalid)) => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceIsInvalid.into()), - _ => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceNotEvaluated.into()), + Some((_, status)) => match status { + pallet_distance::DistanceStatus::Valid => Ok(()), + pallet_distance::DistanceStatus::Invalid => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceIsInvalid.into()), + pallet_distance::DistanceStatus::Pending => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceEvaluationPending.into()), + }, + None => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceEvaluationNotRequested.into()), } } } diff --git a/runtime/common/src/weights/pallet_identity.rs b/runtime/common/src/weights/pallet_identity.rs index 332be4f48..5664f72ae 100644 --- a/runtime/common/src/weights/pallet_identity.rs +++ b/runtime/common/src/weights/pallet_identity.rs @@ -1,28 +1,41 @@ +// Copyright 2021-2022 Axiom-Team +// +// This file is part of Duniter-v2S. +// +// Duniter-v2S is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// Duniter-v2S is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. //! Autogenerated weights for `pallet_identity` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F` -//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `squirrel`, CPU: `Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/release/duniter +// ./target/debug/duniter // benchmark // pallet -// --chain -// dev +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet-identity +// --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --pallet -// * -// --extrinsic -// * -// --steps -// 50 -// --repeat -// 20 -// --output=runtime/common/src/weights/ +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/common/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,24 +60,26 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) /// Storage: Identity NextIdtyIndex (r:1 w:1) /// Proof Skipped: Identity NextIdtyIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Identity IdentityChangeSchedule (r:1 w:1) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) /// Storage: Identity CounterForIdentities (r:1 w:1) /// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Identity IdentitiesRemovableOn (r:1 w:1) - /// Proof Skipped: Identity IdentitiesRemovableOn (max_values: None, max_size: None, mode: Measured) /// Storage: Cert StorageCertsRemovableOn (r:1 w:1) /// Proof Skipped: Cert StorageCertsRemovableOn (max_values: None, max_size: None, mode: Measured) /// Storage: Cert CertsByReceiver (r:1 w:1) /// Proof Skipped: Cert CertsByReceiver (max_values: None, max_size: None, mode: Measured) + /// Storage: SmithCert StorageIdtyCertMeta (r:1 w:0) + /// Proof Skipped: SmithCert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured) /// Storage: Quota IdtyQuota (r:0 w:1) /// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) fn create_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `982` - // Estimated: `6922` - // Minimum execution time: 38_137_000 picoseconds. - Weight::from_parts(39_647_000, 0) - .saturating_add(Weight::from_parts(0, 6922)) - .saturating_add(T::DbWeight::get().reads(13)) + // Measured: `1165` + // Estimated: `7105` + // Minimum execution time: 1_643_969_000 picoseconds. + Weight::from_parts(1_781_521_000, 0) + .saturating_add(Weight::from_parts(0, 7105)) + .saturating_add(T::DbWeight::get().reads(14)) .saturating_add(T::DbWeight::get().writes(12)) } /// Storage: Identity IdentityIndexOf (r:1 w:0) @@ -73,52 +88,18 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) /// Storage: Identity IdentitiesNames (r:1 w:1) /// Proof Skipped: Identity IdentitiesNames (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership PendingMembership (r:1 w:1) - /// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership Membership (r:1 w:0) - /// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured) - /// Storage: Parameters ParametersStorage (r:1 w:0) - /// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Membership PendingMembershipsExpireOn (r:1 w:1) - /// Proof Skipped: Membership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity IdentityChangeSchedule (r:2 w:2) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) fn confirm_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `955` - // Estimated: `4420` - // Minimum execution time: 23_569_000 picoseconds. - Weight::from_parts(24_735_000, 0) - .saturating_add(Weight::from_parts(0, 4420)) - .saturating_add(T::DbWeight::get().reads(7)) + // Measured: `661` + // Estimated: `6601` + // Minimum execution time: 564_892_000 picoseconds. + Weight::from_parts(588_761_000, 0) + .saturating_add(Weight::from_parts(0, 6601)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Identity Identities (r:1 w:1) - /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership PendingMembership (r:1 w:1) - /// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured) - /// Storage: Cert StorageIdtyCertMeta (r:1 w:0) - /// Proof Skipped: Cert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured) - /// Storage: Parameters ParametersStorage (r:1 w:0) - /// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Distance IdentityDistanceStatus (r:1 w:0) - /// Proof Skipped: Distance IdentityDistanceStatus (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership Membership (r:1 w:1) - /// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership CounterForMembership (r:1 w:1) - /// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Membership MembershipsExpireOn (r:1 w:1) - /// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: UniversalDividend CurrentUdIndex (r:1 w:0) - /// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen) - fn validate_identity() -> Weight { - // Proof Size summary in bytes: - // Measured: `1948` - // Estimated: `5413` - // Minimum execution time: 39_059_000 picoseconds. - Weight::from_parts(42_214_000, 0) - .saturating_add(Weight::from_parts(0, 5413)) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(5)) - } /// Storage: Identity IdentityIndexOf (r:2 w:2) /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) /// Storage: Identity Identities (r:1 w:1) @@ -129,81 +110,37 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { /// Proof: System BlockHash (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) /// Storage: System Account (r:2 w:2) /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) - /// Storage: AuthorityMembers Members (r:1 w:0) - /// Proof Skipped: AuthorityMembers Members (max_values: None, max_size: None, mode: Measured) fn change_owner_key() -> Weight { // Proof Size summary in bytes: - // Measured: `1119` - // Estimated: `7059` - // Minimum execution time: 76_290_000 picoseconds. - Weight::from_parts(79_765_000, 0) - .saturating_add(Weight::from_parts(0, 7059)) - .saturating_add(T::DbWeight::get().reads(8)) + // Measured: `837` + // Estimated: `6777` + // Minimum execution time: 991_641_000 picoseconds. + Weight::from_parts(1_071_332_000, 0) + .saturating_add(Weight::from_parts(0, 6777)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: Identity Identities (r:1 w:1) /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership Membership (r:1 w:0) - /// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured) /// Storage: System BlockHash (r:1 w:0) /// Proof: System BlockHash (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: Identity IdentityChangeSchedule (r:2 w:2) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) /// Storage: Membership Membership (r:1 w:1) /// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity CounterForIdentities (r:1 w:1) - /// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) - /// Storage: Cert CertsByReceiver (r:1 w:1) - /// Proof Skipped: Cert CertsByReceiver (max_values: None, max_size: None, mode: Measured) - /// Storage: Cert StorageIdtyCertMeta (r:2 w:2) - /// Proof Skipped: Cert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured) - /// Storage: Parameters ParametersStorage (r:1 w:0) - /// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Identity IdentityIndexOf (r:0 w:1) - /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Quota IdtyQuota (r:0 w:1) - /// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) - fn revoke_identity() -> Weight { - // Proof Size summary in bytes: - // Measured: `1498` - // Estimated: `7438` - // Minimum execution time: 84_313_000 picoseconds. - Weight::from_parts(87_192_000, 0) - .saturating_add(Weight::from_parts(0, 7438)) - .saturating_add(T::DbWeight::get().reads(11)) - .saturating_add(T::DbWeight::get().writes(10)) - } - /// Storage: Identity Identities (r:1 w:1) - /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership Membership (r:1 w:0) + /// Storage: SmithMembership Membership (r:1 w:1) /// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership Membership (r:1 w:1) - /// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity CounterForIdentities (r:1 w:1) - /// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) - /// Storage: Cert CertsByReceiver (r:1 w:1) - /// Proof Skipped: Cert CertsByReceiver (max_values: None, max_size: None, mode: Measured) - /// Storage: Cert StorageIdtyCertMeta (r:2 w:2) - /// Proof Skipped: Cert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured) - /// Storage: Parameters ParametersStorage (r:1 w:0) - /// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Identity IdentityIndexOf (r:0 w:1) - /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity IdentitiesNames (r:0 w:1) - /// Proof Skipped: Identity IdentitiesNames (max_values: None, max_size: None, mode: Measured) /// Storage: Quota IdtyQuota (r:0 w:1) /// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) - fn force_remove_identity() -> Weight { + fn revoke_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `1343` - // Estimated: `7283` - // Minimum execution time: 38_696_000 picoseconds. - Weight::from_parts(39_816_000, 0) - .saturating_add(Weight::from_parts(0, 7283)) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(10)) + // Measured: `778` + // Estimated: `6718` + // Minimum execution time: 829_174_000 picoseconds. + Weight::from_parts(869_308_000, 0) + .saturating_add(Weight::from_parts(0, 6718)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: Identity IdentitiesNames (r:0 w:998) /// Proof Skipped: Identity IdentitiesNames (max_values: None, max_size: None, mode: Measured) @@ -212,11 +149,11 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 804_000 picoseconds. - Weight::from_parts(888_000, 0) + // Minimum execution time: 51_362_000 picoseconds. + Weight::from_parts(80_389_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 939 - .saturating_add(Weight::from_parts(642_823, 0).saturating_mul(i.into())) + // Standard Error: 75_232 + .saturating_add(Weight::from_parts(30_016_649, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } /// Storage: System Account (r:1 w:1) @@ -225,8 +162,8 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { // Proof Size summary in bytes: // Measured: `67` // Estimated: `3591` - // Minimum execution time: 3_775_000 picoseconds. - Weight::from_parts(4_240_000, 0) + // Minimum execution time: 154_343_000 picoseconds. + Weight::from_parts(156_117_000, 0) .saturating_add(Weight::from_parts(0, 3591)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -241,8 +178,8 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { // Proof Size summary in bytes: // Measured: `307` // Estimated: `3772` - // Minimum execution time: 45_159_000 picoseconds. - Weight::from_parts(46_401_000, 0) + // Minimum execution time: 538_773_000 picoseconds. + Weight::from_parts(591_354_000, 0) .saturating_add(Weight::from_parts(0, 3772)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -251,23 +188,33 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 28_000 picoseconds. - Weight::from_parts(31_000, 0) + // Minimum execution time: 4_529_000 picoseconds. + Weight::from_parts(7_360_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: Identity Identities (r:1 w:0) /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) - fn do_remove_identity_noop() -> Weight { + fn do_revoke_identity_noop() -> Weight { // Proof Size summary in bytes: // Measured: `269` // Estimated: `3734` - // Minimum execution time: 3_245_000 picoseconds. - Weight::from_parts(3_383_000, 0) + // Minimum execution time: 103_668_000 picoseconds. + Weight::from_parts(107_679_000, 0) .saturating_add(Weight::from_parts(0, 3734)) .saturating_add(T::DbWeight::get().reads(1)) } /// Storage: Identity Identities (r:1 w:1) /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity IdentityChangeSchedule (r:2 w:1) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) + /// Storage: Membership Membership (r:1 w:1) + /// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured) + /// Storage: Membership CounterForMembership (r:1 w:1) + /// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Membership MembershipsExpireOn (r:1 w:1) + /// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) + /// Storage: UniversalDividend CurrentUdIndex (r:1 w:0) + /// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen) /// Storage: SmithMembership Membership (r:1 w:1) /// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured) /// Storage: SmithMembership CounterForMembership (r:1 w:1) @@ -286,6 +233,37 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { /// Proof Skipped: AuthorityMembers IncomingAuthorities (max_values: Some(1), max_size: None, mode: Measured) /// Storage: Session NextKeys (r:1 w:1) /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) + /// Storage: Quota IdtyQuota (r:0 w:1) + /// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) + /// Storage: Session KeyOwner (r:0 w:4) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + fn do_revoke_identity() -> Weight { + // Proof Size summary in bytes: + // Measured: `1525` + // Estimated: `7465` + // Minimum execution time: 2_204_911_000 picoseconds. + Weight::from_parts(2_225_493_000, 0) + .saturating_add(Weight::from_parts(0, 7465)) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(20)) + } + /// Storage: Identity Identities (r:1 w:0) + /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) + fn do_remove_identity_noop() -> Weight { + // Proof Size summary in bytes: + // Measured: `269` + // Estimated: `3734` + // Minimum execution time: 104_296_000 picoseconds. + Weight::from_parts(115_316_000, 0) + .saturating_add(Weight::from_parts(0, 3734)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: Identity Identities (r:1 w:1) + /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity CounterForIdentities (r:1 w:1) + /// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: System Account (r:2 w:2) /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) /// Storage: Membership Membership (r:1 w:1) @@ -294,10 +272,24 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { /// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: Membership MembershipsExpireOn (r:1 w:1) /// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: UniversalDividend CurrentUdIndex (r:1 w:0) - /// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen) - /// Storage: Identity CounterForIdentities (r:1 w:1) - /// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: SmithMembership Membership (r:1 w:1) + /// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured) + /// Storage: SmithMembership CounterForMembership (r:1 w:1) + /// Proof: SmithMembership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: SmithMembership MembershipsExpireOn (r:1 w:1) + /// Proof Skipped: SmithMembership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) + /// Storage: AuthorityMembers Members (r:1 w:1) + /// Proof Skipped: AuthorityMembers Members (max_values: None, max_size: None, mode: Measured) + /// Storage: AuthorityMembers OnlineAuthorities (r:1 w:1) + /// Proof Skipped: AuthorityMembers OnlineAuthorities (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AuthorityMembers OutgoingAuthorities (r:1 w:1) + /// Proof Skipped: AuthorityMembers OutgoingAuthorities (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AuthorityMembers AuthoritiesCounter (r:1 w:1) + /// Proof Skipped: AuthorityMembers AuthoritiesCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AuthorityMembers IncomingAuthorities (r:1 w:1) + /// Proof Skipped: AuthorityMembers IncomingAuthorities (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) /// Storage: Identity IdentityIndexOf (r:0 w:1) /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) /// Storage: Quota IdtyQuota (r:0 w:1) @@ -306,51 +298,67 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> { /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) fn do_remove_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `1525` + // Measured: `1432` // Estimated: `6192` - // Minimum execution time: 57_854_000 picoseconds. - Weight::from_parts(60_976_000, 0) + // Minimum execution time: 2_870_497_000 picoseconds. + Weight::from_parts(4_159_994_000, 0) .saturating_add(Weight::from_parts(0, 6192)) - .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().reads(16)) .saturating_add(T::DbWeight::get().writes(22)) } - /// Storage: Identity IdentitiesRemovableOn (r:1 w:0) - /// Proof Skipped: Identity IdentitiesRemovableOn (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity IdentityChangeSchedule (r:1 w:0) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) fn prune_identities_noop() -> Weight { // Proof Size summary in bytes: // Measured: `108` // Estimated: `3573` - // Minimum execution time: 1_249_000 picoseconds. - Weight::from_parts(1_330_000, 0) + // Minimum execution time: 68_859_000 picoseconds. + Weight::from_parts(71_836_000, 0) .saturating_add(Weight::from_parts(0, 3573)) .saturating_add(T::DbWeight::get().reads(1)) } - /// Storage: Identity IdentitiesRemovableOn (r:1 w:1) - /// Proof Skipped: Identity IdentitiesRemovableOn (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity IdentityChangeSchedule (r:1 w:1) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) /// Storage: Identity Identities (r:1 w:0) /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) fn prune_identities_none() -> Weight { // Proof Size summary in bytes: - // Measured: `293` - // Estimated: `3758` - // Minimum execution time: 4_441_000 picoseconds. - Weight::from_parts(4_690_000, 0) - .saturating_add(Weight::from_parts(0, 3758)) + // Measured: `292` + // Estimated: `3757` + // Minimum execution time: 178_332_000 picoseconds. + Weight::from_parts(186_982_000, 0) + .saturating_add(Weight::from_parts(0, 3757)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity IdentitiesRemovableOn (r:1 w:1) - /// Proof Skipped: Identity IdentitiesRemovableOn (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity Identities (r:1 w:0) + /// Storage: Identity IdentityChangeSchedule (r:1 w:1) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity Identities (r:1 w:1) /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity CounterForIdentities (r:1 w:1) + /// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) + /// Storage: Membership Membership (r:1 w:1) + /// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured) + /// Storage: Cert CertsByReceiver (r:1 w:0) + /// Proof Skipped: Cert CertsByReceiver (max_values: None, max_size: None, mode: Measured) + /// Storage: SmithMembership Membership (r:1 w:1) + /// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured) + /// Storage: SmithCert CertsByReceiver (r:1 w:0) + /// Proof Skipped: SmithCert CertsByReceiver (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity IdentityIndexOf (r:0 w:1) + /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Quota IdtyQuota (r:0 w:1) + /// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) fn prune_identities_err() -> Weight { // Proof Size summary in bytes: - // Measured: `360` - // Estimated: `3825` - // Minimum execution time: 5_680_000 picoseconds. - Weight::from_parts(6_083_000, 0) - .saturating_add(Weight::from_parts(0, 3825)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `1177` + // Estimated: `4642` + // Minimum execution time: 1_427_848_000 picoseconds. + Weight::from_parts(2_637_229_000, 0) + .saturating_add(Weight::from_parts(0, 4642)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(8)) } } diff --git a/runtime/common/src/weights/pallet_membership_membership.rs b/runtime/common/src/weights/pallet_membership_membership.rs index 64d9bd04f..127922e2f 100644 --- a/runtime/common/src/weights/pallet_membership_membership.rs +++ b/runtime/common/src/weights/pallet_membership_membership.rs @@ -1,28 +1,41 @@ +// Copyright 2021-2022 Axiom-Team +// +// This file is part of Duniter-v2S. +// +// Duniter-v2S is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// Duniter-v2S is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. //! Autogenerated weights for `pallet_membership` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-14, STEPS: `8`, REPEAT: `4`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F` -//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `squirrel`, CPU: `Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/release/duniter +// ./target/debug/duniter // benchmark // pallet -// --chain -// dev +// --chain=dev +// --steps=8 +// --repeat=4 +// --pallet=pallet-membership +// --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --pallet -// * -// --extrinsic -// * -// --steps -// 50 -// --repeat -// 20 -// --output=runtime/common/src/weights/ +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/common/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -37,21 +50,6 @@ pub struct WeightInfo<T>(PhantomData<T>); impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { /// Storage: Identity IdentityIndexOf (r:1 w:0) /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity Identities (r:1 w:0) - /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) - fn request_membership() -> Weight { - // Proof Size summary in bytes: - // Measured: `429` - // Estimated: `3894` - // Minimum execution time: 6_310_000 picoseconds. - Weight::from_parts(6_733_000, 0) - .saturating_add(Weight::from_parts(0, 3894)) - .saturating_add(T::DbWeight::get().reads(2)) - } - /// Storage: Identity IdentityIndexOf (r:1 w:0) - /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership PendingMembership (r:1 w:1) - /// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured) /// Storage: Cert StorageIdtyCertMeta (r:1 w:0) /// Proof Skipped: Cert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured) /// Storage: Parameters ParametersStorage (r:1 w:0) @@ -68,15 +66,17 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) /// Storage: UniversalDividend CurrentUdIndex (r:1 w:0) /// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen) + /// Storage: Identity IdentityChangeSchedule (r:1 w:0) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) fn claim_membership() -> Weight { // Proof Size summary in bytes: - // Measured: `1302` - // Estimated: `4767` - // Minimum execution time: 27_879_000 picoseconds. - Weight::from_parts(30_454_000, 0) - .saturating_add(Weight::from_parts(0, 4767)) + // Measured: `1272` + // Estimated: `4737` + // Minimum execution time: 1_213_348_000 picoseconds. + Weight::from_parts(1_439_442_000, 0) + .saturating_add(Weight::from_parts(0, 4737)) .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: Identity IdentityIndexOf (r:1 w:0) /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) @@ -94,8 +94,8 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { // Proof Size summary in bytes: // Measured: `988` // Estimated: `6928` - // Minimum execution time: 20_913_000 picoseconds. - Weight::from_parts(22_331_000, 0) + // Minimum execution time: 714_537_000 picoseconds. + Weight::from_parts(862_085_000, 0) .saturating_add(Weight::from_parts(0, 6928)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) @@ -108,118 +108,57 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { /// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: Membership MembershipsExpireOn (r:1 w:1) /// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity Identities (r:1 w:0) + /// Storage: Identity Identities (r:1 w:1) /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) /// Storage: UniversalDividend CurrentUdIndex (r:1 w:0) /// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen) + /// Storage: Identity IdentityChangeSchedule (r:2 w:1) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) fn revoke_membership() -> Weight { // Proof Size summary in bytes: // Measured: `703` - // Estimated: `4168` - // Minimum execution time: 16_631_000 picoseconds. - Weight::from_parts(18_080_000, 0) - .saturating_add(Weight::from_parts(0, 4168)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(3)) + // Estimated: `6643` + // Minimum execution time: 847_926_000 picoseconds. + Weight::from_parts(1_282_028_000, 0) + .saturating_add(Weight::from_parts(0, 6643)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) } fn on_initialize() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 26_000 picoseconds. - Weight::from_parts(27_000, 0) + // Minimum execution time: 4_012_000 picoseconds. + Weight::from_parts(4_629_000, 0) .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: Membership PendingMembershipsExpireOn (r:1 w:1) - /// Proof Skipped: Membership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership PendingMembership (r:1024 w:1024) - /// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity Identities (r:1024 w:4) - /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership Membership (r:4 w:3) - /// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership CounterForMembership (r:1 w:1) - /// Proof: SmithMembership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: SmithMembership MembershipsExpireOn (r:1 w:1) - /// Proof Skipped: SmithMembership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: AuthorityMembers Members (r:3 w:3) - /// Proof Skipped: AuthorityMembers Members (max_values: None, max_size: None, mode: Measured) - /// Storage: AuthorityMembers OnlineAuthorities (r:1 w:1) - /// Proof Skipped: AuthorityMembers OnlineAuthorities (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AuthorityMembers OutgoingAuthorities (r:1 w:1) - /// Proof Skipped: AuthorityMembers OutgoingAuthorities (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AuthorityMembers AuthoritiesCounter (r:1 w:1) - /// Proof Skipped: AuthorityMembers AuthoritiesCounter (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AuthorityMembers IncomingAuthorities (r:1 w:1) - /// Proof Skipped: AuthorityMembers IncomingAuthorities (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Session NextKeys (r:3 w:3) - /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// Storage: System Account (r:4 w:4) - /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) - /// Storage: Membership Membership (r:4 w:4) - /// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured) - /// Storage: Membership CounterForMembership (r:1 w:1) - /// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Membership MembershipsExpireOn (r:1 w:1) - /// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: UniversalDividend CurrentUdIndex (r:1 w:0) - /// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen) - /// Storage: Identity CounterForIdentities (r:1 w:1) - /// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Identity IdentityIndexOf (r:0 w:4) - /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Quota IdtyQuota (r:0 w:4) - /// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) - /// Storage: Session KeyOwner (r:0 w:12) - /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) - /// The range of component `i` is `[0, 1024]`. - /// The range of component `i` is `[0, 1024]`. - fn expire_pending_memberships(i: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `2214 + i * (19 ±0)` - // Estimated: `13117 + i * (2495 ±0)` - // Minimum execution time: 2_147_000 picoseconds. - Weight::from_parts(104_974_304, 0) - .saturating_add(Weight::from_parts(0, 13117)) - // Standard Error: 3_603 - .saturating_add(Weight::from_parts(3_246_507, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(27)) - .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) - .saturating_add(T::DbWeight::get().writes(47)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) - .saturating_add(Weight::from_parts(0, 2495).saturating_mul(i.into())) - } - /// Storage: Parameters ParametersStorage (r:1 w:0) - /// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured) /// Storage: Membership MembershipsExpireOn (r:1 w:1) /// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) /// Storage: Membership Membership (r:1024 w:1024) /// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured) /// Storage: Membership CounterForMembership (r:1 w:1) /// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Membership PendingMembershipsExpireOn (r:1 w:1) - /// Proof Skipped: Membership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity Identities (r:1024 w:0) + /// Storage: Identity Identities (r:1024 w:4) /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) /// Storage: UniversalDividend CurrentUdIndex (r:1 w:0) /// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen) - /// Storage: Membership PendingMembership (r:0 w:1024) - /// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured) + /// Storage: Identity IdentityChangeSchedule (r:2 w:1) + /// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 1024]`. /// The range of component `i` is `[0, 1024]`. fn expire_memberships(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `714 + i * (23 ±0)` - // Estimated: `4199 + i * (2499 ±0)` - // Minimum execution time: 4_828_000 picoseconds. - Weight::from_parts(5_150_000, 0) - .saturating_add(Weight::from_parts(0, 4199)) - // Standard Error: 885 - .saturating_add(Weight::from_parts(3_785_083, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(5)) + // Measured: `567 + i * (23 ±0)` + // Estimated: `6583 + i * (2499 ±0)` + // Minimum execution time: 86_925_000 picoseconds. + Weight::from_parts(89_056_000, 0) + .saturating_add(Weight::from_parts(0, 6583)) + // Standard Error: 2_429_589 + .saturating_add(Weight::from_parts(295_368_241, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) - .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 2499).saturating_mul(i.into())) } } diff --git a/runtime/common/src/weights/pallet_membership_smith_membership.rs b/runtime/common/src/weights/pallet_membership_smith_membership.rs index be9d722ae..d7008fec4 100644 --- a/runtime/common/src/weights/pallet_membership_smith_membership.rs +++ b/runtime/common/src/weights/pallet_membership_smith_membership.rs @@ -1,28 +1,41 @@ +// Copyright 2021-2022 Axiom-Team +// +// This file is part of Duniter-v2S. +// +// Duniter-v2S is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// Duniter-v2S is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. //! Autogenerated weights for `pallet_membership` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-14, STEPS: `8`, REPEAT: `4`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F` -//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `squirrel`, CPU: `Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/release/duniter +// ./target/debug/duniter // benchmark // pallet -// --chain -// dev +// --chain=dev +// --steps=8 +// --repeat=4 +// --pallet=pallet-membership +// --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --pallet -// * -// --extrinsic -// * -// --steps -// 50 -// --repeat -// 20 -// --output=runtime/common/src/weights/ +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/common/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -37,30 +50,6 @@ pub struct WeightInfo<T>(PhantomData<T>); impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { /// Storage: Identity IdentityIndexOf (r:1 w:0) /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Identity Identities (r:1 w:0) - /// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership PendingMembership (r:1 w:1) - /// Proof Skipped: SmithMembership PendingMembership (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership Membership (r:1 w:0) - /// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured) - /// Storage: Parameters ParametersStorage (r:1 w:0) - /// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: SmithMembership PendingMembershipsExpireOn (r:1 w:1) - /// Proof Skipped: SmithMembership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - fn request_membership() -> Weight { - // Proof Size summary in bytes: - // Measured: `706` - // Estimated: `4171` - // Minimum execution time: 14_737_000 picoseconds. - Weight::from_parts(15_859_000, 0) - .saturating_add(Weight::from_parts(0, 4171)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) - } - /// Storage: Identity IdentityIndexOf (r:1 w:0) - /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership PendingMembership (r:1 w:1) - /// Proof Skipped: SmithMembership PendingMembership (max_values: None, max_size: None, mode: Measured) /// Storage: SmithCert StorageIdtyCertMeta (r:1 w:0) /// Proof Skipped: SmithCert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured) /// Storage: Parameters ParametersStorage (r:1 w:0) @@ -73,13 +62,13 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { /// Proof Skipped: SmithMembership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) fn claim_membership() -> Weight { // Proof Size summary in bytes: - // Measured: `734` - // Estimated: `4199` - // Minimum execution time: 19_034_000 picoseconds. - Weight::from_parts(20_081_000, 0) - .saturating_add(Weight::from_parts(0, 4199)) - .saturating_add(T::DbWeight::get().reads(7)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `704` + // Estimated: `4169` + // Minimum execution time: 667_020_000 picoseconds. + Weight::from_parts(729_140_000, 0) + .saturating_add(Weight::from_parts(0, 4169)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: Identity IdentityIndexOf (r:1 w:0) /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured) @@ -95,8 +84,8 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { // Proof Size summary in bytes: // Measured: `717` // Estimated: `6657` - // Minimum execution time: 16_561_000 picoseconds. - Weight::from_parts(17_959_000, 0) + // Minimum execution time: 794_915_000 picoseconds. + Weight::from_parts(930_094_000, 0) .saturating_add(Weight::from_parts(0, 6657)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) @@ -127,8 +116,8 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { // Proof Size summary in bytes: // Measured: `1183` // Estimated: `4648` - // Minimum execution time: 34_770_000 picoseconds. - Weight::from_parts(38_431_000, 0) + // Minimum execution time: 1_199_726_000 picoseconds. + Weight::from_parts(1_499_376_000, 0) .saturating_add(Weight::from_parts(0, 4648)) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(13)) @@ -137,58 +126,47 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 25_000 picoseconds. - Weight::from_parts(27_000, 0) + // Minimum execution time: 3_972_000 picoseconds. + Weight::from_parts(4_845_000, 0) .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: SmithMembership PendingMembershipsExpireOn (r:1 w:1) - /// Proof Skipped: SmithMembership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership PendingMembership (r:1024 w:1024) - /// Proof Skipped: SmithMembership PendingMembership (max_values: None, max_size: None, mode: Measured) - /// The range of component `i` is `[0, 1024]`. - /// The range of component `i` is `[0, 1024]`. - fn expire_pending_memberships(i: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `179 + i * (19 ±0)` - // Estimated: `3649 + i * (2495 ±0)` - // Minimum execution time: 2_213_000 picoseconds. - Weight::from_parts(2_309_000, 0) - .saturating_add(Weight::from_parts(0, 3649)) - // Standard Error: 981 - .saturating_add(Weight::from_parts(2_257_315, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into()))) - .saturating_add(T::DbWeight::get().writes(1)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) - .saturating_add(Weight::from_parts(0, 2495).saturating_mul(i.into())) - } - /// Storage: Parameters ParametersStorage (r:1 w:0) - /// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured) /// Storage: SmithMembership MembershipsExpireOn (r:1 w:1) /// Proof Skipped: SmithMembership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured) /// Storage: SmithMembership Membership (r:1024 w:1024) /// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured) /// Storage: SmithMembership CounterForMembership (r:1 w:1) /// Proof: SmithMembership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: SmithMembership PendingMembershipsExpireOn (r:1 w:1) - /// Proof Skipped: SmithMembership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured) - /// Storage: SmithMembership PendingMembership (r:0 w:1024) - /// Proof Skipped: SmithMembership PendingMembership (max_values: None, max_size: None, mode: Measured) + /// Storage: AuthorityMembers Members (r:1024 w:3) + /// Proof Skipped: AuthorityMembers Members (max_values: None, max_size: None, mode: Measured) + /// Storage: AuthorityMembers OnlineAuthorities (r:1 w:1) + /// Proof Skipped: AuthorityMembers OnlineAuthorities (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AuthorityMembers OutgoingAuthorities (r:1 w:1) + /// Proof Skipped: AuthorityMembers OutgoingAuthorities (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AuthorityMembers AuthoritiesCounter (r:1 w:1) + /// Proof Skipped: AuthorityMembers AuthoritiesCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AuthorityMembers IncomingAuthorities (r:1 w:1) + /// Proof Skipped: AuthorityMembers IncomingAuthorities (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session NextKeys (r:3 w:3) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen) + /// Storage: Session KeyOwner (r:0 w:12) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 1024]`. /// The range of component `i` is `[0, 1024]`. fn expire_memberships(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `251 + i * (23 ±0)` - // Estimated: `3735 + i * (2499 ±0)` - // Minimum execution time: 4_948_000 picoseconds. - Weight::from_parts(5_162_000, 0) - .saturating_add(Weight::from_parts(0, 3735)) - // Standard Error: 953 - .saturating_add(Weight::from_parts(3_313_144, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into()))) - .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(i.into()))) + // Measured: `1339 + i * (23 ±0)` + // Estimated: `9830 + i * (2499 ±0)` + // Minimum execution time: 81_859_000 picoseconds. + Weight::from_parts(90_890_000, 0) + .saturating_add(Weight::from_parts(0, 9830)) + // Standard Error: 1_930_380 + .saturating_add(Weight::from_parts(304_822_479, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) + .saturating_add(T::DbWeight::get().writes(16)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 2499).saturating_mul(i.into())) } } diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs index f3b9ec5aa..5b13dec43 100644 --- a/runtime/gdev/src/lib.rs +++ b/runtime/gdev/src/lib.rs @@ -28,8 +28,6 @@ extern crate frame_benchmarking; pub mod parameters; -mod migrations_v400; - pub use self::parameters::*; pub use common_runtime::{ constants::*, entities::*, handlers::*, AccountId, Address, Balance, BlockNumber, @@ -135,7 +133,6 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext<Runtime>, Runtime, AllPalletsWithSystem, - migrations_v400::MigrationsV400, >; pub type TechnicalCommitteeInstance = Instance2; @@ -182,10 +179,8 @@ impl Contains<RuntimeCall> for BaseCallFilter { call, // in main web of trust, membership request and revoke are handeled through identity pallet // the user can not call them directly - RuntimeCall::Membership( - pallet_membership::Call::request_membership { .. } - | pallet_membership::Call::revoke_membership { .. } - ) | RuntimeCall::Session(_) + RuntimeCall::Membership(pallet_membership::Call::revoke_membership { .. }) + | RuntimeCall::Session(_) ) } } @@ -260,7 +255,6 @@ common_runtime::pallets_config! { pub type ConfirmPeriod = pallet_duniter_test_parameters::IdtyConfirmPeriod<Runtime>; pub type IdtyCreationPeriod = pallet_duniter_test_parameters::IdtyCreationPeriod<Runtime>; pub type MembershipPeriod = pallet_duniter_test_parameters::MembershipPeriod<Runtime>; - pub type PendingMembershipPeriod = pallet_duniter_test_parameters::PendingMembershipPeriod<Runtime>; pub type UdCreationPeriod = pallet_duniter_test_parameters::UdCreationPeriod<Runtime>; pub type UdReevalPeriod = pallet_duniter_test_parameters::UdReevalPeriod<Runtime>; pub type WotFirstCertIssuableOn = pallet_duniter_test_parameters::WotFirstCertIssuableOn<Runtime>; @@ -273,8 +267,6 @@ common_runtime::pallets_config! { pallet_duniter_test_parameters::SmithCertMinReceivedCertToIssueCert<Runtime>; pub type SmithValidityPeriod = pallet_duniter_test_parameters::SmithCertValidityPeriod<Runtime>; pub type SmithMembershipPeriod = pallet_duniter_test_parameters::SmithMembershipPeriod<Runtime>; - pub type SmithPendingMembershipPeriod = - pallet_duniter_test_parameters::SmithPendingMembershipPeriod<Runtime>; pub type SmithWotFirstCertIssuableOn = pallet_duniter_test_parameters::SmithWotFirstCertIssuableOn<Runtime>; pub type SmithWotMinCertForMembership = diff --git a/runtime/gdev/src/migrations_v400.rs b/runtime/gdev/src/migrations_v400.rs deleted file mode 100644 index e58e69cb9..000000000 --- a/runtime/gdev/src/migrations_v400.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2021-2022 Axiom-Team -// -// This file is part of Duniter-v2S. -// -// Duniter-v2S is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, version 3 of the License. -// -// Duniter-v2S is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. - -use crate::*; - -pub struct MigrationsV400; -impl frame_support::traits::OnRuntimeUpgrade for MigrationsV400 { - fn on_runtime_upgrade() -> Weight { - let mut weight = Weight::from_parts(1_000_000_000, 0); // Safety margin - - type OldvalueType = AccountId; - - pallet_membership::PendingMembership::<Runtime, Instance1>::translate_values( - |_: OldvalueType| { - *weight.ref_time_mut() += <Runtime as frame_system::Config>::DbWeight::get().write; - Some(()) - }, - ); - - weight - } - - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result<frame_benchmarking::Vec<u8>, &'static str> { - Ok(Vec::new()) - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade(_state: frame_benchmarking::Vec<u8>) -> Result<(), &'static str> { - Ok(()) - } -} diff --git a/runtime/gdev/tests/common/mod.rs b/runtime/gdev/tests/common/mod.rs index 673a02252..5c20cd6ab 100644 --- a/runtime/gdev/tests/common/mod.rs +++ b/runtime/gdev/tests/common/mod.rs @@ -232,8 +232,8 @@ impl ExtBuilder { next_creatable_identity_on: Default::default(), owner_key: owner_key.clone(), old_owner_key: None, - removable_on: 0, - status: IdtyStatus::Validated, + next_scheduled: 0, + status: IdtyStatus::Member, }, }) .collect(), diff --git a/runtime/gdev/tests/fixme_tests.rs b/runtime/gdev/tests/fixme_tests.rs index 2f4d55aac..028f23600 100644 --- a/runtime/gdev/tests/fixme_tests.rs +++ b/runtime/gdev/tests/fixme_tests.rs @@ -20,7 +20,8 @@ mod common; use common::*; -use frame_support::assert_ok; +// use frame_support::assert_ok; +use frame_support::assert_noop; use gdev_runtime::*; use pallet_membership::MembershipRemovalReason; use sp_keyring::AccountKeyring; @@ -30,18 +31,7 @@ use sp_keyring::AccountKeyring; /// identity who has no smith membership or pending membership #[test] fn can_add_smith_cert_without_pending_membership_or_membership() { - // 3 smith (1. Alice, 2. Bob, 3. Charlie) - // 4 identities (4. Dave) - ExtBuilder::new(1, 3, 4).build().execute_with(|| { - run_to_block(1); - - // FIXME Bob can add new smith cert to to dave even he did not requested smith membership - assert_ok!(SmithCert::add_cert( - frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(), - 2, // bob - 4 // dave - )); - }); + // this is fixed because membership request has been removed } /// issue #136 @@ -52,28 +42,32 @@ fn can_still_issue_cert_when_membership_lost() { ExtBuilder::new(1, 3, 4).build().execute_with(|| { run_to_block(1); - // expire Bob membership (could happen for negative distance evaluation for example) - assert_ok!(Membership::force_expire_membership( - 2, // Bob - )); + // expire Bob membership + Membership::do_remove_membership( + 2, + MembershipRemovalReason::System + ); System::assert_has_event(RuntimeEvent::Membership( pallet_membership::Event::MembershipRemoved { member: 2, - reason: MembershipRemovalReason::Expired, + reason: MembershipRemovalReason::System, }, )); - // FIXME this should not be possible - assert_ok!(Cert::add_cert( + // fixed :) + assert_noop!(Cert::add_cert( frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(), - 2, // Bob - 3, // Charlie - )); - System::assert_has_event(RuntimeEvent::Cert( - pallet_certification::Event::CertRenewed { - issuer: 2, - receiver: 3, - }, - )); + 2, // Bob + 3, // Charlie + ), + pallet_duniter_wot::Error::<gdev_runtime::Runtime, pallet_certification::Instance1>::IssuerNotMember + ); + // // not anymore + // System::assert_has_event(RuntimeEvent::Cert( + // pallet_certification::Event::CertRenewed { + // issuer: 2, + // receiver: 3, + // }, + // )); }); } diff --git a/runtime/gdev/tests/integration_tests.rs b/runtime/gdev/tests/integration_tests.rs index cb3819c84..fa7008447 100644 --- a/runtime/gdev/tests/integration_tests.rs +++ b/runtime/gdev/tests/integration_tests.rs @@ -23,7 +23,6 @@ use frame_support::traits::{Get, PalletInfo, StorageInfo, StorageInfoTrait}; use frame_support::{assert_noop, assert_ok}; use frame_support::{StorageHasher, Twox128}; use gdev_runtime::*; -use pallet_duniter_wot::IdtyRemovalWotReason; use pallet_membership::MembershipRemovalReason; use sp_core::Encode; use sp_keyring::AccountKeyring; @@ -284,28 +283,24 @@ fn test_session_change() { }) } -/// test calling force_remove_identity +/// test calling do_remove_identity #[test] -fn test_force_remove_identity() { +fn test_remove_identity() { ExtBuilder::new(1, 3, 4).build().execute_with(|| { run_to_block(2); // remove the identity - assert_ok!(Identity::force_remove_identity( - frame_system::RawOrigin::Root.into(), - 4, - None, - pallet_identity::IdtyRemovalReason::Manual - )); - System::assert_has_event(RuntimeEvent::Membership( - pallet_membership::Event::MembershipRemoved { - member: 4, - reason: MembershipRemovalReason::Revoked, - }, - )); + Identity::do_remove_identity(4, pallet_identity::RemovalReason::Root); + // // membership removal is no more automatic + // System::assert_has_event(RuntimeEvent::Membership( + // pallet_membership::Event::MembershipRemoved { + // member: 4, + // reason: MembershipRemovalReason::System, + // }, + // )); System::assert_has_event(RuntimeEvent::Identity( pallet_identity::Event::IdtyRemoved { idty_index: 4, - reason: pallet_identity::IdtyRemovalReason::Manual, + reason: pallet_identity::RemovalReason::Root, }, )); // since Dave does not have ED, his account is killed @@ -377,15 +372,7 @@ fn test_validate_identity_when_claim() { ), }, )); - - // ferdie can not validate eve identity because already validated - assert_noop!( - Identity::validate_identity( - frame_system::RawOrigin::Signed(AccountKeyring::Ferdie.to_account_id()).into(), - 5, - ), - pallet_identity::Error::<Runtime>::IdtyAlreadyValidated - ); + // not possible anymore to validate identity of someone else }); } @@ -401,15 +388,12 @@ fn test_membership_expiry() { }, )); // membership expiry should not trigger identity removal - assert!(!System::events().iter().any(|record| record.event - == RuntimeEvent::Identity(pallet_identity::Event::IdtyRemoved { - idty_index: 1, - reason: pallet_identity::IdtyRemovalReason::Expired - }))); + assert!(Identity::identity(1).is_some()); }); } #[test] +#[ignore = "long to go to autorevocation period"] fn test_membership_expiry_with_identity_removal() { ExtBuilder::new(1, 3, 4).build().execute_with(|| { run_to_block(100); @@ -422,16 +406,12 @@ fn test_membership_expiry_with_identity_removal() { )); // Trigger pending membership expiry - run_to_block( - 100 + <Runtime as pallet_membership::Config<Instance1>>::PendingMembershipPeriod::get(), - ); + run_to_block(100 + <Runtime as pallet_identity::Config>::AutorevocationPeriod::get()); System::assert_has_event(RuntimeEvent::Identity( - pallet_identity::Event::IdtyRemoved { + pallet_identity::Event::IdtyRevoked { idty_index: 4, - reason: pallet_identity::IdtyRemovalReason::Other( - IdtyRemovalWotReason::MembershipExpired, - ), + reason: pallet_identity::RevocationReason::Expired, }, )); }); @@ -496,9 +476,9 @@ fn test_membership_renewal() { }); } -// test that UD are auto claimed when identity is removed +// test that UD are auto claimed when identity is revoked #[test] -fn test_remove_identity_after_one_ud() { +fn test_revoke_identity_after_one_ud() { ExtBuilder::new(1, 3, 4).build().execute_with(|| { //println!("UdCreationPeriod={}", <Runtime as pallet_universal_dividend::Config>::UdCreationPeriod::get()); run_to_block( @@ -520,18 +500,13 @@ fn test_remove_identity_after_one_ud() { / <Runtime as pallet_babe::Config>::ExpectedBlockTime::get() + 1) as u32, ); - // remove identity - assert_ok!(Identity::force_remove_identity( - frame_system::RawOrigin::Root.into(), - 4, - None, - pallet_identity::IdtyRemovalReason::Manual - )); + // revoke identity + Identity::do_revoke_identity(4, pallet_identity::RevocationReason::Root); // Verify events // universal dividend was automatically paid to dave System::assert_has_event(RuntimeEvent::UniversalDividend( - pallet_universal_dividend::Event::UdsAutoPaidAtRemoval { + pallet_universal_dividend::Event::UdsAutoPaid { count: 1, total: 1_000, who: AccountKeyring::Dave.to_account_id(), @@ -550,14 +525,13 @@ fn test_remove_identity_after_one_ud() { }, )); System::assert_has_event(RuntimeEvent::Identity( - pallet_identity::Event::IdtyRemoved { + pallet_identity::Event::IdtyRevoked { idty_index: 4, - reason: pallet_identity::IdtyRemovalReason::Manual, + reason: pallet_identity::RevocationReason::Root, }, )); - // thanks to the new UD, Dave has existential deposit and is not killed - assert!(Identity::identity(4).is_none()); + assert!(Identity::identity(4).is_some()); // identity still exists, but its status is revoked assert_eq!( Balances::free_balance(AccountKeyring::Dave.to_account_id()), 1_000 @@ -588,9 +562,9 @@ fn test_ud_claimed_membership_on_and_off() { run_to_block(13); // alice identity expires - assert_ok!(Membership::force_expire_membership(1)); + Membership::do_remove_membership(1, MembershipRemovalReason::System); System::assert_has_event(RuntimeEvent::UniversalDividend( - pallet_universal_dividend::Event::UdsAutoPaidAtRemoval { + pallet_universal_dividend::Event::UdsAutoPaid { count: 1, total: 1_000, who: AccountKeyring::Alice.to_account_id(), @@ -665,18 +639,13 @@ fn test_ud_claimed_membership_on_and_off() { }); } -/// test when root removes and identity, all consumers should be deleted +/// test when root revokes and identity, all membership should be deleted #[test] -fn test_remove_smith_identity() { +fn test_revoke_smith_identity() { ExtBuilder::new(1, 3, 4).build().execute_with(|| { run_to_block(2); - assert_ok!(Identity::force_remove_identity( - frame_system::RawOrigin::Root.into(), - 3, - None, - pallet_identity::IdtyRemovalReason::Manual - )); + Identity::do_revoke_identity(3, pallet_identity::RevocationReason::Root); // Verify events System::assert_has_event(RuntimeEvent::SmithMembership( pallet_membership::Event::MembershipRemoved { @@ -694,9 +663,9 @@ fn test_remove_smith_identity() { }, )); System::assert_has_event(RuntimeEvent::Identity( - pallet_identity::Event::IdtyRemoved { + pallet_identity::Event::IdtyRevoked { idty_index: 3, - reason: pallet_identity::IdtyRemovalReason::Manual, + reason: pallet_identity::RevocationReason::Root, }, )); }); @@ -733,59 +702,68 @@ fn test_smith_certification() { /// test the full process to join smith from main wot member to authority member #[test] fn test_smith_process() { - ExtBuilder::new(1, 3, 4).with_initial_balances(vec![(AccountKeyring::Dave.to_account_id(), 1_000)]) - .build().execute_with(|| { - run_to_block(1); - - let alice = AccountKeyring::Alice.to_account_id(); - let bob = AccountKeyring::Bob.to_account_id(); - let charlie = AccountKeyring::Charlie.to_account_id(); + ExtBuilder::new(1, 3, 4) + .with_initial_balances(vec![(AccountKeyring::Dave.to_account_id(), 1_000)]) + .build() + .execute_with(|| { + run_to_block(1); - // Eve can not request smith membership because not member of the smith wot - assert_noop!(SmithMembership::request_membership( - frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into()), - pallet_membership::Error::<gdev_runtime::Runtime, pallet_membership::Instance2>::IdtyIdNotFound, - ); + let alice = AccountKeyring::Alice.to_account_id(); + let bob = AccountKeyring::Bob.to_account_id(); + let charlie = AccountKeyring::Charlie.to_account_id(); - // Dave can request smith membership (currently optional) - assert_ok!(SmithMembership::request_membership( - frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), - )); + // Eve can not request smith membership because not member of the smith wot + // no more membership request - assert_eq!(SmithMembership::pending_membership(5), None); // none for Eve - assert_eq!(SmithMembership::pending_membership(4), Some(())); // Dave + // Dave can request smith membership (currently optional) + // no more membership request - // then Alice Bob and Charlie can certify Dave - assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(alice).into(), 1, 4)); - assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(bob).into(), 2, 4)); - assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(charlie).into(), 3, 4)); + // Alice Bob and Charlie can certify Dave + assert_ok!(SmithCert::add_cert( + frame_system::RawOrigin::Signed(alice).into(), + 1, + 4 + )); + assert_ok!(SmithCert::add_cert( + frame_system::RawOrigin::Signed(bob).into(), + 2, + 4 + )); + assert_ok!(SmithCert::add_cert( + frame_system::RawOrigin::Signed(charlie).into(), + 3, + 4 + )); - // with these three smith certs, Dave can claim membership - assert_ok!(SmithMembership::claim_membership( - frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), - )); + // with these three smith certs, Dave can claim membership + assert_ok!(SmithMembership::claim_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), + )); - // Dave is then member of the smith wot - assert_eq!(SmithMembership::membership(4), Some(sp_membership::MembershipData { - expire_on: 1001, // 1 + 1000 - })); + // Dave is then member of the smith wot + assert_eq!( + SmithMembership::membership(4), + Some(sp_membership::MembershipData { + expire_on: 1001, // 1 + 1000 + }) + ); - // Dave can set his (dummy) session keys - assert_ok!(AuthorityMembers::set_session_keys( - frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), - gdev_runtime::opaque::SessionKeys{ - grandpa: sp_core::ed25519::Public([0u8; 32]).into(), - babe: sp_core::sr25519::Public([0u8; 32]).into(), - im_online: sp_core::sr25519::Public([0u8; 32]).into(), - authority_discovery: sp_core::sr25519::Public([0u8; 32]).into(), - } - )); + // Dave can set his (dummy) session keys + assert_ok!(AuthorityMembers::set_session_keys( + frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), + gdev_runtime::opaque::SessionKeys { + grandpa: sp_core::ed25519::Public([0u8; 32]).into(), + babe: sp_core::sr25519::Public([0u8; 32]).into(), + im_online: sp_core::sr25519::Public([0u8; 32]).into(), + authority_discovery: sp_core::sr25519::Public([0u8; 32]).into(), + } + )); - // Dave can go online - assert_ok!(AuthorityMembers::go_online( - frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), - )); - }) + // Dave can go online + assert_ok!(AuthorityMembers::go_online( + frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), + )); + }) } /// test create new account with balance lower than existential deposit @@ -1060,9 +1038,8 @@ fn test_validate_new_idty_after_few_uds() { pallet_distance::DistanceStatus::Valid )) )); - assert_ok!(Identity::validate_identity( - frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(), - 5, + assert_ok!(Membership::claim_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), )); // The new member should have first_eligible_ud equal to three diff --git a/runtime/gtest/src/lib.rs b/runtime/gtest/src/lib.rs index 841a039fc..88fbd282f 100644 --- a/runtime/gtest/src/lib.rs +++ b/runtime/gtest/src/lib.rs @@ -171,17 +171,10 @@ mod benches { pub struct BaseCallFilter; // implement filter +// session pallet calls are filtered in order to use authority member instead impl Contains<RuntimeCall> for BaseCallFilter { fn contains(call: &RuntimeCall) -> bool { - !matches!( - call, - // in main web of trust, membership request and revoke are handeled through identity pallet - // the user can not call them directly - RuntimeCall::Membership( - pallet_membership::Call::request_membership { .. } - | pallet_membership::Call::revoke_membership { .. } - ) | RuntimeCall::Session(_) - ) + !matches!(call, RuntimeCall::Session(_)) } } diff --git a/runtime/gtest/src/parameters.rs b/runtime/gtest/src/parameters.rs index 9f29ce90f..443e8cffa 100644 --- a/runtime/gtest/src/parameters.rs +++ b/runtime/gtest/src/parameters.rs @@ -71,7 +71,7 @@ parameter_types! { /*********/ // Balances -frame_support::parameter_types! { +parameter_types! { // we take 100 of existential deposit to mimic duniter v1 // and avoid loosing too many accounts during the migration pub const ExistentialDeposit: Balance = 100; @@ -98,7 +98,7 @@ parameter_types! { } // Identity -frame_support::parameter_types! { +parameter_types! { pub const ChangeOwnerKeyPeriod: BlockNumber = MONTHS; pub const ConfirmPeriod: BlockNumber = DAYS; pub const IdtyCreationPeriod: BlockNumber = DAYS; diff --git a/xtask/src/gen_doc.rs b/xtask/src/gen_doc.rs index 5822b5bea..9f077659c 100644 --- a/xtask/src/gen_doc.rs +++ b/xtask/src/gen_doc.rs @@ -203,7 +203,6 @@ impl CallCategory { "Identity", "remove_identity" | "prune_item_identities_names" | "prune_item_identity_index_of", ) => Self::Root, - ("Membership", "request_membership" | "revoke_membership") => Self::Disabled, ("Cert", "del_cert" | "remove_all_certs_received_by") => Self::Root, ("SmithCert", "del_cert" | "remove_all_certs_received_by") => Self::Root, ("TechnicalCommittee", "set_members" | "disapprove_proposal") => Self::Root, -- GitLab