From 8eceaddbbc6f8cd2d3347b5f75e6af5ab49ea1e9 Mon Sep 17 00:00:00 2001 From: librelois <c@elo.tf> Date: Tue, 18 Jan 2022 23:26:09 +0100 Subject: [PATCH] chore: create pallet dumiter-wot and move in wot logic --- Cargo.lock | 29 ++- Cargo.toml | 1 + pallets/certification/src/lib.rs | 12 - pallets/certification/src/traits.rs | 4 - pallets/duniter-wot/Cargo.toml | 93 +++++++ pallets/duniter-wot/src/lib.rs | 356 +++++++++++++++++++++++++++ pallets/duniter-wot/src/mock.rs | 259 +++++++++++++++++++ pallets/duniter-wot/src/tests.rs | 217 ++++++++++++++++ pallets/duniter-wot/src/types.rs | 114 +++++++++ pallets/identity/Cargo.toml | 2 - pallets/identity/src/lib.rs | 262 ++++++++------------ pallets/identity/src/mock.rs | 11 +- pallets/identity/src/traits.rs | 18 +- pallets/identity/src/types.rs | 8 +- pallets/membership/src/lib.rs | 15 +- pallets/membership/src/mock.rs | 2 +- pallets/membership/src/tests.rs | 17 +- primitives/membership/Cargo.toml | 6 + primitives/membership/src/traits.rs | 20 +- runtime/common/Cargo.toml | 7 +- runtime/common/src/authorizations.rs | 96 -------- runtime/common/src/entities.rs | 26 -- runtime/common/src/handlers.rs | 118 +-------- runtime/common/src/lib.rs | 1 - runtime/common/src/pallets_config.rs | 36 +-- runtime/g1/Cargo.toml | 8 +- runtime/g1/src/lib.rs | 31 ++- runtime/g1/src/parameters.rs | 6 + runtime/gdev/Cargo.toml | 6 +- runtime/gdev/src/lib.rs | 28 ++- runtime/gdev/src/parameters.rs | 9 +- runtime/gtest/Cargo.toml | 8 +- runtime/gtest/src/lib.rs | 31 ++- runtime/gtest/src/parameters.rs | 6 + 34 files changed, 1346 insertions(+), 517 deletions(-) create mode 100644 pallets/duniter-wot/Cargo.toml create mode 100644 pallets/duniter-wot/src/lib.rs create mode 100644 pallets/duniter-wot/src/mock.rs create mode 100644 pallets/duniter-wot/src/tests.rs create mode 100644 pallets/duniter-wot/src/types.rs delete mode 100644 runtime/common/src/authorizations.rs diff --git a/Cargo.lock b/Cargo.lock index 1f8f7eb35..7229b35a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -836,6 +836,7 @@ dependencies = [ "frame-support", "frame-system", "pallet-certification", + "pallet-duniter-wot", "pallet-identity", "pallet-membership", "pallet-session", @@ -1894,6 +1895,7 @@ dependencies = [ "pallet-babe", "pallet-balances", "pallet-certification", + "pallet-duniter-wot", "pallet-grandpa", "pallet-identity", "pallet-im-online", @@ -1920,6 +1922,7 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-inherents", + "sp-membership", "sp-offchain", "sp-runtime", "sp-session", @@ -1944,6 +1947,7 @@ dependencies = [ "pallet-babe", "pallet-balances", "pallet-certification", + "pallet-duniter-wot", "pallet-grandpa", "pallet-identity", "pallet-membership", @@ -1965,6 +1969,7 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-inherents", + "sp-membership", "sp-offchain", "sp-runtime", "sp-session", @@ -2122,6 +2127,7 @@ dependencies = [ "pallet-babe", "pallet-balances", "pallet-certification", + "pallet-duniter-wot", "pallet-grandpa", "pallet-identity", "pallet-im-online", @@ -2148,6 +2154,7 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-inherents", + "sp-membership", "sp-offchain", "sp-runtime", "sp-session", @@ -4225,6 +4232,26 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-duniter-wot" +version = "3.0.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-certification", + "pallet-identity", + "pallet-membership", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-membership", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-grandpa" version = "4.0.0-dev" @@ -4260,7 +4287,6 @@ dependencies = [ "serde", "sp-core", "sp-io", - "sp-membership", "sp-runtime", "sp-std", ] @@ -7020,6 +7046,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", + "sp-runtime", "sp-std", ] diff --git a/Cargo.toml b/Cargo.toml index cb8a484d4..225f5d1f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,6 +98,7 @@ resolver = "2" members = [ 'integration-tests', 'pallets/certification', + 'pallets/duniter-wot', 'pallets/identity', 'pallets/membership', 'pallets/ud-accounts-storage', diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs index a129d24e9..3462440a0 100644 --- a/pallets/certification/src/lib.rs +++ b/pallets/certification/src/lib.rs @@ -482,18 +482,6 @@ pub mod pallet { } } -impl<T: Config<I>, I: 'static> IsIdtyAllowedToCreateCert<T::IdtyIndex> for Pallet<T, I> { - fn is_idty_allowed_to_create_cert(idty_index: T::IdtyIndex) -> bool { - if let Ok(cert_meta) = <StorageIdtyCertMeta<T, I>>::try_get(idty_index) { - use frame_support::traits::Get as _; - cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number() - && cert_meta.issued_count < T::MaxByIssuer::get() - } else { - true - } - } -} - impl<T: Config<I>, I: 'static> SetNextIssuableOn<T::BlockNumber, T::IdtyIndex> for Pallet<T, I> { fn set_next_issuable_on( idty_index: T::IdtyIndex, diff --git a/pallets/certification/src/traits.rs b/pallets/certification/src/traits.rs index e4ac1e7e0..aea859b01 100644 --- a/pallets/certification/src/traits.rs +++ b/pallets/certification/src/traits.rs @@ -14,10 +14,6 @@ // 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/>. -pub trait IsIdtyAllowedToCreateCert<IdtyIndex> { - fn is_idty_allowed_to_create_cert(idty_index: IdtyIndex) -> bool; -} - pub trait OnNewcert<IdtyIndex> { fn on_new_cert( issuer: IdtyIndex, diff --git a/pallets/duniter-wot/Cargo.toml b/pallets/duniter-wot/Cargo.toml new file mode 100644 index 000000000..e23031d7e --- /dev/null +++ b/pallets/duniter-wot/Cargo.toml @@ -0,0 +1,93 @@ +[package] +authors = ['librelois <c@elo.tf>'] +description = 'FRAME pallet duniter wot.' +edition = '2018' +homepage = 'https://substrate.dev' +license = 'AGPL-3.0' +name = 'pallet-duniter-wot' +readme = 'README.md' +repository = 'https://git.duniter.org/nodes/rust/duniter-v2s' +version = '3.0.0' + +[features] +default = ['std'] +runtime-benchmarks = ['frame-benchmarking'] +std = [ + 'codec/std', + 'frame-support/std', + 'frame-system/std', + 'frame-benchmarking/std', + 'pallet-certification/std', + 'pallet-identity/std', + 'pallet-membership/std', + 'serde', + 'sp-core/std', + 'sp-membership/std', + 'sp-runtime/std', + 'sp-std/std', +] +try-runtime = ['frame-support/try-runtime'] + +[dependencies] +pallet-certification = { path = "../certification", default-features = false } +pallet-identity = { path = "../identity", default-features = false } +pallet-membership = { path = "../membership", default-features = false } +sp-membership = { path = "../../primitives/membership", default-features = false } + +# substrate +scale-info = { version = "1.0", default-features = false, features = ["derive"] } + +[dependencies.codec] +default-features = false +features = ['derive'] +package = 'parity-scale-codec' +version = '2.3.1' + +[dependencies.frame-benchmarking] +default-features = false +git = 'https://github.com/librelois/substrate.git' +optional = true +branch = 'duniter-monthly-2022-01' + +[dependencies.frame-support] +default-features = false +git = 'https://github.com/librelois/substrate.git' +branch = 'duniter-monthly-2022-01' + +[dependencies.frame-system] +default-features = false +git = 'https://github.com/librelois/substrate.git' +branch = 'duniter-monthly-2022-01' + +[dependencies.serde] +version = "1.0.101" +optional = true +features = ["derive"] + +[dependencies.sp-core] +default-features = false +git = 'https://github.com/librelois/substrate.git' +branch = 'duniter-monthly-2022-01' + +[dependencies.sp-runtime] +default-features = false +git = 'https://github.com/librelois/substrate.git' +branch = 'duniter-monthly-2022-01' + +[dependencies.sp-std] +default-features = false +git = 'https://github.com/librelois/substrate.git' +branch = 'duniter-monthly-2022-01' + +### DOC ### + +[package.metadata.docs.rs] +targets = ['x86_64-unknown-linux-gnu'] +[dev-dependencies.serde] +version = '1.0.119' + +### DEV ### + +[dev-dependencies.sp-io] +git = 'https://github.com/librelois/substrate.git' +branch = 'duniter-monthly-2022-01' diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs new file mode 100644 index 000000000..1f77b043d --- /dev/null +++ b/pallets/duniter-wot/src/lib.rs @@ -0,0 +1,356 @@ +// 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/>. + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::type_complexity)] + +//pub mod traits; +mod types; + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +/*#[cfg(feature = "runtime-benchmarks")] +mod benchmarking;*/ + +pub use pallet::*; +pub use types::*; + +use frame_support::instances::Instance1; +use frame_support::pallet_prelude::*; +use frame_system::RawOrigin; +use pallet_certification::traits::SetNextIssuableOn; +use pallet_identity::{IdtyEvent, IdtyStatus}; +use sp_runtime::traits::IsMember; + +type IdtyIndex = u32; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::traits::StorageVersion; + + /// The current storage version. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet<T>(_); + + // CONFIG // + + #[pallet::config] + pub trait Config: + frame_system::Config + + pallet_certification::Config<Instance1, IdtyIndex = IdtyIndex> + + pallet_identity::Config<IdtyIndex = IdtyIndex, IdtyRight = IdtyRight> + + pallet_membership::Config<Instance1, IdtyId = IdtyIndex> + { + type MinCertForUdRight: Get<u8>; + type MinCertForCertRight: Get<u8>; + type MinCertForCreateIdtyRight: Get<u8>; + type FirstIssuableOn: Get<Self::BlockNumber>; + } + + // INTERNAL FUNCTIONS // + + impl<T: Config> Pallet<T> { + pub(super) fn do_apply_first_issuable_on(idty_index: IdtyIndex) { + let block_number = frame_system::pallet::Pallet::<T>::block_number(); + pallet_certification::Pallet::<T, Instance1>::set_next_issuable_on( + idty_index, + block_number + T::FirstIssuableOn::get(), + ); + } + pub(super) fn do_add_cert_right(idty_index: IdtyIndex) { + match pallet_identity::Pallet::<T>::add_right( + RawOrigin::Root.into(), + idty_index, + IdtyRight::StrongCert, + ) { + Ok(_) => { + Self::do_apply_first_issuable_on(idty_index); + } + Err(e) => { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + } + pub(super) fn do_add_rights(idty_index: IdtyIndex, received_cert_count: u32) { + if received_cert_count >= T::MinCertForUdRight::get() as u32 { + if let Err(e) = pallet_identity::Pallet::<T>::add_right( + RawOrigin::Root.into(), + idty_index, + IdtyRight::Ud, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + if received_cert_count >= T::MinCertForCertRight::get() as u32 { + Self::do_add_cert_right(idty_index); + } + if received_cert_count >= T::MinCertForCreateIdtyRight::get() as u32 { + if let Err(e) = pallet_identity::Pallet::<T>::add_right( + RawOrigin::Root.into(), + idty_index, + IdtyRight::CreateIdty, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + } + } +} + +impl<T: Config> pallet_identity::traits::EnsureIdtyCallAllowed<T> for Pallet<T> { + fn can_create_identity(creator: IdtyIndex) -> bool { + if let Some(cert_meta) = + pallet_certification::Pallet::<T, Instance1>::idty_cert_meta(creator) + { + use frame_support::traits::Get as _; + cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number() + && cert_meta.issued_count < T::MaxByIssuer::get() + } else { + true + } + } + fn can_confirm_identity(idty_index: IdtyIndex) -> bool { + pallet_membership::Pallet::<T, Instance1>::request_membership( + RawOrigin::Root.into(), + idty_index, + ) + .is_ok() + } + fn can_validate_identity(idty_index: IdtyIndex) -> bool { + pallet_membership::Pallet::<T, Instance1>::claim_membership( + RawOrigin::Root.into(), + idty_index, + ) + .is_ok() + } +} + +impl<T: Config> sp_membership::traits::IsIdtyAllowedToClaimMembership<IdtyIndex> for Pallet<T> { + fn is_idty_allowed_to_claim_membership(_: &IdtyIndex) -> bool { + false + } +} + +impl<T: Config> sp_membership::traits::IsIdtyAllowedToRenewMembership<IdtyIndex> for Pallet<T> { + fn is_idty_allowed_to_renew_membership(idty_index: &IdtyIndex) -> bool { + if let Some(idty_value) = pallet_identity::Pallet::<T>::identity(idty_index) { + idty_value.status == IdtyStatus::Validated + } else { + false + } + } +} + +impl<T: Config> sp_membership::traits::IsIdtyAllowedToRequestMembership<IdtyIndex> for Pallet<T> { + fn is_idty_allowed_to_request_membership(idty_index: &IdtyIndex) -> bool { + if let Some(idty_value) = pallet_identity::Pallet::<T>::identity(idty_index) { + idty_value.status == IdtyStatus::Validated + } else { + false + } + } +} + +impl<T: Config> sp_membership::traits::IsOriginAllowedToUseIdty<T::Origin, IdtyIndex> + for Pallet<T> +{ + fn is_origin_allowed_to_use_idty( + origin: &T::Origin, + idty_index: &IdtyIndex, + ) -> sp_membership::OriginPermission { + match origin.clone().into() { + Ok(RawOrigin::Root) => sp_membership::OriginPermission::Root, + Ok(RawOrigin::Signed(account_id)) => { + if let Some(idty_val) = pallet_identity::Pallet::<T>::identity(idty_index) { + if account_id == idty_val.owner_key { + sp_membership::OriginPermission::Allowed + } else { + sp_membership::OriginPermission::Forbidden + } + } else { + sp_membership::OriginPermission::Forbidden + } + } + _ => sp_membership::OriginPermission::Forbidden, + } + } +} + +impl<T: crate::pallet::Config> sp_membership::traits::OnEvent<IdtyIndex> for Pallet<T> { + fn on_event(membership_event: sp_membership::Event<IdtyIndex>) -> Weight { + match membership_event { + sp_membership::Event::<IdtyIndex>::MembershipAcquired(_) => {} + sp_membership::Event::<IdtyIndex>::MembershipExpired(idty_index) => { + if let Err(e) = pallet_identity::Pallet::<T>::remove_all_rights( + RawOrigin::Root.into(), + idty_index, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + sp_membership::Event::<IdtyIndex>::MembershipRenewed(_) => {} + sp_membership::Event::<IdtyIndex>::MembershipRequested(idty_index) => { + if let Some(idty_cert_meta) = + pallet_certification::Pallet::<T, Instance1>::idty_cert_meta(idty_index) + { + let received_count = idty_cert_meta.received_count; + + // TODO insert `receiver` in distance queue if received_count >= MinCertForUdRight + Self::do_add_rights(idty_index, received_count); + } + } + sp_membership::Event::<IdtyIndex>::MembershipRevoked(_) => {} + sp_membership::Event::<IdtyIndex>::PendingMembershipExpired(idty_index) => { + if let Err(e) = pallet_identity::Pallet::<T>::remove_identity( + RawOrigin::Root.into(), + idty_index, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + } + 0 + } +} + +impl<T: Config> pallet_identity::traits::OnIdtyChange<T> for Pallet<T> { + fn on_idty_change(idty_index: IdtyIndex, idty_event: IdtyEvent<T>) -> Weight { + match idty_event { + IdtyEvent::Created { creator } => { + if let Err(e) = <pallet_certification::Pallet<T, Instance1>>::add_cert( + frame_system::Origin::<T>::Root.into(), + creator, + idty_index, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + IdtyEvent::Confirmed => {} + IdtyEvent::Validated => {} + IdtyEvent::Removed => {} + } + 0 + } +} + +impl<T: crate::pallet::Config> pallet_certification::traits::OnNewcert<IdtyIndex> for Pallet<T> { + fn on_new_cert( + _issuer: IdtyIndex, + _issuer_issued_count: u8, + receiver: IdtyIndex, + receiver_received_count: u32, + ) -> Weight { + if pallet_membership::Pallet::<T, Instance1>::is_member(&receiver) { + Self::do_add_rights(receiver, receiver_received_count); + } else if pallet_membership::Pallet::<T, Instance1>::pending_membership(receiver).is_some() + && receiver_received_count >= T::MinCertForUdRight::get() as u32 + { + // TODO insert `receiver` in distance queue + let mut rights = sp_std::vec![IdtyRight::Ud]; + let mut cert_right = false; + if receiver_received_count >= T::MinCertForCertRight::get() as u32 { + rights.push(IdtyRight::StrongCert); + cert_right = true; + } + if receiver_received_count >= T::MinCertForCreateIdtyRight::get() as u32 { + rights.push(IdtyRight::CreateIdty); + } + if let Err(e) = pallet_identity::Pallet::<T>::validate_identity( + RawOrigin::Root.into(), + receiver, + rights, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + return 0; + } + + if cert_right { + Self::do_apply_first_issuable_on(receiver); + } + } + 0 + } +} + +impl<T: crate::pallet::Config> pallet_certification::traits::OnRemovedCert<IdtyIndex> + for Pallet<T> +{ + fn on_removed_cert( + _issuer: IdtyIndex, + _issuer_issued_count: u8, + receiver: IdtyIndex, + receiver_received_count: u32, + _expiration: bool, + ) -> Weight { + if receiver_received_count < T::MinCertForUdRight::get() as u32 { + if let Err(e) = pallet_identity::Pallet::<T>::del_right( + RawOrigin::Root.into(), + receiver, + IdtyRight::Ud, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + if receiver_received_count < T::MinCertForCertRight::get() as u32 { + if let Err(e) = pallet_identity::Pallet::<T>::del_right( + RawOrigin::Root.into(), + receiver, + IdtyRight::StrongCert, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + if receiver_received_count < T::MinCertForCreateIdtyRight::get() as u32 { + if let Err(e) = pallet_identity::Pallet::<T>::del_right( + RawOrigin::Root.into(), + receiver, + IdtyRight::CreateIdty, + ) { + sp_std::if_std! { + println!("{:?}", e) + } + } + } + 0 + } +} diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs new file mode 100644 index 000000000..fabecf7a6 --- /dev/null +++ b/pallets/duniter-wot/src/mock.rs @@ -0,0 +1,259 @@ +// 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 crate::{self as pallet_duniter_wot}; +use frame_support::{parameter_types, traits::Everything}; +use frame_system as system; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, +}; +use std::collections::BTreeMap; + +type AccountId = u64; +type Block = frame_system::mocking::MockBlock<Test>; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event<T>}, + DuniterWot: pallet_duniter_wot::{Pallet}, + Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>}, + Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>}, + Cert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>}, + } +); + +// Sstem +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; +} + +impl system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup<Self::AccountId>; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +// DuniterWot +parameter_types! { + pub const MinCertForUdRight: u8 = 2; + pub const MinCertForCertRight: u8 = 3; + pub const MinCertForCreateIdtyRigh: u8 = 4; + pub const FirstIssuableOn: u64 = 2; +} + +impl pallet_duniter_wot::Config for Test { + type MinCertForUdRight = MinCertForUdRight; + type MinCertForCertRight = MinCertForCertRight; + type MinCertForCreateIdtyRight = MinCertForCreateIdtyRigh; + type FirstIssuableOn = FirstIssuableOn; +} + +// Identity +parameter_types! { + pub const ConfirmPeriod: u64 = 2; + pub const IdtyCreationPeriod: u64 = 3; + pub const MaxInactivityPeriod: u64 = 5; + pub const MaxNoRightPeriod: u64 = 4; + pub const ValidationPeriod: u64 = 2; +} + +pub struct IdtyNameValidatorTestImpl; +impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { + fn validate(idty_name: &pallet_identity::IdtyName) -> bool { + idty_name.0.len() < 16 + } +} + +impl pallet_identity::Config for Test { + type ConfirmPeriod = ConfirmPeriod; + type Event = Event; + type AddRightOrigin = system::EnsureRoot<AccountId>; + type DelRightOrigin = system::EnsureRoot<AccountId>; + type EnsureIdtyCallAllowed = DuniterWot; + type IdtyCreationPeriod = IdtyCreationPeriod; + type IdtyData = (); + type IdtyDataProvider = (); + type IdtyNameValidator = IdtyNameValidatorTestImpl; + type IdtyIndex = IdtyIndex; + type IdtyValidationOrigin = system::EnsureRoot<AccountId>; + type IdtyRight = IdtyRight; + type IsMember = Membership; + type OnIdtyChange = DuniterWot; + type OnRightKeyChange = (); + type MaxNoRightPeriod = MaxNoRightPeriod; +} + +// Membership +parameter_types! { + pub const ExternalizeMembershipStorage: bool = false; + pub const MembershipPeriod: u64 = 5; + pub const PendingMembershipPeriod: u64 = 3; + pub const RenewablePeriod: u64 = 2; + pub const RevocationPeriod: u64 = 4; +} + +impl pallet_membership::Config<Instance1> for Test { + type IsIdtyAllowedToClaimMembership = DuniterWot; + type IsIdtyAllowedToRenewMembership = DuniterWot; + type IsIdtyAllowedToRequestMembership = DuniterWot; + type IsOriginAllowedToUseIdty = DuniterWot; + type Event = Event; + type ExternalizeMembershipStorage = ExternalizeMembershipStorage; + type IdtyId = IdtyIndex; + type OnEvent = DuniterWot; + type MembershipExternalStorage = sp_membership::traits::NoExternalStorage; + type MembershipPeriod = MembershipPeriod; + type PendingMembershipPeriod = PendingMembershipPeriod; + type RenewablePeriod = RenewablePeriod; + type RevocationPeriod = RevocationPeriod; +} + +// Cert +parameter_types! { + pub const MaxByIssuer: u8 = 3; + pub const CertRenewablePeriod: u64 = 4; + pub const CertPeriod: u64 = 2; + pub const ValidityPeriod: u64 = 10; +} + +impl pallet_certification::Config<Instance1> for Test { + type AddCertOrigin = pallet_duniter_wot::AddStrongCertOrigin<Test>; + type CertPeriod = CertPeriod; + type DelCertOrigin = pallet_duniter_wot::DelStrongCertOrigin<Test>; + type Event = Event; + type IdtyIndex = IdtyIndex; + type MaxByIssuer = MaxByIssuer; + type OnNewcert = DuniterWot; + type OnRemovedCert = DuniterWot; + type CertRenewablePeriod = CertRenewablePeriod; + type ValidityPeriod = ValidityPeriod; +} + +pub const NAMES: [&str; 6] = ["Alice", "Bob", "Charlie", "Dave", "Eve", "Ferdie"]; + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext(initial_identities_len: usize) -> sp_io::TestExternalities { + GenesisConfig { + system: SystemConfig::default(), + identity: IdentityConfig { + identities: (1..=initial_identities_len) + .map(|i| pallet_identity::IdtyValue { + data: (), + owner_key: i as u64, + name: pallet_identity::IdtyName::from(NAMES[i]), + next_creatable_identity_on: 0, + removable_on: 0, + rights: vec![ + (IdtyRight::CreateIdty, None), + (IdtyRight::StrongCert, None), + (IdtyRight::Ud, None), + ], + status: pallet_identity::IdtyStatus::Validated, + }) + .collect(), + }, + membership: MembershipConfig { + memberships: (1..=initial_identities_len) + .map(|i| { + ( + i as u32, + sp_membership::MembershipData { + expire_on: MembershipPeriod::get(), + renewable_on: RenewablePeriod::get(), + }, + ) + }) + .collect(), + }, + cert: CertConfig { + certs_by_issuer: clique_wot(initial_identities_len, ValidityPeriod::get()), + }, + } + .build_storage() + .unwrap() + .into() +} + +pub fn run_to_block(n: u64) { + while System::block_number() < n { + DuniterWot::on_finalize(System::block_number()); + Identity::on_finalize(System::block_number()); + Membership::on_finalize(System::block_number()); + Cert::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + System::reset_events(); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + DuniterWot::on_initialize(System::block_number()); + Identity::on_initialize(System::block_number()); + Membership::on_initialize(System::block_number()); + Cert::on_initialize(System::block_number()); + } +} + +fn clique_wot( + initial_identities_len: usize, + cert_validity_period: u64, +) -> BTreeMap<IdtyIndex, BTreeMap<IdtyIndex, u64>> { + let mut certs_by_issuer = BTreeMap::new(); + for i in 1..=initial_identities_len { + certs_by_issuer.insert( + i as IdtyIndex, + (1..=initial_identities_len) + .filter_map(|j| { + if i != j { + Some((j as IdtyIndex, cert_validity_period)) + } else { + None + } + }) + .collect(), + ); + } + certs_by_issuer +} diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs new file mode 100644 index 000000000..7b29034e5 --- /dev/null +++ b/pallets/duniter-wot/src/tests.rs @@ -0,0 +1,217 @@ +// 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 crate::mock::Identity; +use crate::mock::*; +use crate::IdtyRight; +use frame_support::assert_err; +use frame_support::assert_ok; +use frame_support::instances::Instance1; +use frame_system::{EventRecord, Phase}; +use pallet_identity::{IdtyName, IdtyStatus}; + +#[test] +fn test_genesis_build() { + new_test_ext(3).execute_with(|| { + run_to_block(1); + // Verify state + assert_eq!(Identity::identities_count(), 3); + assert_eq!(Identity::identity(1).unwrap().next_creatable_identity_on, 0); + assert_eq!( + pallet_certification::Pallet::<Test, Instance1>::idty_cert_meta(1) + .unwrap() + .next_issuable_on, + 2 + ); + }); +} + +#[test] +fn test_creator_not_allowed_to_create_idty() { + new_test_ext(3).execute_with(|| { + run_to_block(1); + + // Alice should not be able te create an identity before block #2 + // because Alice.next_issuable_on = 2 + assert_err!( + Identity::create_identity(Origin::signed(1), 1, IdtyName::from("Dave"), 4), + pallet_identity::Error::<Test>::CreatorNotAllowedToCreateIdty + ); + }); +} + +#[test] +fn test_create_idty_ok() { + new_test_ext(3).execute_with(|| { + run_to_block(2); + + // Alice should be able te create an identity at block #2 + assert_ok!(Identity::create_identity( + Origin::signed(1), + 1, + IdtyName::from("Dave"), + 4 + )); + // 2 events should have occurred: IdtyCreated and NewCert + let events = System::events(); + assert_eq!(events.len(), 2); + assert_eq!( + events[0], + EventRecord { + phase: Phase::Initialization, + event: Event::Identity(pallet_identity::Event::IdtyCreated( + IdtyName::from("Dave"), + 4 + )), + topics: vec![], + } + ); + assert_eq!( + events[1], + EventRecord { + phase: Phase::Initialization, + event: Event::Cert(pallet_certification::Event::NewCert { + issuer: 1, + issuer_issued_count: 3, + receiver: 4, + receiver_received_count: 1 + }), + topics: vec![], + } + ); + assert_eq!(Identity::identity(4).unwrap().status, IdtyStatus::Created); + assert_eq!(Identity::identity(4).unwrap().removable_on, 4); + }); +} + +#[test] +fn test_ud_right_achievement_ok() { + new_test_ext(3).execute_with(|| { + // Alice create Dave identity + run_to_block(2); + assert_ok!(Identity::create_identity( + Origin::signed(1), + 1, + IdtyName::from("Dave"), + 4 + )); + + // Dave confirm it's identity + run_to_block(3); + assert_ok!(Identity::confirm_identity( + Origin::signed(4), + IdtyName::from("Dave"), + 4 + )); + + // Bob should be able to certify Dave + run_to_block(4); + assert_ok!(Cert::add_cert(Origin::signed(2), 2, 4)); + + let events = System::events(); + // 3 events should have occurred: NewCert, MembershipAcquired, IdtyValidated and IdtyAcquireRight + assert_eq!(events.len(), 4); + println!("{:?}", events[2]); + assert_eq!( + events[0], + EventRecord { + phase: Phase::Initialization, + event: Event::Cert(pallet_certification::Event::NewCert { + issuer: 2, + issuer_issued_count: 3, + receiver: 4, + receiver_received_count: 2 + }), + topics: vec![], + } + ); + assert_eq!( + events[1], + EventRecord { + phase: Phase::Initialization, + event: Event::Membership(pallet_membership::Event::MembershipAcquired(4)), + topics: vec![], + } + ); + assert_eq!( + events[2], + EventRecord { + phase: Phase::Initialization, + event: Event::Identity(pallet_identity::Event::IdtyValidated(IdtyName::from( + "Dave" + ),)), + topics: vec![], + } + ); + assert_eq!( + events[3], + EventRecord { + phase: Phase::Initialization, + event: Event::Identity(pallet_identity::Event::IdtyAcquireRight( + IdtyName::from("Dave"), + IdtyRight::Ud + )), + topics: vec![], + } + ); + }); +} + +#[test] +fn test_confirm_idty_ok() { + new_test_ext(3).execute_with(|| { + run_to_block(2); + + // Alice create Dave identity + assert_ok!(Identity::create_identity( + Origin::signed(1), + 1, + IdtyName::from("Dave"), + 4 + )); + + run_to_block(3); + + // Dave should be able to confirm it's identity + assert_ok!(Identity::confirm_identity( + Origin::signed(4), + IdtyName::from("Dave"), + 4 + )); + let events = System::events(); + // 2 events should have occurred: MembershipRequested and IdtyConfirmed + assert_eq!(events.len(), 2); + //println!("{:?}", events[0]); + assert_eq!( + events[0], + EventRecord { + phase: Phase::Initialization, + event: Event::Membership(pallet_membership::Event::MembershipRequested(4)), + topics: vec![], + } + ); + assert_eq!( + events[1], + EventRecord { + phase: Phase::Initialization, + event: Event::Identity(pallet_identity::Event::IdtyConfirmed(IdtyName::from( + "Dave" + ),)), + topics: vec![], + } + ); + }); +} diff --git a/pallets/duniter-wot/src/types.rs b/pallets/duniter-wot/src/types.rs new file mode 100644 index 000000000..37ae0195b --- /dev/null +++ b/pallets/duniter-wot/src/types.rs @@ -0,0 +1,114 @@ +// 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 pallet_identity::IdtyStatus; + +use crate::{Config, IdtyIndex}; +use frame_support::instances::Instance1; +use frame_support::pallet_prelude::*; +use scale_info::TypeInfo; +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; +use sp_runtime::traits::IsMember; + +pub struct AddStrongCertOrigin<T>(core::marker::PhantomData<T>); +impl<T: Config> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> for AddStrongCertOrigin<T> { + type Success = (); + + fn try_origin( + o: (T::Origin, IdtyIndex, IdtyIndex), + ) -> Result<Self::Success, (T::Origin, IdtyIndex, IdtyIndex)> { + match o.0.clone().into() { + Ok(frame_system::RawOrigin::Root) => Ok(()), + Ok(frame_system::RawOrigin::Signed(who)) => { + if let Some(issuer) = pallet_identity::Pallet::<T>::identity(o.1) { + if let Some(allowed_key) = issuer.get_right_key(IdtyRight::StrongCert) { + if who == allowed_key { + if let Some(receiver) = pallet_identity::Pallet::<T>::identity(o.2) { + match receiver.status { + IdtyStatus::ConfirmedByOwner => Ok(()), + IdtyStatus::Validated => { + if pallet_membership::Pallet::<T, Instance1>::is_member( + &o.2, + ) || pallet_membership::Pallet::<T, Instance1>::pending_membership(&o.2).is_some() { + Ok(()) + } else { + Err(o) + } + } + IdtyStatus::Created => Err(o), + } + } else { + // Receiver not found + Err(o) + } + } else { + // Bad key + Err(o) + } + } else { + // Issuer has not right StrongCert + Err(o) + } + } else { + // Issuer not found + Err(o) + } + } + _ => Err(o), + } + } +} + +pub struct DelStrongCertOrigin<T>(core::marker::PhantomData<T>); +impl<T: Config> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> for DelStrongCertOrigin<T> { + type Success = (); + + fn try_origin( + o: (T::Origin, IdtyIndex, IdtyIndex), + ) -> Result<Self::Success, (T::Origin, IdtyIndex, IdtyIndex)> { + match o.0.clone().into() { + Ok(frame_system::Origin::<T>::Root) => Ok(()), + _ => Err(o), + } + } +} + +#[cfg_attr(feature = "std", derive(Deserialize, Serialize))] +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, TypeInfo)] +pub enum IdtyRight { + CreateIdty, + LightCert, + StrongCert, + Ud, +} +impl Default for IdtyRight { + fn default() -> Self { + Self::Ud + } +} +impl pallet_identity::traits::IdtyRight for IdtyRight { + fn allow_owner_key(self) -> bool { + match self { + Self::CreateIdty | Self::LightCert | IdtyRight::StrongCert | Self::Ud => true, + //IdtyRight::StrongCert => false, + //_ => false, + } + } + fn create_idty_right() -> Self { + Self::CreateIdty + } +} diff --git a/pallets/identity/Cargo.toml b/pallets/identity/Cargo.toml index d7b804275..8537bccbc 100644 --- a/pallets/identity/Cargo.toml +++ b/pallets/identity/Cargo.toml @@ -19,14 +19,12 @@ std = [ 'frame-benchmarking/std', 'serde', 'sp-core/std', - 'sp-membership/std', 'sp-runtime/std', 'sp-std/std', ] try-runtime = ['frame-support/try-runtime'] [dependencies] -sp-membership = { path = "../../primitives/membership", default-features = false } # substrate scale-info = { version = "1.0", default-features = false, features = ["derive"] } diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs index 567ebc9df..bc596940d 100644 --- a/pallets/identity/src/lib.rs +++ b/pallets/identity/src/lib.rs @@ -35,7 +35,6 @@ pub use types::*; use crate::traits::*; use codec::Codec; use frame_support::dispatch::Weight; -use frame_system::RawOrigin; use sp_runtime::traits::{AtLeast32BitUnsigned, One, Saturating, Zero}; use sp_std::fmt::Debug; use sp_std::prelude::*; @@ -46,7 +45,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_support::traits::StorageVersion; use frame_system::pallet_prelude::*; - use sp_membership::traits::MembershipAction as _; + use sp_runtime::traits::IsMember; /// The current storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); @@ -93,6 +92,8 @@ pub mod pallet { type IdtyValidationOrigin: EnsureOrigin<Self::Origin>; /// Rights that an identity can have type IdtyRight: IdtyRight; + /// + type IsMember: sp_runtime::traits::IsMember<Self::IdtyIndex>; /// On identity confirmed by it's owner type OnIdtyChange: OnIdtyChange<Self>; /// On right key change @@ -100,8 +101,6 @@ pub mod pallet { #[pallet::constant] /// Maximum period with no rights, after this period, the identity is permanently deleted type MaxNoRightPeriod: Get<Self::BlockNumber>; - /// - type Membership: sp_membership::traits::MembershipAction<Self::IdtyIndex, Self::Origin>; } // GENESIS STUFFÂ // @@ -226,9 +225,6 @@ pub mod pallet { /// An identity has been validated /// [idty] IdtyValidated(IdtyName), - /// An identity was renewed by it's owner - /// [idty] - IdtyRenewed(IdtyName), /// An identity has acquired a new right /// [idty, right] IdtyAcquireRight(IdtyName, T::IdtyRight), @@ -348,7 +344,9 @@ pub mod pallet { if idty_value.name != idty_name { return Err(Error::<T>::NotSameIdtyName.into()); } - T::Membership::request_membership_(RawOrigin::Signed(who).into(), idty_index)?; + if !T::EnsureIdtyCallAllowed::can_confirm_identity(idty_index) { + return Err(Error::<T>::NotAllowedToConfirmIdty.into()); + } idty_value.status = IdtyStatus::ConfirmedByOwner; @@ -364,56 +362,20 @@ pub mod pallet { } } #[pallet::weight(0)] - pub fn renew_identity( - origin: OriginFor<T>, - idty_name: IdtyName, - idty_index: T::IdtyIndex, - ) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin)?; - - if let Ok(mut idty_value) = <Identities<T>>::try_get(idty_index) { - if who == idty_value.owner_key { - match idty_value.status { - IdtyStatus::Created | IdtyStatus::ConfirmedByOwner => { - Err(Error::<T>::IdtyNotValidated.into()) - } - IdtyStatus::Validated | IdtyStatus::Expired => { - let _post_info = T::Membership::renew_membership_( - RawOrigin::Signed(who).into(), - idty_index, - )?; - - let old_status = idty_value.status; - idty_value.status = IdtyStatus::Validated; - - <Identities<T>>::insert(idty_index, idty_value); - Self::deposit_event(Event::IdtyRenewed(idty_name)); - if old_status == IdtyStatus::Expired { - T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Validated); - } - Ok(().into()) - } - } - } else { - Err(Error::<T>::RequireToBeOwner.into()) - } - } else { - Err(Error::<T>::IdtyNotFound.into()) - } - } - #[pallet::weight(0)] pub fn validate_identity( origin: OriginFor<T>, idty_index: T::IdtyIndex, idty_rights: Vec<T::IdtyRight>, ) -> DispatchResultWithPostInfo { - T::IdtyValidationOrigin::ensure_origin(origin.clone())?; + T::IdtyValidationOrigin::ensure_origin(origin)?; if let Ok(mut idty_value) = <Identities<T>>::try_get(idty_index) { match idty_value.status { IdtyStatus::Created => Err(Error::<T>::IdtyNotConfirmedByOwner.into()), IdtyStatus::ConfirmedByOwner => { - let _post_info = T::Membership::claim_membership_(origin, idty_index)?; + if !T::EnsureIdtyCallAllowed::can_validate_identity(idty_index) { + return Err(Error::<T>::NotAllowedToValidateIdty.into()); + } idty_value.removable_on = T::BlockNumber::zero(); idty_value.rights = @@ -446,9 +408,7 @@ pub mod pallet { } Ok(().into()) } - IdtyStatus::Validated | IdtyStatus::Expired => { - Err(Error::<T>::IdtyAlreadyValidated.into()) - } + IdtyStatus::Validated => Err(Error::<T>::IdtyAlreadyValidated.into()), } } else { Err(Error::<T>::IdtyNotFound.into()) @@ -467,6 +427,10 @@ pub mod pallet { return Err(Error::<T>::IdtyNotValidated.into()); } + if !T::IsMember::is_member(&idty_index) { + return Err(Error::<T>::IdtyNotMember.into()); + } + if let Err(index) = idty_value .rights .binary_search_by(|(right_, _)| right_.cmp(&right)) @@ -501,49 +465,12 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { T::DelRightOrigin::ensure_origin(origin)?; - if let Ok(mut idty_value) = <Identities<T>>::try_get(idty_index) { + if let Ok(idty_value) = <Identities<T>>::try_get(idty_index) { if idty_value.status != IdtyStatus::Validated { return Err(Error::<T>::IdtyNotValidated.into()); } - if let Ok(index) = idty_value - .rights - .binary_search_by(|(right_, _)| right_.cmp(&right)) - { - let name = idty_value.name.clone(); - let old_key_opt = if let Some(ref subkey) = idty_value.rights[index].1 { - Some(subkey.clone()) - } else if right.allow_owner_key() { - Some(idty_value.owner_key.clone()) - } else { - None - }; - idty_value.rights.remove(index); - - if idty_value.rights.is_empty() { - let block_number = frame_system::pallet::Pallet::<T>::block_number(); - let removable_on = block_number + T::MaxNoRightPeriod::get(); - idty_value.removable_on = removable_on; - <IdentitiesRemovableOn<T>>::append( - removable_on, - (idty_index, IdtyStatus::Validated), - ); - } - - <Identities<T>>::insert(idty_index, idty_value); - Self::deposit_event(Event::<T>::IdtyLostRight(name, right)); - if old_key_opt.is_some() { - T::OnRightKeyChange::on_right_key_change( - idty_index, - right, - old_key_opt, - None, - ); - } - Ok(().into()) - } else { - Err(Error::<T>::RightNotExist.into()) - } + Self::do_remove_right(idty_index, idty_value, right) } else { Err(Error::<T>::IdtyNotFound.into()) } @@ -563,6 +490,10 @@ pub mod pallet { return Err(Error::<T>::IdtyNotValidated.into()); } + if !T::IsMember::is_member(&idty_index) { + return Err(Error::<T>::IdtyNotMember.into()); + } + if let Ok(index) = idty_value .rights .binary_search_by(|(right_, _)| right_.cmp(&right)) @@ -602,6 +533,35 @@ pub mod pallet { Err(Error::<T>::IdtyNotFound.into()) } } + + #[pallet::weight(0)] + pub fn remove_all_rights( + origin: OriginFor<T>, + idty_index: T::IdtyIndex, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + if let Ok(idty_value) = <Identities<T>>::try_get(idty_index) { + for (right, _key_opt) in &idty_value.rights { + Self::do_remove_right(idty_index, idty_value.clone(), *right)?; + } + Ok(().into()) + } else { + Err(Error::<T>::IdtyNotFound.into()) + } + } + + #[pallet::weight(0)] + pub fn remove_identity( + origin: OriginFor<T>, + idty_index: T::IdtyIndex, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + Self::do_remove_identity(idty_index); + + Ok(().into()) + } } // ERRORS // @@ -628,10 +588,16 @@ pub mod pallet { IdtyNotConfirmedByOwner, /// Identity not found IdtyNotFound, + /// Idty not member + IdtyNotMember, /// Identity not validated IdtyNotValidated, /// Identity not yet renewable IdtyNotYetRenewable, + /// Not allowed to confirm identity + NotAllowedToConfirmIdty, + /// Not allowed to validate identity + NotAllowedToValidateIdty, /// Not same identity name NotSameIdtyName, /// This operation requires to be the owner of the identity @@ -666,32 +632,53 @@ pub mod pallet { panic!("storage corrupted") } } - pub(super) fn do_expire_identity(idty_index: T::IdtyIndex) -> Weight { - let mut total_weight: Weight = 0; - - let block_number = frame_system::pallet::Pallet::<T>::block_number(); - let removable_on = block_number + T::MaxNoRightPeriod::get(); - <Identities<T>>::mutate_exists(idty_index, |idty_val_opt| { - if let Some(ref mut idty_val) = idty_val_opt { - idty_val.removable_on = removable_on; - idty_val.rights = Vec::with_capacity(0); - } - }); - <IdentitiesRemovableOn<T>>::append(removable_on, (idty_index, IdtyStatus::Expired)); - total_weight += T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Expired); - - total_weight - } pub(super) fn do_remove_identity(idty_index: T::IdtyIndex) -> Weight { - let mut total_weight: Weight = 0; - if let Some(idty_val) = <Identities<T>>::take(idty_index) { <IdentitiesByDid<T>>::remove(idty_val.name); } Self::dec_identities_counter(); - total_weight += T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Removed); + T::OnIdtyChange::on_idty_change(idty_index, IdtyEvent::Removed); - total_weight + 0 + } + pub(super) fn do_remove_right( + idty_index: T::IdtyIndex, + mut idty_value: IdtyValue<T::AccountId, T::BlockNumber, T::IdtyData, T::IdtyRight>, + right: T::IdtyRight, + ) -> DispatchResultWithPostInfo { + if let Ok(index) = idty_value + .rights + .binary_search_by(|(right_, _)| right_.cmp(&right)) + { + let name = idty_value.name.clone(); + let old_key_opt = if let Some(ref subkey) = idty_value.rights[index].1 { + Some(subkey.clone()) + } else if right.allow_owner_key() { + Some(idty_value.owner_key.clone()) + } else { + None + }; + idty_value.rights.remove(index); + + if idty_value.rights.is_empty() { + let block_number = frame_system::pallet::Pallet::<T>::block_number(); + let removable_on = block_number + T::MaxNoRightPeriod::get(); + idty_value.removable_on = removable_on; + <IdentitiesRemovableOn<T>>::append( + removable_on, + (idty_index, IdtyStatus::Validated), + ); + } + + <Identities<T>>::insert(idty_index, idty_value); + Self::deposit_event(Event::<T>::IdtyLostRight(name, right)); + if old_key_opt.is_some() { + T::OnRightKeyChange::on_right_key_change(idty_index, right, old_key_opt, None); + } + Ok(().into()) + } else { + Err(Error::<T>::RightNotExist.into()) + } } fn get_next_idty_index() -> T::IdtyIndex { if let Ok(next_index) = <NextIdtyIndex<T>>::try_get() { @@ -712,15 +699,10 @@ pub mod pallet { fn prune_identities(block_number: T::BlockNumber) -> Weight { let mut total_weight: Weight = 0; - use frame_support::storage::generator::StorageMap as _; - if let Some(identities) = IdentitiesRemovableOn::<T>::from_query_to_optional_value( - IdentitiesRemovableOn::<T>::take(block_number), - ) { - for (idty_index, idty_status) in identities { - 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) - } + for (idty_index, idty_status) in IdentitiesRemovableOn::<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) } } } @@ -729,45 +711,3 @@ pub mod pallet { } } } - -impl<T: Config> sp_membership::traits::IsOriginAllowedToUseIdty<T::Origin, T::IdtyIndex> - for Pallet<T> -{ - fn is_origin_allowed_to_use_idty( - origin: &T::Origin, - idty_index: &T::IdtyIndex, - ) -> sp_membership::OriginPermission { - match origin.clone().into() { - Ok(RawOrigin::Root) => sp_membership::OriginPermission::Root, - Ok(RawOrigin::Signed(account_id)) => { - if let Some(idty_val) = Pallet::<T>::identity(idty_index) { - if account_id == idty_val.owner_key { - sp_membership::OriginPermission::Allowed - } else { - sp_membership::OriginPermission::Forbidden - } - } else { - sp_membership::OriginPermission::Forbidden - } - } - _ => sp_membership::OriginPermission::Forbidden, - } - } -} - -impl<T: Config> sp_membership::traits::OnEvent<T::IdtyIndex> for Pallet<T> { - fn on_event(membership_event: sp_membership::Event<T::IdtyIndex>) -> Weight { - match membership_event { - sp_membership::Event::<T::IdtyIndex>::MembershipAcquired(_) => 0, - sp_membership::Event::<T::IdtyIndex>::MembershipExpired(idty_index) => { - Pallet::<T>::do_expire_identity(idty_index) - } - sp_membership::Event::<T::IdtyIndex>::MembershipRenewed(_) => 0, - sp_membership::Event::<T::IdtyIndex>::MembershipRequested(_) => 0, - sp_membership::Event::<T::IdtyIndex>::MembershipRevoked(_) => 0, - sp_membership::Event::<T::IdtyIndex>::PendingMembershipExpired(idty_index) => { - Pallet::<T>::do_remove_identity(idty_index) - } - } - } -} diff --git a/pallets/identity/src/mock.rs b/pallets/identity/src/mock.rs index 51e77fff1..5985e5d53 100644 --- a/pallets/identity/src/mock.rs +++ b/pallets/identity/src/mock.rs @@ -28,7 +28,7 @@ use serde::{Deserialize, Serialize}; use sp_core::H256; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, IdentityLookup}, + traits::{BlakeTwo256, IdentityLookup, IsMember}, BuildStorage, }; @@ -128,6 +128,13 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl { } } +pub struct IsMemberTestImpl; +impl IsMember<u64> for IsMemberTestImpl { + fn is_member(_: &u64) -> bool { + true + } +} + impl pallet_identity::Config for Test { type ConfirmPeriod = ConfirmPeriod; type Event = Event; @@ -141,10 +148,10 @@ impl pallet_identity::Config for Test { type IdtyIndex = u64; type IdtyValidationOrigin = system::EnsureRoot<AccountId>; type IdtyRight = IdtyRight; + type IsMember = IsMemberTestImpl; type OnIdtyChange = (); type OnRightKeyChange = (); type MaxNoRightPeriod = MaxNoRightPeriod; - type Membership = (); } // Build genesis storage according to the mock runtime. diff --git a/pallets/identity/src/traits.rs b/pallets/identity/src/traits.rs index d5b1e19b7..635944278 100644 --- a/pallets/identity/src/traits.rs +++ b/pallets/identity/src/traits.rs @@ -21,10 +21,18 @@ use sp_std::fmt::Debug; pub trait EnsureIdtyCallAllowed<T: Config> { fn can_create_identity(creator: T::IdtyIndex) -> bool; + fn can_confirm_identity(idty_index: T::IdtyIndex) -> bool; + fn can_validate_identity(idty_index: T::IdtyIndex) -> bool; } impl<T: Config> EnsureIdtyCallAllowed<T> for () { - fn can_create_identity(_creator: T::IdtyIndex) -> bool { + fn can_create_identity(_: T::IdtyIndex) -> bool { + true + } + fn can_confirm_identity(_: T::IdtyIndex) -> bool { + true + } + fn can_validate_identity(_: T::IdtyIndex) -> bool { true } } @@ -67,14 +75,6 @@ pub trait IdtyRight: fn create_idty_right() -> Self; } -pub enum IdtyEvent<T: Config> { - Created { creator: T::IdtyIndex }, - Confirmed, - Validated, - Expired, - Removed, -} - pub trait OnIdtyChange<T: Config> { fn on_idty_change(idty_index: T::IdtyIndex, idty_event: IdtyEvent<T>) -> Weight; } diff --git a/pallets/identity/src/types.rs b/pallets/identity/src/types.rs index b4231157b..f1f2e8fcd 100644 --- a/pallets/identity/src/types.rs +++ b/pallets/identity/src/types.rs @@ -23,6 +23,13 @@ use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_std::vec::Vec; +pub enum IdtyEvent<T: crate::Config> { + Created { creator: T::IdtyIndex }, + Confirmed, + Validated, + Removed, +} + #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)] pub struct IdtyName(pub Vec<u8>); @@ -63,7 +70,6 @@ pub enum IdtyStatus { Created, ConfirmedByOwner, Validated, - Expired, } impl Default for IdtyStatus { fn default() -> Self { diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs index dd93b656e..cf4cb466d 100644 --- a/pallets/membership/src/lib.rs +++ b/pallets/membership/src/lib.rs @@ -43,6 +43,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_support::traits::StorageVersion; use frame_system::pallet_prelude::*; + use sp_runtime::traits::IsMember; /// The current storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); @@ -132,7 +133,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn pending_membership)] pub type PendingMembership<T: Config<I>, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, T::IdtyId, (), OptionQuery>; + StorageMap<_, Blake2_128Concat, T::IdtyId, T::BlockNumber, OptionQuery>; #[pallet::storage] #[pallet::getter(fn pending_memberships_expire_on)] @@ -186,6 +187,8 @@ pub mod pallet { IdtyNotAllowedToRenewMembership, /// Membership already acquired MembershipAlreadyAcquired, + /// Membership already requested + MembershipAlreadyRequested, /// Membership not yet renewable MembershipNotYetRenewable, /// Membership not found @@ -238,6 +241,9 @@ pub mod pallet { if !allowed { return Err(Error::<T, I>::IdtyNotAllowedToRequestMembership.into()); } + 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()); } @@ -248,7 +254,7 @@ pub mod pallet { let block_number = frame_system::pallet::Pallet::<T>::block_number(); let expire_on = block_number + T::PendingMembershipPeriod::get(); - PendingMembership::<T, I>::insert(idty_id, ()); + PendingMembership::<T, I>::insert(idty_id, expire_on); PendingMembershipsExpireOn::<T, I>::append(expire_on, idty_id); Self::deposit_event(Event::MembershipRequested(idty_id)); T::OnEvent::on_event(sp_membership::Event::MembershipRequested(idty_id)); @@ -261,6 +267,9 @@ pub mod pallet { origin: OriginFor<T>, idty_id: T::IdtyId, ) -> DispatchResultWithPostInfo { + if Membership::<T, I>::contains_key(&idty_id) { + return Err(Error::<T, I>::MembershipAlreadyAcquired.into()); + } let allowed = match T::IsOriginAllowedToUseIdty::is_origin_allowed_to_use_idty(&origin, &idty_id) { @@ -482,7 +491,7 @@ impl<T: Config<I>, I: 'static> IsInPendingMemberships<T::IdtyId> for Pallet<T, I } } -impl<T: Config<I>, I: 'static> IsMember<T::IdtyId> for Pallet<T, I> { +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::is_member_inner(idty_id) } diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs index 3a9869bf0..14eb7438f 100644 --- a/pallets/membership/src/mock.rs +++ b/pallets/membership/src/mock.rs @@ -109,7 +109,7 @@ impl pallet_membership::Config for Test { type ExternalizeMembershipStorage = ExternalizeMembershipStorage; type IdtyId = IdtyId; type OnEvent = (); - type MembershipExternalStorage = (); + type MembershipExternalStorage = crate::NoExternalStorage; type MembershipPeriod = MembershipPeriod; type PendingMembershipPeriod = PendingMembershipPeriod; type RenewablePeriod = RenewablePeriod; diff --git a/pallets/membership/src/tests.rs b/pallets/membership/src/tests.rs index 0ac452280..a40782f21 100644 --- a/pallets/membership/src/tests.rs +++ b/pallets/membership/src/tests.rs @@ -19,8 +19,9 @@ use crate::mock::*; use crate::{Error, Event}; use frame_support::assert_ok; use maplit::btreemap; -use sp_membership::traits::{IsInPendingMemberships, IsMember}; +use sp_membership::traits::IsInPendingMemberships; use sp_membership::MembershipData; +use sp_runtime::traits::IsMember; fn default_gen_conf() -> DefaultMembershipConfig { DefaultMembershipConfig { @@ -61,12 +62,24 @@ fn test_membership_not_yet_renewable() { } #[test] -fn test_membership_request_not_found() { +fn test_membership_already_acquired() { new_test_ext(default_gen_conf()).execute_with(|| { run_to_block(1); // Merbership 0 cannot be reclaimed assert_eq!( DefaultMembership::claim_membership(Origin::signed(0), 0), + Err(Error::<Test, _>::MembershipAlreadyAcquired.into()) + ); + }); +} + +#[test] +fn test_membership_request_not_found() { + new_test_ext(default_gen_conf()).execute_with(|| { + run_to_block(1); + // Merbership 0 cannot be reclaimed + assert_eq!( + DefaultMembership::claim_membership(Origin::signed(1), 1), Err(Error::<Test, _>::MembershipRequestNotFound.into()) ); }); diff --git a/primitives/membership/Cargo.toml b/primitives/membership/Cargo.toml index 29bb6472d..716ad19ae 100644 --- a/primitives/membership/Cargo.toml +++ b/primitives/membership/Cargo.toml @@ -15,6 +15,7 @@ std = [ 'codec/std', 'frame-support/std', 'serde', + 'sp-runtime/std', 'sp-std/std', ] try-runtime = ['frame-support/try-runtime'] @@ -40,6 +41,11 @@ version = "1.0.101" optional = true features = ["derive"] +[dependencies.sp-runtime] +default-features = false +git = 'https://github.com/librelois/substrate.git' +branch = 'duniter-monthly-2022-01' + [dependencies.sp-std] default-features = false git = 'https://github.com/librelois/substrate.git' diff --git a/primitives/membership/src/traits.rs b/primitives/membership/src/traits.rs index 580eaa82e..e77c8d143 100644 --- a/primitives/membership/src/traits.rs +++ b/primitives/membership/src/traits.rs @@ -61,16 +61,6 @@ pub trait IsInPendingMemberships<IdtyId> { fn is_in_pending_memberships(idty_id: IdtyId) -> bool; } -pub trait IsMember<IdtyId> { - fn is_member(idty_id: &IdtyId) -> bool; -} - -impl<IdtyId> IsMember<IdtyId> for () { - fn is_member(_: &IdtyId) -> bool { - false - } -} - pub trait OnEvent<IdtyId> { fn on_event(event: crate::Event<IdtyId>) -> Weight; } @@ -116,7 +106,7 @@ impl<IdtyId, Origin> MembershipAction<IdtyId, Origin> for () { } pub trait MembershipExternalStorage<BlockNumber: Decode + Encode + TypeInfo, IdtyId>: - IsMember<IdtyId> + sp_runtime::traits::IsMember<IdtyId> { fn insert(idty_id: IdtyId, membership_data: MembershipData<BlockNumber>); fn get(idty_id: &IdtyId) -> Option<MembershipData<BlockNumber>>; @@ -125,8 +115,14 @@ pub trait MembershipExternalStorage<BlockNumber: Decode + Encode + TypeInfo, Idt static INVALID_CONF_MSG: &str = "invalid pallet configuration: if `MembershipExternalStorage` = (), you must set `ExternalizeMembershipStorage` to `false`."; +pub struct NoExternalStorage; +impl<IdtyId> sp_runtime::traits::IsMember<IdtyId> for NoExternalStorage { + fn is_member(_: &IdtyId) -> bool { + panic!("{}", INVALID_CONF_MSG) + } +} impl<BlockNumber: Decode + Encode + TypeInfo, IdtyId> MembershipExternalStorage<BlockNumber, IdtyId> - for () + for NoExternalStorage { fn insert(_: IdtyId, _: MembershipData<BlockNumber>) { panic!("{}", INVALID_CONF_MSG) diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index c1ba7a867..07f972d8f 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -11,6 +11,7 @@ runtime-benchmarks = [ 'frame-support/runtime-benchmarks', 'frame-system/runtime-benchmarks', 'pallet-certification/runtime-benchmarks', + 'pallet-duniter-wot/runtime-benchmarks', 'pallet-identity/runtime-benchmarks', 'pallet-membership/runtime-benchmarks', 'pallet-ud-accounts-storage/runtime-benchmarks', @@ -21,6 +22,7 @@ std = [ 'frame-support/std', 'frame-system/std', 'pallet-certification/std', + 'pallet-duniter-wot/std', 'pallet-identity/std', 'pallet-membership/std', 'pallet-ud-accounts-storage/std', @@ -33,12 +35,15 @@ std = [ [dependencies] pallet-certification = { path = '../../pallets/certification', default-features = false } +pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = false } pallet-identity = { path = '../../pallets/identity', default-features = false } pallet-membership = { path = '../../pallets/membership', default-features = false } pallet-ud-accounts-storage = { path = '../../pallets/ud-accounts-storage', default-features = false } + +# Crates.io smallvec = "1.6.1" -# substrate +# Substrate scale-info = { version = "1.0", default-features = false, features = ["derive"] } [dependencies.codec] diff --git a/runtime/common/src/authorizations.rs b/runtime/common/src/authorizations.rs deleted file mode 100644 index d5be8c5a9..000000000 --- a/runtime/common/src/authorizations.rs +++ /dev/null @@ -1,96 +0,0 @@ -// 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 crate::entities::IdtyRight; -use crate::{BlockNumber, IdtyIndex}; -use frame_support::traits::EnsureOrigin; -use pallet_certification::traits::IsIdtyAllowedToCreateCert; -use pallet_identity::IdtyStatus; - -pub struct EnsureIdtyCallAllowedImpl<Runtime, IsIdtyAllowedToCreateCertImpl>( - core::marker::PhantomData<(Runtime, IsIdtyAllowedToCreateCertImpl)>, -); -impl< - Runtime: frame_system::Config<BlockNumber = BlockNumber> - + pallet_identity::Config<IdtyIndex = IdtyIndex>, - IsIdtyAllowedToCreateCertImpl: IsIdtyAllowedToCreateCert<IdtyIndex>, - > pallet_identity::traits::EnsureIdtyCallAllowed<Runtime> - for EnsureIdtyCallAllowedImpl<Runtime, IsIdtyAllowedToCreateCertImpl> -{ - fn can_create_identity(creator: IdtyIndex) -> bool { - IsIdtyAllowedToCreateCertImpl::is_idty_allowed_to_create_cert(creator) - } -} - -pub struct AddStrongCertOrigin<Runtime>(core::marker::PhantomData<Runtime>); -impl<Runtime: pallet_identity::Config<IdtyIndex = IdtyIndex, IdtyRight = IdtyRight>> - EnsureOrigin<(Runtime::Origin, IdtyIndex, IdtyIndex)> for AddStrongCertOrigin<Runtime> -{ - type Success = (); - - fn try_origin( - o: (Runtime::Origin, IdtyIndex, IdtyIndex), - ) -> Result<Self::Success, (Runtime::Origin, IdtyIndex, IdtyIndex)> { - match o.0.clone().into() { - Ok(frame_system::RawOrigin::Root) => Ok(()), - Ok(frame_system::RawOrigin::Signed(who)) => { - if let Some(issuer) = pallet_identity::Pallet::<Runtime>::identity(o.1) { - if let Some(allowed_key) = issuer.get_right_key(IdtyRight::StrongCert) { - if who == allowed_key { - if let Some(receiver) = - pallet_identity::Pallet::<Runtime>::identity(o.2) - { - match receiver.status { - IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => Ok(()), - IdtyStatus::Created | IdtyStatus::Expired => Err(o), - } - } else { - // Receiver not found - Err(o) - } - } else { - // Bad key - Err(o) - } - } else { - // Issuer has not right StrongCert - Err(o) - } - } else { - // Issuer not found - Err(o) - } - } - _ => Err(o), - } - } -} - -pub struct DelStrongCertOrigin<Runtime>(core::marker::PhantomData<Runtime>); -impl<Runtime: frame_system::Config> EnsureOrigin<(Runtime::Origin, IdtyIndex, IdtyIndex)> - for DelStrongCertOrigin<Runtime> -{ - type Success = (); - - fn try_origin( - o: (Runtime::Origin, IdtyIndex, IdtyIndex), - ) -> Result<Self::Success, (Runtime::Origin, IdtyIndex, IdtyIndex)> { - match o.0.clone().into() { - Ok(frame_system::Origin::<Runtime>::Root) => Ok(()), - _ => Err(o), - } - } -} diff --git a/runtime/common/src/entities.rs b/runtime/common/src/entities.rs index 0943cd78f..068fd129e 100644 --- a/runtime/common/src/entities.rs +++ b/runtime/common/src/entities.rs @@ -21,32 +21,6 @@ use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -#[cfg_attr(feature = "std", derive(Deserialize, Serialize))] -#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, TypeInfo)] -pub enum IdtyRight { - CreateIdty, - LightCert, - StrongCert, - Ud, -} -impl Default for IdtyRight { - fn default() -> Self { - Self::Ud - } -} -impl pallet_identity::traits::IdtyRight for IdtyRight { - fn allow_owner_key(self) -> bool { - match self { - Self::CreateIdty | Self::LightCert | IdtyRight::StrongCert | Self::Ud => true, - //IdtyRight::StrongCert => false, - //_ => false, - } - } - fn create_idty_right() -> Self { - Self::CreateIdty - } -} - #[cfg_attr(feature = "std", derive(Deserialize, Serialize))] #[derive( Encode, Decode, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, TypeInfo, diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs index 54406b331..63b54fc81 100644 --- a/runtime/common/src/handlers.rs +++ b/runtime/common/src/handlers.rs @@ -14,39 +14,7 @@ // 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 crate::entities::IdtyRight; -use crate::BlockNumber; -use frame_support::instances::Instance1; -use frame_support::pallet_prelude::Get; -use frame_support::weights::Weight; -use pallet_identity::traits::IdtyEvent; - -pub struct OnIdtyChangeHandler<Runtime>(core::marker::PhantomData<Runtime>); -impl< - IdtyIndex, - Runtime: pallet_identity::Config<IdtyIndex = IdtyIndex> - + pallet_certification::Config<Instance1, IdtyIndex = IdtyIndex>, - > pallet_identity::traits::OnIdtyChange<Runtime> for OnIdtyChangeHandler<Runtime> -{ - fn on_idty_change(idty_index: IdtyIndex, idty_event: IdtyEvent<Runtime>) -> Weight { - let total_weight = 0; - match idty_event { - IdtyEvent::Created { creator } => { - // totad_weight += StrongCert::WeightInfo::add_cert(); - let _ = <pallet_certification::Pallet<Runtime, Instance1>>::add_cert( - frame_system::Origin::<Runtime>::Root.into(), - creator, - idty_index, - ); - } - IdtyEvent::Confirmed => {} - IdtyEvent::Validated => {} - IdtyEvent::Expired => {} - IdtyEvent::Removed => {} - }; - total_weight - } -} +use pallet_duniter_wot::IdtyRight; pub struct OnRightKeyChangeHandler<Runtime>(core::marker::PhantomData<Runtime>); impl< @@ -72,87 +40,3 @@ impl< }; } } - -pub struct OnNewStrongCertHandler< - FirstIssuableOn, - Runtime, - SetNextIssuableOnImpl, - const MIN_STRONG_CERT_FOR_UD: u32, - const MIN_STRONG_CERT_FOR_STRONG_CERT: u32, ->(core::marker::PhantomData<(FirstIssuableOn, Runtime, SetNextIssuableOnImpl)>); -impl< - FirstIssuableOn: Get<BlockNumber>, - IdtyIndex: Copy, - Runtime: frame_system::Config<BlockNumber = BlockNumber> - + pallet_identity::Config<IdtyIndex = IdtyIndex, IdtyRight = IdtyRight>, - SetNextIssuableOnImpl: pallet_certification::traits::SetNextIssuableOn<BlockNumber, IdtyIndex>, - const MIN_STRONG_CERT_FOR_UD: u32, - const MIN_STRONG_CERT_FOR_STRONG_CERT: u32, - > pallet_certification::traits::OnNewcert<IdtyIndex> - for OnNewStrongCertHandler< - FirstIssuableOn, - Runtime, - SetNextIssuableOnImpl, - MIN_STRONG_CERT_FOR_UD, - MIN_STRONG_CERT_FOR_STRONG_CERT, - > -{ - fn on_new_cert( - _issuer: IdtyIndex, - _issuer_issued_count: u8, - receiver: IdtyIndex, - receiver_received_count: u32, - ) -> frame_support::dispatch::Weight { - let total_weight = 0; - if receiver_received_count == MIN_STRONG_CERT_FOR_UD { - // total_weight += Identity::WeightInfo::add_right(); - let _ = <pallet_identity::Pallet<Runtime>>::validate_identity( - frame_system::Origin::<Runtime>::Root.into(), - receiver, - sp_std::vec![IdtyRight::Ud], - ); - } else if receiver_received_count == MIN_STRONG_CERT_FOR_STRONG_CERT { - // total_weight += Identity::WeightInfo::add_right(); - let _ = <pallet_identity::Pallet<Runtime>>::add_right( - frame_system::Origin::<Runtime>::Root.into(), - receiver, - IdtyRight::StrongCert, - ); - let _ = SetNextIssuableOnImpl::set_next_issuable_on( - receiver, - frame_system::Pallet::<Runtime>::block_number() + FirstIssuableOn::get(), - ); - } - total_weight - } -} - -pub struct OnRemovedStrongCertHandler<Runtime, const MIN_STRONG_CERT_FOR_UD: u32>( - core::marker::PhantomData<Runtime>, -); -impl< - IdtyIndex, - Runtime: pallet_identity::Config<IdtyIndex = IdtyIndex, IdtyRight = IdtyRight>, - const MIN_STRONG_CERT_FOR_UD: u32, - > pallet_certification::traits::OnRemovedCert<IdtyIndex> - for OnRemovedStrongCertHandler<Runtime, MIN_STRONG_CERT_FOR_UD> -{ - fn on_removed_cert( - _issuer: IdtyIndex, - _issuer_issued_count: u8, - receiver: IdtyIndex, - receiver_received_count: u32, - _expiration: bool, - ) -> frame_support::dispatch::Weight { - let total_weight = 0; - if receiver_received_count < MIN_STRONG_CERT_FOR_UD { - // total_weight += Identity::WeightInfo::del_right(); - let _ = <pallet_identity::Pallet<Runtime>>::del_right( - frame_system::Origin::<Runtime>::Root.into(), - receiver, - IdtyRight::Ud, - ); - } - total_weight - } -} diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index ac789e56f..e7f9d336f 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -17,7 +17,6 @@ #![cfg_attr(not(feature = "std"), no_std)] mod apis; -pub mod authorizations; pub mod constants; pub mod entities; pub mod fees; diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs index 8fb5add39..df3e5a6a3 100644 --- a/runtime/common/src/pallets_config.rs +++ b/runtime/common/src/pallets_config.rs @@ -184,12 +184,19 @@ macro_rules! pallets_config { // WEBÂ OFÂ TRUST // + impl pallet_duniter_wot::Config for Runtime { + type MinCertForUdRight = MinCertForUdRight; + type MinCertForCertRight = MinCertForCertRight; + type MinCertForCreateIdtyRight = MinCertForCreateIdtyRight; + type FirstIssuableOn = FirstIssuableOn; + } + impl pallet_identity::Config for Runtime { type ConfirmPeriod = ConfirmPeriod; type Event = Event; type AddRightOrigin = EnsureRoot<Self::AccountId>; type DelRightOrigin = EnsureRoot<Self::AccountId>; - type EnsureIdtyCallAllowed = EnsureIdtyCallAllowedImpl<Runtime, StrongCert>; + type EnsureIdtyCallAllowed = DuniterWot; type IdtyCreationPeriod = IdtyCreationPeriod; type IdtyDataProvider = (); type IdtyData = (); @@ -197,22 +204,22 @@ macro_rules! pallets_config { type IdtyIndex = IdtyIndex; type IdtyValidationOrigin = EnsureRoot<Self::AccountId>; type IdtyRight = IdtyRight; - type OnIdtyChange = OnIdtyChangeHandler<Runtime>; + type IsMember = Membership; + type OnIdtyChange = DuniterWot; type OnRightKeyChange = OnRightKeyChangeHandler<Runtime>; type MaxNoRightPeriod = MaxNoRightPeriod; - type Membership = Membership; } impl pallet_membership::Config<frame_support::instances::Instance1> for Runtime { - type IsIdtyAllowedToClaimMembership = (); - type IsIdtyAllowedToRenewMembership = (); - type IsIdtyAllowedToRequestMembership = (); - type IsOriginAllowedToUseIdty = Identity; + type IsIdtyAllowedToClaimMembership = DuniterWot; + type IsIdtyAllowedToRenewMembership = DuniterWot; + type IsIdtyAllowedToRequestMembership = DuniterWot; + type IsOriginAllowedToUseIdty = DuniterWot; type Event = Event; type ExternalizeMembershipStorage = frame_support::traits::ConstBool<false>; type IdtyId = IdtyIndex; - type OnEvent = Identity; - type MembershipExternalStorage = (); + type OnEvent = DuniterWot; + type MembershipExternalStorage = sp_membership::traits::NoExternalStorage; type MembershipPeriod = MembershipPeriod; type PendingMembershipPeriod = PendingMembershipPeriod; type RenewablePeriod = RenewablePeriod; @@ -220,20 +227,19 @@ macro_rules! pallets_config { } impl pallet_certification::Config<frame_support::instances::Instance1> for Runtime { - type AddCertOrigin = AddStrongCertOrigin<Runtime>; + type AddCertOrigin = pallet_duniter_wot::AddStrongCertOrigin<Runtime>; type CertPeriod = CertPeriod; - type DelCertOrigin = DelStrongCertOrigin<Runtime>; + type DelCertOrigin = pallet_duniter_wot::DelStrongCertOrigin<Runtime>; type Event = Event; type IdtyIndex = IdtyIndex; type MaxByIssuer = MaxByIssuer; - type OnNewcert = - OnNewStrongCertHandler<FirstIssuableOn, Runtime, StrongCert, MIN_STRONG_CERT_FOR_UD, MIN_STRONG_CERT_FOR_STRONG_CERT>; - type OnRemovedCert = OnRemovedStrongCertHandler<Runtime, MIN_STRONG_CERT_FOR_UD>; + type OnNewcert = DuniterWot; + type OnRemovedCert = DuniterWot; type CertRenewablePeriod = StrongCertRenewablePeriod; type ValidityPeriod = ValidityPeriod; } - // MUNTISIG // + // MULTISIG // impl pallet_multisig::Config for Runtime { type Event = Event; diff --git a/runtime/g1/Cargo.toml b/runtime/g1/Cargo.toml index 53fe0a764..10bba58dc 100644 --- a/runtime/g1/Cargo.toml +++ b/runtime/g1/Cargo.toml @@ -36,6 +36,7 @@ std = [ 'pallet-babe/std', 'pallet-balances/std', 'pallet-certification/std', + 'pallet-duniter-wot/std', 'pallet-grandpa/std', 'pallet-identity/std', 'pallet-im-online/std', @@ -58,6 +59,7 @@ std = [ 'sp-core/std', 'sp-inherents/std', 'sp-offchain/std', + 'sp-membership/std', 'sp-runtime/std', 'sp-session/std', 'sp-std/std', @@ -66,13 +68,15 @@ std = [ ] [dependencies] +common-runtime = { path = "../common", default-features = false } +common-runtime-except-gdev = { path = "../common-except-gdev", default-features = false } pallet-certification = { path = '../../pallets/certification', default-features = false } +pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = false } pallet-identity = { path = '../../pallets/identity', default-features = false } pallet-membership = { path = '../../pallets/membership', default-features = false } pallet-ud-accounts-storage = { path = '../../pallets/ud-accounts-storage', default-features = false } pallet-universal-dividend = { path = '../../pallets/universal-dividend', default-features = false } -common-runtime = { path = "../common", default-features = false } -common-runtime-except-gdev = { path = "../common-except-gdev", default-features = false } +sp-membership = { path = '../../primitives/membership', default-features = false } # substrate scale-info = { version = "1.0", default-features = false, features = ["derive"] } diff --git a/runtime/g1/src/lib.rs b/runtime/g1/src/lib.rs index 8c9a46e1c..b5e924e44 100644 --- a/runtime/g1/src/lib.rs +++ b/runtime/g1/src/lib.rs @@ -26,12 +26,11 @@ pub mod parameters; pub use self::parameters::*; pub use common_runtime::{ - constants::*, - entities::{IdtyRight, ValidatorFullIdentification}, - AccountId, Address, Balance, BlockNumber, FullIdentificationOfImpl, Hash, Header, IdtyIndex, - IdtyNameValidatorImpl, Index, Signature, + constants::*, entities::ValidatorFullIdentification, AccountId, Address, Balance, BlockNumber, + FullIdentificationOfImpl, Hash, Header, IdtyIndex, IdtyNameValidatorImpl, Index, Signature, }; pub use pallet_balances::Call as BalancesCall; +pub use pallet_duniter_wot::IdtyRight; pub use pallet_identity::{IdtyStatus, IdtyValue}; pub use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use pallet_session::historical as session_historical; @@ -42,14 +41,7 @@ pub use pallet_universal_dividend; pub use sp_runtime::BuildStorage; pub use sp_runtime::{KeyTypeId, Perbill, Permill}; -use common_runtime::{ - authorizations::{AddStrongCertOrigin, DelStrongCertOrigin, EnsureIdtyCallAllowedImpl}, - handlers::{ - OnIdtyChangeHandler, OnNewStrongCertHandler, OnRemovedStrongCertHandler, - OnRightKeyChangeHandler, - }, - SessionManagerImpl, -}; +use common_runtime::{handlers::OnRightKeyChangeHandler, SessionManagerImpl}; use frame_system::EnsureRoot; use pallet_grandpa::fg_primitives; use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; @@ -143,7 +135,13 @@ pub type Executive = frame_executive::Executive< pub struct BaseCallFilter; impl frame_support::traits::Contains<Call> for BaseCallFilter { fn contains(call: &Call) -> bool { - !matches!(call, Call::Membership(_) | Call::Session(_)) + !matches!( + call, + Call::Membership( + pallet_membership::Call::claim_membership { .. } + | pallet_membership::Call::revoke_membership { .. } + ) | Call::Session(_) + ) } } @@ -194,9 +192,10 @@ construct_runtime!( UniversalDividend: pallet_universal_dividend::{Pallet, Call, Config<T>, Storage, Event<T>} = 41, // Web Of Trust - Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 50, - Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 51, - StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52, + DuniterWot: pallet_duniter_wot::{Pallet} = 50, + Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 51, + Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52, + StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 53, // Multisig dispatch. Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 60, diff --git a/runtime/g1/src/parameters.rs b/runtime/g1/src/parameters.rs index 5e334ce48..6cfd3ed99 100644 --- a/runtime/g1/src/parameters.rs +++ b/runtime/g1/src/parameters.rs @@ -92,6 +92,12 @@ parameter_types! { /* WOT */ /*******/ +parameter_types! { + pub MinCertForUdRight: u8 = 5; + pub MinCertForCertRight: u8 = 5; + pub MinCertForCreateIdtyRight: u8 = 5; +} + // Identity pub const IDTY_CREATE_PERIOD: BlockNumber = 100; parameter_types! { diff --git a/runtime/gdev/Cargo.toml b/runtime/gdev/Cargo.toml index 0578b60d7..db07d67d8 100644 --- a/runtime/gdev/Cargo.toml +++ b/runtime/gdev/Cargo.toml @@ -36,6 +36,7 @@ std = [ 'pallet-babe/std', 'pallet-balances/std', 'pallet-certification/std', + 'pallet-duniter-wot/std', 'pallet-identity/std', 'pallet-membership/std', 'pallet-grandpa/std', @@ -54,6 +55,7 @@ std = [ 'sp-core/std', 'sp-inherents/std', 'sp-offchain/std', + 'sp-membership/std', 'sp-runtime/std', 'sp-session/std', 'sp-std/std', @@ -62,12 +64,14 @@ std = [ ] [dependencies] +common-runtime = { path = "../common", default-features = false } pallet-certification = { path = '../../pallets/certification', default-features = false } +pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = false } pallet-identity = { path = '../../pallets/identity', default-features = false } pallet-membership = { path = '../../pallets/membership', default-features = false } pallet-ud-accounts-storage = { path = '../../pallets/ud-accounts-storage', default-features = false } pallet-universal-dividend = { path = '../../pallets/universal-dividend', default-features = false } -common-runtime = { path = "../common", default-features = false } +sp-membership = { path = '../../primitives/membership', default-features = false } # substrate scale-info = { version = "1.0", default-features = false, features = ["derive"] } diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs index b394fc9d8..468b82482 100644 --- a/runtime/gdev/src/lib.rs +++ b/runtime/gdev/src/lib.rs @@ -26,10 +26,11 @@ pub mod parameters; pub use self::parameters::*; pub use common_runtime::{ - constants::*, entities::IdtyRight, AccountId, Address, Balance, BlockNumber, Hash, Header, - IdtyIndex, IdtyNameValidatorImpl, Index, Signature, + constants::*, AccountId, Address, Balance, BlockNumber, Hash, Header, IdtyIndex, + IdtyNameValidatorImpl, Index, Signature, }; pub use pallet_balances::Call as BalancesCall; +pub use pallet_duniter_wot::IdtyRight; pub use pallet_identity::{IdtyStatus, IdtyValue}; use pallet_transaction_payment::CurrencyAdapter; pub use pallet_universal_dividend; @@ -37,13 +38,7 @@ pub use pallet_universal_dividend; pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; -use common_runtime::{ - authorizations::{AddStrongCertOrigin, DelStrongCertOrigin, EnsureIdtyCallAllowedImpl}, - handlers::{ - OnIdtyChangeHandler, OnNewStrongCertHandler, OnRemovedStrongCertHandler, - OnRightKeyChangeHandler, - }, -}; +use common_runtime::handlers::OnRightKeyChangeHandler; use frame_system::EnsureRoot; use pallet_grandpa::fg_primitives; use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; @@ -135,7 +130,13 @@ pub type Executive = frame_executive::Executive< pub struct BaseCallFilter; impl frame_support::traits::Contains<Call> for BaseCallFilter { fn contains(call: &Call) -> bool { - !matches!(call, Call::Membership(_)) + !matches!( + call, + Call::Membership( + pallet_membership::Call::claim_membership { .. } + | pallet_membership::Call::revoke_membership { .. } + ) + ) } } @@ -175,9 +176,10 @@ construct_runtime!( UniversalDividend: pallet_universal_dividend::{Pallet, Call, Config<T>, Storage, Event<T>} = 41, // Web Of Trust - Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 50, - Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 51, - StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52, + DuniterWot: pallet_duniter_wot::{Pallet} = 50, + Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 51, + Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52, + StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 53, // Multisig dispatch. Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 60, diff --git a/runtime/gdev/src/parameters.rs b/runtime/gdev/src/parameters.rs index b6a1697f9..b47c41d07 100644 --- a/runtime/gdev/src/parameters.rs +++ b/runtime/gdev/src/parameters.rs @@ -46,6 +46,13 @@ frame_support::parameter_types! { pub const TransactionByteFee: Balance = 0; } +// Wot +parameter_types! { + pub MinCertForUdRight: u8 = 2; + pub MinCertForCertRight: u8 = 3; + pub MinCertForCreateIdtyRight: u8 = 3; +} + // Identity pub const IDTY_CREATE_PERIOD: BlockNumber = 100; frame_support::parameter_types! { @@ -69,7 +76,7 @@ parameter_types! { pub const CertPeriod: BlockNumber = 15; pub const MaxByIssuer: u8 = 100; pub const StrongCertRenewablePeriod: BlockNumber = 50;//6 * MONTHS; - pub const ValidityPeriod: BlockNumber = 200;//2 * YEARS; + pub const ValidityPeriod: BlockNumber = 2_000;//2 * YEARS; } // Universal dividend diff --git a/runtime/gtest/Cargo.toml b/runtime/gtest/Cargo.toml index 3109fb572..307d4537e 100644 --- a/runtime/gtest/Cargo.toml +++ b/runtime/gtest/Cargo.toml @@ -36,6 +36,7 @@ std = [ 'pallet-babe/std', 'pallet-balances/std', 'pallet-certification/std', + 'pallet-duniter-wot/std', 'pallet-grandpa/std', 'pallet-identity/std', 'pallet-membership/std', @@ -58,6 +59,7 @@ std = [ 'sp-core/std', 'sp-inherents/std', 'sp-offchain/std', + 'sp-membership/std', 'sp-runtime/std', 'sp-session/std', 'sp-std/std', @@ -66,13 +68,15 @@ std = [ ] [dependencies] +common-runtime = { path = "../common", default-features = false } +common-runtime-except-gdev = { path = "../common-except-gdev", default-features = false } pallet-certification = { path = '../../pallets/certification', default-features = false } +pallet-duniter-wot = { path = '../../pallets/duniter-wot', default-features = false } pallet-identity = { path = '../../pallets/identity', default-features = false } pallet-membership = { path = '../../pallets/membership', default-features = false } pallet-ud-accounts-storage = { path = '../../pallets/ud-accounts-storage', default-features = false } pallet-universal-dividend = { path = '../../pallets/universal-dividend', default-features = false } -common-runtime = { path = "../common", default-features = false } -common-runtime-except-gdev = { path = "../common-except-gdev", default-features = false } +sp-membership = { path = '../../primitives/membership', default-features = false } # substrate scale-info = { version = "1.0", default-features = false, features = ["derive"] } diff --git a/runtime/gtest/src/lib.rs b/runtime/gtest/src/lib.rs index eba0587aa..354a96f62 100644 --- a/runtime/gtest/src/lib.rs +++ b/runtime/gtest/src/lib.rs @@ -26,12 +26,11 @@ pub mod parameters; pub use self::parameters::*; pub use common_runtime::{ - constants::*, - entities::{IdtyRight, ValidatorFullIdentification}, - AccountId, Address, Balance, BlockNumber, FullIdentificationOfImpl, Hash, Header, IdtyIndex, - IdtyNameValidatorImpl, Index, Signature, + constants::*, entities::ValidatorFullIdentification, AccountId, Address, Balance, BlockNumber, + FullIdentificationOfImpl, Hash, Header, IdtyIndex, IdtyNameValidatorImpl, Index, Signature, }; pub use pallet_balances::Call as BalancesCall; +pub use pallet_duniter_wot::IdtyRight; pub use pallet_identity::{IdtyStatus, IdtyValue}; pub use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use pallet_session::historical as session_historical; @@ -42,14 +41,7 @@ pub use pallet_universal_dividend; pub use sp_runtime::BuildStorage; pub use sp_runtime::{KeyTypeId, Perbill, Permill}; -use common_runtime::{ - authorizations::{AddStrongCertOrigin, DelStrongCertOrigin, EnsureIdtyCallAllowedImpl}, - handlers::{ - OnIdtyChangeHandler, OnNewStrongCertHandler, OnRemovedStrongCertHandler, - OnRightKeyChangeHandler, - }, - SessionManagerImpl, -}; +use common_runtime::{handlers::OnRightKeyChangeHandler, SessionManagerImpl}; use frame_system::EnsureRoot; use pallet_grandpa::fg_primitives; use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; @@ -143,7 +135,13 @@ pub type Executive = frame_executive::Executive< pub struct BaseCallFilter; impl frame_support::traits::Contains<Call> for BaseCallFilter { fn contains(call: &Call) -> bool { - !matches!(call, Call::Membership(_) | Call::Session(_)) + !matches!( + call, + Call::Membership( + pallet_membership::Call::claim_membership { .. } + | pallet_membership::Call::revoke_membership { .. } + ) | Call::Session(_) + ) } } @@ -194,9 +192,10 @@ construct_runtime!( UniversalDividend: pallet_universal_dividend::{Pallet, Call, Config<T>, Storage, Event<T>} = 41, // Web Of Trust - Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 50, - Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 51, - StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52, + DuniterWot: pallet_duniter_wot::{Pallet} = 50, + Identity: pallet_identity::{Pallet, Call, Config<T>, Storage, Event<T>} = 51, + Membership: pallet_membership::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 52, + StrongCert: pallet_certification::<Instance1>::{Pallet, Call, Config<T>, Storage, Event<T>} = 53, // Multisig dispatch. Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 60, diff --git a/runtime/gtest/src/parameters.rs b/runtime/gtest/src/parameters.rs index ed4ca96bd..26eea171d 100644 --- a/runtime/gtest/src/parameters.rs +++ b/runtime/gtest/src/parameters.rs @@ -91,6 +91,12 @@ parameter_types! { /* WOT */ /*******/ +parameter_types! { + pub MinCertForUdRight: u8 = 5; + pub MinCertForCertRight: u8 = 5; + pub MinCertForCreateIdtyRight: u8 = 5; +} + // Identity pub const IDTY_CREATE_PERIOD: BlockNumber = 100; frame_support::parameter_types! { -- GitLab