From fe571d884ebaab8b12a1bf299de45c7efc633c98 Mon Sep 17 00:00:00 2001
From: Benjamin Gallois <business@gallois.cc>
Date: Thu, 26 Oct 2023 11:24:05 +0200
Subject: [PATCH] Fix benchmarks (nodes/rust/duniter-v2s!185)

* refac(benchmark) refactore BenchmarkSetupHandler

* fix(pallet_membership): fix benchmarks

* fix(pallet_identity): fix benchmarks
---
 pallets/distance/src/lib.rs            | 21 +++++++++++++++++
 pallets/identity/src/benchmarking.rs   |  1 +
 pallets/identity/src/lib.rs            |  3 +++
 pallets/identity/src/mock.rs           |  2 ++
 pallets/identity/src/traits.rs         | 10 +++++++++
 pallets/membership/src/benchmarking.rs |  8 +++++--
 pallets/membership/src/lib.rs          | 12 ++++++++++
 pallets/membership/src/mock.rs         |  2 ++
 runtime/common/src/pallets_config.rs   |  6 +++++
 runtime/common/src/providers.rs        | 31 ++++++++++++++++++++++++++
 10 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/pallets/distance/src/lib.rs b/pallets/distance/src/lib.rs
index 3ed6ab290..92ed6acc0 100644
--- a/pallets/distance/src/lib.rs
+++ b/pallets/distance/src/lib.rs
@@ -276,6 +276,27 @@ pub mod pallet {
         }
     }
 
