diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs index 06226d5b42bb7da7b3a0efcec375519cb75cde54..dd6396b8fc4872cc38e7ef2ca4ae0b454b73b07f 100644 --- a/pallets/duniter-wot/src/mock.rs +++ b/pallets/duniter-wot/src/mock.rs @@ -145,6 +145,7 @@ impl pallet_membership::Config<Instance1> for Test { type CheckCallAllowed = DuniterWot; type IdtyId = IdtyIndex; type IdtyIdOf = IdentityIndexOf<Self>; + type AccountIdOf = (); type MembershipPeriod = MembershipPeriod; type MetaData = (); type OnEvent = DuniterWot; @@ -198,6 +199,7 @@ impl pallet_membership::Config<Instance2> for Test { type CheckCallAllowed = SmithsSubWot; type IdtyId = IdtyIndex; type IdtyIdOf = IdentityIndexOf<Self>; + type AccountIdOf = (); type MembershipPeriod = SmithsMembershipPeriod; type MetaData = (); type OnEvent = SmithsSubWot; diff --git a/pallets/membership/Cargo.toml b/pallets/membership/Cargo.toml index 2d0c23a9d239db6b36ff0234262eed180f83fb20..a0beee7528e93404167d7163ee8def77462a5148 100644 --- a/pallets/membership/Cargo.toml +++ b/pallets/membership/Cargo.toml @@ -11,7 +11,9 @@ version = '3.0.0' [features] default = ['std'] -runtime-benchmarks = ['frame-benchmarking'] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", +] std = [ 'codec/std', 'frame-support/std', @@ -73,6 +75,7 @@ default-features = false git = 'https://github.com/duniter/substrate' branch = 'duniter-substrate-v0.9.32' + ### DOC ### [package.metadata.docs.rs] diff --git a/pallets/membership/src/benchmarking.rs b/pallets/membership/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..63cd53c9796cbc5dbdd0182601f1e9733bd72ddf --- /dev/null +++ b/pallets/membership/src/benchmarking.rs @@ -0,0 +1,99 @@ +// 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/>. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_benchmarking::benchmarks_instance_pallet; +use frame_support::dispatch::UnfilteredDispatchable; +use frame_system::RawOrigin; +use sp_runtime::traits::Convert; + +#[cfg(test)] +use maplit::btreemap; + +use crate::Pallet; + +fn assert_has_event<T: Config<I>, I: 'static>(generic_event: <T as Config<I>>::RuntimeEvent) { + frame_system::Pallet::<T>::assert_has_event(generic_event.into()); +} + +benchmarks_instance_pallet! { + where_clause { + where + T::IdtyId: From<u32>, + } + force_request_membership { + let idty: T::IdtyId = 5.into(); + }: _<T::RuntimeOrigin>(RawOrigin::Root.into(), idty, T::MetaData ::default() ) + verify { + assert_has_event::<T, I>(Event::<T, I>::MembershipRequested(idty).into()); + } + request_membership { + 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 { metadata: T::MetaData ::default()}; + }: { + call.dispatch_bypass_filter(caller_origin).ok(); + //Ok::<(), DispatchError>(()) + } + verify { + if T::CheckCallAllowed::check_idty_allowed_to_request_membership(&idty).is_ok() { + assert_has_event::<T, I>(Event::<T, I>::MembershipRequested(idty).into()); + } + } + claim_membership { + let idty: T::IdtyId = 3.into(); + Membership::<T, I>::take(idty); + PendingMembership::<T, I>::insert(idty.clone(), T::MetaData::default()); + 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::RuntimeOrigin>(caller_origin, Some(idty)) + verify { + assert_has_event::<T, I>(Event::<T, I>::MembershipAcquired(idty).into()); + } + renew_membership { + let idty: T::IdtyId = 3.into(); + 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::RuntimeOrigin>(caller_origin, Some(idty)) + verify { + assert_has_event::<T, I>(Event::<T, I>::MembershipRenewed(idty).into()); + } + revoke_membership { + let idty: T::IdtyId = 3.into(); + 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::RuntimeOrigin>(caller_origin, Some(idty)) + verify { + assert_has_event::<T, I>(Event::<T, I>::MembershipRevoked(idty).into()); + } + + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext(crate::mock::DefaultMembershipConfig { + memberships: btreemap![ + 3 => MembershipData { + expire_on: 3, + }, + ],}), + crate::mock::Test + ); +} diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs index 475287c408af498ebdd9be5268068b8b68e1f3c7..76037d965cf6d8c39b4519d7a15801f606fc258a 100644 --- a/pallets/membership/src/lib.rs +++ b/pallets/membership/src/lib.rs @@ -23,8 +23,8 @@ mod mock; #[cfg(test)] mod tests; -/*#[cfg(feature = "runtime-benchmarks")] -mod benchmarking;*/ +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; pub use pallet::*; @@ -65,6 +65,8 @@ pub mod pallet { type IdtyId: Copy + MaybeSerializeDeserialize + Parameter + Ord; /// Something that give the IdtyId on an account id type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyId>>; + /// Something that give the account id on an OdtyId + type AccountIdOf: Convert<Self::IdtyId, Option<Self::AccountId>>; /// Optional metadata type MetaData: Default + Parameter + Validate<Self::AccountId>; #[pallet::constant] diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs index 93bb61d0db04e8f607cc809990f4debcc1421495..53d7f081bfdc0665682ff29a1f529465aef6cda5 100644 --- a/pallets/membership/src/mock.rs +++ b/pallets/membership/src/mock.rs @@ -86,6 +86,7 @@ impl pallet_membership::Config for Test { type CheckCallAllowed = (); type IdtyId = IdtyId; type IdtyIdOf = ConvertInto; + type AccountIdOf = ConvertInto; type MembershipPeriod = MembershipPeriod; type MetaData = (); type OnEvent = (); diff --git a/runtime/common/src/entities.rs b/runtime/common/src/entities.rs index 5b328d84353ae1a6985b23877ff775485fb1b677..1dd74188115d7234b3f7e4317c43182814bd8996 100644 --- a/runtime/common/src/entities.rs +++ b/runtime/common/src/entities.rs @@ -51,6 +51,18 @@ macro_rules! declare_session_keys { Self::Identity::type_info() } } + + // Dummy implementation only for benchmarking + impl Default for SessionKeysWrapper { + fn default() -> Self { + SessionKeysWrapper(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(), + }) + } + } } } } @@ -106,11 +118,27 @@ pub struct SmithsMembershipMetaData<SessionKeysWrapper> { pub p2p_endpoint: sp_runtime::RuntimeString, pub session_keys: SessionKeysWrapper, } -impl<SessionKeysWrapper> Default for SmithsMembershipMetaData<SessionKeysWrapper> { + +impl<SessionKeysWrapper: Default> Default for SmithsMembershipMetaData<SessionKeysWrapper> { + #[cfg(not(feature = "runtime-benchmarks"))] fn default() -> Self { unreachable!() } + #[cfg(feature = "runtime-benchmarks")] + // dummy implementation for benchmarking + fn default() -> Self { + SmithsMembershipMetaData { + owner_key: AccountId::from([ + // Dave (FIXME avoid stupid metadata) + 48, 103, 33, 33, 29, 84, 4, 189, 157, 168, 142, 2, 4, 54, 10, 26, 154, 184, 184, + 124, 102, 193, 188, 47, 205, 211, 127, 60, 34, 34, 204, 32, + ]), + p2p_endpoint: sp_runtime::RuntimeString::default(), + session_keys: SessionKeysWrapper::default(), + } + } } + impl<SessionKeysWrapper> sp_membership::traits::Validate<AccountId> for SmithsMembershipMetaData<SessionKeysWrapper> { diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs index 6c34a13ffd3473d88c23070c636c41acaa813c8b..f57a40cc468a9e197f3037ff5d93a1b5ec8a0b59 100644 --- a/runtime/common/src/pallets_config.rs +++ b/runtime/common/src/pallets_config.rs @@ -446,6 +446,7 @@ macro_rules! pallets_config { type CheckCallAllowed = Wot; type IdtyId = IdtyIndex; type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>; + type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>; type MembershipPeriod = MembershipPeriod; type MetaData = (); type OnEvent = OnMembershipEventHandler<Wot, Runtime>; @@ -481,6 +482,7 @@ macro_rules! pallets_config { type CheckCallAllowed = SmithsSubWot; type IdtyId = IdtyIndex; type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>; + type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>; type MembershipPeriod = SmithMembershipPeriod; type MetaData = SmithsMembershipMetaData<opaque::SessionKeysWrapper>; type OnEvent = OnSmithMembershipEventHandler<SmithsSubWot, Runtime>; diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs index 71f4bb92ad2c092c7c05338faf5436fa36f7685e..21ccecf858d818cbc1ede99646c85933bb147b38 100644 --- a/runtime/gdev/src/lib.rs +++ b/runtime/gdev/src/lib.rs @@ -149,6 +149,8 @@ mod benches { [common_runtime::duniter_account, Account] [pallet_certification, Cert] [pallet_certification, SmithsCert] + [pallet_membership, Membership] + [pallet_membership, SmithsMembership] // Substrate [pallet_balances, Balances] [frame_benchmarking::baseline, Baseline::<Runtime>]