Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pallet_pooled_staking to Dancelight #774

Merged
merged 16 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions solo-chains/runtime/dancelight/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ pallet-author-noting-runtime-api = { workspace = true }
pallet-configuration = { workspace = true }
pallet-data-preservers = { workspace = true }
pallet-inflation-rewards = { workspace = true }
pallet-pooled-staking = { workspace = true }
pallet-registrar = { workspace = true }
pallet-registrar-runtime-api = { workspace = true }
pallet-services-payment = { workspace = true }
Expand Down
117 changes: 114 additions & 3 deletions solo-chains/runtime/dancelight/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ pub struct TreasuryBenchmarkHelper<T>(PhantomData<T>);

#[cfg(feature = "runtime-benchmarks")]
use frame_support::traits::Currency;
use frame_support::traits::ValidatorRegistration;
#[cfg(feature = "runtime-benchmarks")]
use pallet_treasury::ArgumentsFactory;
use runtime_parachains::configuration::HostConfiguration;
Expand Down Expand Up @@ -1302,7 +1303,9 @@ impl pallet_beefy_mmr::Config for Runtime {

impl paras_sudo_wrapper::Config for Runtime {}

use pallet_pooled_staking::traits::{IsCandidateEligible, Timer};
use pallet_staking::SessionInterface;

pub struct DancelightSessionInterface;
impl SessionInterface<AccountId> for DancelightSessionInterface {
fn disable_validator(validator_index: u32) -> bool {
Expand Down Expand Up @@ -1634,10 +1637,97 @@ impl pallet_inflation_rewards::Config for Runtime {
type InflationRate = InflationRate;
type OnUnbalanced = OnUnbalancedInflation;
type PendingRewardsAccount = PendingRewardsAccount;
type StakingRewardsDistributor = InvulnerableRewardDistribution<Self, Balances, ()>;
type StakingRewardsDistributor = InvulnerableRewardDistribution<Self, Balances, PooledStaking>;
type RewardsPortion = RewardsPortion;
}

parameter_types! {
pub StakingAccount: AccountId32 = PalletId(*b"POOLSTAK").into_account_truncating();
pub const InitialManualClaimShareValue: u128 = MILLIUNITS;
pub const InitialAutoCompoundingShareValue: u128 = MILLIUNITS;
pub const MinimumSelfDelegation: u128 = 10_000 * UNITS;
pub const RewardsCollatorCommission: Perbill = Perbill::from_percent(20);
// Need to wait 2 sessions before being able to join or leave staking pools
pub const StakingSessionDelay: u32 = 2;
}

pub struct SessionTimer<G>(PhantomData<G>);
tmpolaczyk marked this conversation as resolved.
Show resolved Hide resolved

impl<G> Timer for SessionTimer<G>
where
G: Get<u32>,
{
type Instant = u32;

fn now() -> Self::Instant {
Session::current_index()
}

fn is_elapsed(instant: &Self::Instant) -> bool {
let delay = G::get();
let Some(end) = instant.checked_add(delay) else {
return false;
};
end <= Self::now()
}

#[cfg(feature = "runtime-benchmarks")]
fn elapsed_instant() -> Self::Instant {
let delay = G::get();
Self::now()
.checked_add(delay)
.expect("overflow when computing valid elapsed instant")
}

#[cfg(feature = "runtime-benchmarks")]
fn skip_to_elapsed() {
let session_to_reach = Self::elapsed_instant();
while Self::now() < session_to_reach {
Session::rotate_session();
}
}
}

pub struct CandidateHasRegisteredKeys;
impl IsCandidateEligible<AccountId> for CandidateHasRegisteredKeys {
fn is_candidate_eligible(a: &AccountId) -> bool {
<Session as ValidatorRegistration<AccountId>>::is_registered(a)
}
#[cfg(feature = "runtime-benchmarks")]
fn make_candidate_eligible(a: &AccountId, eligible: bool) {
use sp_core::crypto::UncheckedFrom;
if eligible {
let account_slice: &[u8; 32] = a.as_ref();
let _ = Session::set_keys(
RuntimeOrigin::signed(a.clone()),
SessionKeys {
nimbus: NimbusId::unchecked_from(*account_slice),
},
vec![],
);
} else {
let _ = Session::purge_keys(RuntimeOrigin::signed(a.clone()));
}
}
}

impl pallet_pooled_staking::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type Balance = Balance;
type StakingAccount = StakingAccount;
type InitialManualClaimShareValue = InitialManualClaimShareValue;
type InitialAutoCompoundingShareValue = InitialAutoCompoundingShareValue;
type MinimumSelfDelegation = MinimumSelfDelegation;
type RuntimeHoldReason = RuntimeHoldReason;
type RewardsCollatorCommission = RewardsCollatorCommission;
type JoiningRequestTimer = SessionTimer<StakingSessionDelay>;
type LeavingRequestTimer = SessionTimer<StakingSessionDelay>;
type EligibleCandidatesBufferSize = ConstU32<100>;
type EligibleCandidatesFilter = CandidateHasRegisteredKeys;
type WeightInfo = (); //weights::pallet_pooled_staking::SubstrateWeight<Runtime>;
}

construct_runtime! {
pub enum Runtime
{
Expand Down Expand Up @@ -1683,6 +1773,7 @@ construct_runtime! {

// InflationRewards must be after Session
InflationRewards: pallet_inflation_rewards = 33,
PooledStaking: pallet_pooled_staking = 34,

// Governance stuff; uncallable initially.
Treasury: pallet_treasury = 40,
Expand Down Expand Up @@ -2080,6 +2171,7 @@ mod benches {
[pallet_external_validators, ExternalValidators]
[pallet_external_validator_slashes, ExternalValidatorSlashes]
[pallet_invulnerables, TanssiInvulnerables]
[pallet_pooled_staking, PooledStaking]
// XCM
[pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
[pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::<Runtime>]
Expand Down Expand Up @@ -3007,8 +3099,27 @@ impl tanssi_initializer::ApplyNewSession<Runtime> for OwnApplySession {
ContainerRegistrar::initializer_on_new_session(&session_index);

let invulnerables = TanssiInvulnerables::invulnerables().to_vec();

let next_collators = invulnerables;
let candidates_staking =
pallet_pooled_staking::SortedEligibleCandidates::<Runtime>::get().to_vec();
// Max number of collators is set in pallet_configuration
let target_session_index = session_index.saturating_add(1);
let max_collators = <CollatorConfiguration as GetHostConfiguration<u32>>::max_collators(
target_session_index,
);
let next_collators: Vec<_> = invulnerables
.iter()
.cloned()
.chain(candidates_staking.into_iter().filter_map(|elig| {
let cand = elig.candidate;
if invulnerables.contains(&cand) {
tmpolaczyk marked this conversation as resolved.
Show resolved Hide resolved
// If a candidate is both in pallet_invulnerables and pallet_staking, do not count it twice
None
} else {
Some(cand)
}
}))
.take(max_collators as usize)
.collect();

// Queue next session keys.
let queued_amalgamated = next_collators
Expand Down
Loading