From db241e71e5b3ed75b43eb531d2ab00dd710a2c5a Mon Sep 17 00:00:00 2001
From: bgallois <benjamin@gallois.cc>
Date: Wed, 5 Feb 2025 11:43:42 +0100
Subject: [PATCH] revoke identity unlink account

---
 Cargo.lock                                    |  1 +
 pallets/duniter-account/Cargo.toml            |  3 +++
 pallets/duniter-account/src/benchmarking.rs   | 10 +++++++++
 pallets/duniter-account/src/lib.rs            | 19 ++++++++++++++++
 pallets/duniter-account/src/weights.rs        | 11 ++++++++++
 runtime/common/src/handlers.rs                | 18 ++++++++-------
 .../g1/src/weights/pallet_duniter_account.rs  | 22 +++++++++++++++----
 .../src/weights/pallet_duniter_account.rs     | 22 +++++++++++++++----
 runtime/gdev/tests/integration_tests.rs       | 17 ++++++++++++++
 .../src/weights/pallet_duniter_account.rs     | 22 +++++++++++++++----
 10 files changed, 125 insertions(+), 20 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index be8a37afd..d420f9d4f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8878,6 +8878,7 @@ dependencies = [
 name = "pallet-duniter-account"
 version = "1.0.0"
 dependencies = [
+ "duniter-primitives",
  "frame-benchmarking",
  "frame-support",
  "frame-system",
diff --git a/pallets/duniter-account/Cargo.toml b/pallets/duniter-account/Cargo.toml
index ed9a58d17..f8b374914 100644
--- a/pallets/duniter-account/Cargo.toml
+++ b/pallets/duniter-account/Cargo.toml
@@ -23,6 +23,7 @@ runtime-benchmarks = [
 ]
 std = [
 	"codec/std",
+	"duniter-primitives/std",
 	"frame-benchmarking?/std",
 	"frame-support/std",
 	"frame-system/std",
@@ -39,6 +40,7 @@ std = [
 	"sp-runtime/std",
 ]
 try-runtime = [
+	"duniter-primitives/try-runtime",
 	"frame-support/try-runtime",
 	"frame-system/try-runtime",
 	"pallet-balances/try-runtime",
@@ -57,6 +59,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 # local
 pallet-quota = { workspace = true }
 pallet-identity = { workspace = true }
+duniter-primitives = { workspace = true }
 codec = { workspace = true, features = ["derive"] }
 log = { workspace = true }
 pallet-balances = { workspace = true }
diff --git a/pallets/duniter-account/src/benchmarking.rs b/pallets/duniter-account/src/benchmarking.rs
index f92774262..fcd4e2fb2 100644
--- a/pallets/duniter-account/src/benchmarking.rs
+++ b/pallets/duniter-account/src/benchmarking.rs
@@ -34,4 +34,14 @@ mod benchmarks {
         #[extrinsic_call]
         _(RawOrigin::Signed(account));
     }
+
+    #[benchmark]
+    fn on_revoke_identity() {
+        let idty: IdtyIdOf<T> = 1u32.into();
+
+        #[block]
+        {
+            <Pallet<T> as pallet_identity::traits::OnRemoveIdty<T>>::on_revoked(&idty);
+        }
+    }
 }
diff --git a/pallets/duniter-account/src/lib.rs b/pallets/duniter-account/src/lib.rs
index 82fb57f09..727ea10e7 100644
--- a/pallets/duniter-account/src/lib.rs
+++ b/pallets/duniter-account/src/lib.rs
@@ -216,6 +216,25 @@ pub mod pallet {
     }
 }
 
+/// Implementing identity removal event handling for the pallet.
+impl<T: Config> pallet_identity::traits::OnRemoveIdty<T> for Pallet<T> {
+    fn on_removed(_idty_index: &IdtyIdOf<T>) -> Weight {
+        Weight::zero()
+    }
+
+    /// This implementation unlinks account associated with the identity.
+    fn on_revoked(idty_index: &IdtyIdOf<T>) -> Weight {
+        if let Some(account) = <pallet_identity::Pallet<T> as duniter_primitives::Idty<
+            IdtyIdOf<T>,
+            T::AccountId,
+        >>::owner_key(*idty_index)
+        {
+            Self::do_unlink_identity(account);
+        }
+        <T as pallet::Config>::WeightInfo::on_revoke_identity()
+    }
+}
+
 // implement account linker
 impl<T> pallet_identity::traits::LinkIdty<T::AccountId, IdtyIdOf<T>> for Pallet<T>
 where
diff --git a/pallets/duniter-account/src/weights.rs b/pallets/duniter-account/src/weights.rs
index 6f9544f5b..4b5c36fde 100644
--- a/pallets/duniter-account/src/weights.rs
+++ b/pallets/duniter-account/src/weights.rs
@@ -21,6 +21,7 @@ use frame_support::weights::{constants::RocksDbWeight, Weight};
 /// Weight functions needed for pallet_universal_dividend.
 pub trait WeightInfo {
     fn unlink_identity() -> Weight;
+    fn on_revoke_identity() -> Weight;
 }
 
 // Insecure weights implementation, use it for tests only!
@@ -36,4 +37,14 @@ impl WeightInfo for () {
             .saturating_add(Weight::from_parts(0, 3591))
             .saturating_add(RocksDbWeight::get().reads(1))
     }
+
+    fn on_revoke_identity() -> Weight {
+        // Proof Size summary in bytes:
+        //  Measured:  `0`
+        //  Estimated: `3591`
+        // Minimum execution time: 95_130_000 picoseconds.
+        Weight::from_parts(110_501_000, 0)
+            .saturating_add(Weight::from_parts(0, 3591))
+            .saturating_add(RocksDbWeight::get().reads(1))
+    }
 }
diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs
index 078bb6d7c..91b791345 100644
--- a/runtime/common/src/handlers.rs
+++ b/runtime/common/src/handlers.rs
@@ -50,19 +50,21 @@ impl<Runtime: pallet_duniter_wot::Config + pallet_quota::Config>
 /// Runtime handler for OnRemoveIdty, calling all implementations of
 /// OnRemoveIdty and implementing logic at the runtime level.
 pub struct OnRemoveIdtyHandler<Runtime>(core::marker::PhantomData<Runtime>);
-impl<Runtime: pallet_duniter_wot::Config + pallet_quota::Config>
-    pallet_identity::traits::OnRemoveIdty<Runtime> for OnRemoveIdtyHandler<Runtime>
+impl<
+        Runtime: pallet_duniter_wot::Config + pallet_quota::Config + pallet_duniter_account::Config,
+    > pallet_identity::traits::OnRemoveIdty<Runtime> for OnRemoveIdtyHandler<Runtime>
 {
     fn on_removed(idty_index: &IdtyIndex) -> Weight {
-        let mut weight = pallet_duniter_wot::Pallet::<Runtime>::on_removed(idty_index);
-        weight += pallet_quota::Pallet::<Runtime>::on_removed(idty_index);
-        weight
+        pallet_duniter_wot::Pallet::<Runtime>::on_removed(idty_index)
+            .saturating_add(pallet_quota::Pallet::<Runtime>::on_removed(idty_index))
     }
 
     fn on_revoked(idty_index: &IdtyIndex) -> Weight {
-        let mut weight = pallet_duniter_wot::Pallet::<Runtime>::on_revoked(idty_index);
-        weight += pallet_quota::Pallet::<Runtime>::on_revoked(idty_index);
-        weight
+        pallet_duniter_wot::Pallet::<Runtime>::on_revoked(idty_index)
+            .saturating_add(pallet_duniter_account::Pallet::<Runtime>::on_revoked(
+                idty_index,
+            ))
+            .saturating_add(pallet_quota::Pallet::<Runtime>::on_revoked(idty_index))
     }
 }
 
diff --git a/runtime/g1/src/weights/pallet_duniter_account.rs b/runtime/g1/src/weights/pallet_duniter_account.rs
index 63e8003bb..7979b05fe 100644
--- a/runtime/g1/src/weights/pallet_duniter_account.rs
+++ b/runtime/g1/src/weights/pallet_duniter_account.rs
@@ -17,7 +17,7 @@
 //! Autogenerated weights for `pallet_duniter_account`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-01-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-02-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
 //! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
@@ -29,7 +29,7 @@
 // --genesis-builder=spec-genesis
 // --steps=50
 // --repeat=20
-// --pallet=*
+// --pallet=pallet_duniter-account
 // --extrinsic=*
 // --wasm-execution=compiled
 // --heap-pages=4096
@@ -53,10 +53,24 @@ impl<T: frame_system::Config> pallet_duniter_account::WeightInfo for WeightInfo<
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3558`
-		// Minimum execution time: 4_566_000 picoseconds.
-		Weight::from_parts(4_728_000, 0)
+		// Minimum execution time: 4_528_000 picoseconds.
+		Weight::from_parts(4_834_000, 0)
 			.saturating_add(Weight::from_parts(0, 3558))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `Identity::Identities` (r:1 w:0)
+	/// Proof: `Identity::Identities` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `MaxEncodedLen`)
+	fn on_revoke_identity() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `384`
+		//  Estimated: `3849`
+		// Minimum execution time: 12_142_000 picoseconds.
+		Weight::from_parts(13_467_000, 0)
+			.saturating_add(Weight::from_parts(0, 3849))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
 }
diff --git a/runtime/gdev/src/weights/pallet_duniter_account.rs b/runtime/gdev/src/weights/pallet_duniter_account.rs
index 3f4d9cd5c..99cd56094 100644
--- a/runtime/gdev/src/weights/pallet_duniter_account.rs
+++ b/runtime/gdev/src/weights/pallet_duniter_account.rs
@@ -17,7 +17,7 @@
 //! Autogenerated weights for `pallet_duniter_account`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-01-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-02-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
 //! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
@@ -29,7 +29,7 @@
 // --genesis-builder=spec-genesis
 // --steps=50
 // --repeat=20
-// --pallet=*
+// --pallet=pallet_duniter-account
 // --extrinsic=*
 // --wasm-execution=compiled
 // --heap-pages=4096
@@ -53,10 +53,24 @@ impl<T: frame_system::Config> pallet_duniter_account::WeightInfo for WeightInfo<
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3558`
-		// Minimum execution time: 4_307_000 picoseconds.
-		Weight::from_parts(4_532_000, 0)
+		// Minimum execution time: 4_500_000 picoseconds.
+		Weight::from_parts(4_694_000, 0)
 			.saturating_add(Weight::from_parts(0, 3558))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `Identity::Identities` (r:1 w:0)
+	/// Proof: `Identity::Identities` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `MaxEncodedLen`)
+	fn on_revoke_identity() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `384`
+		//  Estimated: `3849`
+		// Minimum execution time: 11_751_000 picoseconds.
+		Weight::from_parts(12_335_000, 0)
+			.saturating_add(Weight::from_parts(0, 3849))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
 }
