diff --git a/polkadot/runtime/rococo/src/weights/pallet_indices.rs b/polkadot/runtime/rococo/src/weights/pallet_indices.rs index 434db97d4a79f..900863d436844 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_indices.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_indices.rs @@ -17,27 +17,28 @@ //! Autogenerated weights for `pallet_indices` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-02-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `52baa5cae416`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// frame-omni-bencher +// v1 // benchmark // pallet -// --chain=rococo-dev +// --extrinsic=* +// --runtime=target/production/wbuild/rococo-runtime/rococo_runtime.wasm +// --pallet=pallet_indices +// --header=/__w/polkadot-sdk/polkadot-sdk/polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights +// --wasm-execution=compiled // --steps=50 // --repeat=20 +// --heap-pages=4096 // --no-storage-info -// --no-median-slopes // --no-min-squares -// --pallet=pallet_indices -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -56,8 +57,8 @@ impl pallet_indices::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `4` // Estimated: `3534` - // Minimum execution time: 18_092_000 picoseconds. - Weight::from_parts(18_533_000, 0) + // Minimum execution time: 22_250_000 picoseconds. + Weight::from_parts(23_442_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -70,8 +71,8 @@ impl pallet_indices::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `203` // Estimated: `3593` - // Minimum execution time: 31_616_000 picoseconds. - Weight::from_parts(32_556_000, 0) + // Minimum execution time: 35_315_000 picoseconds. + Weight::from_parts(37_456_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -82,8 +83,8 @@ impl pallet_indices::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `100` // Estimated: `3534` - // Minimum execution time: 19_593_000 picoseconds. - Weight::from_parts(20_100_000, 0) + // Minimum execution time: 23_413_000 picoseconds. + Weight::from_parts(24_307_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -96,8 +97,8 @@ impl pallet_indices::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `203` // Estimated: `3593` - // Minimum execution time: 21_429_000 picoseconds. - Weight::from_parts(22_146_000, 0) + // Minimum execution time: 25_799_000 picoseconds. + Weight::from_parts(26_614_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -108,8 +109,20 @@ impl pallet_indices::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `100` // Estimated: `3534` - // Minimum execution time: 20_425_000 picoseconds. - Weight::from_parts(21_023_000, 0) + // Minimum execution time: 26_905_000 picoseconds. + Weight::from_parts(27_574_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `100` + // Estimated: `3534` + // Minimum execution time: 23_596_000 picoseconds. + Weight::from_parts(24_227_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/westend/src/weights/pallet_indices.rs b/polkadot/runtime/westend/src/weights/pallet_indices.rs index 42316cd907801..c10ec047953f2 100644 --- a/polkadot/runtime/westend/src/weights/pallet_indices.rs +++ b/polkadot/runtime/westend/src/weights/pallet_indices.rs @@ -16,28 +16,29 @@ //! Autogenerated weights for `pallet_indices` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-02-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 +//! HOSTNAME: `52baa5cae416`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// frame-omni-bencher +// v1 // benchmark // pallet -// --chain=westend-dev +// --extrinsic=* +// --runtime=target/production/wbuild/westend-runtime/westend_runtime.wasm +// --pallet=pallet_indices +// --header=/__w/polkadot-sdk/polkadot-sdk/polkadot/file_header.txt +// --output=./polkadot/runtime/westend/src/weights +// --wasm-execution=compiled // --steps=50 // --repeat=20 +// --heap-pages=4096 // --no-storage-info -// --no-median-slopes // --no-min-squares -// --pallet=pallet_indices -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/westend/src/weights/ +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,66 +51,78 @@ use core::marker::PhantomData; /// Weight functions for `pallet_indices`. pub struct WeightInfo(PhantomData); impl pallet_indices::WeightInfo for WeightInfo { - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn claim() -> Weight { // Proof Size summary in bytes: - // Measured: `142` + // Measured: `4` // Estimated: `3534` - // Minimum execution time: 24_553_000 picoseconds. - Weight::from_parts(25_288_000, 0) + // Minimum execution time: 25_952_000 picoseconds. + Weight::from_parts(27_224_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `341` + // Measured: `203` // Estimated: `3593` - // Minimum execution time: 35_932_000 picoseconds. - Weight::from_parts(36_801_000, 0) + // Minimum execution time: 38_643_000 picoseconds. + Weight::from_parts(39_612_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn free() -> Weight { // Proof Size summary in bytes: - // Measured: `238` + // Measured: `100` // Estimated: `3534` - // Minimum execution time: 25_574_000 picoseconds. - Weight::from_parts(26_123_000, 0) + // Minimum execution time: 26_744_000 picoseconds. + Weight::from_parts(28_195_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `341` + // Measured: `203` // Estimated: `3593` - // Minimum execution time: 27_605_000 picoseconds. - Weight::from_parts(28_569_000, 0) + // Minimum execution time: 29_213_000 picoseconds. + Weight::from_parts(30_369_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn freeze() -> Weight { // Proof Size summary in bytes: - // Measured: `238` + // Measured: `100` + // Estimated: `3534` + // Minimum execution time: 30_370_000 picoseconds. + Weight::from_parts(31_164_000, 0) + .saturating_add(Weight::from_parts(0, 3534)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `100` // Estimated: `3534` - // Minimum execution time: 27_447_000 picoseconds. - Weight::from_parts(28_136_000, 0) + // Minimum execution time: 27_134_000 picoseconds. + Weight::from_parts(28_175_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/prdoc/pr_7587.prdoc b/prdoc/pr_7587.prdoc new file mode 100644 index 0000000000000..22796fde9e080 --- /dev/null +++ b/prdoc/pr_7587.prdoc @@ -0,0 +1,11 @@ +title: '[AHM] Poke deposits: Indices pallet' +doc: +- audience: Runtime Dev + description: Add a new extrinsic `poke_deposit` to `pallet-indices`. This extrinsic will be used to re-adjust the deposits made in the pallet after Asset Hub Migration. +crates: +- name: pallet-indices + bump: major +- name: rococo-runtime + bump: major +- name: westend-runtime + bump: major diff --git a/substrate/frame/indices/src/benchmarking.rs b/substrate/frame/indices/src/benchmarking.rs index 28f5e3bf5cf08..9e81915df153b 100644 --- a/substrate/frame/indices/src/benchmarking.rs +++ b/substrate/frame/indices/src/benchmarking.rs @@ -21,6 +21,7 @@ use crate::*; use frame_benchmarking::v2::*; +use frame_support::traits::Get; use frame_system::RawOrigin; use sp_runtime::traits::Bounded; @@ -112,6 +113,59 @@ mod benchmarks { Ok(()) } + #[benchmark] + fn poke_deposit() -> Result<(), BenchmarkError> { + let account_index = T::AccountIndex::from(SEED); + // Setup accounts + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + let original_deposit = T::Deposit::get(); + + // Claim the index + Pallet::::claim(RawOrigin::Signed(caller.clone()).into(), account_index)?; + + // Verify the initial deposit amount in storage and reserved balance + assert_eq!(Accounts::::get(account_index).unwrap().1, original_deposit); + assert_eq!(T::Currency::reserved_balance(&caller), original_deposit); + + // The additional amount we'll add to the deposit for the index + let additional_amount = 2u32.into(); + + // Reserve the additional amount from the caller's balance + T::Currency::reserve(&caller, additional_amount)?; + + // Verify the additional amount was reserved + assert_eq!( + T::Currency::reserved_balance(&caller), + original_deposit.saturating_add(additional_amount) + ); + + // Increase the deposited amount in storage by additional_amount + Accounts::::try_mutate(account_index, |maybe_value| -> Result<(), BenchmarkError> { + let (account, amount, perm) = maybe_value + .take() + .ok_or(BenchmarkError::Stop("Mutating storage to change deposits failed"))?; + *maybe_value = Some((account, amount.saturating_add(additional_amount), perm)); + Ok(()) + })?; + + // Verify the deposit was increased by additional_amount + assert_eq!( + Accounts::::get(account_index).unwrap().1, + original_deposit.saturating_add(additional_amount) + ); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), account_index); + + assert!(Accounts::::contains_key(account_index)); + assert_eq!(Accounts::::get(account_index).unwrap().0, caller); + assert_eq!(Accounts::::get(account_index).unwrap().1, original_deposit); + assert_eq!(T::Currency::reserved_balance(&caller), original_deposit); + Ok(()) + } + // TODO in another PR: lookup and unlookup trait weights (not critical) impl_benchmark_test_suite!(Pallet, mock::new_test_ext(), mock::Test); diff --git a/substrate/frame/indices/src/lib.rs b/substrate/frame/indices/src/lib.rs index 740d69365df3e..1629a730176f7 100644 --- a/substrate/frame/indices/src/lib.rs +++ b/substrate/frame/indices/src/lib.rs @@ -232,6 +232,64 @@ pub mod pallet { Self::deposit_event(Event::IndexFrozen { index, who }); Ok(()) } + + /// Poke the deposit reserved for an index. + /// + /// The dispatch origin for this call must be _Signed_ and the signing account must have a + /// non-frozen account `index`. + /// + /// The transaction fees is waived if the deposit is changed after poking/reconsideration. + /// + /// - `index`: the index whose deposit is to be poked/reconsidered. + /// + /// Emits `DepositPoked` if successful. + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::poke_deposit())] + pub fn poke_deposit( + origin: OriginFor, + index: T::AccountIndex, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + + Accounts::::try_mutate(index, |maybe_value| -> DispatchResultWithPostInfo { + let (account, old_amount, perm) = + maybe_value.take().ok_or(Error::::NotAssigned)?; + ensure!(!perm, Error::::Permanent); + ensure!(account == who, Error::::NotOwner); + + let new_amount = T::Deposit::get(); + + if old_amount == new_amount { + *maybe_value = Some((account, old_amount, perm)); + return Ok(Pays::Yes.into()); + } else if new_amount > old_amount { + // Need to reserve more + let extra = new_amount.saturating_sub(old_amount); + T::Currency::reserve(&who, extra)?; + } else if new_amount < old_amount { + // Need to unreserve some + let excess = old_amount.saturating_sub(new_amount); + let remaining_unreserved = T::Currency::unreserve(&who, excess); + // Defensive logging if we can't unreserve the full amount. + if !remaining_unreserved.is_zero() { + defensive!( + "Failed to unreserve full amount. (Index, Requested, Actual): ", + (index, excess, excess - remaining_unreserved) + ); + } + } + + *maybe_value = Some((account, new_amount, perm)); + + Self::deposit_event(Event::DepositPoked { + who, + index, + old_deposit: old_amount, + new_deposit: new_amount, + }); + Ok(Pays::No.into()) + }) + } } #[pallet::event] @@ -243,6 +301,13 @@ pub mod pallet { IndexFreed { index: T::AccountIndex }, /// A account index has been frozen to its current account ID. IndexFrozen { index: T::AccountIndex, who: T::AccountId }, + /// A deposit to reserve an index has been poked/reconsidered. + DepositPoked { + who: T::AccountId, + index: T::AccountIndex, + old_deposit: BalanceOf, + new_deposit: BalanceOf, + }, } #[pallet::error] diff --git a/substrate/frame/indices/src/mock.rs b/substrate/frame/indices/src/mock.rs index 80d0a88881f97..41cd0603c4af8 100644 --- a/substrate/frame/indices/src/mock.rs +++ b/substrate/frame/indices/src/mock.rs @@ -20,11 +20,15 @@ #![cfg(test)] use crate::{self as pallet_indices, Config}; -use frame_support::{derive_impl, traits::ConstU64}; +use frame_support::{derive_impl, parameter_types}; use sp_runtime::BuildStorage; type Block = frame_system::mocking::MockBlock; +parameter_types! { + pub static IndexDeposit: u64 = 1; +} + frame_support::construct_runtime!( pub enum Test { @@ -50,7 +54,7 @@ impl pallet_balances::Config for Test { impl Config for Test { type AccountIndex = u64; type Currency = Balances; - type Deposit = ConstU64<1>; + type Deposit = IndexDeposit; type RuntimeEvent = RuntimeEvent; type WeightInfo = (); } @@ -63,5 +67,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities { } .assimilate_storage(&mut t) .unwrap(); - t.into() + let mut ext: sp_io::TestExternalities = t.into(); + // Initialize the block number to 1 for event registration + ext.execute_with(|| System::set_block_number(1)); + ext } diff --git a/substrate/frame/indices/src/tests.rs b/substrate/frame/indices/src/tests.rs index 56b1019000389..5792737f27536 100644 --- a/substrate/frame/indices/src/tests.rs +++ b/substrate/frame/indices/src/tests.rs @@ -20,7 +20,7 @@ #![cfg(test)] use super::{mock::*, *}; -use frame_support::{assert_noop, assert_ok}; +use frame_support::{assert_noop, assert_ok, pallet_prelude::Pays}; use pallet_balances::Error as BalancesError; use sp_runtime::MultiAddress::Id; @@ -119,3 +119,119 @@ fn force_transfer_index_on_free_should_work() { assert_eq!(Indices::lookup_index(0), Some(3)); }); } + +#[test] +fn poke_deposit_should_fail_for_unassigned_index() { + new_test_ext().execute_with(|| { + assert_noop!(Indices::poke_deposit(Some(1).into(), 0), Error::::NotAssigned); + }); +} + +#[test] +fn poke_deposit_should_fail_for_wrong_owner() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_noop!(Indices::poke_deposit(Some(2).into(), 0), Error::::NotOwner); + }); +} + +#[test] +fn poke_deposit_should_fail_for_permanent_index() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_ok!(Indices::freeze(Some(1).into(), 0)); + assert_noop!(Indices::poke_deposit(Some(1).into(), 0), Error::::Permanent); + }); +} + +#[test] +fn poke_deposit_should_fail_for_insufficient_balance() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + + // Set deposit higher than available balance + IndexDeposit::set(1000); + + assert_noop!( + Indices::poke_deposit(Some(1).into(), 0), + BalancesError::::InsufficientBalance + ); + }); +} + +#[test] +fn poke_deposit_should_work_when_deposit_increases() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_eq!(Balances::reserved_balance(1), 1); + + // Change deposit to 3 + IndexDeposit::set(3); + + // poke_deposit should work and be free + let initial_balance = Balances::free_balance(1); + let result = Indices::poke_deposit(Some(1).into(), 0); + assert_ok!(result.as_ref()); + let post_info = result.unwrap(); + assert_eq!(post_info.pays_fee, Pays::No); + assert_eq!(Balances::reserved_balance(1), 3); + + // Balance should only reduce by the deposit difference + assert_eq!(Balances::free_balance(1), initial_balance - 2); + + System::assert_has_event( + Event::DepositPoked { who: 1, index: 0, old_deposit: 1, new_deposit: 3 }.into(), + ); + }); +} + +#[test] +fn poke_deposit_should_work_when_deposit_decreases() { + new_test_ext().execute_with(|| { + // Set initial deposit to 3 + IndexDeposit::set(3); + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_eq!(Balances::reserved_balance(1), 3); + + // Change deposit to 1 + IndexDeposit::set(1); + + let initial_balance = Balances::free_balance(1); + let result = Indices::poke_deposit(Some(1).into(), 0); + assert_ok!(result.as_ref()); + let post_info = result.unwrap(); + assert_eq!(post_info.pays_fee, Pays::No); + assert_eq!(Balances::reserved_balance(1), 1); + + // Balance should increase by the unreserved amount + assert_eq!(Balances::free_balance(1), initial_balance + 2); + + System::assert_has_event( + Event::DepositPoked { who: 1, index: 0, old_deposit: 3, new_deposit: 1 }.into(), + ); + }); +} + +#[test] +fn poke_deposit_should_charge_fee_when_deposit_unchanged() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_eq!(Balances::reserved_balance(1), 1); + + // poke_deposit with same deposit amount + let result = Indices::poke_deposit(Some(1).into(), 0); + assert_ok!(result.as_ref()); + // Verify fee payment + let post_info = result.unwrap(); + assert_eq!(post_info.pays_fee, Pays::Yes); + + // Reserved balance should remain the same + assert_eq!(Balances::reserved_balance(1), 1); + + // Verify no DepositPoked event was emitted + assert!(!System::events().iter().any(|record| matches!( + record.event, + RuntimeEvent::Indices(Event::DepositPoked { .. }) + ))); + }); +} diff --git a/substrate/frame/indices/src/weights.rs b/substrate/frame/indices/src/weights.rs index 567e9bab54bdf..f868e3f9c627b 100644 --- a/substrate/frame/indices/src/weights.rs +++ b/substrate/frame/indices/src/weights.rs @@ -15,36 +15,57 @@ // See the License for the specific language governing permissions and // limitations under the License. +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + //! Autogenerated weights for `pallet_indices` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-02-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `52baa5cae416`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// frame-omni-bencher +// v1 // benchmark // pallet -// --chain=dev +// --extrinsic=* +// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm +// --pallet=pallet_indices +// --header=/__w/polkadot-sdk/polkadot-sdk/substrate/HEADER-APACHE2 +// --output=/__w/polkadot-sdk/polkadot-sdk/substrate/frame/indices/src/weights.rs +// --wasm-execution=compiled // --steps=50 // --repeat=20 -// --pallet=pallet_indices +// --heap-pages=4096 +// --template=substrate/.maintain/frame-weight-template.hbs // --no-storage-info -// --no-median-slopes // --no-min-squares -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/indices/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --no-median-slopes +// --genesis-builder-policy=none +// --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic,pallet_nomination_pools,pallet_remark,pallet_transaction_storage,pallet_election_provider_multi_block,pallet_election_provider_multi_block::signed,pallet_election_provider_multi_block::unsigned,pallet_election_provider_multi_block::verifier #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] #![allow(missing_docs)] +#![allow(dead_code)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; @@ -56,6 +77,7 @@ pub trait WeightInfo { fn free() -> Weight; fn force_transfer() -> Weight; fn freeze() -> Weight; + fn poke_deposit() -> Weight; } /// Weights for `pallet_indices` using the Substrate node and recommended hardware. @@ -65,10 +87,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn claim() -> Weight { // Proof Size summary in bytes: - // Measured: `76` + // Measured: `0` // Estimated: `3534` - // Minimum execution time: 23_283_000 picoseconds. - Weight::from_parts(24_326_000, 3534) + // Minimum execution time: 19_421_000 picoseconds. + Weight::from_parts(19_829_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -78,10 +100,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `312` + // Measured: `178` // Estimated: `3593` - // Minimum execution time: 40_906_000 picoseconds. - Weight::from_parts(42_117_000, 3593) + // Minimum execution time: 33_020_000 picoseconds. + Weight::from_parts(33_682_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -89,10 +111,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn free() -> Weight { // Proof Size summary in bytes: - // Measured: `172` + // Measured: `75` // Estimated: `3534` - // Minimum execution time: 27_419_000 picoseconds. - Weight::from_parts(28_544_000, 3534) + // Minimum execution time: 20_137_000 picoseconds. + Weight::from_parts(20_374_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -102,10 +124,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `275` + // Measured: `177` // Estimated: `3593` - // Minimum execution time: 30_098_000 picoseconds. - Weight::from_parts(31_368_000, 3593) + // Minimum execution time: 23_914_000 picoseconds. + Weight::from_parts(24_248_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -113,10 +135,21 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn freeze() -> Weight { // Proof Size summary in bytes: - // Measured: `172` + // Measured: `75` + // Estimated: `3534` + // Minimum execution time: 23_055_000 picoseconds. + Weight::from_parts(23_461_000, 3534) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `75` // Estimated: `3534` - // Minimum execution time: 30_356_000 picoseconds. - Weight::from_parts(31_036_000, 3534) + // Minimum execution time: 20_179_000 picoseconds. + Weight::from_parts(20_464_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -128,10 +161,10 @@ impl WeightInfo for () { /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn claim() -> Weight { // Proof Size summary in bytes: - // Measured: `76` + // Measured: `0` // Estimated: `3534` - // Minimum execution time: 23_283_000 picoseconds. - Weight::from_parts(24_326_000, 3534) + // Minimum execution time: 19_421_000 picoseconds. + Weight::from_parts(19_829_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -141,10 +174,10 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `312` + // Measured: `178` // Estimated: `3593` - // Minimum execution time: 40_906_000 picoseconds. - Weight::from_parts(42_117_000, 3593) + // Minimum execution time: 33_020_000 picoseconds. + Weight::from_parts(33_682_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -152,10 +185,10 @@ impl WeightInfo for () { /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn free() -> Weight { // Proof Size summary in bytes: - // Measured: `172` + // Measured: `75` // Estimated: `3534` - // Minimum execution time: 27_419_000 picoseconds. - Weight::from_parts(28_544_000, 3534) + // Minimum execution time: 20_137_000 picoseconds. + Weight::from_parts(20_374_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -165,10 +198,10 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `275` + // Measured: `177` // Estimated: `3593` - // Minimum execution time: 30_098_000 picoseconds. - Weight::from_parts(31_368_000, 3593) + // Minimum execution time: 23_914_000 picoseconds. + Weight::from_parts(24_248_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -176,10 +209,21 @@ impl WeightInfo for () { /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn freeze() -> Weight { // Proof Size summary in bytes: - // Measured: `172` + // Measured: `75` + // Estimated: `3534` + // Minimum execution time: 23_055_000 picoseconds. + Weight::from_parts(23_461_000, 3534) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `75` // Estimated: `3534` - // Minimum execution time: 30_356_000 picoseconds. - Weight::from_parts(31_036_000, 3534) + // Minimum execution time: 20_179_000 picoseconds. + Weight::from_parts(20_464_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) }