diff --git a/polkadot/runtime/rococo/src/governance/mod.rs b/polkadot/runtime/rococo/src/governance/mod.rs index ef2adf60753d5..ca92151e7d45e 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; 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 d027f788d71f6..352f1ea691911 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; 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 0000000000000..c7d9792957eef --- /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 905b8735c5df9..47d2508ec95e9 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1005,6 +1005,7 @@ impl pallet_conviction_voting::Config for Runtime { type MaxVotes = ConstU32<512>; type MaxTurnout = frame_support::traits::TotalIssuanceOf; 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 31bd6b85ec866..3dd2ad24298d3 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 = + <>::BlockNumberProvider as BlockNumberProvider>::BlockNumber; + type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; type VotingOf = Voting< BalanceOf, ::AccountId, - BlockNumberFor, + BlockNumberFor, PollIndexOf, >::MaxVotes, >; #[allow(dead_code)] type DelegatingOf = - Delegating, ::AccountId, BlockNumberFor>; + Delegating, ::AccountId, BlockNumberFor>; pub type TallyOf = Tally, >::MaxTurnout>; pub type VotesOf = BalanceOf; type PollIndexOf = <>::Polls as Polling>>::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 - + LockableCurrency> + + LockableCurrency> + fungible::Inspect; /// The implementation of the logic which conducts polls. type Polls: Polling< TallyOf, Votes = BalanceOf, - Moment = BlockNumberFor, + Moment = BlockNumberFor, >; /// 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>; + type VoteLockingPeriod: Get>; + /// 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, I: 'static> Pallet { let unlock_at = end.saturating_add( T::VoteLockingPeriod::get().saturating_mul(lock_periods.into()), ); - let now = frame_system::Pallet::::block_number(); + let now = T::BlockNumberProvider::current_block_number(); if now < unlock_at { ensure!( matches!(scope, UnvoteScope::Any), @@ -620,7 +625,7 @@ impl, I: 'static> Pallet { &class, conviction.votes(balance), ); - let now = frame_system::Pallet::::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, I: 'static> Pallet { /// a security hole) but may be reduced from what they are currently. fn update_lock(class: &ClassOf, who: &T::AccountId) { let class_lock_needed = VotingFor::::mutate(who, class, |voting| { - voting.rejig(frame_system::Pallet::::block_number()); + voting.rejig(T::BlockNumberProvider::current_block_number()); voting.locked_balance() }); let lock_needed = ClassLocksFor::::mutate(who, |locks| { diff --git a/substrate/frame/conviction-voting/src/tests.rs b/substrate/frame/conviction-voting/src/tests.rs index b1b1fab5ae50e..8e8b41ba63eb4 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; 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 8f5b484e4e3f5..46f17a0fcc633 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. ///