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

[stable2412] Backport #7685 #7738

Draft
wants to merge 1 commit into
base: stable2412
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 7 additions & 0 deletions polkadot/runtime/test-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,14 @@ impl pallet_staking::Config for Runtime {
type BenchmarkingConfig = polkadot_runtime_common::StakingBenchmarkingConfig;
type EventListeners = ();
type WeightInfo = ();
<<<<<<< HEAD
type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy;
=======
type MaxValidatorSet = MaxAuthorities;
type MaxInvulnerables = ConstU32<20>;
type MaxDisabledValidators = ConstU32<100>;
type Filter = frame_support::traits::Nothing;
>>>>>>> f7e98b40 ([Nomination Pool] Make staking restrictions configurable (#7685))
}

parameter_types! {
Expand Down
13 changes: 12 additions & 1 deletion polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use frame_support::{
traits::{
fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, Contains, EitherOf,
EitherOfDiverse, EnsureOriginWithArg, EverythingBut, FromContains, InstanceFilter,
KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, ProcessMessageError,
KeyOwnerProofSystem, LinearStoragePrice, Nothing, ProcessMessage, ProcessMessageError,
VariantCountOf, WithdrawReasons,
},
weights::{ConstantMultiplier, WeightMeter, WeightToFee as _},
Expand Down Expand Up @@ -755,7 +755,13 @@ impl pallet_staking::Config for Runtime {
type BenchmarkingConfig = polkadot_runtime_common::StakingBenchmarkingConfig;
type EventListeners = (NominationPools, DelegatedStaking);
type WeightInfo = weights::pallet_staking::WeightInfo<Runtime>;
<<<<<<< HEAD
type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy;
=======
type MaxInvulnerables = frame_support::traits::ConstU32<20>;
type MaxDisabledValidators = ConstU32<100>;
type Filter = Nothing;
>>>>>>> f7e98b40 ([Nomination Pool] Make staking restrictions configurable (#7685))
}

impl pallet_fast_unstake::Config for Runtime {
Expand Down Expand Up @@ -1516,6 +1522,11 @@ impl pallet_nomination_pools::Config for Runtime {
type PalletId = PoolsPalletId;
type MaxPointsToBalance = MaxPointsToBalance;
type AdminOrigin = EitherOf<EnsureRoot<AccountId>, StakingAdmin>;
<<<<<<< HEAD
=======
type BlockNumberProvider = System;
type Filter = Nothing;
>>>>>>> f7e98b40 ([Nomination Pool] Make staking restrictions configurable (#7685))
}

parameter_types! {
Expand Down
20 changes: 20 additions & 0 deletions prdoc/pr_7685.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
title: 'Introduce filters to restrict accounts from staking'

doc:
- audience: Runtime Dev
description: |
Introduce filters to restrict accounts from staking.
This is useful for restricting certain accounts from staking, for example, accounts staking via pools, and vice
versa.

crates:
- name: pallet-staking
bump: minor
- name: pallet-nomination-pools
bump: minor
- name: westend-runtime
bump: patch
- name: pallet-delegated-staking
bump: patch
- name: pallet-nomination-pools-benchmarking
bump: patch
11 changes: 11 additions & 0 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,13 @@ impl pallet_staking::Config for Runtime {
type EventListeners = NominationPools;
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
type BenchmarkingConfig = StakingBenchmarkingConfig;
<<<<<<< HEAD
type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy;
=======
type MaxInvulnerables = ConstU32<20>;
type MaxDisabledValidators = ConstU32<100>;
type Filter = Nothing;
>>>>>>> f7e98b40 ([Nomination Pool] Make staking restrictions configurable (#7685))
}

impl pallet_fast_unstake::Config for Runtime {
Expand Down Expand Up @@ -960,6 +966,11 @@ impl pallet_nomination_pools::Config for Runtime {
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 4>,
>;
<<<<<<< HEAD
=======
type BlockNumberProvider = System;
type Filter = Nothing;
>>>>>>> f7e98b40 ([Nomination Pool] Make staking restrictions configurable (#7685))
}

parameter_types! {
Expand Down
10 changes: 0 additions & 10 deletions substrate/frame/delegated-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,6 @@ pub mod pallet {
// Existing `agent` cannot register again and a delegator cannot become an `agent`.
ensure!(!Self::is_agent(&who) && !Self::is_delegator(&who), Error::<T>::NotAllowed);

// They cannot be already a direct staker in the staking pallet.
ensure!(!Self::is_direct_staker(&who), Error::<T>::AlreadyStaking);

// Reward account cannot be same as `agent` account.
ensure!(reward_account != who, Error::<T>::InvalidRewardDestination);

Expand Down Expand Up @@ -407,7 +404,6 @@ pub mod pallet {
// Ensure delegator is sane.
ensure!(!Self::is_agent(&delegator), Error::<T>::NotAllowed);
ensure!(!Self::is_delegator(&delegator), Error::<T>::NotAllowed);
ensure!(!Self::is_direct_staker(&delegator), Error::<T>::AlreadyStaking);

// ensure agent is sane.
ensure!(Self::is_agent(&agent), Error::<T>::NotAgent);
Expand Down Expand Up @@ -442,12 +438,6 @@ pub mod pallet {
Error::<T>::InvalidDelegation
);

// Implementation note: Staking uses deprecated locks (similar to freeze) which are not
// mutually exclusive of holds. This means, if we allow delegating for existing stakers,
// already staked funds might be reused for delegation. We avoid that by just blocking
// this.
ensure!(!Self::is_direct_staker(&delegator), Error::<T>::AlreadyStaking);

// ensure agent is sane.
ensure!(Self::is_agent(&agent), Error::<T>::NotAgent);

Expand Down
6 changes: 6 additions & 0 deletions substrate/frame/delegated-staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ impl pallet_staking::Config for Runtime {
type VoterList = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
type TargetList = pallet_staking::UseValidatorsMap<Self>;
type EventListeners = (Pools, DelegatedStaking);
type Filter = pallet_nomination_pools::AllPoolMembers<Self>;
}

parameter_types! {
Expand Down Expand Up @@ -160,6 +161,11 @@ impl pallet_nomination_pools::Config for Runtime {
type StakeAdapter =
pallet_nomination_pools::adapter::DelegateStake<Self, Staking, DelegatedStaking>;
type AdminOrigin = frame_system::EnsureRoot<Self::AccountId>;
<<<<<<< HEAD
=======
type BlockNumberProvider = System;
type Filter = pallet_staking::AllStakers<Runtime>;
>>>>>>> f7e98b40 ([Nomination Pool] Make staking restrictions configurable (#7685))
}

frame_support::construct_runtime!(
Expand Down
83 changes: 30 additions & 53 deletions substrate/frame/delegated-staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,31 +65,6 @@ fn cannot_become_agent() {
DelegatedStaking::register_agent(RawOrigin::Signed(100).into(), 100),
Error::<T>::InvalidRewardDestination
);

// an existing validator cannot become agent
assert_noop!(
DelegatedStaking::register_agent(
RawOrigin::Signed(mock::GENESIS_VALIDATOR).into(),
100
),
Error::<T>::AlreadyStaking
);

// an existing direct staker to `CoreStaking` cannot become an agent.
assert_noop!(
DelegatedStaking::register_agent(
RawOrigin::Signed(mock::GENESIS_NOMINATOR_ONE).into(),
100
),
Error::<T>::AlreadyStaking
);
assert_noop!(
DelegatedStaking::register_agent(
RawOrigin::Signed(mock::GENESIS_NOMINATOR_TWO).into(),
100
),
Error::<T>::AlreadyStaking
);
});
}

Expand Down Expand Up @@ -637,18 +612,6 @@ mod staking_integration {
DelegatedStaking::register_agent(RawOrigin::Signed(202).into(), 203),
Error::<T>::NotAllowed
);
// existing staker cannot become a delegate
assert_noop!(
DelegatedStaking::register_agent(
RawOrigin::Signed(GENESIS_NOMINATOR_ONE).into(),
201
),
Error::<T>::AlreadyStaking
);
assert_noop!(
DelegatedStaking::register_agent(RawOrigin::Signed(GENESIS_VALIDATOR).into(), 201),
Error::<T>::AlreadyStaking
);
});
}

Expand Down Expand Up @@ -1361,7 +1324,7 @@ mod pool_integration {
}

#[test]
fn existing_pool_member_can_stake() {
fn existing_pool_member_cannot_stake() {
// A pool member is able to stake directly since staking only uses free funds but once a
// staker, they cannot join/add extra bond to the pool. They can still withdraw funds.
ExtBuilder::default().build_and_execute(|| {
Expand All @@ -1375,28 +1338,42 @@ mod pool_integration {
fund(&delegator, 1000);
assert_ok!(Pools::join(RawOrigin::Signed(delegator).into(), 200, pool_id));

// THEN: they can still stake directly.
// THEN: they cannot stake anymore
assert_noop!(
Staking::bond(
RuntimeOrigin::signed(delegator),
500,
RewardDestination::Account(101)
),
StakingError::<T>::Restricted
);
});
}

#[test]
fn stakers_cannot_join_pool() {
ExtBuilder::default().build_and_execute(|| {
start_era(1);
// GIVEN: a pool.
fund(&200, 1000);
let pool_id = create_pool(200, 800);

// WHEN: an account is a staker.
let staker = 100;
fund(&staker, 1000);

assert_ok!(Staking::bond(
RuntimeOrigin::signed(delegator),
RuntimeOrigin::signed(staker),
500,
RewardDestination::Account(101)
));
assert_ok!(Staking::nominate(
RuntimeOrigin::signed(delegator),
vec![GENESIS_VALIDATOR]
));
assert_ok!(Staking::nominate(RuntimeOrigin::signed(staker), vec![GENESIS_VALIDATOR]));

// The delegator cannot add any extra bond to the pool anymore.
// THEN: they cannot join pool.
assert_noop!(
Pools::bond_extra(RawOrigin::Signed(delegator).into(), BondExtra::FreeBalance(100)),
Error::<T>::AlreadyStaking
Pools::join(RawOrigin::Signed(staker).into(), 200, pool_id),
PoolsError::<T>::Restricted
);

// But they can unbond
assert_ok!(Pools::unbond(RawOrigin::Signed(delegator).into(), delegator, 50));
// and withdraw
start_era(4);
assert_ok!(Pools::withdraw_unbonded(RawOrigin::Signed(delegator).into(), delegator, 0));
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ use pallet_staking::StakerStatus;
use parking_lot::RwLock;
use std::sync::Arc;

use frame_support::derive_impl;

use crate::{log, log_current_time};
use frame_support::{derive_impl, traits::Nothing};

pub const INIT_TIMESTAMP: BlockNumber = 30_000;
pub const BLOCK_TIME: BlockNumber = 1000;
Expand Down Expand Up @@ -272,6 +271,26 @@ impl pallet_nomination_pools::Config for Runtime {
type MaxUnbonding = MaxUnbonding;
type MaxPointsToBalance = frame_support::traits::ConstU8<10>;
type AdminOrigin = frame_system::EnsureRoot<Self::AccountId>;
<<<<<<< HEAD
=======
type BlockNumberProvider = System;
type Filter = Nothing;
}

parameter_types! {
pub const DelegatedStakingPalletId: PalletId = PalletId(*b"py/dlstk");
pub const SlashRewardFraction: Perbill = Perbill::from_percent(1);
}

impl pallet_delegated_staking::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type PalletId = DelegatedStakingPalletId;
type Currency = Balances;
type OnSlash = ();
type SlashRewardFraction = SlashRewardFraction;
type RuntimeHoldReason = RuntimeHoldReason;
type CoreStaking = Staking;
>>>>>>> f7e98b40 ([Nomination Pool] Make staking restrictions configurable (#7685))
}

parameter_types! {
Expand Down
7 changes: 6 additions & 1 deletion substrate/frame/nomination-pools/benchmarking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use frame_support::{
derive_impl,
pallet_prelude::*,
parameter_types,
traits::{ConstU64, VariantCountOf},
traits::{ConstU64, Nothing, VariantCountOf},
PalletId,
};
use sp_runtime::{
Expand Down Expand Up @@ -139,6 +139,11 @@ impl pallet_nomination_pools::Config for Runtime {
type PalletId = PoolsPalletId;
type MaxPointsToBalance = MaxPointsToBalance;
type AdminOrigin = frame_system::EnsureRoot<Self::AccountId>;
<<<<<<< HEAD
=======
type BlockNumberProvider = System;
type Filter = Nothing;
>>>>>>> f7e98b40 ([Nomination Pool] Make staking restrictions configurable (#7685))
}

parameter_types! {
Expand Down
Loading
Loading