From f9b04638fb2a1c263d32f4356cdfeee186d4fd24 Mon Sep 17 00:00:00 2001
From: cgeek <cem.moreau@gmail.com>
Date: Sun, 17 Dec 2023 15:05:36 +0100
Subject: [PATCH] feat(smith-members): max stock of certifications per smith

---
 pallets/smith-members/src/lib.rs   | 13 +++++++++----
 pallets/smith-members/src/mock.rs  |  2 +-
 pallets/smith-members/src/tests.rs | 14 ++++++++++++++
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/pallets/smith-members/src/lib.rs b/pallets/smith-members/src/lib.rs
index 3a7cd8bec..1245ea28e 100644
--- a/pallets/smith-members/src/lib.rs
+++ b/pallets/smith-members/src/lib.rs
@@ -245,6 +245,8 @@ pub mod pallet {
         ReceiverHasNotBeenInvited,
         /// Smith must be a member of the main WoT
         NotAMember,
+        /// A smith has a limited stock of certifications
+        TooMuchCertificationsIssued,
     }
 
     #[pallet::call]
@@ -357,13 +359,16 @@ impl<T: Config> Pallet<T> {
         receiver: T::IdtyIndex,
     ) -> DispatchResultWithPostInfo {
         ensure!(issuer != receiver, Error::<T>::CannotCertifySelf);
-        let issuer_status = Smiths::<T>::get(issuer)
-            .ok_or(Error::<T>::IssuerHasNoSmithStatus)?
-            .status;
+        let issuer = Smiths::<T>::get(issuer).ok_or(Error::<T>::IssuerHasNoSmithStatus)?;
         ensure!(
-            issuer_status == SmithStatus::Smith,
+            issuer.status == SmithStatus::Smith,
             Error::<T>::IssuerIsNotASmith
         );
+        let issued_certs = issuer.issued_certs.len() as u32;
+        ensure!(
+            issued_certs < T::MaxByIssuer::get(),
+            Error::<T>::TooMuchCertificationsIssued
+        );
         let receiver_status = Smiths::<T>::get(receiver)
             .ok_or(Error::<T>::ReceiverHasNotBeenInvited)?
             .status;
diff --git a/pallets/smith-members/src/mock.rs b/pallets/smith-members/src/mock.rs
index b32cf9b0f..d68d9782e 100644
--- a/pallets/smith-members/src/mock.rs
+++ b/pallets/smith-members/src/mock.rs
@@ -95,7 +95,7 @@ impl pallet_smith_members::Config for Runtime {
     type IdtyIdOf = ConvertInto;
     type MinCertForMembership = ConstU32<2>;
     type MinCertForCreateIdtyRight = ConstU32<3>;
-    type MaxByIssuer = ConstU32<5>;
+    type MaxByIssuer = ConstU32<3>;
     type InactivityMaxDuration = ConstU32<5>;
     type OnSmithDelete = ();
     type IdtyIdOfAuthorityId = ConvertInto;
diff --git a/pallets/smith-members/src/tests.rs b/pallets/smith-members/src/tests.rs
index 42b417077..54c4652bf 100644
--- a/pallets/smith-members/src/tests.rs
+++ b/pallets/smith-members/src/tests.rs
@@ -387,5 +387,19 @@ fn smith_coming_back_recovers_its_issued_certs() {
                 received_certs: vec![1, 3]
             })
         );
+        // We can verify it with the stock rule
+        assert_ok!(Pallet::<Runtime>::certify_smith(
+            RuntimeOrigin::signed(2),
+            3
+        ));
+        assert_ok!(Pallet::<Runtime>::certify_smith(
+            RuntimeOrigin::signed(2),
+            4
+        ));
+        // Max stock is reached (3 = 1 recovered + 2 new)
+        assert_err!(
+            Pallet::<Runtime>::certify_smith(RuntimeOrigin::signed(2), 5),
+            Error::<Runtime>::TooMuchCertificationsIssued
+        );
     });
 }
-- 
GitLab