diff --git a/Cargo.lock b/Cargo.lock index be8a37afdcf99d369590c2ccd545b3835053ff71..b8f42cc068abe956a266a2166f141a36a1c77ed2 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", @@ -9546,6 +9547,7 @@ dependencies = [ "scale-info", "sp-core", "sp-io", + "sp-membership", "sp-runtime", ] diff --git a/end2end-tests/cucumber-features/distance_fail.feature b/end2end-tests/cucumber-features/distance_fail.feature index 1abb9df532bda6e0dd03da47b8885fe39af3d30e..e465b715a5321c2201a9f452e55d9c7760f1e079 100644 --- a/end2end-tests/cucumber-features/distance_fail.feature +++ b/end2end-tests/cucumber-features/distance_fail.feature @@ -31,12 +31,14 @@ Feature: Distance fail When bob certifies ferdie Then ferdie should be certified by bob Then ferdie should have 0 ÄžD reserved - Then ferdie should have 1449 cÄžD + # 700 + 750 - 2(one transaction fee, not a member yet) + Then ferdie should have 1448 cÄžD When ferdie requests distance evaluation Then ferdie should have 10 ÄžD reserved - Then ferdie should have 449 cÄžD + # 1448 - 1000 - 2(one transaction fee, not a member yet) + Then ferdie should have 446 cÄžD When 7 blocks later - Then treasury should contain 102 cÄžD + Then treasury should contain 105 cÄžD When alice runs distance oracle When 7 blocks later Then ferdie should be certified by alice @@ -45,6 +47,6 @@ Feature: Distance fail Then ferdie identity should be unvalidated # Ferdie got his reserve slashed Then ferdie should have 0 ÄžD reserved - Then ferdie should have 449 cÄžD + Then ferdie should have 446 cÄžD # Slashed amount is transfered to treasury - Then treasury should contain 1102 cÄžD + Then treasury should contain 1105 cÄžD diff --git a/end2end-tests/cucumber-features/identity_creation.feature b/end2end-tests/cucumber-features/identity_creation.feature index 97ae14b029732fc33643301a75cccdbb94fcdaf2..3bb8fee162300da4dbc73639a04a7698da1e2925 100644 --- a/end2end-tests/cucumber-features/identity_creation.feature +++ b/end2end-tests/cucumber-features/identity_creation.feature @@ -24,13 +24,15 @@ Feature: Identity creation Then dave should be certified by bob Then dave should be certified by charlie Then dave should have 0 ÄžD reserved - Then dave should have 1449 cÄžD + # 700 + 750 - 2(one transaction fee, not a member yet) + Then dave should have 1448 cÄžD When dave requests distance evaluation Then dave should have 10 ÄžD reserved - Then dave should have 449 cÄžD + # 1448 - 1000 - 2(one transaction fee, not a member yet) + Then dave should have 446 cÄžD When 7 blocks later When alice runs distance oracle When 7 blocks later Then dave identity should be member Then dave should have 0 ÄžD reserved - Then dave should have 1449 cÄžD + Then dave should have 1446 cÄžD 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/pallets/quota/Cargo.toml b/pallets/quota/Cargo.toml index 9df99355f7735a97d06dc783a59d6852a444e01c..d23f77648be15c77e612c48a34450372fb2b16cc 100644 --- a/pallets/quota/Cargo.toml +++ b/pallets/quota/Cargo.toml @@ -16,6 +16,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-identity/runtime-benchmarks", + "sp-membership/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] try-runtime = [ @@ -23,8 +24,8 @@ try-runtime = [ "frame-system/try-runtime", "pallet-balances/runtime-benchmarks", "pallet-balances/try-runtime", - "pallet-identity/runtime-benchmarks", "pallet-identity/try-runtime", + "sp-membership/try-runtime", "sp-runtime/try-runtime", ] std = [ @@ -34,6 +35,7 @@ std = [ "frame-system/std", "pallet-balances/std", "pallet-identity/std", + "sp-membership/std", "scale-info/std", "sp-core/std", "sp-io/std", @@ -50,6 +52,7 @@ frame-support = { workspace = true } frame-system = { workspace = true } pallet-balances = { workspace = true } pallet-identity = { workspace = true } +sp-membership = { workspace = true } scale-info = { workspace = true, features = ["derive"] } sp-core = { workspace = true } sp-runtime = { workspace = true } diff --git a/pallets/quota/src/lib.rs b/pallets/quota/src/lib.rs index 9ea7aa21050c7cadcde0a1c40275b0a6dfa3bb03..25782264e959a6cd8d091d4fa0a3060449c59e75 100644 --- a/pallets/quota/src/lib.rs +++ b/pallets/quota/src/lib.rs @@ -360,17 +360,20 @@ impl<T: Config> RefundFee<T> for Pallet<T> { /// Checks if an identity is eligible for a refund. /// -/// This function returns `true` for all identities, regardless of their status. -/// If the identity has no quotas or has been deleted, the refund request is still queued, -/// but when handled, no refund will be issued (and `NoQuotaForIdty` may be raised). -fn is_eligible_for_refund<T: pallet_identity::Config>(_identity: IdtyId<T>) -> bool { - true +/// This function returns `true` only if the identity exists and has a status of `Member`. +/// If the identity does not exist or has a different status, it returns `false`, and the refund request will not be processed. +/// +fn is_eligible_for_refund<T: pallet_identity::Config>(idty_index: IdtyId<T>) -> bool { + pallet_identity::Identities::<T>::get(idty_index).map_or_else( + || false, + |id| id.status == pallet_identity::IdtyStatus::Member, + ) } -/// Implementing the on new identity event handler for the pallet. -impl<T: Config> pallet_identity::traits::OnNewIdty<T> for Pallet<T> { +/// Implementing the on new membership event handler for the pallet. +impl<T: Config> sp_membership::traits::OnNewMembership<IdtyId<T>> for Pallet<T> { /// This implementation initializes the identity quota for the newly created identity. - fn on_created(idty_index: &IdtyId<T>, _creator: &T::IdtyIndex) { + fn on_created(idty_index: &IdtyId<T>) { IdtyQuota::<T>::insert( idty_index, Quota { @@ -379,10 +382,12 @@ impl<T: Config> pallet_identity::traits::OnNewIdty<T> for Pallet<T> { }, ); } + + fn on_renewed(_idty_index: &IdtyId<T>) {} } /// Implementing the on remove identity event handler for the pallet. -impl<T: Config> pallet_identity::traits::OnRemoveIdty<T> for Pallet<T> { +impl<T: Config> sp_membership::traits::OnRemoveMembership<IdtyId<T>> for Pallet<T> { /// This implementation removes the identity quota associated with the removed identity. fn on_removed(idty_id: &IdtyId<T>) -> Weight { let mut weight = Weight::zero(); @@ -394,9 +399,4 @@ impl<T: Config> pallet_identity::traits::OnRemoveIdty<T> for Pallet<T> { add_db_reads_writes(1, 1); weight } - - /// This implementation removes the identity quota associated with the removed identity. - fn on_revoked(idty_id: &IdtyId<T>) -> Weight { - Self::on_removed(idty_id) - } } diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs index 078bb6d7c28e01178db82b17c0e42c7ca0c2a315..3fdd7b2d395730e3bb4f45cbb12ae1bc7f3f1817 100644 --- a/runtime/common/src/handlers.rs +++ b/runtime/common/src/handlers.rs @@ -38,31 +38,28 @@ where /// Runtime handler for OnNewIdty, calling all implementations of /// OnNewIdty and implementing logic at the runtime level. pub struct OnNewIdtyHandler<Runtime>(core::marker::PhantomData<Runtime>); -impl<Runtime: pallet_duniter_wot::Config + pallet_quota::Config> - pallet_identity::traits::OnNewIdty<Runtime> for OnNewIdtyHandler<Runtime> +impl<Runtime: pallet_duniter_wot::Config> pallet_identity::traits::OnNewIdty<Runtime> + for OnNewIdtyHandler<Runtime> { fn on_created(idty_index: &IdtyIndex, creator: &IdtyIndex) { pallet_duniter_wot::Pallet::<Runtime>::on_created(idty_index, creator); - pallet_quota::Pallet::<Runtime>::on_created(idty_index, creator); } } /// 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> +impl<Runtime: pallet_duniter_wot::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) } 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), + ) } } @@ -73,13 +70,16 @@ impl< Runtime: frame_system::Config<AccountId = AccountId> + pallet_identity::Config<IdtyData = IdtyData, IdtyIndex = IdtyIndex> + pallet_duniter_wot::Config - + pallet_universal_dividend::Config, + + pallet_universal_dividend::Config + + pallet_quota::Config, > sp_membership::traits::OnNewMembership<IdtyIndex> for OnNewMembershipHandler<Runtime> { fn on_created(idty_index: &IdtyIndex) { // duniter-wot related actions pallet_duniter_wot::Pallet::<Runtime>::on_created(idty_index); + pallet_quota::Pallet::<Runtime>::on_created(idty_index); + // When main membership is acquired, it starts getting right to UD. pallet_identity::Identities::<Runtime>::mutate_exists(idty_index, |idty_val_opt| { if let Some(ref mut idty_val) = idty_val_opt { @@ -105,6 +105,7 @@ impl< + pallet_identity::Config<IdtyData = IdtyData, IdtyIndex = IdtyIndex> + pallet_smith_members::Config<IdtyIndex = IdtyIndex> + pallet_duniter_wot::Config + + pallet_quota::Config + pallet_universal_dividend::Config, > sp_membership::traits::OnRemoveMembership<IdtyIndex> for OnRemoveMembershipHandler<Runtime> { @@ -125,7 +126,8 @@ impl< } } }); - weight += Runtime::DbWeight::get().reads_writes(1, 1); + weight.saturating_add(pallet_quota::Pallet::<Runtime>::on_removed(idty_index)); + weight.saturating_add(Runtime::DbWeight::get().reads_writes(1, 1)); // When membership is removed, also remove from smith member. weight.saturating_add( 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/gdev/tests/xt_tests.rs b/runtime/gdev/tests/xt_tests.rs index 6fcc2060c37257f7f12b5d234a3e864e08bd999b..efac8a18f5da8a26a11df9f340da5c8799faf55b 100644 --- a/runtime/gdev/tests/xt_tests.rs +++ b/runtime/gdev/tests/xt_tests.rs @@ -207,3 +207,100 @@ fn test_refund_reaped_linked_account() { assert!(pallet_quota::RefundQueue::<Runtime>::get().is_empty()); }) } + +/// test no refund on_idle when account is not a member +#[test] +fn test_no_member_no_refund() { + ExtBuilder::new(1, 3, 4) + .with_initial_balances(vec![ + (AccountKeyring::Alice.to_account_id(), 10_000), + (AccountKeyring::Bob.to_account_id(), 10_000), + ]) + .build() + .execute_with(|| { + // Revoked identities are not eligible for a refund + let revocation_payload = pallet_identity::RevocationPayload { + idty_index: 2u32, + genesis_hash: System::block_hash(0), + }; + let signature = AccountKeyring::Bob.sign( + &( + pallet_identity::REVOCATION_PAYLOAD_PREFIX, + revocation_payload, + ) + .encode(), + ); + assert_ok!(Identity::revoke_identity( + RuntimeOrigin::signed(AccountKeyring::Bob.to_account_id()), + 2, + AccountKeyring::Bob.to_account_id(), + signature.into() + )); + assert_eq!( + pallet_identity::Identities::<Runtime>::get(&2) + .unwrap() + .status, + pallet_identity::IdtyStatus::Revoked + ); + let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { + dest: AccountKeyring::Ferdie.to_account_id().into(), + value: 500, + }); + let xt = get_unchecked_extrinsic(call, 4u64, 8u64, AccountKeyring::Bob, 0u64, 0); + assert_ok!(Executive::apply_extrinsic(xt)); + assert!(pallet_quota::RefundQueue::<Runtime>::get().is_empty()); + + // Unconfirmed identities are not eligible for a refund + assert_ok!(Identity::create_identity( + RuntimeOrigin::signed(AccountKeyring::Alice.to_account_id()), + AccountKeyring::Ferdie.to_account_id(), + )); + assert_eq!( + pallet_identity::Identities::<Runtime>::get(&5) + .unwrap() + .status, + pallet_identity::IdtyStatus::Unconfirmed + ); + let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { + dest: AccountKeyring::Alice.to_account_id().into(), + value: 500, + }); + let xt = + get_unchecked_extrinsic(call.clone(), 4u64, 8u64, AccountKeyring::Ferdie, 0u64, 0); + assert_ok!(Executive::apply_extrinsic(xt)); + assert!(pallet_quota::RefundQueue::<Runtime>::get().is_empty()); + + // Unvalidated identities are not eligible for a refund + assert_ok!(Identity::confirm_identity( + RuntimeOrigin::signed(AccountKeyring::Ferdie.to_account_id()), + "ferdie".into(), + )); + assert_eq!( + pallet_identity::Identities::<Runtime>::get(&5) + .unwrap() + .status, + pallet_identity::IdtyStatus::Unvalidated + ); + let xt = + get_unchecked_extrinsic(call.clone(), 4u64, 8u64, AccountKeyring::Ferdie, 0u64, 1); + assert_ok!(Executive::apply_extrinsic(xt)); + assert!(pallet_quota::RefundQueue::<Runtime>::get().is_empty()); + + // NotMember identities are not eligible for a refund + pallet_identity::Pallet::<Runtime>::membership_removed(1); + assert_eq!( + pallet_identity::Identities::<Runtime>::get(&1) + .unwrap() + .status, + pallet_identity::IdtyStatus::NotMember + ); + let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { + dest: AccountKeyring::Bob.to_account_id().into(), + value: 500, + }); + let xt = + get_unchecked_extrinsic(call.clone(), 4u64, 8u64, AccountKeyring::Alice, 0u64, 0); + assert_ok!(Executive::apply_extrinsic(xt)); + assert!(pallet_quota::RefundQueue::<Runtime>::get().is_empty()); + }) +} 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)) + } }