diff --git a/Cargo.lock b/Cargo.lock index 6c9ecc52cf6a7bfda823a5a72d2fb83796931baf..63b4431af3fdceeb3272e92886716713c859a1ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8881,6 +8881,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 ed9a58d1782f7e2f8b14b8479bd0d2505550d819..f8b37491484fdcb33775086203f78a80712f8355 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 f927742625e1dfb609818763dbd81d7b05cca762..fcd4e2fb22034ebfe308f58349b0cc95e39a52e4 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 82fb57f09fd8ec0cc1e9fd27a1cc847cab7b2dee..727ea10e7a53642e181b83b3bd7624ef67230889 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 6f9544f5b2b1e8c635a43b37ae1da87467754269..4b5c36fdea18cb04a9eec7ba80d57800488b1ffd 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 078bb6d7c28e01178db82b17c0e42c7ca0c2a315..91b791345802eb128cc942ee0e2748495800f150 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 63e8003bb279d25d5b09a68536f13572e1218bec..7979b05fefe6260ee7b52a0080330113a981c3ed 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 3f4d9cd5cb418c678cd52d22a81426c426c51dcb..99cd560948402c7c8c72bca0cc750be89324ce41 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 911d2be7e54d1a0d68a24119dd30e52cdb04f5c7..34d3150dff821b7f137e74652c172a7d42c6bbee 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 9731c3b385dada7e749e390f1fd03ce30b49afb5..d1e5585ea1cd2da137a11b8c62c4acfd4dfe95bb 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)) + } }