From 834f9a50b6796fe7750837b7cac4ca48696900a0 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sun, 7 Apr 2024 18:41:07 +0530 Subject: [PATCH 01/10] POC --- Cargo.lock | 1 + substrate/frame/system/Cargo.toml | 1 + .../system/src/extensions/check_nonce.rs | 30 +- substrate/frame/system/src/mock.rs | 422 ++++++++++++++++++ substrate/frame/system/src/tests.rs | 47 +- 5 files changed, 471 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc340ff11197..de44c851fa50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5805,6 +5805,7 @@ dependencies = [ "docify", "frame-support", "log", + "num-traits", "parity-scale-codec", "scale-info", "serde", diff --git a/substrate/frame/system/Cargo.toml b/substrate/frame/system/Cargo.toml index 16b3b946e221..777040874cba 100644 --- a/substrate/frame/system/Cargo.toml +++ b/substrate/frame/system/Cargo.toml @@ -19,6 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] cfg-if = "1.0" codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } log = { workspace = true } +num-traits = { version = "0.2", default-features = false } scale-info = { version = "2.11.1", default-features = false, features = ["derive", "serde"] } serde = { features = ["alloc", "derive"], workspace = true } frame-support = { path = "../support", default-features = false } diff --git a/substrate/frame/system/src/extensions/check_nonce.rs b/substrate/frame/system/src/extensions/check_nonce.rs index 7504a814aef1..cca5a23edd7b 100644 --- a/substrate/frame/system/src/extensions/check_nonce.rs +++ b/substrate/frame/system/src/extensions/check_nonce.rs @@ -142,7 +142,7 @@ mod tests { crate::Account::::insert( 1, crate::AccountInfo { - nonce: 1, + nonce: 1u32.into(), consumers: 0, providers: 1, sufficients: 0, @@ -153,20 +153,20 @@ mod tests { let len = 0_usize; // stale assert_noop!( - CheckNonce::(0).validate(&1, CALL, &info, len), + CheckNonce::(0u32.into()).validate(&1, CALL, &info, len), InvalidTransaction::Stale ); assert_noop!( - CheckNonce::(0).pre_dispatch(&1, CALL, &info, len), + CheckNonce::(0u32.into()).pre_dispatch(&1, CALL, &info, len), InvalidTransaction::Stale ); // correct - assert_ok!(CheckNonce::(1).validate(&1, CALL, &info, len)); - assert_ok!(CheckNonce::(1).pre_dispatch(&1, CALL, &info, len)); + assert_ok!(CheckNonce::(1u32.into()).validate(&1, CALL, &info, len)); + assert_ok!(CheckNonce::(1u32.into()).pre_dispatch(&1, CALL, &info, len)); // future - assert_ok!(CheckNonce::(5).validate(&1, CALL, &info, len)); + assert_ok!(CheckNonce::(5u32.into()).validate(&1, CALL, &info, len)); assert_noop!( - CheckNonce::(5).pre_dispatch(&1, CALL, &info, len), + CheckNonce::(5u32.into()).pre_dispatch(&1, CALL, &info, len), InvalidTransaction::Future ); }) @@ -178,7 +178,7 @@ mod tests { crate::Account::::insert( 2, crate::AccountInfo { - nonce: 1, + nonce: 1u32.into(), consumers: 0, providers: 1, sufficients: 0, @@ -188,7 +188,7 @@ mod tests { crate::Account::::insert( 3, crate::AccountInfo { - nonce: 1, + nonce: 1u32.into(), consumers: 0, providers: 0, sufficients: 1, @@ -199,19 +199,19 @@ mod tests { let len = 0_usize; // Both providers and sufficients zero assert_noop!( - CheckNonce::(1).validate(&1, CALL, &info, len), + CheckNonce::(1u32.into()).validate(&1, CALL, &info, len), InvalidTransaction::Payment ); assert_noop!( - CheckNonce::(1).pre_dispatch(&1, CALL, &info, len), + CheckNonce::(1u32.into()).pre_dispatch(&1, CALL, &info, len), InvalidTransaction::Payment ); // Non-zero providers - assert_ok!(CheckNonce::(1).validate(&2, CALL, &info, len)); - assert_ok!(CheckNonce::(1).pre_dispatch(&2, CALL, &info, len)); + assert_ok!(CheckNonce::(1u32.into()).validate(&2, CALL, &info, len)); + assert_ok!(CheckNonce::(1u32.into()).pre_dispatch(&2, CALL, &info, len)); // Non-zero sufficients - assert_ok!(CheckNonce::(1).validate(&3, CALL, &info, len)); - assert_ok!(CheckNonce::(1).pre_dispatch(&3, CALL, &info, len)); + assert_ok!(CheckNonce::(1u32.into()).validate(&3, CALL, &info, len)); + assert_ok!(CheckNonce::(1u32.into()).pre_dispatch(&3, CALL, &info, len)); }) } } diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index e1959e572e99..3dfb65174282 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -18,6 +18,10 @@ use crate::{self as frame_system, *}; use frame_support::{derive_impl, parameter_types}; use sp_runtime::{BuildStorage, Perbill}; +use core::{fmt::Display, ops::{Add, AddAssign, BitAnd, BitOr, BitXor, Deref, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, Shr, Sub, SubAssign}}; +use num_traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub, Num, NumCast, PrimInt, Saturating, ToPrimitive}; +use sp_runtime::{Deserialize, Serialize}; +use codec::{Compact, CompactAs, Decode, Encode, MaxEncodedLen}; type Block = mocking::MockBlock; @@ -78,6 +82,423 @@ impl OnKilledAccount for RecordKilled { } } +#[derive(Encode, Decode, Copy, Clone, PartialOrd, Ord, Eq, PartialEq, TypeInfo, Debug, MaxEncodedLen, Serialize, Deserialize)] +pub struct Nonce(u64); + +impl Deref for Nonce { + type Target = u64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Default for Nonce { + fn default() -> Self { + Self(System::block_number()) + } +} +impl From for Nonce { + fn from(value: u32) -> Self { + Self(value as u64) + } +} +impl From for Nonce { + fn from(value: u16) -> Self { + Self(value as u64) + } +} +impl CheckedNeg for Nonce { + fn checked_neg(&self) -> Option { + self.0.checked_neg().map(Self) + } +} +impl CheckedRem for Nonce { + fn checked_rem(&self, rhs: &Self) -> Option { + self.0.checked_rem(rhs.0).map(Self) + } +} + +impl CheckedShr for Nonce { + fn checked_shr(&self, n: u32) -> Option { + self.0.checked_shr(n).map(Self) + } +} + +impl CheckedShl for Nonce { + fn checked_shl(&self, n: u32) -> Option { + self.0.checked_shl(n).map(Self) + } +} + +impl Rem for Nonce { + type Output = Self; + fn rem(self, rhs: Self) -> Self { + Self(self.0 % rhs.0) + } +} + +impl Rem for Nonce { + type Output = Self; + fn rem(self, rhs: u32) -> Self { + Self(self.0 % (rhs as u64)) + } +} + +impl Shr for Nonce { + type Output = Self; + fn shr(self, rhs: u32) -> Self { + Self(self.0 >> rhs) + } +} + +impl Shr for Nonce { + type Output = Self; + fn shr(self, rhs: usize) -> Self { + Self(self.0 >> rhs) + } +} + +impl Shl for Nonce { + type Output = Self; + fn shl(self, rhs: u32) -> Self { + Self(self.0 << rhs) + } +} + +impl Shl for Nonce { + type Output = Self; + fn shl(self, rhs: usize) -> Self { + Self(self.0 << rhs) + } +} + +impl RemAssign for Nonce { + fn rem_assign(&mut self, rhs: Self) { + self.0 %= rhs.0 + } +} + +impl DivAssign for Nonce { + fn div_assign(&mut self, rhs: Self) { + self.0 /= rhs.0 + } +} + +impl MulAssign for Nonce { + fn mul_assign(&mut self, rhs: Self) { + self.0 *= rhs.0 + } +} + +impl SubAssign for Nonce { + fn sub_assign(&mut self, rhs: Self) { + self.0 -= rhs.0 + } +} + +impl AddAssign for Nonce { + fn add_assign(&mut self, rhs: Self) { + self.0 += rhs.0 + } +} + +impl From for Nonce { + fn from(value: u8) -> Self { + Self(value as u64) + } +} + +impl Display for Nonce { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl From for u32 { + fn from(n: Nonce) -> u32 { + n.0 as u32 + } +} + +impl From for u16 { + fn from(n: Nonce) -> u16 { + n.0 as u16 + } +} + +impl From for u128 { + fn from(n: Nonce) -> u128 { + n.0 as u128 + } +} + +impl From for usize { + fn from(n: Nonce) -> usize { + n.0 as usize + } +} + +impl From for Nonce { + fn from(n: u64) -> Nonce { + Nonce(n) + } +} + +impl From for Nonce { + fn from(n: u128) -> Nonce { + Nonce(n as u64) + } +} + +impl From for Nonce { + fn from(n: usize) -> Nonce { + Nonce(n as u64) + } +} + +impl From for u8 { + fn from(n: Nonce) -> u8 { + n.0 as u8 + } +} + +impl From for u64 { + fn from(n: Nonce) -> u64 { + n.0 + } +} + +impl Zero for Nonce { + fn zero() -> Self { + Nonce(0) + } + + fn is_zero(&self) -> bool { + self.0 == 0 + } +} + +impl Bounded for Nonce { + fn min_value() -> Self { + Nonce(u64::min_value()) + } + + fn max_value() -> Self { + Nonce(u64::max_value()) + } +} + +impl PrimInt for Nonce { + fn count_ones(self) -> u32 { + self.0.count_ones() + } + + fn leading_zeros(self) -> u32 { + self.0.leading_zeros() + } + + fn trailing_zeros(self) -> u32 { + self.0.trailing_zeros() + } + + fn rotate_left(self, n: u32) -> Self { + Nonce(self.0.rotate_left(n)) + } + + fn rotate_right(self, n: u32) -> Self { + Nonce(self.0.rotate_right(n)) + } + + fn swap_bytes(self) -> Self { + Nonce(self.0.swap_bytes()) + } + + fn from_be(x: Self) -> Self { + Nonce(u64::from_be(x.0)) + } + + fn from_le(x: Self) -> Self { + Nonce(u64::from_le(x.0)) + } + + fn to_be(self) -> Self { + Nonce(self.0.to_be()) + } + + fn to_le(self) -> Self { + Nonce(self.0.to_le()) + } + + fn count_zeros(self) -> u32 { + self.0.count_zeros() + } + + fn signed_shl(self, n: u32) -> Self { + Nonce(self.0.wrapping_shl(n)) + } + + fn signed_shr(self, n: u32) -> Self { + Nonce(self.0.wrapping_shr(n)) + } + + fn unsigned_shl(self, n: u32) -> Self { + Nonce(self.0.wrapping_shl(n)) + } + + fn unsigned_shr(self, n: u32) -> Self { + Nonce(self.0.wrapping_shr(n)) + } + + fn pow(self, exp: u32) -> Self { + Nonce(self.0.pow(exp)) + } +} + +impl Saturating for Nonce { + fn saturating_add(self, rhs: Self) -> Self { + Nonce(self.0.saturating_add(rhs.0)) + } + + fn saturating_sub(self, rhs: Self) -> Self { + Nonce(self.0.saturating_sub(rhs.0)) + } +} + +impl Div for Nonce { + type Output = Self; + fn div(self, rhs: Self) -> Self { + Nonce(self.0 / rhs.0) + } +} + +impl Mul for Nonce { + type Output = Self; + fn mul(self, rhs: Self) -> Self { + Nonce(self.0 * rhs.0) + } +} + +impl CheckedDiv for Nonce { + fn checked_div(&self, rhs: &Self) -> Option { + self.0.checked_div(rhs.0).map(Self) + } +} + +impl CheckedMul for Nonce { + fn checked_mul(&self, rhs: &Self) -> Option { + self.0.checked_mul(rhs.0).map(Self) + } +} + +impl Sub for Nonce { + type Output = Self; + fn sub(self, rhs: Self) -> Self { + Nonce(self.0 - rhs.0) + } +} + +impl CheckedSub for Nonce { + fn checked_sub(&self, rhs: &Self) -> Option { + self.0.checked_sub(rhs.0).map(Self) + } +} + +impl Add for Nonce { + type Output = Self; + fn add(self, rhs: Self) -> Self { + Nonce(self.0 + rhs.0) + } +} + +impl CheckedAdd for Nonce { + fn checked_add(&self, rhs: &Self) -> Option { + self.0.checked_add(rhs.0).map(Self) + } +} + +impl BitAnd for Nonce { + type Output = Self; + fn bitand(self, rhs: Self) -> Self { + Nonce(self.0 & rhs.0) + } +} + +impl BitOr for Nonce { + type Output = Self; + fn bitor(self, rhs: Self) -> Self { + Nonce(self.0 | rhs.0) + } +} + +impl BitXor for Nonce { + type Output = Self; + fn bitxor(self, rhs: Self) -> Self { + Nonce(self.0 ^ rhs.0) + } +} + +impl One for Nonce { + fn one() -> Self { + Nonce(1) + } +} + +impl Not for Nonce { + type Output = Self; + fn not(self) -> Self { + Nonce(!self.0) + } +} + +impl NumCast for Nonce { + fn from(n: T) -> Option { + n.to_u64().map(Nonce) + } +} + +impl Num for Nonce { + type FromStrRadixErr = ::FromStrRadixErr; + + fn from_str_radix(s: &str, radix: u32) -> Result { + u64::from_str_radix(s, radix).map(Nonce) + } +} + +impl ToPrimitive for Nonce { + fn to_i64(&self) -> Option { + self.0.to_i64() + } + + fn to_u64(&self) -> Option { + Some(self.0) + } + + fn to_i128(&self) -> Option { + self.0.to_i128() + } + + fn to_u128(&self) -> Option { + Some(self.0 as u128) + } +} + +impl From> for Nonce { + fn from(c: Compact) -> Self { + c.0 + } +} + +impl CompactAs for Nonce { + type As = u64; + + fn encode_as(&self) -> &Self::As { + &self.0 + } + + fn decode_from(val: Self::As) -> Result { + Ok(Nonce(val)) + } +} + #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] impl Config for Test { type BlockWeights = RuntimeBlockWeights; @@ -87,6 +508,7 @@ impl Config for Test { type AccountData = u32; type OnKilledAccount = RecordKilled; type MultiBlockMigrator = MockedMigrator; + type Nonce = Nonce; } parameter_types! { diff --git a/substrate/frame/system/src/tests.rs b/substrate/frame/system/src/tests.rs index b889b5ca046e..f26749f1c3a3 100644 --- a/substrate/frame/system/src/tests.rs +++ b/substrate/frame/system/src/tests.rs @@ -102,7 +102,7 @@ fn stored_map_works() { assert_eq!( Account::::get(0), - AccountInfo { nonce: 0, providers: 1, consumers: 0, sufficients: 0, data: 42 } + AccountInfo { nonce: 0u32.into(), providers: 1, consumers: 0, sufficients: 0, data: 42 } ); assert_ok!(System::inc_consumers(&0)); @@ -126,26 +126,26 @@ fn provider_ref_handover_to_self_sufficient_ref_works() { new_test_ext().execute_with(|| { assert_eq!(System::inc_providers(&0), IncRefStatus::Created); System::inc_account_nonce(&0); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); // a second reference coming and going doesn't change anything. assert_eq!(System::inc_sufficients(&0), IncRefStatus::Existed); assert_eq!(System::dec_sufficients(&0), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); // a provider reference coming and going doesn't change anything. assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); // decreasing the providers with a self-sufficient present should not delete the account assert_eq!(System::inc_sufficients(&0), IncRefStatus::Existed); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); // decreasing the sufficients should delete the account assert_eq!(System::dec_sufficients(&0), DecRefStatus::Reaped); - assert_eq!(System::account_nonce(&0), 0); + assert_eq!(System::account_nonce(&0), 0u32.into()); }); } @@ -154,26 +154,26 @@ fn self_sufficient_ref_handover_to_provider_ref_works() { new_test_ext().execute_with(|| { assert_eq!(System::inc_sufficients(&0), IncRefStatus::Created); System::inc_account_nonce(&0); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); // a second reference coming and going doesn't change anything. assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); // a sufficient reference coming and going doesn't change anything. assert_eq!(System::inc_sufficients(&0), IncRefStatus::Existed); assert_eq!(System::dec_sufficients(&0), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); // decreasing the sufficients with a provider present should not delete the account assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); assert_eq!(System::dec_sufficients(&0), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); // decreasing the providers should delete the account assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Reaped); - assert_eq!(System::account_nonce(&0), 0); + assert_eq!(System::account_nonce(&0), 0u32.into()); }); } @@ -182,7 +182,7 @@ fn sufficient_cannot_support_consumer() { new_test_ext().execute_with(|| { assert_eq!(System::inc_sufficients(&0), IncRefStatus::Created); System::inc_account_nonce(&0); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); assert_noop!(System::inc_consumers(&0), DispatchError::NoProviders); assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); @@ -198,18 +198,18 @@ fn provider_required_to_support_consumer() { assert_eq!(System::inc_providers(&0), IncRefStatus::Created); System::inc_account_nonce(&0); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1); + assert_eq!(System::account_nonce(&0), 1u32.into()); assert_ok!(System::inc_consumers(&0)); assert_noop!(System::dec_providers(&0), DispatchError::ConsumerRemaining); System::dec_consumers(&0); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Reaped); - assert_eq!(System::account_nonce(&0), 0); + assert_eq!(System::account_nonce(&0), 0u32.into()); }); } @@ -858,3 +858,20 @@ fn last_runtime_upgrade_spec_version_usage() { } } } + +#[test] +fn test_default_account_nonce() { + new_test_ext().execute_with(|| { + System::set_block_number(2); + assert_eq!(System::account_nonce(&1), 2u32.into()); + + System::inc_account_nonce(&1); + assert_eq!(System::account_nonce(&1), 3u32.into()); + + System::set_block_number(5); + assert_eq!(System::account_nonce(&1), 3u32.into()); + + Account::::remove(&1); + assert_eq!(System::account_nonce(&1), 5u32.into()); + }); +} From 6c36112ad4b3dba699a564a3f68ca22050852717 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Tue, 9 Apr 2024 10:21:16 +0530 Subject: [PATCH 02/10] Moves nonce type to primitives --- Cargo.lock | 2 +- substrate/frame/system/Cargo.toml | 1 - substrate/frame/system/src/mock.rs | 427 +------------------ substrate/primitives/runtime/Cargo.toml | 2 + substrate/primitives/runtime/src/lib.rs | 1 + substrate/primitives/runtime/src/nonce.rs | 483 ++++++++++++++++++++++ 6 files changed, 494 insertions(+), 422 deletions(-) create mode 100644 substrate/primitives/runtime/src/nonce.rs diff --git a/Cargo.lock b/Cargo.lock index de44c851fa50..030f8214131e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5805,7 +5805,6 @@ dependencies = [ "docify", "frame-support", "log", - "num-traits", "parity-scale-codec", "scale-info", "serde", @@ -18971,6 +18970,7 @@ dependencies = [ "hash256-std-hasher", "impl-trait-for-tuples", "log", + "num-traits", "parity-scale-codec", "paste", "rand", diff --git a/substrate/frame/system/Cargo.toml b/substrate/frame/system/Cargo.toml index 777040874cba..16b3b946e221 100644 --- a/substrate/frame/system/Cargo.toml +++ b/substrate/frame/system/Cargo.toml @@ -19,7 +19,6 @@ targets = ["x86_64-unknown-linux-gnu"] cfg-if = "1.0" codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } log = { workspace = true } -num-traits = { version = "0.2", default-features = false } scale-info = { version = "2.11.1", default-features = false, features = ["derive", "serde"] } serde = { features = ["alloc", "derive"], workspace = true } frame-support = { path = "../support", default-features = false } diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index 3dfb65174282..1cec982ca641 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -17,11 +17,7 @@ use crate::{self as frame_system, *}; use frame_support::{derive_impl, parameter_types}; -use sp_runtime::{BuildStorage, Perbill}; -use core::{fmt::Display, ops::{Add, AddAssign, BitAnd, BitOr, BitXor, Deref, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, Shr, Sub, SubAssign}}; -use num_traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub, Num, NumCast, PrimInt, Saturating, ToPrimitive}; -use sp_runtime::{Deserialize, Serialize}; -use codec::{Compact, CompactAs, Decode, Encode, MaxEncodedLen}; +use sp_runtime::{BuildStorage, Perbill, nonce::NonceWithDefault}; type Block = mocking::MockBlock; @@ -82,420 +78,11 @@ impl OnKilledAccount for RecordKilled { } } -#[derive(Encode, Decode, Copy, Clone, PartialOrd, Ord, Eq, PartialEq, TypeInfo, Debug, MaxEncodedLen, Serialize, Deserialize)] -pub struct Nonce(u64); - -impl Deref for Nonce { - type Target = u64; - fn deref(&self) -> &Self::Target { - &self.0 - } -} -impl Default for Nonce { - fn default() -> Self { - Self(System::block_number()) - } -} -impl From for Nonce { - fn from(value: u32) -> Self { - Self(value as u64) - } -} -impl From for Nonce { - fn from(value: u16) -> Self { - Self(value as u64) - } -} -impl CheckedNeg for Nonce { - fn checked_neg(&self) -> Option { - self.0.checked_neg().map(Self) - } -} -impl CheckedRem for Nonce { - fn checked_rem(&self, rhs: &Self) -> Option { - self.0.checked_rem(rhs.0).map(Self) - } -} - -impl CheckedShr for Nonce { - fn checked_shr(&self, n: u32) -> Option { - self.0.checked_shr(n).map(Self) - } -} - -impl CheckedShl for Nonce { - fn checked_shl(&self, n: u32) -> Option { - self.0.checked_shl(n).map(Self) - } -} - -impl Rem for Nonce { - type Output = Self; - fn rem(self, rhs: Self) -> Self { - Self(self.0 % rhs.0) - } -} - -impl Rem for Nonce { - type Output = Self; - fn rem(self, rhs: u32) -> Self { - Self(self.0 % (rhs as u64)) - } -} - -impl Shr for Nonce { - type Output = Self; - fn shr(self, rhs: u32) -> Self { - Self(self.0 >> rhs) - } -} - -impl Shr for Nonce { - type Output = Self; - fn shr(self, rhs: usize) -> Self { - Self(self.0 >> rhs) - } -} - -impl Shl for Nonce { - type Output = Self; - fn shl(self, rhs: u32) -> Self { - Self(self.0 << rhs) - } -} - -impl Shl for Nonce { - type Output = Self; - fn shl(self, rhs: usize) -> Self { - Self(self.0 << rhs) - } -} - -impl RemAssign for Nonce { - fn rem_assign(&mut self, rhs: Self) { - self.0 %= rhs.0 - } -} - -impl DivAssign for Nonce { - fn div_assign(&mut self, rhs: Self) { - self.0 /= rhs.0 - } -} - -impl MulAssign for Nonce { - fn mul_assign(&mut self, rhs: Self) { - self.0 *= rhs.0 - } -} - -impl SubAssign for Nonce { - fn sub_assign(&mut self, rhs: Self) { - self.0 -= rhs.0 - } -} - -impl AddAssign for Nonce { - fn add_assign(&mut self, rhs: Self) { - self.0 += rhs.0 - } -} - -impl From for Nonce { - fn from(value: u8) -> Self { - Self(value as u64) - } -} - -impl Display for Nonce { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "{}", self.0) - } -} - -impl From for u32 { - fn from(n: Nonce) -> u32 { - n.0 as u32 - } -} - -impl From for u16 { - fn from(n: Nonce) -> u16 { - n.0 as u16 - } -} - -impl From for u128 { - fn from(n: Nonce) -> u128 { - n.0 as u128 - } -} - -impl From for usize { - fn from(n: Nonce) -> usize { - n.0 as usize - } -} - -impl From for Nonce { - fn from(n: u64) -> Nonce { - Nonce(n) - } -} - -impl From for Nonce { - fn from(n: u128) -> Nonce { - Nonce(n as u64) - } -} - -impl From for Nonce { - fn from(n: usize) -> Nonce { - Nonce(n as u64) - } -} - -impl From for u8 { - fn from(n: Nonce) -> u8 { - n.0 as u8 - } -} - -impl From for u64 { - fn from(n: Nonce) -> u64 { - n.0 - } -} - -impl Zero for Nonce { - fn zero() -> Self { - Nonce(0) - } - - fn is_zero(&self) -> bool { - self.0 == 0 - } -} - -impl Bounded for Nonce { - fn min_value() -> Self { - Nonce(u64::min_value()) - } - - fn max_value() -> Self { - Nonce(u64::max_value()) - } -} - -impl PrimInt for Nonce { - fn count_ones(self) -> u32 { - self.0.count_ones() - } - - fn leading_zeros(self) -> u32 { - self.0.leading_zeros() - } - - fn trailing_zeros(self) -> u32 { - self.0.trailing_zeros() - } - - fn rotate_left(self, n: u32) -> Self { - Nonce(self.0.rotate_left(n)) - } - - fn rotate_right(self, n: u32) -> Self { - Nonce(self.0.rotate_right(n)) - } - - fn swap_bytes(self) -> Self { - Nonce(self.0.swap_bytes()) - } - - fn from_be(x: Self) -> Self { - Nonce(u64::from_be(x.0)) - } - - fn from_le(x: Self) -> Self { - Nonce(u64::from_le(x.0)) - } - - fn to_be(self) -> Self { - Nonce(self.0.to_be()) - } - - fn to_le(self) -> Self { - Nonce(self.0.to_le()) - } - - fn count_zeros(self) -> u32 { - self.0.count_zeros() - } - - fn signed_shl(self, n: u32) -> Self { - Nonce(self.0.wrapping_shl(n)) - } - - fn signed_shr(self, n: u32) -> Self { - Nonce(self.0.wrapping_shr(n)) - } - - fn unsigned_shl(self, n: u32) -> Self { - Nonce(self.0.wrapping_shl(n)) - } - - fn unsigned_shr(self, n: u32) -> Self { - Nonce(self.0.wrapping_shr(n)) - } - - fn pow(self, exp: u32) -> Self { - Nonce(self.0.pow(exp)) - } -} - -impl Saturating for Nonce { - fn saturating_add(self, rhs: Self) -> Self { - Nonce(self.0.saturating_add(rhs.0)) - } - - fn saturating_sub(self, rhs: Self) -> Self { - Nonce(self.0.saturating_sub(rhs.0)) - } -} - -impl Div for Nonce { - type Output = Self; - fn div(self, rhs: Self) -> Self { - Nonce(self.0 / rhs.0) - } -} - -impl Mul for Nonce { - type Output = Self; - fn mul(self, rhs: Self) -> Self { - Nonce(self.0 * rhs.0) - } -} - -impl CheckedDiv for Nonce { - fn checked_div(&self, rhs: &Self) -> Option { - self.0.checked_div(rhs.0).map(Self) - } -} - -impl CheckedMul for Nonce { - fn checked_mul(&self, rhs: &Self) -> Option { - self.0.checked_mul(rhs.0).map(Self) - } -} - -impl Sub for Nonce { - type Output = Self; - fn sub(self, rhs: Self) -> Self { - Nonce(self.0 - rhs.0) - } -} - -impl CheckedSub for Nonce { - fn checked_sub(&self, rhs: &Self) -> Option { - self.0.checked_sub(rhs.0).map(Self) - } -} - -impl Add for Nonce { - type Output = Self; - fn add(self, rhs: Self) -> Self { - Nonce(self.0 + rhs.0) - } -} - -impl CheckedAdd for Nonce { - fn checked_add(&self, rhs: &Self) -> Option { - self.0.checked_add(rhs.0).map(Self) - } -} - -impl BitAnd for Nonce { - type Output = Self; - fn bitand(self, rhs: Self) -> Self { - Nonce(self.0 & rhs.0) - } -} - -impl BitOr for Nonce { - type Output = Self; - fn bitor(self, rhs: Self) -> Self { - Nonce(self.0 | rhs.0) - } -} - -impl BitXor for Nonce { - type Output = Self; - fn bitxor(self, rhs: Self) -> Self { - Nonce(self.0 ^ rhs.0) - } -} - -impl One for Nonce { - fn one() -> Self { - Nonce(1) - } -} - -impl Not for Nonce { - type Output = Self; - fn not(self) -> Self { - Nonce(!self.0) - } -} - -impl NumCast for Nonce { - fn from(n: T) -> Option { - n.to_u64().map(Nonce) - } -} - -impl Num for Nonce { - type FromStrRadixErr = ::FromStrRadixErr; - - fn from_str_radix(s: &str, radix: u32) -> Result { - u64::from_str_radix(s, radix).map(Nonce) - } -} - -impl ToPrimitive for Nonce { - fn to_i64(&self) -> Option { - self.0.to_i64() - } - - fn to_u64(&self) -> Option { - Some(self.0) - } - - fn to_i128(&self) -> Option { - self.0.to_i128() - } - - fn to_u128(&self) -> Option { - Some(self.0 as u128) - } -} - -impl From> for Nonce { - fn from(c: Compact) -> Self { - c.0 - } -} - -impl CompactAs for Nonce { - type As = u64; - - fn encode_as(&self) -> &Self::As { - &self.0 - } - - fn decode_from(val: Self::As) -> Result { - Ok(Nonce(val)) +#[derive(Debug, TypeInfo)] +pub struct BlockNumberProvider; +impl Get for BlockNumberProvider { + fn get() -> u64 { + System::block_number() } } @@ -508,7 +95,7 @@ impl Config for Test { type AccountData = u32; type OnKilledAccount = RecordKilled; type MultiBlockMigrator = MockedMigrator; - type Nonce = Nonce; + type Nonce = NonceWithDefault; } parameter_types! { diff --git a/substrate/primitives/runtime/Cargo.toml b/substrate/primitives/runtime/Cargo.toml index fb5fd60fbbfd..0389c9f5b2f4 100644 --- a/substrate/primitives/runtime/Cargo.toml +++ b/substrate/primitives/runtime/Cargo.toml @@ -22,6 +22,7 @@ either = { version = "1.5", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } impl-trait-for-tuples = "0.2.2" log = { workspace = true } +num-traits = { version = "0.2.17", default-features = false } paste = "1.0" rand = { version = "0.8.5", optional = true } scale-info = { version = "2.11.1", default-features = false, features = ["derive"] } @@ -54,6 +55,7 @@ std = [ "either/use_std", "hash256-std-hasher/std", "log/std", + "num-traits/std", "rand", "scale-info/std", "serde/std", diff --git a/substrate/primitives/runtime/src/lib.rs b/substrate/primitives/runtime/src/lib.rs index 44bf3c969e54..3487045637d3 100644 --- a/substrate/primitives/runtime/src/lib.rs +++ b/substrate/primitives/runtime/src/lib.rs @@ -84,6 +84,7 @@ pub mod curve; pub mod generic; pub mod legacy; mod multiaddress; +pub mod nonce; pub mod offchain; pub mod runtime_logger; mod runtime_string; diff --git a/substrate/primitives/runtime/src/nonce.rs b/substrate/primitives/runtime/src/nonce.rs new file mode 100644 index 000000000000..44f01e4e4ac5 --- /dev/null +++ b/substrate/primitives/runtime/src/nonce.rs @@ -0,0 +1,483 @@ +// 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. + +use core::{fmt::Display, marker::PhantomData, ops::{Add, AddAssign, BitAnd, BitOr, BitXor, Deref, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, Shr, Sub, SubAssign}}; +use codec::{Compact, CompactAs, Decode, Encode, MaxEncodedLen}; +use num_traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub, Num, NumCast, PrimInt, Saturating, ToPrimitive}; +use scale_info::TypeInfo; +use sp_core::Get; +use crate::traits::{Bounded, One, Zero}; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct NonceWithDefault>( + u64, + PhantomData, +); + +impl> NonceWithDefault { + pub fn new(value: u64) -> Self { + Self(value, PhantomData) + } +} + +impl> Clone for NonceWithDefault { + fn clone(&self) -> Self { + Self(self.0, PhantomData) + } +} + +impl> Copy for NonceWithDefault {} + +impl> PartialEq for NonceWithDefault { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl> Eq for NonceWithDefault {} + +impl> PartialOrd for NonceWithDefault { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl> Ord for NonceWithDefault { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.0.cmp(&other.0) + } +} + +impl> Deref for NonceWithDefault { + type Target = u64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl> Default for NonceWithDefault { + fn default() -> Self { + // Self::new(System::block_number()) + Self::new(D::get()) + } +} +impl> From for NonceWithDefault { + fn from(value: u32) -> Self { + Self::new(value as u64) + } +} +impl> From for NonceWithDefault { + fn from(value: u16) -> Self { + Self::new(value as u64) + } +} +impl> CheckedNeg for NonceWithDefault { + fn checked_neg(&self) -> Option { + self.0.checked_neg().map(Self::new) + } +} +impl> CheckedRem for NonceWithDefault { + fn checked_rem(&self, rhs: &Self) -> Option { + self.0.checked_rem(rhs.0).map(Self::new) + } +} + +impl> CheckedShr for NonceWithDefault { + fn checked_shr(&self, n: u32) -> Option { + self.0.checked_shr(n).map(Self::new) + } +} + +impl> CheckedShl for NonceWithDefault { + fn checked_shl(&self, n: u32) -> Option { + self.0.checked_shl(n).map(Self::new) + } +} + +impl> Rem for NonceWithDefault { + type Output = Self; + fn rem(self, rhs: Self) -> Self { + Self::new(self.0 % rhs.0) + } +} + +impl> Rem for NonceWithDefault { + type Output = Self; + fn rem(self, rhs: u32) -> Self { + Self::new(self.0 % (rhs as u64)) + } +} + +impl> Shr for NonceWithDefault { + type Output = Self; + fn shr(self, rhs: u32) -> Self { + Self::new(self.0 >> rhs) + } +} + +impl> Shr for NonceWithDefault { + type Output = Self; + fn shr(self, rhs: usize) -> Self { + Self::new(self.0 >> rhs) + } +} + +impl> Shl for NonceWithDefault { + type Output = Self; + fn shl(self, rhs: u32) -> Self { + Self::new(self.0 << rhs) + } +} + +impl> Shl for NonceWithDefault { + type Output = Self; + fn shl(self, rhs: usize) -> Self { + Self::new(self.0 << rhs) + } +} + +impl> RemAssign for NonceWithDefault { + fn rem_assign(&mut self, rhs: Self) { + self.0 %= rhs.0 + } +} + +impl> DivAssign for NonceWithDefault { + fn div_assign(&mut self, rhs: Self) { + self.0 /= rhs.0 + } +} + +impl> MulAssign for NonceWithDefault { + fn mul_assign(&mut self, rhs: Self) { + self.0 *= rhs.0 + } +} + +impl> SubAssign for NonceWithDefault { + fn sub_assign(&mut self, rhs: Self) { + self.0 -= rhs.0 + } +} + +impl> AddAssign for NonceWithDefault { + fn add_assign(&mut self, rhs: Self) { + self.0 += rhs.0 + } +} + +impl> From for NonceWithDefault { + fn from(value: u8) -> Self { + Self::new(value as u64) + } +} + +impl> Display for NonceWithDefault { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl> From> for u32 { + fn from(n: NonceWithDefault) -> u32 { + n.0 as u32 + } +} + +impl> From> for u16 { + fn from(n: NonceWithDefault) -> u16 { + n.0 as u16 + } +} + +impl> From> for u128 { + fn from(n: NonceWithDefault) -> u128 { + n.0 as u128 + } +} + +impl> From> for usize { + fn from(n: NonceWithDefault) -> usize { + n.0 as usize + } +} + +impl> From for NonceWithDefault { + fn from(n: u64) -> NonceWithDefault { + Self::new(n) + } +} + +impl> From for NonceWithDefault { + fn from(n: u128) -> NonceWithDefault { + Self::new(n as u64) + } +} + +impl> From for NonceWithDefault { + fn from(n: usize) -> NonceWithDefault { + Self::new(n as u64) + } +} + +impl> From> for u8 { + fn from(n: NonceWithDefault) -> u8 { + n.0 as u8 + } +} + +impl> From> for u64 { + fn from(n: NonceWithDefault) -> u64 { + n.0 + } +} + +impl> Zero for NonceWithDefault { + fn zero() -> Self { + Self::new(0) + } + + fn is_zero(&self) -> bool { + self.0 == 0 + } +} + +impl> Bounded for NonceWithDefault { + fn min_value() -> Self { + Self::new(u64::min_value()) + } + + fn max_value() -> Self { + Self::new(u64::max_value()) + } +} + +impl> PrimInt for NonceWithDefault { + fn count_ones(self) -> u32 { + self.0.count_ones() + } + + fn leading_zeros(self) -> u32 { + self.0.leading_zeros() + } + + fn trailing_zeros(self) -> u32 { + self.0.trailing_zeros() + } + + fn rotate_left(self, n: u32) -> Self { + Self::new(self.0.rotate_left(n)) + } + + fn rotate_right(self, n: u32) -> Self { + Self::new(self.0.rotate_right(n)) + } + + fn swap_bytes(self) -> Self { + Self::new(self.0.swap_bytes()) + } + + fn from_be(x: Self) -> Self { + Self::new(u64::from_be(x.0)) + } + + fn from_le(x: Self) -> Self { + Self::new(u64::from_le(x.0)) + } + + fn to_be(self) -> Self { + Self::new(self.0.to_be()) + } + + fn to_le(self) -> Self { + Self::new(self.0.to_le()) + } + + fn count_zeros(self) -> u32 { + self.0.count_zeros() + } + + fn signed_shl(self, n: u32) -> Self { + Self::new(self.0.wrapping_shl(n)) + } + + fn signed_shr(self, n: u32) -> Self { + Self::new(self.0.wrapping_shr(n)) + } + + fn unsigned_shl(self, n: u32) -> Self { + Self::new(self.0.wrapping_shl(n)) + } + + fn unsigned_shr(self, n: u32) -> Self { + Self::new(self.0.wrapping_shr(n)) + } + + fn pow(self, exp: u32) -> Self { + Self::new(self.0.pow(exp)) + } +} + +impl> Saturating for NonceWithDefault { + fn saturating_add(self, rhs: Self) -> Self { + Self::new(self.0.saturating_add(rhs.0)) + } + + fn saturating_sub(self, rhs: Self) -> Self { + Self::new(self.0.saturating_sub(rhs.0)) + } +} + +impl> Div for NonceWithDefault { + type Output = Self; + fn div(self, rhs: Self) -> Self { + Self::new(self.0 / rhs.0) + } +} + +impl> Mul for NonceWithDefault { + type Output = Self; + fn mul(self, rhs: Self) -> Self { + Self::new(self.0 * rhs.0) + } +} + +impl> CheckedDiv for NonceWithDefault { + fn checked_div(&self, rhs: &Self) -> Option { + self.0.checked_div(rhs.0).map(Self::new) + } +} + +impl> CheckedMul for NonceWithDefault { + fn checked_mul(&self, rhs: &Self) -> Option { + self.0.checked_mul(rhs.0).map(Self::new) + } +} + +impl> Sub for NonceWithDefault { + type Output = Self; + fn sub(self, rhs: Self) -> Self { + Self::new(self.0 - rhs.0) + } +} + +impl> CheckedSub for NonceWithDefault { + fn checked_sub(&self, rhs: &Self) -> Option { + self.0.checked_sub(rhs.0).map(Self::new) + } +} + +impl> Add for NonceWithDefault { + type Output = Self; + fn add(self, rhs: Self) -> Self { + Self::new(self.0 + rhs.0) + } +} + +impl> CheckedAdd for NonceWithDefault { + fn checked_add(&self, rhs: &Self) -> Option { + self.0.checked_add(rhs.0).map(Self::new) + } +} + +impl> BitAnd for NonceWithDefault { + type Output = Self; + fn bitand(self, rhs: Self) -> Self { + Self::new(self.0 & rhs.0) + } +} + +impl> BitOr for NonceWithDefault { + type Output = Self; + fn bitor(self, rhs: Self) -> Self { + Self::new(self.0 | rhs.0) + } +} + +impl> BitXor for NonceWithDefault { + type Output = Self; + fn bitxor(self, rhs: Self) -> Self { + Self::new(self.0 ^ rhs.0) + } +} + +impl> One for NonceWithDefault { + fn one() -> Self { + Self::new(1) + } +} + +impl> Not for NonceWithDefault { + type Output = Self; + fn not(self) -> Self { + Self::new(!self.0) + } +} + +impl> NumCast for NonceWithDefault { + fn from(n: T) -> Option { + n.to_u64().map(Self::new) + } +} + +impl> Num for NonceWithDefault { + type FromStrRadixErr = ::FromStrRadixErr; + + fn from_str_radix(s: &str, radix: u32) -> Result { + u64::from_str_radix(s, radix).map(Self::new) + } +} + +impl> ToPrimitive for NonceWithDefault { + fn to_i64(&self) -> Option { + self.0.to_i64() + } + + fn to_u64(&self) -> Option { + Some(self.0) + } + + fn to_i128(&self) -> Option { + self.0.to_i128() + } + + fn to_u128(&self) -> Option { + Some(self.0 as u128) + } +} + +impl> From>> for NonceWithDefault { + fn from(c: Compact>) -> Self { + c.0 + } +} + +impl> CompactAs for NonceWithDefault { + type As = u64; + + fn encode_as(&self) -> &Self::As { + &self.0 + } + + fn decode_from(val: Self::As) -> Result { + Ok(Self::new(val)) + } +} From 312bcdc407d0636b7408250dd1849398fcc67c0f Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Tue, 9 Apr 2024 11:13:18 +0530 Subject: [PATCH 03/10] Makes generic over nonce type --- substrate/frame/system/src/mock.rs | 4 +- substrate/frame/system/src/tests.rs | 8 +- substrate/primitives/runtime/src/nonce.rs | 281 +++++++++++---------- substrate/primitives/runtime/src/traits.rs | 28 ++ 4 files changed, 185 insertions(+), 136 deletions(-) diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index 1cec982ca641..cf4e8f16a991 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -17,7 +17,7 @@ use crate::{self as frame_system, *}; use frame_support::{derive_impl, parameter_types}; -use sp_runtime::{BuildStorage, Perbill, nonce::NonceWithDefault}; +use sp_runtime::{nonce::NonceWithDefault, BuildStorage, Perbill}; type Block = mocking::MockBlock; @@ -95,7 +95,7 @@ impl Config for Test { type AccountData = u32; type OnKilledAccount = RecordKilled; type MultiBlockMigrator = MockedMigrator; - type Nonce = NonceWithDefault; + type Nonce = NonceWithDefault; } parameter_types! { diff --git a/substrate/frame/system/src/tests.rs b/substrate/frame/system/src/tests.rs index f26749f1c3a3..a0a02ee7ea9a 100644 --- a/substrate/frame/system/src/tests.rs +++ b/substrate/frame/system/src/tests.rs @@ -102,7 +102,13 @@ fn stored_map_works() { assert_eq!( Account::::get(0), - AccountInfo { nonce: 0u32.into(), providers: 1, consumers: 0, sufficients: 0, data: 42 } + AccountInfo { + nonce: 0u32.into(), + providers: 1, + consumers: 0, + sufficients: 0, + data: 42 + } ); assert_ok!(System::inc_consumers(&0)); diff --git a/substrate/primitives/runtime/src/nonce.rs b/substrate/primitives/runtime/src/nonce.rs index 44f01e4e4ac5..240ccf444be3 100644 --- a/substrate/primitives/runtime/src/nonce.rs +++ b/substrate/primitives/runtime/src/nonce.rs @@ -15,262 +15,277 @@ // See the License for the specific language governing permissions and // limitations under the License. -use core::{fmt::Display, marker::PhantomData, ops::{Add, AddAssign, BitAnd, BitOr, BitXor, Deref, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, Shr, Sub, SubAssign}}; +use crate::traits::{Bounded, Nonce, One, Zero}; use codec::{Compact, CompactAs, Decode, Encode, MaxEncodedLen}; -use num_traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub, Num, NumCast, PrimInt, Saturating, ToPrimitive}; +use core::{ + fmt::Display, + marker::PhantomData, + ops::{ + Add, AddAssign, BitAnd, BitOr, BitXor, Deref, Div, DivAssign, Mul, MulAssign, Not, Rem, + RemAssign, Shl, Shr, Sub, SubAssign, + }, +}; +use num_traits::{ + CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub, + Num, NumCast, PrimInt, Saturating, ToPrimitive, +}; use scale_info::TypeInfo; use sp_core::Get; -use crate::traits::{Bounded, One, Zero}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; #[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct NonceWithDefault>( - u64, - PhantomData, -); +pub struct NonceWithDefault, N: Nonce>(N, PhantomData); -impl> NonceWithDefault { - pub fn new(value: u64) -> Self { - Self(value, PhantomData) - } +impl, N: Nonce> NonceWithDefault { + pub fn new(value: N) -> Self { + Self(value, PhantomData) + } } -impl> Clone for NonceWithDefault { - fn clone(&self) -> Self { - Self(self.0, PhantomData) - } +impl, N: Nonce> Clone for NonceWithDefault { + fn clone(&self) -> Self { + Self(self.0, PhantomData) + } } -impl> Copy for NonceWithDefault {} +impl, N: Nonce> Copy for NonceWithDefault {} -impl> PartialEq for NonceWithDefault { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } +impl, N: Nonce> PartialEq for NonceWithDefault { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } } -impl> Eq for NonceWithDefault {} +impl, N: Nonce> Eq for NonceWithDefault {} -impl> PartialOrd for NonceWithDefault { - fn partial_cmp(&self, other: &Self) -> Option { - self.0.partial_cmp(&other.0) - } +impl, N: Nonce> PartialOrd for NonceWithDefault { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } } -impl> Ord for NonceWithDefault { - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.0.cmp(&other.0) - } +impl, N: Nonce> Ord for NonceWithDefault { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.0.cmp(&other.0) + } } -impl> Deref for NonceWithDefault { - type Target = u64; +impl, N: Nonce> Deref for NonceWithDefault { + type Target = N; fn deref(&self) -> &Self::Target { &self.0 } } -impl> Default for NonceWithDefault { +impl, N: Nonce> Default for NonceWithDefault { fn default() -> Self { - // Self::new(System::block_number()) - Self::new(D::get()) + Self::new(D::get()) } } -impl> From for NonceWithDefault { +impl, N: Nonce> From for NonceWithDefault { fn from(value: u32) -> Self { - Self::new(value as u64) + Self::new(value.into()) } } -impl> From for NonceWithDefault { +impl, N: Nonce> From for NonceWithDefault { fn from(value: u16) -> Self { - Self::new(value as u64) + Self::new(value.into()) } } -impl> CheckedNeg for NonceWithDefault { +impl, N: Nonce> CheckedNeg for NonceWithDefault { fn checked_neg(&self) -> Option { self.0.checked_neg().map(Self::new) } } -impl> CheckedRem for NonceWithDefault { +impl, N: Nonce> CheckedRem for NonceWithDefault { fn checked_rem(&self, rhs: &Self) -> Option { - self.0.checked_rem(rhs.0).map(Self::new) + self.0.checked_rem(&rhs.0).map(Self::new) } } -impl> CheckedShr for NonceWithDefault { +impl, N: Nonce> CheckedShr for NonceWithDefault { fn checked_shr(&self, n: u32) -> Option { self.0.checked_shr(n).map(Self::new) } } -impl> CheckedShl for NonceWithDefault { +impl, N: Nonce> CheckedShl for NonceWithDefault { fn checked_shl(&self, n: u32) -> Option { self.0.checked_shl(n).map(Self::new) } } -impl> Rem for NonceWithDefault { +impl, N: Nonce> Rem for NonceWithDefault { type Output = Self; fn rem(self, rhs: Self) -> Self { Self::new(self.0 % rhs.0) } } -impl> Rem for NonceWithDefault { +impl, N: Nonce> Rem for NonceWithDefault { type Output = Self; fn rem(self, rhs: u32) -> Self { - Self::new(self.0 % (rhs as u64)) + Self::new(self.0 % (rhs.into())) } } -impl> Shr for NonceWithDefault { +impl, N: Nonce> Shr for NonceWithDefault { type Output = Self; fn shr(self, rhs: u32) -> Self { Self::new(self.0 >> rhs) } } -impl> Shr for NonceWithDefault { +impl, N: Nonce> Shr for NonceWithDefault { type Output = Self; fn shr(self, rhs: usize) -> Self { Self::new(self.0 >> rhs) } } -impl> Shl for NonceWithDefault { +impl, N: Nonce> Shl for NonceWithDefault { type Output = Self; fn shl(self, rhs: u32) -> Self { Self::new(self.0 << rhs) } } -impl> Shl for NonceWithDefault { +impl, N: Nonce> Shl for NonceWithDefault { type Output = Self; fn shl(self, rhs: usize) -> Self { Self::new(self.0 << rhs) } } -impl> RemAssign for NonceWithDefault { +impl, N: Nonce> RemAssign for NonceWithDefault { fn rem_assign(&mut self, rhs: Self) { self.0 %= rhs.0 } } -impl> DivAssign for NonceWithDefault { +impl, N: Nonce> DivAssign for NonceWithDefault { fn div_assign(&mut self, rhs: Self) { self.0 /= rhs.0 } } -impl> MulAssign for NonceWithDefault { +impl, N: Nonce> MulAssign for NonceWithDefault { fn mul_assign(&mut self, rhs: Self) { self.0 *= rhs.0 } } -impl> SubAssign for NonceWithDefault { +impl, N: Nonce> SubAssign for NonceWithDefault { fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 } } -impl> AddAssign for NonceWithDefault { +impl, N: Nonce> AddAssign for NonceWithDefault { fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 } } -impl> From for NonceWithDefault { +impl, N: Nonce> From for NonceWithDefault { fn from(value: u8) -> Self { - Self::new(value as u64) + Self::new(value.into()) } } -impl> Display for NonceWithDefault { +impl, N: Nonce> Display for NonceWithDefault { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{}", self.0) } } -impl> From> for u32 { - fn from(n: NonceWithDefault) -> u32 { - n.0 as u32 +impl, N: Nonce> TryFrom for NonceWithDefault { + type Error = >::Error; + fn try_from(n: u64) -> Result, Self::Error> { + N::try_from(n).map(Self::new) } } -impl> From> for u16 { - fn from(n: NonceWithDefault) -> u16 { - n.0 as u16 +impl, N: Nonce> TryFrom for NonceWithDefault { + type Error = >::Error; + fn try_from(n: u128) -> Result, Self::Error> { + N::try_from(n).map(Self::new) } } -impl> From> for u128 { - fn from(n: NonceWithDefault) -> u128 { - n.0 as u128 +impl, N: Nonce> TryFrom for NonceWithDefault { + type Error = >::Error; + fn try_from(n: usize) -> Result, Self::Error> { + N::try_from(n).map(Self::new) } } -impl> From> for usize { - fn from(n: NonceWithDefault) -> usize { - n.0 as usize +impl, N: Nonce> TryFrom> for u8 { + type Error = >::Error; + fn try_from(value: NonceWithDefault) -> Result { + value.0.try_into() } } -impl> From for NonceWithDefault { - fn from(n: u64) -> NonceWithDefault { - Self::new(n) +impl, N: Nonce> TryFrom> for u16 { + type Error = >::Error; + fn try_from(value: NonceWithDefault) -> Result { + value.0.try_into() } } -impl> From for NonceWithDefault { - fn from(n: u128) -> NonceWithDefault { - Self::new(n as u64) +impl, N: Nonce> TryFrom> for u32 { + type Error = >::Error; + fn try_from(value: NonceWithDefault) -> Result { + value.0.try_into() } } -impl> From for NonceWithDefault { - fn from(n: usize) -> NonceWithDefault { - Self::new(n as u64) +impl, N: Nonce> TryFrom> for u64 { + type Error = >::Error; + fn try_from(value: NonceWithDefault) -> Result { + value.0.try_into() } } -impl> From> for u8 { - fn from(n: NonceWithDefault) -> u8 { - n.0 as u8 +impl, N: Nonce> TryFrom> for u128 { + type Error = >::Error; + fn try_from(value: NonceWithDefault) -> Result { + value.0.try_into() } } -impl> From> for u64 { - fn from(n: NonceWithDefault) -> u64 { - n.0 +impl, N: Nonce> TryFrom> for usize { + type Error = >::Error; + fn try_from(value: NonceWithDefault) -> Result { + value.0.try_into() } } -impl> Zero for NonceWithDefault { +impl, N: Nonce> Zero for NonceWithDefault { fn zero() -> Self { - Self::new(0) + Self::new(N::zero()) } fn is_zero(&self) -> bool { - self.0 == 0 + self.0 == N::zero() } } -impl> Bounded for NonceWithDefault { +impl, N: Nonce> Bounded for NonceWithDefault { fn min_value() -> Self { - Self::new(u64::min_value()) + Self::new(N::min_value()) } fn max_value() -> Self { - Self::new(u64::max_value()) + Self::new(N::max_value()) } } -impl> PrimInt for NonceWithDefault { +impl, N: Nonce> PrimInt for NonceWithDefault { fn count_ones(self) -> u32 { self.0.count_ones() } @@ -296,11 +311,11 @@ impl> PrimInt for NonceWithDefault { } fn from_be(x: Self) -> Self { - Self::new(u64::from_be(x.0)) + Self::new(N::from_be(x.0)) } fn from_le(x: Self) -> Self { - Self::new(u64::from_le(x.0)) + Self::new(N::from_le(x.0)) } fn to_be(self) -> Self { @@ -314,21 +329,21 @@ impl> PrimInt for NonceWithDefault { fn count_zeros(self) -> u32 { self.0.count_zeros() } - + fn signed_shl(self, n: u32) -> Self { - Self::new(self.0.wrapping_shl(n)) + Self::new(self.0.signed_shl(n)) } fn signed_shr(self, n: u32) -> Self { - Self::new(self.0.wrapping_shr(n)) + Self::new(self.0.signed_shr(n)) } fn unsigned_shl(self, n: u32) -> Self { - Self::new(self.0.wrapping_shl(n)) + Self::new(self.0.unsigned_shl(n)) } fn unsigned_shr(self, n: u32) -> Self { - Self::new(self.0.wrapping_shr(n)) + Self::new(self.0.unsigned_shr(n)) } fn pow(self, exp: u32) -> Self { @@ -336,123 +351,123 @@ impl> PrimInt for NonceWithDefault { } } -impl> Saturating for NonceWithDefault { +impl, N: Nonce> Saturating for NonceWithDefault { fn saturating_add(self, rhs: Self) -> Self { - Self::new(self.0.saturating_add(rhs.0)) + Self::new(::saturating_add(*self, rhs.0)) } fn saturating_sub(self, rhs: Self) -> Self { - Self::new(self.0.saturating_sub(rhs.0)) + Self::new(::saturating_sub(*self, rhs.0)) } } -impl> Div for NonceWithDefault { +impl, N: Nonce> Div for NonceWithDefault { type Output = Self; fn div(self, rhs: Self) -> Self { Self::new(self.0 / rhs.0) } } -impl> Mul for NonceWithDefault { +impl, N: Nonce> Mul for NonceWithDefault { type Output = Self; fn mul(self, rhs: Self) -> Self { Self::new(self.0 * rhs.0) } } -impl> CheckedDiv for NonceWithDefault { +impl, N: Nonce> CheckedDiv for NonceWithDefault { fn checked_div(&self, rhs: &Self) -> Option { - self.0.checked_div(rhs.0).map(Self::new) + self.0.checked_div(&rhs.0).map(Self::new) } } -impl> CheckedMul for NonceWithDefault { +impl, N: Nonce> CheckedMul for NonceWithDefault { fn checked_mul(&self, rhs: &Self) -> Option { - self.0.checked_mul(rhs.0).map(Self::new) + self.0.checked_mul(&rhs.0).map(Self::new) } } -impl> Sub for NonceWithDefault { +impl, N: Nonce> Sub for NonceWithDefault { type Output = Self; fn sub(self, rhs: Self) -> Self { Self::new(self.0 - rhs.0) } } -impl> CheckedSub for NonceWithDefault { +impl, N: Nonce> CheckedSub for NonceWithDefault { fn checked_sub(&self, rhs: &Self) -> Option { - self.0.checked_sub(rhs.0).map(Self::new) + self.0.checked_sub(&rhs.0).map(Self::new) } } -impl> Add for NonceWithDefault { +impl, N: Nonce> Add for NonceWithDefault { type Output = Self; fn add(self, rhs: Self) -> Self { Self::new(self.0 + rhs.0) } } -impl> CheckedAdd for NonceWithDefault { +impl, N: Nonce> CheckedAdd for NonceWithDefault { fn checked_add(&self, rhs: &Self) -> Option { - self.0.checked_add(rhs.0).map(Self::new) + self.0.checked_add(&rhs.0).map(Self::new) } } -impl> BitAnd for NonceWithDefault { +impl, N: Nonce> BitAnd for NonceWithDefault { type Output = Self; fn bitand(self, rhs: Self) -> Self { Self::new(self.0 & rhs.0) } } -impl> BitOr for NonceWithDefault { +impl, N: Nonce> BitOr for NonceWithDefault { type Output = Self; fn bitor(self, rhs: Self) -> Self { Self::new(self.0 | rhs.0) } } -impl> BitXor for NonceWithDefault { +impl, N: Nonce> BitXor for NonceWithDefault { type Output = Self; fn bitxor(self, rhs: Self) -> Self { Self::new(self.0 ^ rhs.0) } } -impl> One for NonceWithDefault { +impl, N: Nonce> One for NonceWithDefault { fn one() -> Self { - Self::new(1) + Self::new(N::one()) } } -impl> Not for NonceWithDefault { +impl, N: Nonce> Not for NonceWithDefault { type Output = Self; fn not(self) -> Self { - Self::new(!self.0) + Self::new(self.0.not()) } } -impl> NumCast for NonceWithDefault { +impl, N: Nonce> NumCast for NonceWithDefault { fn from(n: T) -> Option { - n.to_u64().map(Self::new) + ::from(n).map_or(None, |n| Some(Self::new(n))) } } -impl> Num for NonceWithDefault { - type FromStrRadixErr = ::FromStrRadixErr; +impl, N: Nonce> Num for NonceWithDefault { + type FromStrRadixErr = ::FromStrRadixErr; fn from_str_radix(s: &str, radix: u32) -> Result { - u64::from_str_radix(s, radix).map(Self::new) + N::from_str_radix(s, radix).map(Self::new) } } -impl> ToPrimitive for NonceWithDefault { +impl, N: Nonce> ToPrimitive for NonceWithDefault { fn to_i64(&self) -> Option { self.0.to_i64() } fn to_u64(&self) -> Option { - Some(self.0) + self.0.to_u64() } fn to_i128(&self) -> Option { @@ -460,18 +475,18 @@ impl> ToPrimitive for NonceWithDefault { } fn to_u128(&self) -> Option { - Some(self.0 as u128) + self.0.to_u128() } } -impl> From>> for NonceWithDefault { - fn from(c: Compact>) -> Self { +impl, N: Nonce> From>> for NonceWithDefault { + fn from(c: Compact>) -> Self { c.0 } } -impl> CompactAs for NonceWithDefault { - type As = u64; +impl, N: Nonce> CompactAs for NonceWithDefault { + type As = N; fn encode_as(&self) -> &Self::As { &self.0 diff --git a/substrate/primitives/runtime/src/traits.rs b/substrate/primitives/runtime/src/traits.rs index 5a6c306dd2a1..cee8ce9e939a 100644 --- a/substrate/primitives/runtime/src/traits.rs +++ b/substrate/primitives/runtime/src/traits.rs @@ -28,6 +28,7 @@ use crate::{ }; use codec::{Codec, Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen}; use impl_trait_for_tuples::impl_for_tuples; +use num_traits::{PrimInt, ToPrimitive}; #[cfg(feature = "serde")] use serde::{de::DeserializeOwned, Deserialize, Serialize}; use sp_application_crypto::AppCrypto; @@ -2497,3 +2498,30 @@ mod tests { signature_verify_test!(bls381) } } + +pub trait Nonce: + Member + + Debug + + Default + + MaybeDisplay + + AtLeast32Bit + + Copy + + MaxEncodedLen + + ToPrimitive + + PrimInt +{ +} + +impl< + T: Member + + Debug + + Default + + MaybeDisplay + + AtLeast32Bit + + Copy + + MaxEncodedLen + + ToPrimitive + + PrimInt, + > Nonce for T +{ +} From 298f84ebd7865ae089f32623a337016232d8ad98 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Tue, 30 Apr 2024 10:25:13 +0530 Subject: [PATCH 04/10] Adds TypeWithDefault --- substrate/frame/system/src/mock.rs | 8 +- substrate/primitives/runtime/src/lib.rs | 2 +- substrate/primitives/runtime/src/traits.rs | 28 --- .../src/{nonce.rs => type_with_default.rs} | 206 +++++++++--------- 4 files changed, 110 insertions(+), 134 deletions(-) rename substrate/primitives/runtime/src/{nonce.rs => type_with_default.rs} (50%) diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index cf4e8f16a991..fff848b3b0e5 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -17,7 +17,7 @@ use crate::{self as frame_system, *}; use frame_support::{derive_impl, parameter_types}; -use sp_runtime::{nonce::NonceWithDefault, BuildStorage, Perbill}; +use sp_runtime::{type_with_default::TypeWithDefault, BuildStorage, Perbill}; type Block = mocking::MockBlock; @@ -79,8 +79,8 @@ impl OnKilledAccount for RecordKilled { } #[derive(Debug, TypeInfo)] -pub struct BlockNumberProvider; -impl Get for BlockNumberProvider { +pub struct DefaultNonceProvider; +impl Get for DefaultNonceProvider { fn get() -> u64 { System::block_number() } @@ -95,7 +95,7 @@ impl Config for Test { type AccountData = u32; type OnKilledAccount = RecordKilled; type MultiBlockMigrator = MockedMigrator; - type Nonce = NonceWithDefault; + type Nonce = TypeWithDefault; } parameter_types! { diff --git a/substrate/primitives/runtime/src/lib.rs b/substrate/primitives/runtime/src/lib.rs index 3487045637d3..e4e6b98ff77c 100644 --- a/substrate/primitives/runtime/src/lib.rs +++ b/substrate/primitives/runtime/src/lib.rs @@ -84,7 +84,6 @@ pub mod curve; pub mod generic; pub mod legacy; mod multiaddress; -pub mod nonce; pub mod offchain; pub mod runtime_logger; mod runtime_string; @@ -92,6 +91,7 @@ mod runtime_string; pub mod testing; pub mod traits; pub mod transaction_validity; +pub mod type_with_default; pub use crate::runtime_string::*; diff --git a/substrate/primitives/runtime/src/traits.rs b/substrate/primitives/runtime/src/traits.rs index cee8ce9e939a..5a6c306dd2a1 100644 --- a/substrate/primitives/runtime/src/traits.rs +++ b/substrate/primitives/runtime/src/traits.rs @@ -28,7 +28,6 @@ use crate::{ }; use codec::{Codec, Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen}; use impl_trait_for_tuples::impl_for_tuples; -use num_traits::{PrimInt, ToPrimitive}; #[cfg(feature = "serde")] use serde::{de::DeserializeOwned, Deserialize, Serialize}; use sp_application_crypto::AppCrypto; @@ -2498,30 +2497,3 @@ mod tests { signature_verify_test!(bls381) } } - -pub trait Nonce: - Member - + Debug - + Default - + MaybeDisplay - + AtLeast32Bit - + Copy - + MaxEncodedLen - + ToPrimitive - + PrimInt -{ -} - -impl< - T: Member - + Debug - + Default - + MaybeDisplay - + AtLeast32Bit - + Copy - + MaxEncodedLen - + ToPrimitive - + PrimInt, - > Nonce for T -{ -} diff --git a/substrate/primitives/runtime/src/nonce.rs b/substrate/primitives/runtime/src/type_with_default.rs similarity index 50% rename from substrate/primitives/runtime/src/nonce.rs rename to substrate/primitives/runtime/src/type_with_default.rs index 240ccf444be3..274fabfea0dc 100644 --- a/substrate/primitives/runtime/src/nonce.rs +++ b/substrate/primitives/runtime/src/type_with_default.rs @@ -15,8 +15,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::traits::{Bounded, Nonce, One, Zero}; -use codec::{Compact, CompactAs, Decode, Encode, MaxEncodedLen}; +//! Provides a type that wraps another type and provides a default value. + +use crate::traits::{Bounded, One, Zero}; +use codec::{Compact, CompactAs, Decode, Encode, HasCompact, MaxEncodedLen}; use core::{ fmt::Display, marker::PhantomData, @@ -35,257 +37,259 @@ use sp_core::Get; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +/// A type that wraps another type and provides a default value. #[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct NonceWithDefault, N: Nonce>(N, PhantomData); +pub struct TypeWithDefault>(T, PhantomData); -impl, N: Nonce> NonceWithDefault { - pub fn new(value: N) -> Self { +impl> TypeWithDefault { + fn new(value: T) -> Self { Self(value, PhantomData) } } -impl, N: Nonce> Clone for NonceWithDefault { +impl> Clone for TypeWithDefault { fn clone(&self) -> Self { - Self(self.0, PhantomData) + Self(self.0.clone(), PhantomData) } } -impl, N: Nonce> Copy for NonceWithDefault {} +impl> Copy for TypeWithDefault {} -impl, N: Nonce> PartialEq for NonceWithDefault { +impl> PartialEq for TypeWithDefault { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } -impl, N: Nonce> Eq for NonceWithDefault {} +impl> Eq for TypeWithDefault {} -impl, N: Nonce> PartialOrd for NonceWithDefault { +impl> PartialOrd for TypeWithDefault { fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) } } -impl, N: Nonce> Ord for NonceWithDefault { +impl> Ord for TypeWithDefault { fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.cmp(&other.0) } } -impl, N: Nonce> Deref for NonceWithDefault { - type Target = N; +impl> Deref for TypeWithDefault { + type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } -impl, N: Nonce> Default for NonceWithDefault { +impl> Default for TypeWithDefault { fn default() -> Self { Self::new(D::get()) } } -impl, N: Nonce> From for NonceWithDefault { + +impl, D: Get> From for TypeWithDefault { fn from(value: u32) -> Self { Self::new(value.into()) } } -impl, N: Nonce> From for NonceWithDefault { +impl, D: Get> From for TypeWithDefault { fn from(value: u16) -> Self { Self::new(value.into()) } } -impl, N: Nonce> CheckedNeg for NonceWithDefault { +impl> CheckedNeg for TypeWithDefault { fn checked_neg(&self) -> Option { self.0.checked_neg().map(Self::new) } } -impl, N: Nonce> CheckedRem for NonceWithDefault { +impl> CheckedRem for TypeWithDefault { fn checked_rem(&self, rhs: &Self) -> Option { self.0.checked_rem(&rhs.0).map(Self::new) } } -impl, N: Nonce> CheckedShr for NonceWithDefault { +impl> CheckedShr for TypeWithDefault { fn checked_shr(&self, n: u32) -> Option { self.0.checked_shr(n).map(Self::new) } } -impl, N: Nonce> CheckedShl for NonceWithDefault { +impl> CheckedShl for TypeWithDefault { fn checked_shl(&self, n: u32) -> Option { self.0.checked_shl(n).map(Self::new) } } -impl, N: Nonce> Rem for NonceWithDefault { +impl, D: Get> Rem for TypeWithDefault { type Output = Self; fn rem(self, rhs: Self) -> Self { Self::new(self.0 % rhs.0) } } -impl, N: Nonce> Rem for NonceWithDefault { +impl, D: Get> Rem for TypeWithDefault { type Output = Self; fn rem(self, rhs: u32) -> Self { Self::new(self.0 % (rhs.into())) } } -impl, N: Nonce> Shr for NonceWithDefault { +impl, D: Get> Shr for TypeWithDefault { type Output = Self; fn shr(self, rhs: u32) -> Self { Self::new(self.0 >> rhs) } } -impl, N: Nonce> Shr for NonceWithDefault { +impl, D: Get> Shr for TypeWithDefault { type Output = Self; fn shr(self, rhs: usize) -> Self { Self::new(self.0 >> rhs) } } -impl, N: Nonce> Shl for NonceWithDefault { +impl, D: Get> Shl for TypeWithDefault { type Output = Self; fn shl(self, rhs: u32) -> Self { Self::new(self.0 << rhs) } } -impl, N: Nonce> Shl for NonceWithDefault { +impl, D: Get> Shl for TypeWithDefault { type Output = Self; fn shl(self, rhs: usize) -> Self { Self::new(self.0 << rhs) } } -impl, N: Nonce> RemAssign for NonceWithDefault { +impl> RemAssign for TypeWithDefault { fn rem_assign(&mut self, rhs: Self) { self.0 %= rhs.0 } } -impl, N: Nonce> DivAssign for NonceWithDefault { +impl> DivAssign for TypeWithDefault { fn div_assign(&mut self, rhs: Self) { self.0 /= rhs.0 } } -impl, N: Nonce> MulAssign for NonceWithDefault { +impl> MulAssign for TypeWithDefault { fn mul_assign(&mut self, rhs: Self) { self.0 *= rhs.0 } } -impl, N: Nonce> SubAssign for NonceWithDefault { +impl> SubAssign for TypeWithDefault { fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 } } -impl, N: Nonce> AddAssign for NonceWithDefault { +impl> AddAssign for TypeWithDefault { fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 } } -impl, N: Nonce> From for NonceWithDefault { +impl, D: Get> From for TypeWithDefault { fn from(value: u8) -> Self { Self::new(value.into()) } } -impl, N: Nonce> Display for NonceWithDefault { +impl> Display for TypeWithDefault { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{}", self.0) } } -impl, N: Nonce> TryFrom for NonceWithDefault { - type Error = >::Error; - fn try_from(n: u64) -> Result, Self::Error> { - N::try_from(n).map(Self::new) +impl, D: Get> TryFrom for TypeWithDefault { + type Error = >::Error; + fn try_from(n: u64) -> Result, Self::Error> { + T::try_from(n).map(Self::new) } } -impl, N: Nonce> TryFrom for NonceWithDefault { - type Error = >::Error; - fn try_from(n: u128) -> Result, Self::Error> { - N::try_from(n).map(Self::new) +impl, D: Get> TryFrom for TypeWithDefault { + type Error = >::Error; + fn try_from(n: u128) -> Result, Self::Error> { + T::try_from(n).map(Self::new) } } -impl, N: Nonce> TryFrom for NonceWithDefault { - type Error = >::Error; - fn try_from(n: usize) -> Result, Self::Error> { - N::try_from(n).map(Self::new) +impl, D: Get> TryFrom for TypeWithDefault { + type Error = >::Error; + fn try_from(n: usize) -> Result, Self::Error> { + T::try_from(n).map(Self::new) } } -impl, N: Nonce> TryFrom> for u8 { - type Error = >::Error; - fn try_from(value: NonceWithDefault) -> Result { +impl, D: Get> TryFrom> for u8 { + type Error = >::Error; + fn try_from(value: TypeWithDefault) -> Result { value.0.try_into() } } -impl, N: Nonce> TryFrom> for u16 { - type Error = >::Error; - fn try_from(value: NonceWithDefault) -> Result { +impl, D: Get> TryFrom> for u16 { + type Error = >::Error; + fn try_from(value: TypeWithDefault) -> Result { value.0.try_into() } } -impl, N: Nonce> TryFrom> for u32 { - type Error = >::Error; - fn try_from(value: NonceWithDefault) -> Result { +impl, D: Get> TryFrom> for u32 { + type Error = >::Error; + fn try_from(value: TypeWithDefault) -> Result { value.0.try_into() } } -impl, N: Nonce> TryFrom> for u64 { - type Error = >::Error; - fn try_from(value: NonceWithDefault) -> Result { +impl, D: Get> TryFrom> for u64 { + type Error = >::Error; + fn try_from(value: TypeWithDefault) -> Result { value.0.try_into() } } -impl, N: Nonce> TryFrom> for u128 { - type Error = >::Error; - fn try_from(value: NonceWithDefault) -> Result { +impl, D: Get> TryFrom> for u128 { + type Error = >::Error; + fn try_from(value: TypeWithDefault) -> Result { value.0.try_into() } } -impl, N: Nonce> TryFrom> for usize { - type Error = >::Error; - fn try_from(value: NonceWithDefault) -> Result { +impl, D: Get> TryFrom> for usize { + type Error = >::Error; + fn try_from(value: TypeWithDefault) -> Result { value.0.try_into() } } -impl, N: Nonce> Zero for NonceWithDefault { +impl> Zero for TypeWithDefault { fn zero() -> Self { - Self::new(N::zero()) + Self::new(T::zero()) } fn is_zero(&self) -> bool { - self.0 == N::zero() + self.0 == T::zero() } } -impl, N: Nonce> Bounded for NonceWithDefault { +impl> Bounded for TypeWithDefault { fn min_value() -> Self { - Self::new(N::min_value()) + Self::new(T::min_value()) } fn max_value() -> Self { - Self::new(N::max_value()) + Self::new(T::max_value()) } } -impl, N: Nonce> PrimInt for NonceWithDefault { +impl> PrimInt for TypeWithDefault { fn count_ones(self) -> u32 { self.0.count_ones() } @@ -311,11 +315,11 @@ impl, N: Nonce> PrimInt for NonceWithDefault { } fn from_be(x: Self) -> Self { - Self::new(N::from_be(x.0)) + Self::new(T::from_be(x.0)) } fn from_le(x: Self) -> Self { - Self::new(N::from_le(x.0)) + Self::new(T::from_le(x.0)) } fn to_be(self) -> Self { @@ -351,117 +355,117 @@ impl, N: Nonce> PrimInt for NonceWithDefault { } } -impl, N: Nonce> Saturating for NonceWithDefault { +impl> Saturating for TypeWithDefault { fn saturating_add(self, rhs: Self) -> Self { - Self::new(::saturating_add(*self, rhs.0)) + Self::new(self.0.saturating_add(rhs.0)) } fn saturating_sub(self, rhs: Self) -> Self { - Self::new(::saturating_sub(*self, rhs.0)) + Self::new(self.0.saturating_sub(rhs.0)) } } -impl, N: Nonce> Div for NonceWithDefault { +impl, D: Get> Div for TypeWithDefault { type Output = Self; fn div(self, rhs: Self) -> Self { Self::new(self.0 / rhs.0) } } -impl, N: Nonce> Mul for NonceWithDefault { +impl, D: Get> Mul for TypeWithDefault { type Output = Self; fn mul(self, rhs: Self) -> Self { Self::new(self.0 * rhs.0) } } -impl, N: Nonce> CheckedDiv for NonceWithDefault { +impl> CheckedDiv for TypeWithDefault { fn checked_div(&self, rhs: &Self) -> Option { self.0.checked_div(&rhs.0).map(Self::new) } } -impl, N: Nonce> CheckedMul for NonceWithDefault { +impl> CheckedMul for TypeWithDefault { fn checked_mul(&self, rhs: &Self) -> Option { self.0.checked_mul(&rhs.0).map(Self::new) } } -impl, N: Nonce> Sub for NonceWithDefault { +impl, D: Get> Sub for TypeWithDefault { type Output = Self; fn sub(self, rhs: Self) -> Self { Self::new(self.0 - rhs.0) } } -impl, N: Nonce> CheckedSub for NonceWithDefault { +impl> CheckedSub for TypeWithDefault { fn checked_sub(&self, rhs: &Self) -> Option { self.0.checked_sub(&rhs.0).map(Self::new) } } -impl, N: Nonce> Add for NonceWithDefault { +impl, D: Get> Add for TypeWithDefault { type Output = Self; fn add(self, rhs: Self) -> Self { Self::new(self.0 + rhs.0) } } -impl, N: Nonce> CheckedAdd for NonceWithDefault { +impl> CheckedAdd for TypeWithDefault { fn checked_add(&self, rhs: &Self) -> Option { self.0.checked_add(&rhs.0).map(Self::new) } } -impl, N: Nonce> BitAnd for NonceWithDefault { +impl, D: Get> BitAnd for TypeWithDefault { type Output = Self; fn bitand(self, rhs: Self) -> Self { Self::new(self.0 & rhs.0) } } -impl, N: Nonce> BitOr for NonceWithDefault { +impl, D: Get> BitOr for TypeWithDefault { type Output = Self; fn bitor(self, rhs: Self) -> Self { Self::new(self.0 | rhs.0) } } -impl, N: Nonce> BitXor for NonceWithDefault { +impl, D: Get> BitXor for TypeWithDefault { type Output = Self; fn bitxor(self, rhs: Self) -> Self { Self::new(self.0 ^ rhs.0) } } -impl, N: Nonce> One for NonceWithDefault { +impl> One for TypeWithDefault { fn one() -> Self { - Self::new(N::one()) + Self::new(T::one()) } } -impl, N: Nonce> Not for NonceWithDefault { +impl, D: Get> Not for TypeWithDefault { type Output = Self; fn not(self) -> Self { Self::new(self.0.not()) } } -impl, N: Nonce> NumCast for NonceWithDefault { - fn from(n: T) -> Option { - ::from(n).map_or(None, |n| Some(Self::new(n))) +impl> NumCast for TypeWithDefault { + fn from(n: P) -> Option { + ::from(n).map_or(None, |n| Some(Self::new(n))) } } -impl, N: Nonce> Num for NonceWithDefault { - type FromStrRadixErr = ::FromStrRadixErr; +impl> Num for TypeWithDefault { + type FromStrRadixErr = ::FromStrRadixErr; fn from_str_radix(s: &str, radix: u32) -> Result { - N::from_str_radix(s, radix).map(Self::new) + T::from_str_radix(s, radix).map(Self::new) } } -impl, N: Nonce> ToPrimitive for NonceWithDefault { +impl> ToPrimitive for TypeWithDefault { fn to_i64(&self) -> Option { self.0.to_i64() } @@ -479,14 +483,14 @@ impl, N: Nonce> ToPrimitive for NonceWithDefault { } } -impl, N: Nonce> From>> for NonceWithDefault { - fn from(c: Compact>) -> Self { +impl> From>> for TypeWithDefault { + fn from(c: Compact>) -> Self { c.0 } } -impl, N: Nonce> CompactAs for NonceWithDefault { - type As = N; +impl> CompactAs for TypeWithDefault { + type As = T; fn encode_as(&self) -> &Self::As { &self.0 From fb1e9c1ba946d4923bebc7e4fc9883c6003d1e76 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Tue, 30 Apr 2024 10:31:03 +0530 Subject: [PATCH 05/10] Adds PrDoc --- prdoc/pr_4034.prdoc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 prdoc/pr_4034.prdoc diff --git a/prdoc/pr_4034.prdoc b/prdoc/pr_4034.prdoc new file mode 100644 index 000000000000..c0908568dd2e --- /dev/null +++ b/prdoc/pr_4034.prdoc @@ -0,0 +1,14 @@ +title: "Introduces `TypeWithDefault>`" + +doc: + - audience: Runtime Dev + description: | + This PR introduces a new type `TypeWithDefault, N: Nonce>` to be able to provide + a custom default for any type. This can, then, be used to provide the nonce type that + returns the current block number as the default, to avoid replay of immortal transactions. + +crates: +- name: sp-runtime + bump: minor +- name: frame-system + bump: patch From 7967f9760f6071f240d03711ee1547ad5b332f6f Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Tue, 30 Apr 2024 10:33:03 +0530 Subject: [PATCH 06/10] Minor --- prdoc/pr_4034.prdoc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/prdoc/pr_4034.prdoc b/prdoc/pr_4034.prdoc index c0908568dd2e..fad120dab69e 100644 --- a/prdoc/pr_4034.prdoc +++ b/prdoc/pr_4034.prdoc @@ -3,12 +3,13 @@ title: "Introduces `TypeWithDefault>`" doc: - audience: Runtime Dev description: | - This PR introduces a new type `TypeWithDefault, N: Nonce>` to be able to provide - a custom default for any type. This can, then, be used to provide the nonce type that - returns the current block number as the default, to avoid replay of immortal transactions. + This PR introduces a new type `TypeWithDefault>` to be able to provide a + custom default for any type. This can, then, be used to provide the nonce type that returns + the current block number as the default, to avoid replay of immortal transactions. crates: - name: sp-runtime bump: minor - name: frame-system bump: patch +g \ No newline at end of file From 35ed5a725789726355a8f578fdaf3981ffe31ad4 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Tue, 30 Apr 2024 10:35:10 +0530 Subject: [PATCH 07/10] Minor --- prdoc/pr_4034.prdoc | 1 - 1 file changed, 1 deletion(-) diff --git a/prdoc/pr_4034.prdoc b/prdoc/pr_4034.prdoc index fad120dab69e..994811b5d672 100644 --- a/prdoc/pr_4034.prdoc +++ b/prdoc/pr_4034.prdoc @@ -12,4 +12,3 @@ crates: bump: minor - name: frame-system bump: patch -g \ No newline at end of file From 6e7257c6f30793b4a26baa80a584513212568764 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 2 May 2024 15:39:03 +0530 Subject: [PATCH 08/10] Uses u64 instead of u32 --- .../system/src/extensions/check_nonce.rs | 30 +++++++-------- substrate/frame/system/src/tests.rs | 38 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/substrate/frame/system/src/extensions/check_nonce.rs b/substrate/frame/system/src/extensions/check_nonce.rs index cca5a23edd7b..894ab72eb593 100644 --- a/substrate/frame/system/src/extensions/check_nonce.rs +++ b/substrate/frame/system/src/extensions/check_nonce.rs @@ -142,7 +142,7 @@ mod tests { crate::Account::::insert( 1, crate::AccountInfo { - nonce: 1u32.into(), + nonce: 1u64.into(), consumers: 0, providers: 1, sufficients: 0, @@ -153,20 +153,20 @@ mod tests { let len = 0_usize; // stale assert_noop!( - CheckNonce::(0u32.into()).validate(&1, CALL, &info, len), + CheckNonce::(0u64.into()).validate(&1, CALL, &info, len), InvalidTransaction::Stale ); assert_noop!( - CheckNonce::(0u32.into()).pre_dispatch(&1, CALL, &info, len), + CheckNonce::(0u64.into()).pre_dispatch(&1, CALL, &info, len), InvalidTransaction::Stale ); // correct - assert_ok!(CheckNonce::(1u32.into()).validate(&1, CALL, &info, len)); - assert_ok!(CheckNonce::(1u32.into()).pre_dispatch(&1, CALL, &info, len)); + assert_ok!(CheckNonce::(1u64.into()).validate(&1, CALL, &info, len)); + assert_ok!(CheckNonce::(1u64.into()).pre_dispatch(&1, CALL, &info, len)); // future - assert_ok!(CheckNonce::(5u32.into()).validate(&1, CALL, &info, len)); + assert_ok!(CheckNonce::(5u64.into()).validate(&1, CALL, &info, len)); assert_noop!( - CheckNonce::(5u32.into()).pre_dispatch(&1, CALL, &info, len), + CheckNonce::(5u64.into()).pre_dispatch(&1, CALL, &info, len), InvalidTransaction::Future ); }) @@ -178,7 +178,7 @@ mod tests { crate::Account::::insert( 2, crate::AccountInfo { - nonce: 1u32.into(), + nonce: 1u64.into(), consumers: 0, providers: 1, sufficients: 0, @@ -188,7 +188,7 @@ mod tests { crate::Account::::insert( 3, crate::AccountInfo { - nonce: 1u32.into(), + nonce: 1u64.into(), consumers: 0, providers: 0, sufficients: 1, @@ -199,19 +199,19 @@ mod tests { let len = 0_usize; // Both providers and sufficients zero assert_noop!( - CheckNonce::(1u32.into()).validate(&1, CALL, &info, len), + CheckNonce::(1u64.into()).validate(&1, CALL, &info, len), InvalidTransaction::Payment ); assert_noop!( - CheckNonce::(1u32.into()).pre_dispatch(&1, CALL, &info, len), + CheckNonce::(1u64.into()).pre_dispatch(&1, CALL, &info, len), InvalidTransaction::Payment ); // Non-zero providers - assert_ok!(CheckNonce::(1u32.into()).validate(&2, CALL, &info, len)); - assert_ok!(CheckNonce::(1u32.into()).pre_dispatch(&2, CALL, &info, len)); + assert_ok!(CheckNonce::(1u64.into()).validate(&2, CALL, &info, len)); + assert_ok!(CheckNonce::(1u64.into()).pre_dispatch(&2, CALL, &info, len)); // Non-zero sufficients - assert_ok!(CheckNonce::(1u32.into()).validate(&3, CALL, &info, len)); - assert_ok!(CheckNonce::(1u32.into()).pre_dispatch(&3, CALL, &info, len)); + assert_ok!(CheckNonce::(1u64.into()).validate(&3, CALL, &info, len)); + assert_ok!(CheckNonce::(1u64.into()).pre_dispatch(&3, CALL, &info, len)); }) } } diff --git a/substrate/frame/system/src/tests.rs b/substrate/frame/system/src/tests.rs index a0a02ee7ea9a..4eff53789d08 100644 --- a/substrate/frame/system/src/tests.rs +++ b/substrate/frame/system/src/tests.rs @@ -103,7 +103,7 @@ fn stored_map_works() { assert_eq!( Account::::get(0), AccountInfo { - nonce: 0u32.into(), + nonce: 0u64.into(), providers: 1, consumers: 0, sufficients: 0, @@ -132,26 +132,26 @@ fn provider_ref_handover_to_self_sufficient_ref_works() { new_test_ext().execute_with(|| { assert_eq!(System::inc_providers(&0), IncRefStatus::Created); System::inc_account_nonce(&0); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); // a second reference coming and going doesn't change anything. assert_eq!(System::inc_sufficients(&0), IncRefStatus::Existed); assert_eq!(System::dec_sufficients(&0), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); // a provider reference coming and going doesn't change anything. assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); // decreasing the providers with a self-sufficient present should not delete the account assert_eq!(System::inc_sufficients(&0), IncRefStatus::Existed); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); // decreasing the sufficients should delete the account assert_eq!(System::dec_sufficients(&0), DecRefStatus::Reaped); - assert_eq!(System::account_nonce(&0), 0u32.into()); + assert_eq!(System::account_nonce(&0), 0u64.into()); }); } @@ -160,26 +160,26 @@ fn self_sufficient_ref_handover_to_provider_ref_works() { new_test_ext().execute_with(|| { assert_eq!(System::inc_sufficients(&0), IncRefStatus::Created); System::inc_account_nonce(&0); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); // a second reference coming and going doesn't change anything. assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); // a sufficient reference coming and going doesn't change anything. assert_eq!(System::inc_sufficients(&0), IncRefStatus::Existed); assert_eq!(System::dec_sufficients(&0), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); // decreasing the sufficients with a provider present should not delete the account assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); assert_eq!(System::dec_sufficients(&0), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); // decreasing the providers should delete the account assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Reaped); - assert_eq!(System::account_nonce(&0), 0u32.into()); + assert_eq!(System::account_nonce(&0), 0u64.into()); }); } @@ -188,7 +188,7 @@ fn sufficient_cannot_support_consumer() { new_test_ext().execute_with(|| { assert_eq!(System::inc_sufficients(&0), IncRefStatus::Created); System::inc_account_nonce(&0); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); assert_noop!(System::inc_consumers(&0), DispatchError::NoProviders); assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); @@ -204,18 +204,18 @@ fn provider_required_to_support_consumer() { assert_eq!(System::inc_providers(&0), IncRefStatus::Created); System::inc_account_nonce(&0); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); assert_eq!(System::inc_providers(&0), IncRefStatus::Existed); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Exists); - assert_eq!(System::account_nonce(&0), 1u32.into()); + assert_eq!(System::account_nonce(&0), 1u64.into()); assert_ok!(System::inc_consumers(&0)); assert_noop!(System::dec_providers(&0), DispatchError::ConsumerRemaining); System::dec_consumers(&0); assert_eq!(System::dec_providers(&0).unwrap(), DecRefStatus::Reaped); - assert_eq!(System::account_nonce(&0), 0u32.into()); + assert_eq!(System::account_nonce(&0), 0u64.into()); }); } @@ -869,15 +869,15 @@ fn last_runtime_upgrade_spec_version_usage() { fn test_default_account_nonce() { new_test_ext().execute_with(|| { System::set_block_number(2); - assert_eq!(System::account_nonce(&1), 2u32.into()); + assert_eq!(System::account_nonce(&1), 2u64.into()); System::inc_account_nonce(&1); - assert_eq!(System::account_nonce(&1), 3u32.into()); + assert_eq!(System::account_nonce(&1), 3u64.into()); System::set_block_number(5); - assert_eq!(System::account_nonce(&1), 3u32.into()); + assert_eq!(System::account_nonce(&1), 3u64.into()); Account::::remove(&1); - assert_eq!(System::account_nonce(&1), 5u32.into()); + assert_eq!(System::account_nonce(&1), 5u64.into()); }); } From b07deeb496877e1f030a5d92feda2ac33cf30c11 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 2 May 2024 16:01:14 +0530 Subject: [PATCH 09/10] Adds convert for u64 --- .../runtime/src/type_with_default.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/substrate/primitives/runtime/src/type_with_default.rs b/substrate/primitives/runtime/src/type_with_default.rs index 274fabfea0dc..24a5f686e167 100644 --- a/substrate/primitives/runtime/src/type_with_default.rs +++ b/substrate/primitives/runtime/src/type_with_default.rs @@ -89,21 +89,30 @@ impl> Default for TypeWithDefault { } } +impl, D: Get> From for TypeWithDefault { + fn from(value: u16) -> Self { + Self::new(value.into()) + } +} + impl, D: Get> From for TypeWithDefault { fn from(value: u32) -> Self { Self::new(value.into()) } } -impl, D: Get> From for TypeWithDefault { - fn from(value: u16) -> Self { + +impl, D: Get> From for TypeWithDefault { + fn from(value: u64) -> Self { Self::new(value.into()) } } + impl> CheckedNeg for TypeWithDefault { fn checked_neg(&self) -> Option { self.0.checked_neg().map(Self::new) } } + impl> CheckedRem for TypeWithDefault { fn checked_rem(&self, rhs: &Self) -> Option { self.0.checked_rem(&rhs.0).map(Self::new) @@ -206,13 +215,6 @@ impl> Display for TypeWithDefault { } } -impl, D: Get> TryFrom for TypeWithDefault { - type Error = >::Error; - fn try_from(n: u64) -> Result, Self::Error> { - T::try_from(n).map(Self::new) - } -} - impl, D: Get> TryFrom for TypeWithDefault { type Error = >::Error; fn try_from(n: u128) -> Result, Self::Error> { From c731b874f1d7a1a3cf9c0ae0595249718b24fa9b Mon Sep 17 00:00:00 2001 From: gupnik Date: Fri, 3 May 2024 15:04:01 +0200 Subject: [PATCH 10/10] Update substrate/primitives/runtime/src/type_with_default.rs Co-authored-by: Oliver Tale-Yazdi --- substrate/primitives/runtime/src/type_with_default.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substrate/primitives/runtime/src/type_with_default.rs b/substrate/primitives/runtime/src/type_with_default.rs index 24a5f686e167..1465393640dc 100644 --- a/substrate/primitives/runtime/src/type_with_default.rs +++ b/substrate/primitives/runtime/src/type_with_default.rs @@ -38,6 +38,8 @@ use sp_core::Get; use serde::{Deserialize, Serialize}; /// A type that wraps another type and provides a default value. +/// +/// Passes through arithmetical and many other operations to the inner value. #[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TypeWithDefault>(T, PhantomData);