diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index f165091beda47..66a257dbf5b27 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -821,6 +821,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 0000000000000..8e2fd8ddaca8d --- /dev/null +++ b/prdoc/pr_6623.prdoc @@ -0,0 +1,15 @@ +# 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 block number provider in the Society pallet configurable so that runtimes can choose between using the system block number or an alternative source like the relay chain’s block number. + If you want to keep the existing behavior, simply set the provider to System. For scenarios that require a different notion of block number—such as using a relay chain number you can select another provider, + ensuring flexibility in how the Society pallet references the current block. + +crates: +- name: pallet-society + 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 220929fdfd838..389f1af3ad4c9 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1716,6 +1716,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 dc8e3cab775f5..cf23e608fc7fb 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 b893bb6fba7d3..39aa6bf3566b2 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 396ed787c784c..45bd977535d5f 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 63fc5059279b1..d19bac27a7d4f 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 {