diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 5da9da86f02e..cedf1b0f5ce5 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -806,6 +806,7 @@ impl pallet_society::Config for Runtime { type MaxPayouts = ConstU32<8>; type MaxBids = ConstU32<512>; type PalletId = SocietyPalletId; + type BlockNumberProvider = System; type WeightInfo = (); } diff --git a/prdoc/pr_6623.prdoc b/prdoc/pr_6623.prdoc new file mode 100644 index 000000000000..8675d9b362e7 --- /dev/null +++ b/prdoc/pr_6623.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 Society Pallet to Support Block Number Provider + +doc: + - audience: Runtime Dev + description: | + This PR makes the society pallet uses the relay chain as a block provider for a parachain on a regular schedule. + To migrate existing society implementations, simply add `type BlockNumberProvider = System` to have the same behavior as before. + +crates: +- name: pallet-society + bump: minor \ 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 bff263548087..86be362c86f9 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1687,6 +1687,7 @@ impl pallet_society::Config for Runtime { type ChallengePeriod = ChallengePeriod; type MaxPayouts = MaxPayouts; type MaxBids = MaxBids; + type BlockNumberProvider = System; type WeightInfo = pallet_society::weights::SubstrateWeight; } diff --git a/substrate/frame/society/src/benchmarking.rs b/substrate/frame/society/src/benchmarking.rs index dc8e3cab775f..cf23e608fc7f 100644 --- a/substrate/frame/society/src/benchmarking.rs +++ b/substrate/frame/society/src/benchmarking.rs @@ -29,6 +29,10 @@ use sp_runtime::traits::Bounded; use crate::Pallet as Society; +fn set_block_number, I: 'static>(n: BlockNumberFor) { + >::BlockNumberProvider::set_block_number(n); +} + fn mock_balance_deposit, I: 'static>() -> BalanceOf { T::Currency::minimum_balance().saturating_mul(1_000u32.into()) } @@ -352,9 +356,7 @@ mod benchmarks { let _ = Society::::insert_member(&skeptic, 0u32.into()); Skeptic::::put(&skeptic); if let Period::Voting { more, .. } = Society::::period() { - frame_system::Pallet::::set_block_number( - frame_system::Pallet::::block_number() + more, - ); + set_block_number::(T::BlockNumberProvider::current_block_number() + more) } #[extrinsic_call] diff --git a/substrate/frame/society/src/lib.rs b/substrate/frame/society/src/lib.rs index b893bb6fba7d..39aa6bf3566b 100644 --- a/substrate/frame/society/src/lib.rs +++ b/substrate/frame/society/src/lib.rs @@ -271,7 +271,9 @@ use frame_support::{ }, PalletId, }; -use frame_system::pallet_prelude::*; +use frame_system::pallet_prelude::{ + ensure_signed, BlockNumberFor as SystemBlockNumberFor, OriginFor, +}; use rand_chacha::{ rand_core::{RngCore, SeedableRng}, ChaChaRng, @@ -289,6 +291,10 @@ use sp_runtime::{ pub use weights::WeightInfo; pub use pallet::*; +use sp_runtime::traits::BlockNumberProvider; + +pub type BlockNumberFor = + <>::BlockNumberProvider as BlockNumberProvider>::BlockNumber; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; @@ -423,7 +429,7 @@ impl BidKind { } pub type PayoutsFor = - BoundedVec<(BlockNumberFor, BalanceOf), >::MaxPayouts>; + BoundedVec<(BlockNumberFor, BalanceOf), >::MaxPayouts>; /// Information concerning a member. #[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -443,7 +449,7 @@ pub struct PayoutRecord { pub type PayoutRecordFor = PayoutRecord< BalanceOf, - BoundedVec<(BlockNumberFor, BalanceOf), >::MaxPayouts>, + BoundedVec<(BlockNumberFor, BalanceOf), >::MaxPayouts>, >; /// Record for an individual new member who was elevated from a candidate recently. @@ -491,7 +497,7 @@ pub mod pallet { type Currency: ReservableCurrency; /// Something that provides randomness in the runtime. - type Randomness: Randomness>; + type Randomness: Randomness>; /// The maximum number of strikes before a member gets funds slashed. #[pallet::constant] @@ -504,23 +510,23 @@ pub mod pallet { /// The number of blocks on which new candidates should be voted on. Together with /// `ClaimPeriod`, this sums to the number of blocks between candidate intake periods. #[pallet::constant] - type VotingPeriod: Get>; + type VotingPeriod: Get>; /// The number of blocks on which new candidates can claim their membership and be the /// named head. #[pallet::constant] - type ClaimPeriod: Get>; + type ClaimPeriod: Get>; /// The maximum duration of the payout lock. #[pallet::constant] - type MaxLockDuration: Get>; + type MaxLockDuration: Get>; /// The origin that is allowed to call `found`. type FounderSetOrigin: EnsureOrigin; /// The number of blocks between membership challenges. #[pallet::constant] - type ChallengePeriod: Get>; + type ChallengePeriod: Get>; /// The maximum number of payouts a member may have waiting unclaimed. #[pallet::constant] @@ -532,6 +538,8 @@ pub mod pallet { /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; + /// Provider for the block number. Normally this is the `frame_system` pallet. + type BlockNumberProvider: BlockNumberProvider; } #[pallet::error] @@ -757,8 +765,8 @@ pub mod pallet { StorageDoubleMap<_, Twox64Concat, RoundIndex, Twox64Concat, T::AccountId, Vote>; #[pallet::hooks] - impl, I: 'static> Hooks> for Pallet { - fn on_initialize(n: BlockNumberFor) -> Weight { + impl, I: 'static> Hooks> for Pallet { + fn on_initialize(n: SystemBlockNumberFor) -> Weight { let mut weight = Weight::zero(); let weights = T::BlockWeights::get(); @@ -1018,9 +1026,9 @@ pub mod pallet { Error::::NoPayout ); let mut record = Payouts::::get(&who); - + let block_number = T::BlockNumberProvider::current_block_number(); if let Some((when, amount)) = record.payouts.first() { - if when <= &>::block_number() { + if when <= &block_number { record.paid = record.paid.checked_add(amount).ok_or(Overflow)?; T::Currency::transfer(&Self::payouts(), &who, *amount, AllowDeath)?; record.payouts.remove(0); @@ -1397,11 +1405,11 @@ pub enum Period { impl, I: 'static> Pallet { /// Get the period we are currently in. - fn period() -> Period> { + fn period() -> Period> { let claim_period = T::ClaimPeriod::get(); let voting_period = T::VotingPeriod::get(); let rotation_period = voting_period + claim_period; - let now = frame_system::Pallet::::block_number(); + let now = T::BlockNumberProvider::current_block_number(); let phase = now % rotation_period; if phase < voting_period { Period::Voting { elapsed: phase, more: voting_period - phase } @@ -1728,7 +1736,7 @@ impl, I: 'static> Pallet { }); NextHead::::put(next_head); - let now = >::block_number(); + let now = T::BlockNumberProvider::current_block_number(); let maturity = now + Self::lock_duration(MemberCount::::get()); Self::reward_bidder(&candidate, candidacy.bid, candidacy.kind, maturity); @@ -1890,7 +1898,7 @@ impl, I: 'static> Pallet { candidate: &T::AccountId, value: BalanceOf, kind: BidKind>, - maturity: BlockNumberFor, + maturity: BlockNumberFor, ) { let value = match kind { BidKind::Deposit(deposit) => { @@ -1927,7 +1935,7 @@ impl, I: 'static> Pallet { /// /// It is the caller's duty to ensure that `who` is already a member. This does nothing if `who` /// is not a member or if `value` is zero. - fn bump_payout(who: &T::AccountId, when: BlockNumberFor, value: BalanceOf) { + fn bump_payout(who: &T::AccountId, when: BlockNumberFor, value: BalanceOf) { if value.is_zero() { return } @@ -2010,7 +2018,7 @@ impl, I: 'static> Pallet { /// /// This is a rather opaque calculation based on the formula here: /// https://www.desmos.com/calculator/9itkal1tce - fn lock_duration(x: u32) -> BlockNumberFor { + fn lock_duration(x: u32) -> BlockNumberFor { let lock_pc = 100 - 50_000 / (x + 500); Percent::from_percent(lock_pc as u8) * T::MaxLockDuration::get() } diff --git a/substrate/frame/society/src/migrations.rs b/substrate/frame/society/src/migrations.rs index 396ed787c784..45bd977535d5 100644 --- a/substrate/frame/society/src/migrations.rs +++ b/substrate/frame/society/src/migrations.rs @@ -170,7 +170,7 @@ pub(crate) mod v0 { Pallet, Twox64Concat, ::AccountId, - Vec<(frame_system::pallet_prelude::BlockNumberFor, BalanceOf)>, + Vec<(BlockNumberFor, BalanceOf)>, ValueQuery, >; #[storage_alias] diff --git a/substrate/frame/society/src/mock.rs b/substrate/frame/society/src/mock.rs index 3c27c08a1061..008642de809a 100644 --- a/substrate/frame/society/src/mock.rs +++ b/substrate/frame/society/src/mock.rs @@ -83,6 +83,7 @@ impl Config for Test { type MaxPayouts = MaxPayouts; type MaxBids = MaxBids; type WeightInfo = (); + type BlockNumberProvider = System; } pub struct EnvBuilder {