diff --git a/polkadot/runtime/rococo/src/governance/mod.rs b/polkadot/runtime/rococo/src/governance/mod.rs index 2be549be29ed14a80c3856cc0db2fa359c83cbcc..4052dfcdd0bec1aff309db08446bfe5acb765df0 100644 --- a/polkadot/runtime/rococo/src/governance/mod.rs +++ b/polkadot/runtime/rococo/src/governance/mod.rs @@ -47,6 +47,7 @@ impl pallet_conviction_voting::Config for Runtime { type MaxTurnout = frame_support::traits::tokens::currency::ActiveIssuanceOf<Balances, Self::AccountId>; type Polls = Referenda; + type BlockNumberProvider = System; } parameter_types! { diff --git a/polkadot/runtime/westend/src/governance/mod.rs b/polkadot/runtime/westend/src/governance/mod.rs index abc25ebaa470833a9bd188b5747ac641638a2fcc..aa4294f033b049a926a8537d0add3766c474197c 100644 --- a/polkadot/runtime/westend/src/governance/mod.rs +++ b/polkadot/runtime/westend/src/governance/mod.rs @@ -44,6 +44,7 @@ impl pallet_conviction_voting::Config for Runtime { type MaxTurnout = frame_support::traits::tokens::currency::ActiveIssuanceOf<Balances, Self::AccountId>; type Polls = Referenda; + type BlockNumberProvider = System; } parameter_types! { diff --git a/prdoc/pr_6621.prdoc b/prdoc/pr_6621.prdoc new file mode 100644 index 0000000000000000000000000000000000000000..c7d9792957eef62a6ab5bbfd5fd685745f4f4ad1 --- /dev/null +++ b/prdoc/pr_6621.prdoc @@ -0,0 +1,14 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Update Conviction Voting Pallet to Support Block Number Provider + +doc: + - audience: Runtime Dev + description: | + This PR makes the block number provider used in the society pallet configurable. Before this PR, society pallet always used the system block number, + with this PR some runtime can opt to use the relay chain block number instead. + +crates: +- name: pallet-conviction-voting + bump: major \ No newline at end of file diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index db5392d943c001e4e93162ddb131834635eb8eb7..4e04dc22468768a3e3430eb14e40d223bebc95ca 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1004,6 +1004,7 @@ impl pallet_conviction_voting::Config for Runtime { type MaxVotes = ConstU32<512>; type MaxTurnout = frame_support::traits::TotalIssuanceOf<Balances, Self::AccountId>; type Polls = Referenda; + type BlockNumberProvider = System; } parameter_types! { diff --git a/substrate/frame/conviction-voting/src/lib.rs b/substrate/frame/conviction-voting/src/lib.rs index 31bd6b85ec866303b82e978c939d414cc11999bc..3dd2ad24298d344d4122933546406fd3dc8c9fb9 100644 --- a/substrate/frame/conviction-voting/src/lib.rs +++ b/substrate/frame/conviction-voting/src/lib.rs @@ -37,7 +37,6 @@ use frame_support::{ ReservableCurrency, WithdrawReasons, }, }; -use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::{ traits::{AtLeast32BitUnsigned, Saturating, StaticLookup, Zero}, ArithmeticError, DispatchError, Perbill, @@ -55,6 +54,7 @@ pub use self::{ vote::{AccountVote, Casting, Delegating, Vote, Voting}, weights::WeightInfo, }; +use sp_runtime::traits::BlockNumberProvider; #[cfg(test)] mod tests; @@ -64,19 +64,22 @@ pub mod benchmarking; const CONVICTION_VOTING_ID: LockIdentifier = *b"pyconvot"; +pub type BlockNumberFor<T, I> = + <<T as Config<I>>::BlockNumberProvider as BlockNumberProvider>::BlockNumber; + type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source; type BalanceOf<T, I = ()> = <<T as Config<I>>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance; type VotingOf<T, I = ()> = Voting< BalanceOf<T, I>, <T as frame_system::Config>::AccountId, - BlockNumberFor<T>, + BlockNumberFor<T, I>, PollIndexOf<T, I>, <T as Config<I>>::MaxVotes, >; #[allow(dead_code)] type DelegatingOf<T, I = ()> = - Delegating<BalanceOf<T, I>, <T as frame_system::Config>::AccountId, BlockNumberFor<T>>; + Delegating<BalanceOf<T, I>, <T as frame_system::Config>::AccountId, BlockNumberFor<T, I>>; pub type TallyOf<T, I = ()> = Tally<BalanceOf<T, I>, <T as Config<I>>::MaxTurnout>; pub type VotesOf<T, I = ()> = BalanceOf<T, I>; type PollIndexOf<T, I = ()> = <<T as Config<I>>::Polls as Polling<TallyOf<T, I>>>::Index; @@ -94,7 +97,7 @@ pub mod pallet { traits::ClassCountOf, Twox64Concat, }; - use frame_system::pallet_prelude::*; + use frame_system::pallet_prelude::{ensure_signed, OriginFor}; use sp_runtime::BoundedVec; #[pallet::pallet] @@ -109,14 +112,14 @@ pub mod pallet { type WeightInfo: WeightInfo; /// Currency type with which voting happens. type Currency: ReservableCurrency<Self::AccountId> - + LockableCurrency<Self::AccountId, Moment = BlockNumberFor<Self>> + + LockableCurrency<Self::AccountId, Moment = BlockNumberFor<Self, I>> + fungible::Inspect<Self::AccountId>; /// The implementation of the logic which conducts polls. type Polls: Polling< TallyOf<Self, I>, Votes = BalanceOf<Self, I>, - Moment = BlockNumberFor<Self>, + Moment = BlockNumberFor<Self, I>, >; /// The maximum amount of tokens which may be used for voting. May just be @@ -136,7 +139,9 @@ pub mod pallet { /// It should be no shorter than enactment period to ensure that in the case of an approval, /// those successful voters are locked into the consequences that their votes entail. #[pallet::constant] - type VoteLockingPeriod: Get<BlockNumberFor<Self>>; + type VoteLockingPeriod: Get<BlockNumberFor<Self, I>>; + /// Provider for the block number. Normally this is the `frame_system` pallet. + type BlockNumberProvider: BlockNumberProvider; } /// All voting for a particular voter in a particular voting class. We store the balance for the @@ -479,7 +484,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { let unlock_at = end.saturating_add( T::VoteLockingPeriod::get().saturating_mul(lock_periods.into()), ); - let now = frame_system::Pallet::<T>::block_number(); + let now = T::BlockNumberProvider::current_block_number(); if now < unlock_at { ensure!( matches!(scope, UnvoteScope::Any), @@ -620,7 +625,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { &class, conviction.votes(balance), ); - let now = frame_system::Pallet::<T>::block_number(); + let now = T::BlockNumberProvider::current_block_number(); let lock_periods = conviction.lock_periods().into(); prior.accumulate( now.saturating_add( @@ -666,7 +671,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> { /// a security hole) but may be reduced from what they are currently. fn update_lock(class: &ClassOf<T, I>, who: &T::AccountId) { let class_lock_needed = VotingFor::<T, I>::mutate(who, class, |voting| { - voting.rejig(frame_system::Pallet::<T>::block_number()); + voting.rejig(T::BlockNumberProvider::current_block_number()); voting.locked_balance() }); let lock_needed = ClassLocksFor::<T, I>::mutate(who, |locks| { diff --git a/substrate/frame/conviction-voting/src/tests.rs b/substrate/frame/conviction-voting/src/tests.rs index b1b1fab5ae50e79bf0fdb2ac36494c51b573167c..8e8b41ba63eb49d60392fb2da8a458249731cf14 100644 --- a/substrate/frame/conviction-voting/src/tests.rs +++ b/substrate/frame/conviction-voting/src/tests.rs @@ -154,6 +154,7 @@ impl Config for Test { type WeightInfo = (); type MaxTurnout = frame_support::traits::TotalIssuanceOf<Balances, Self::AccountId>; type Polls = TestPolls; + type BlockNumberProvider = System; } pub fn new_test_ext() -> sp_io::TestExternalities { diff --git a/substrate/primitives/runtime/src/traits/mod.rs b/substrate/primitives/runtime/src/traits/mod.rs index 8f5b484e4e3f5b84401ec5c0567bbfc83a853bf3..46f17a0fcc6337a9973b13ca03604c9c115f441e 100644 --- a/substrate/primitives/runtime/src/traits/mod.rs +++ b/substrate/primitives/runtime/src/traits/mod.rs @@ -2351,7 +2351,8 @@ pub trait BlockNumberProvider { + Debug + MaxEncodedLen + Copy - + EncodeLike; + + EncodeLike + + Default; /// Returns the current block number. ///