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

[Staking] Delegators can stake but stakers can't delegate #4904

Merged
merged 2 commits into from
Jul 3, 2024
Merged
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
4 changes: 0 additions & 4 deletions substrate/frame/delegated-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,10 +823,6 @@ impl<T: Config> Pallet<T> {
) -> Result<(), sp_runtime::TryRuntimeError> {
let mut delegation_aggregation = BTreeMap::<T::AccountId, BalanceOf<T>>::new();
for (delegator, delegation) in delegations.iter() {
ensure!(
T::CoreStaking::status(delegator).is_err(),
"delegator should not be directly staked"
);
ensure!(!Self::is_agent(delegator), "delegator cannot be an agent");

delegation_aggregation
Expand Down
43 changes: 41 additions & 2 deletions substrate/frame/delegated-staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::*;
use crate::mock::*;
use frame_support::{assert_noop, assert_ok, traits::fungible::InspectHold};
use pallet_nomination_pools::{Error as PoolsError, Event as PoolsEvent};
use pallet_staking::Error as StakingError;
use pallet_staking::{Error as StakingError, RewardDestination};
use sp_staking::{Agent, DelegationInterface, Delegator, StakerStatus};

#[test]
Expand Down Expand Up @@ -337,7 +337,6 @@ fn apply_pending_slash() {
/// Integration tests with pallet-staking.
mod staking_integration {
use super::*;
use pallet_staking::RewardDestination;
use sp_staking::Stake;

#[test]
Expand Down Expand Up @@ -1217,6 +1216,46 @@ mod pool_integration {
});
}

#[test]
fn existing_pool_member_can_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(|| {
start_era(1);
// GIVEN: a pool.
fund(&200, 1000);
let pool_id = create_pool(200, 800);

// WHEN: delegator joins a pool
let delegator = 100;
fund(&delegator, 1000);
assert_ok!(Pools::join(RawOrigin::Signed(delegator).into(), 200, pool_id));

// THEN: they can still stake directly.
assert_ok!(Staking::bond(
RuntimeOrigin::signed(delegator),
500,
RewardDestination::Account(101)
));
assert_ok!(Staking::nominate(
RuntimeOrigin::signed(delegator),
vec![GENESIS_VALIDATOR]
));

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

// 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));
});
}

fn create_pool(creator: AccountId, amount: Balance) -> u32 {
fund(&creator, amount * 2);
assert_ok!(Pools::create(
Expand Down
Loading