diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs index 4d1d14a10158..72025f8f4a47 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork use crate as ethereum_beacon_client; -use frame_support::parameter_types; +use frame_support::{derive_impl, parameter_types}; use pallet_timestamp; use primitives::{Fork, ForkVersions}; use sp_core::H256; @@ -33,6 +33,7 @@ pub mod minimal { pub const SS58Prefix: u8 = 42; } + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; type OnSetCode = (); @@ -202,6 +203,7 @@ pub mod mainnet { pub const SS58Prefix: u8 = 42; } + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; type OnSetCode = (); diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs index 6b79a55e3c93..5458c0d52939 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs @@ -3,7 +3,7 @@ use super::*; use frame_support::{ - parameter_types, + derive_impl, parameter_types, traits::{ConstU128, ConstU32, Everything}, weights::IdentityFee, }; @@ -46,6 +46,7 @@ parameter_types! { type Balance = u128; +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = Everything; type BlockWeights = (); diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/src/mock.rs b/bridges/snowbridge/parachain/pallets/outbound-queue/src/mock.rs index dd8fee4e2ed0..e21798a9b681 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/src/mock.rs @@ -3,7 +3,7 @@ use super::*; use frame_support::{ - parameter_types, + derive_impl, parameter_types, traits::{Everything, Hooks}, weights::IdentityFee, }; @@ -37,6 +37,7 @@ parameter_types! { pub const BlockHashCount: u64 = 250; } +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = Everything; type BlockWeights = (); diff --git a/bridges/snowbridge/parachain/pallets/system/src/mock.rs b/bridges/snowbridge/parachain/pallets/system/src/mock.rs index 7a4f61189305..088b01eec474 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/mock.rs @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 Snowfork use crate as snowbridge_system; use frame_support::{ - parameter_types, + derive_impl, parameter_types, traits::{tokens::fungible::Mutate, ConstU128, ConstU16, ConstU64, ConstU8}, weights::IdentityFee, PalletId, @@ -95,6 +95,7 @@ frame_support::construct_runtime!( } ); +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); diff --git a/prdoc/pr_1557.prdoc b/prdoc/pr_1557.prdoc new file mode 100644 index 000000000000..16b69999619d --- /dev/null +++ b/prdoc/pr_1557.prdoc @@ -0,0 +1,17 @@ +title: Adds ability to configure default account nonce + +doc: + - audience: Runtime Dev + description: | + Introduces the ability to configure the default nonce. This will also be used if the account is reaped. + By default, the current behaviour is maintained and nonce starts from 0. + +migrations: + db: [] + + runtime: [] + +crates: + - name: frame-system + +host_functions: [] diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 069217bcee46..aad4616f8a91 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -298,6 +298,7 @@ pub mod pallet { type BaseCallFilter = frame_support::traits::Everything; type BlockHashCount = frame_support::traits::ConstU64<10>; type OnSetCode = (); + type DefaultNonce = (); } /// Default configurations of this pallet in a solo-chain environment. @@ -392,6 +393,9 @@ pub mod pallet { /// The set code logic, just the default since we're not a parachain. type OnSetCode = (); + + /// The default nonce when an account is created. + type DefaultNonce = (); } /// Default configurations of this pallet in a relay-chain environment. @@ -463,6 +467,7 @@ pub mod pallet { type RuntimeTask: Task; /// This stores the number of previous transactions associated with a sender account. + #[pallet::no_default_bounds] type Nonce: Parameter + Member + MaybeSerializeDeserialize @@ -570,6 +575,9 @@ pub mod pallet { /// The maximum number of consumers allowed on a single account. type MaxConsumers: ConsumerLimits; + + /// The default nonce when an account is created. + type DefaultNonce: Get; } #[pallet::pallet] @@ -837,6 +845,7 @@ pub mod pallet { T::AccountId, AccountInfo, ValueQuery, + GetDefaultAccountInfo, >; /// Total extrinsics count for the current block. @@ -1036,7 +1045,10 @@ pub type RefCount = u32; /// Information of an account. #[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] pub struct AccountInfo { - /// The number of transactions this account has sent. + /// A value that increases with every transaction that the account has sent. + /// + /// Gets reset when the account gets reaped and is initialized to the default nonce as provided + /// in the config. pub nonce: Nonce, /// The number of other modules that currently depend on this account's existence. The account /// cannot be reaped until this is zero. @@ -1052,6 +1064,17 @@ pub struct AccountInfo { pub data: AccountData, } +type NonceOf = ::Nonce; +type AccountDataOf = ::AccountData; +type AccountInfoOf = AccountInfo, AccountDataOf>; + +pub struct GetDefaultAccountInfo(PhantomData); +impl Get> for GetDefaultAccountInfo { + fn get() -> AccountInfoOf { + AccountInfo { nonce: T::DefaultNonce::get(), ..Default::default() } + } +} + /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade /// happened. #[derive(sp_runtime::RuntimeDebug, Encode, Decode, TypeInfo)] @@ -1909,7 +1932,7 @@ impl Pallet { /// Increment a particular account's nonce by 1. pub fn inc_account_nonce(who: impl EncodeLike) { - Account::::mutate(who, |a| a.nonce += T::Nonce::one()); + Account::::mutate(who, |a| a.nonce.saturating_inc()); } /// Note what the extrinsic data of the current extrinsic index is. diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index e33ac2f56c87..c67eccb71a59 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -85,6 +85,13 @@ impl OnKilledAccount for RecordKilled { } } +pub struct SetDefaultNonceToBlockNumber; +impl Get for SetDefaultNonceToBlockNumber { + fn get() -> u64 { + System::block_number().into() + } +} + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl Config for Test { type BaseCallFilter = frame_support::traits::Everything; @@ -110,6 +117,7 @@ impl Config for Test { type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = ConstU32<16>; + type DefaultNonce = SetDefaultNonceToBlockNumber; } pub type SysEvent = frame_system::Event; diff --git a/substrate/frame/system/src/tests.rs b/substrate/frame/system/src/tests.rs index 053cec24f89c..cc88d46e187e 100644 --- a/substrate/frame/system/src/tests.rs +++ b/substrate/frame/system/src/tests.rs @@ -803,6 +803,23 @@ fn ensure_signed_stuff_works() { } } +#[test] +fn test_default_account_nonce() { + new_test_ext().execute_with(|| { + System::set_block_number(2); + assert_eq!(System::account_nonce(&1), 2); + + System::inc_account_nonce(&1); + assert_eq!(System::account_nonce(&1), 3); + + System::set_block_number(5); + assert_eq!(System::account_nonce(&1), 3); + + Account::::remove(&1); + assert_eq!(System::account_nonce(&1), 5); + }); +} + pub fn from_actual_ref_time(ref_time: Option) -> PostDispatchInfo { PostDispatchInfo { actual_weight: ref_time.map(|t| Weight::from_all(t)),