+    // BENCHMARK FUNCTIONS //
+
+    impl<T: Config> Pallet<T> {
+        /// Force the distance status using IdtyIndex and AccountId
+        /// only to prepare identity for benchmarking.
+        pub fn set_distance_status(
+            identity: <T as pallet_identity::Config>::IdtyIndex,
+            status: Option<(<T as frame_system::Config>::AccountId, DistanceStatus)>,
+        ) -> DispatchResult {
+            IdentityDistanceStatus::<T>::set(identity, status);
+            DistanceStatusExpireOn::<T>::mutate(
+                pallet_session::CurrentIndex::<T>::get() + T::ResultExpiration::get(),
+                move |identities| {
+                    identities
+                        .try_push(identity)
+                        .map_err(|_| Error::<T>::ManyEvaluationsInBlock.into())
+                },
+            )
+        }
+    }
+
     // INTERNAL FUNCTIONS //
 
     impl<T: Config> Pallet<T> {
diff --git a/pallets/identity/src/benchmarking.rs b/pallets/identity/src/benchmarking.rs
index 1cee79c28..27894c2aa 100644
--- a/pallets/identity/src/benchmarking.rs
+++ b/pallets/identity/src/benchmarking.rs
@@ -147,6 +147,7 @@ benchmarks! {
         let owner_key: T::AccountId = Identities::<T>::get(index).unwrap().owner_key;
         let owner_key_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(owner_key.clone()).into();
         Pallet::<T>::confirm_identity(owner_key_origin.clone(), name.clone())?;
+        T::BenchmarkSetupHandler::force_status_ok(&index, &owner_key);
     }: _<T::RuntimeOrigin>(caller_origin, index)
     verify {
         assert_has_event::<T>(Event::<T>::IdtyValidated { idty_index: index }.into());
diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs
index 25733edb5..46b953a07 100644
--- a/pallets/identity/src/lib.rs
+++ b/pallets/identity/src/lib.rs
@@ -114,6 +114,9 @@ pub mod pallet {
         type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
         /// Type representing the weight of this pallet
         type WeightInfo: WeightInfo;
+        /// Type representing the a distance handler to prepare identity for benchmarking
+        #[cfg(feature = "runtime-benchmarks")]
+        type BenchmarkSetupHandler: SetDistance<Self::IdtyIndex, Self::AccountId>;
     }
 
     // GENESIS STUFFĂ‚ //
diff --git a/pallets/identity/src/mock.rs b/pallets/identity/src/mock.rs
index ce6032d08..7621c4955 100644
--- a/pallets/identity/src/mock.rs
+++ b/pallets/identity/src/mock.rs
@@ -117,6 +117,8 @@ impl pallet_identity::Config for Test {
     type RevocationSignature = Signature;
     type RuntimeEvent = RuntimeEvent;
     type WeightInfo = ();
+    #[cfg(feature = "runtime-benchmarks")]
+    type BenchmarkSetupHandler = ();
 }
 
 // Build genesis storage according to the mock runtime.
diff --git a/pallets/identity/src/traits.rs b/pallets/identity/src/traits.rs
index 54b50a06c..1d8dd0152 100644
--- a/pallets/identity/src/traits.rs
+++ b/pallets/identity/src/traits.rs
@@ -76,3 +76,13 @@ impl<IndtyIndex> RemoveIdentityConsumers<IndtyIndex> for () {
         Weight::zero()
     }
 }
+
+#[cfg(feature = "runtime-benchmarks")]
+pub trait SetDistance<IndtyIndex, AccountId> {
+    fn force_status_ok(idty_index: &IndtyIndex, account: &AccountId) -> ();
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+impl<IdtyIndex, AccountId> SetDistance<IdtyIndex, AccountId> for () {
+    fn force_status_ok(_idty_id: &IdtyIndex, _account: &AccountId) -> () {}
+}
diff --git a/pallets/membership/src/benchmarking.rs b/pallets/membership/src/benchmarking.rs
index 9b0ad18d0..3021d59f5 100644
--- a/pallets/membership/src/benchmarking.rs
+++ b/pallets/membership/src/benchmarking.rs
@@ -56,19 +56,23 @@ benchmarks_instance_pallet! {
         }
     }
     claim_membership {
-        let idty: T::IdtyId = 3.into();
+        let idty_index: u32 = 3;
+        let idty: T::IdtyId = idty_index.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::BenchmarkSetupHandler::force_status_ok(&idty_index, &caller);
     }: _<T::RuntimeOrigin>(caller_origin)
     verify {
         assert_has_event::<T, I>(Event::<T, I>::MembershipAcquired(idty).into());
     }
     renew_membership {
-        let idty: T::IdtyId = 3.into();
+        let idty_index: u32 = 3;
+        let idty: T::IdtyId = idty_index.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::BenchmarkSetupHandler::force_status_ok(&idty_index, &caller);
     }: _<T::RuntimeOrigin>(caller_origin)
     verify {
         assert_has_event::<T, I>(Event::<T, I>::MembershipRenewed(idty).into());
diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs
index 8fec34f89..6a90624e7 100644
--- a/pallets/membership/src/lib.rs
+++ b/pallets/membership/src/lib.rs
@@ -42,6 +42,16 @@ use sp_std::prelude::*;
 #[cfg(feature = "std")]
 use std::collections::BTreeMap;
 
+#[cfg(feature = "runtime-benchmarks")]
+pub trait SetDistance<IdtyId, AccountId> {
+    fn force_status_ok(idty_index: &IdtyId, account: &AccountId) -> ();
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+impl<IdtyId, AccountId> SetDistance<IdtyId, AccountId> for () {
+    fn force_status_ok(_idty_id: &IdtyId, _account: &AccountId) -> () {}
+}
+
 #[frame_support::pallet]
 pub mod pallet {
     use super::*;
@@ -83,6 +93,8 @@ pub mod pallet {
         type RuntimeEvent: From<Event<Self, I>>
             + IsType<<Self as frame_system::Config>::RuntimeEvent>;
         type WeightInfo: WeightInfo;
+        #[cfg(feature = "runtime-benchmarks")]
+        type BenchmarkSetupHandler: SetDistance<u32, Self::AccountId>;
     }
 
     // GENESIS STUFFĂ‚ //
diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs
index b4a65ac6a..d97f1f86a 100644
--- a/pallets/membership/src/mock.rs
+++ b/pallets/membership/src/mock.rs
@@ -93,6 +93,8 @@ impl pallet_membership::Config for Test {
     type PendingMembershipPeriod = PendingMembershipPeriod;
     type RuntimeEvent = RuntimeEvent;
     type WeightInfo = ();
+    #[cfg(feature = "runtime-benchmarks")]
+    type BenchmarkSetupHandler = ();
 }
 
 // Build genesis storage according to the mock runtime.
diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs
index 665bd8193..e5aaa8c3f 100644
--- a/runtime/common/src/pallets_config.rs
+++ b/runtime/common/src/pallets_config.rs
@@ -454,6 +454,8 @@ parameter_types! {
             type RevocationSignature = Signature;
             type RuntimeEvent = RuntimeEvent;
             type WeightInfo = common_runtime::weights::pallet_identity::WeightInfo<Runtime>;
+            #[cfg(feature = "runtime-benchmarks")]
+            type BenchmarkSetupHandler = common_runtime::providers::BenchmarkSetupHandler<Runtime>;
         }
 
         impl pallet_membership::Config<frame_support::instances::Instance1> for Runtime {
@@ -467,6 +469,8 @@ parameter_types! {
             type PendingMembershipPeriod = PendingMembershipPeriod;
             type RuntimeEvent = RuntimeEvent;
             type WeightInfo = common_runtime::weights::pallet_membership_membership::WeightInfo<Runtime>;
+            #[cfg(feature = "runtime-benchmarks")]
+            type BenchmarkSetupHandler = common_runtime::providers::BenchmarkSetupHandler<Runtime>;
         }
 
         impl pallet_certification::Config<Instance1> for Runtime {
@@ -514,6 +518,8 @@ parameter_types! {
             type PendingMembershipPeriod = SmithPendingMembershipPeriod;
             type RuntimeEvent = RuntimeEvent;
             type WeightInfo = common_runtime::weights::pallet_membership_smith_membership::WeightInfo<Runtime>;
+            #[cfg(feature = "runtime-benchmarks")]
+            type BenchmarkSetupHandler = common_runtime::providers::BenchmarkSetupHandler<Runtime>;
         }
 
         impl pallet_certification::Config<Instance2> for Runtime {
diff --git a/runtime/common/src/providers.rs b/runtime/common/src/providers.rs
index 151f70ece..e8ddf8102 100644
--- a/runtime/common/src/providers.rs
+++ b/runtime/common/src/providers.rs
@@ -121,3 +121,34 @@ where
         )
     }
 }
+
+#[cfg(feature = "runtime-benchmarks")]
+pub struct BenchmarkSetupHandler<T>(PhantomData<T>);
+
+// Macro implementing the BenchmarkSetupHandler trait for pallets requiring identity preparation for benchmarks.
+#[cfg(feature = "runtime-benchmarks")]
+macro_rules! impl_benchmark_setup_handler {
+    ($t:ty) => {
+        impl<T> $t for BenchmarkSetupHandler<T>
+        where
+            T: pallet_distance::Config,
+        {
+            fn force_status_ok(
+                idty_id: &<T as pallet_identity::Config>::IdtyIndex,
+                account: &<T as frame_system::Config>::AccountId,
+            ) -> () {
+                let _ = pallet_distance::Pallet::<T>::set_distance_status(
+                    *idty_id,
+                    Some((account.clone(), pallet_distance::DistanceStatus::Valid)),
+                );
+            }
+            // TODO: All the required preparation for the benchmarks, depending on the coupling
+            // between pallets, would be implemented here when moving away from prepared identities from the gdev-benchmark.
+        }
+    };
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+impl_benchmark_setup_handler!(pallet_membership::SetDistance<<T as pallet_identity::Config>::IdtyIndex, T::AccountId>);
+#[cfg(feature = "runtime-benchmarks")]
+impl_benchmark_setup_handler!(pallet_identity::traits::SetDistance<<T as pallet_identity::Config>::IdtyIndex, T::AccountId>);
-- 
GitLab