diff --git a/runtime/gdev/tests/integration_tests.rs b/runtime/gdev/tests/integration_tests.rs
index 911d2be7e..34d3150df 100644
--- a/runtime/gdev/tests/integration_tests.rs
+++ b/runtime/gdev/tests/integration_tests.rs
@@ -669,6 +669,23 @@ fn test_membership_renewal() {
         });
 }
 
+// test that identity is unlinked when identity is revoked
+#[test]
+fn test_revoke_identity_should_unlink() {
+    ExtBuilder::new(1, 3, 4).build().execute_with(|| {
+        run_to_block(1);
+
+        // revoke identity
+        Identity::do_revoke_identity(1, pallet_identity::RevocationReason::Root);
+
+        assert_eq!(
+            frame_system::Pallet::<Runtime>::get(&AccountKeyring::Alice.to_account_id())
+                .linked_idty,
+            None
+        );
+    })
+}
+
 // test that UD are auto claimed when identity is revoked
 #[test]
 fn test_revoke_identity_after_one_ud() {
diff --git a/runtime/gtest/src/weights/pallet_duniter_account.rs b/runtime/gtest/src/weights/pallet_duniter_account.rs
index 9731c3b38..d1e5585ea 100644
--- a/runtime/gtest/src/weights/pallet_duniter_account.rs
+++ b/runtime/gtest/src/weights/pallet_duniter_account.rs
@@ -17,7 +17,7 @@
 //! Autogenerated weights for `pallet_duniter_account`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2025-01-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2025-02-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
 //! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024
@@ -29,7 +29,7 @@
 // --genesis-builder=spec-genesis
 // --steps=50
 // --repeat=20
-// --pallet=*
+// --pallet=pallet_duniter-account
 // --extrinsic=*
 // --wasm-execution=compiled
 // --heap-pages=4096
@@ -53,10 +53,24 @@ impl<T: frame_system::Config> pallet_duniter_account::WeightInfo for WeightInfo<
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3558`
-		// Minimum execution time: 4_257_000 picoseconds.
-		Weight::from_parts(4_495_000, 0)
+		// Minimum execution time: 4_425_000 picoseconds.
+		Weight::from_parts(4_688_000, 0)
 			.saturating_add(Weight::from_parts(0, 3558))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `Identity::Identities` (r:1 w:0)
+	/// Proof: `Identity::Identities` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `MaxEncodedLen`)
+	fn on_revoke_identity() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `384`
+		//  Estimated: `3849`
+		// Minimum execution time: 11_832_000 picoseconds.
+		Weight::from_parts(12_747_000, 0)
+			.saturating_add(Weight::from_parts(0, 3849))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
 }
-- 
GitLab