mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 16:57:58 +00:00
[Feature] Add deposit to fast-unstake (#12366)
* [Feature] Add deposit to fast-unstake * disable on ErasToCheckPerBlock == 0 * removed signed ext * remove obsolete import * remove some obsolete stuff * fix some comments * fixed all the comments * remove obsolete imports * fix some tests * CallNotAllowed tests * Update frame/fast-unstake/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * fix tests * fix deregister + tests * more fixes * make sure we go above existential deposit * fixed the last test * some nit fixes * fix node * fix bench * last bench fix * Update frame/fast-unstake/src/lib.rs * ".git/.scripts/fmt.sh" 1 Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: command-bot <>
This commit is contained in:
@@ -35,6 +35,7 @@ fn test_setup_works() {
|
||||
#[test]
|
||||
fn register_works() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
// Controller account registers for fast unstake.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
// Ensure stash is in the queue.
|
||||
@@ -42,9 +43,38 @@ fn register_works() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_insufficient_funds_fails() {
|
||||
use pallet_balances::Error as BalancesError;
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
<T as Config>::DepositCurrency::make_free_balance_be(&1, 3);
|
||||
|
||||
// Controller account registers for fast unstake.
|
||||
assert_noop!(
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)),
|
||||
BalancesError::<T, _>::InsufficientBalance,
|
||||
);
|
||||
|
||||
// Ensure stash is in the queue.
|
||||
assert_eq!(Queue::<T>::get(1), None);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_disabled_fails() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
assert_noop!(
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)),
|
||||
Error::<T>::CallNotAllowed
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_register_if_not_bonded() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
// Mint accounts 1 and 2 with 200 tokens.
|
||||
for _ in 1..2 {
|
||||
let _ = Balances::make_free_balance_be(&1, 200);
|
||||
@@ -60,8 +90,9 @@ fn cannot_register_if_not_bonded() {
|
||||
#[test]
|
||||
fn cannot_register_if_in_queue() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
// Insert some Queue item
|
||||
Queue::<T>::insert(1, ());
|
||||
Queue::<T>::insert(1, 10);
|
||||
// Cannot re-register, already in queue
|
||||
assert_noop!(
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)),
|
||||
@@ -73,8 +104,13 @@ fn cannot_register_if_in_queue() {
|
||||
#[test]
|
||||
fn cannot_register_if_head() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
// Insert some Head item for stash
|
||||
Head::<T>::put(UnstakeRequest { stash: 1, checked: bounded_vec![] });
|
||||
Head::<T>::put(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![],
|
||||
deposit: DepositAmount::get(),
|
||||
});
|
||||
// Controller attempts to regsiter
|
||||
assert_noop!(
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)),
|
||||
@@ -86,6 +122,7 @@ fn cannot_register_if_head() {
|
||||
#[test]
|
||||
fn cannot_register_if_has_unlocking_chunks() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
// Start unbonding half of staked tokens
|
||||
assert_ok!(Staking::unbond(RuntimeOrigin::signed(2), 50_u128));
|
||||
// Cannot register for fast unstake with unlock chunks active
|
||||
@@ -99,18 +136,37 @@ fn cannot_register_if_has_unlocking_chunks() {
|
||||
#[test]
|
||||
fn deregister_works() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
|
||||
assert_eq!(<T as Config>::DepositCurrency::reserved_balance(&1), 0);
|
||||
|
||||
// Controller account registers for fast unstake.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(<T as Config>::DepositCurrency::reserved_balance(&1), DepositAmount::get());
|
||||
|
||||
// Controller then changes mind and deregisters.
|
||||
assert_ok!(FastUnstake::deregister(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(<T as Config>::DepositCurrency::reserved_balance(&1), 0);
|
||||
|
||||
// Ensure stash no longer exists in the queue.
|
||||
assert_eq!(Queue::<T>::get(1), None);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deregister_disabled_fails() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
ErasToCheckPerBlock::<T>::put(0);
|
||||
assert_noop!(FastUnstake::deregister(RuntimeOrigin::signed(2)), Error::<T>::CallNotAllowed);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cannot_deregister_if_not_controller() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
// Controller account registers for fast unstake.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
// Stash tries to deregister.
|
||||
@@ -121,6 +177,7 @@ fn cannot_deregister_if_not_controller() {
|
||||
#[test]
|
||||
fn cannot_deregister_if_not_queued() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
// Controller tries to deregister without first registering
|
||||
assert_noop!(FastUnstake::deregister(RuntimeOrigin::signed(2)), Error::<T>::NotQueued);
|
||||
});
|
||||
@@ -129,10 +186,15 @@ fn cannot_deregister_if_not_queued() {
|
||||
#[test]
|
||||
fn cannot_deregister_already_head() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
// Controller attempts to register, should fail
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
// Insert some Head item for stash.
|
||||
Head::<T>::put(UnstakeRequest { stash: 1, checked: bounded_vec![] });
|
||||
Head::<T>::put(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![],
|
||||
deposit: DepositAmount::get(),
|
||||
});
|
||||
// Controller attempts to deregister
|
||||
assert_noop!(FastUnstake::deregister(RuntimeOrigin::signed(2)), Error::<T>::AlreadyHead);
|
||||
});
|
||||
@@ -165,14 +227,14 @@ mod on_idle {
|
||||
|
||||
// set up Queue item
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_eq!(Queue::<T>::get(1), Some(DepositAmount::get()));
|
||||
|
||||
// call on_idle with no remaining weight
|
||||
FastUnstake::on_idle(System::block_number(), Weight::from_ref_time(0));
|
||||
|
||||
// assert nothing changed in Queue and Head
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_eq!(Queue::<T>::get(1), Some(DepositAmount::get()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -185,7 +247,7 @@ mod on_idle {
|
||||
|
||||
// given
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_eq!(Queue::<T>::get(1), Some(DepositAmount::get()));
|
||||
|
||||
assert_eq!(Queue::<T>::count(), 1);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
@@ -204,7 +266,11 @@ mod on_idle {
|
||||
);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3]
|
||||
})
|
||||
);
|
||||
|
||||
// when: another 1 era.
|
||||
@@ -220,7 +286,11 @@ mod on_idle {
|
||||
);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2]
|
||||
})
|
||||
);
|
||||
|
||||
// when: then 5 eras, we only need 2 more.
|
||||
@@ -242,7 +312,11 @@ mod on_idle {
|
||||
);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
})
|
||||
);
|
||||
|
||||
// when: not enough weight to unstake:
|
||||
@@ -254,7 +328,11 @@ mod on_idle {
|
||||
assert_eq!(fast_unstake_events_since_last_call(), vec![]);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
})
|
||||
);
|
||||
|
||||
// when: enough weight to get over at least one iteration: then we are unblocked and can
|
||||
@@ -285,12 +363,16 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// given
|
||||
assert_eq!(<T as Config>::DepositCurrency::reserved_balance(&1), 0);
|
||||
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(4)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(6)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(8)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(10)));
|
||||
|
||||
assert_eq!(<T as Config>::DepositCurrency::reserved_balance(&1), DepositAmount::get());
|
||||
|
||||
assert_eq!(Queue::<T>::count(), 5);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
|
||||
@@ -300,7 +382,11 @@ mod on_idle {
|
||||
// then
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
})
|
||||
);
|
||||
assert_eq!(Queue::<T>::count(), 4);
|
||||
|
||||
@@ -317,10 +403,16 @@ mod on_idle {
|
||||
// then
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 5, checked: bounded_vec![3, 2, 1, 0] }),
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 5,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
}),
|
||||
);
|
||||
assert_eq!(Queue::<T>::count(), 3);
|
||||
|
||||
assert_eq!(<T as Config>::DepositCurrency::reserved_balance(&1), 0);
|
||||
|
||||
assert_eq!(
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![
|
||||
@@ -340,9 +432,9 @@ mod on_idle {
|
||||
|
||||
// register multi accounts for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_eq!(Queue::<T>::get(1), Some(DepositAmount::get()));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(4)));
|
||||
assert_eq!(Queue::<T>::get(3), Some(()));
|
||||
assert_eq!(Queue::<T>::get(3), Some(DepositAmount::get()));
|
||||
|
||||
// assert 2 queue items are in Queue & None in Head to start with
|
||||
assert_eq!(Queue::<T>::count(), 2);
|
||||
@@ -391,7 +483,7 @@ mod on_idle {
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_eq!(Queue::<T>::get(1), Some(DepositAmount::get()));
|
||||
|
||||
// process on idle
|
||||
next_block(true);
|
||||
@@ -402,7 +494,11 @@ mod on_idle {
|
||||
// assert head item present
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
@@ -425,9 +521,11 @@ mod on_idle {
|
||||
ErasToCheckPerBlock::<T>::put(BondingDuration::get() + 1);
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
Balances::make_free_balance_be(&2, 100);
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_eq!(Queue::<T>::get(1), Some(DepositAmount::get()));
|
||||
|
||||
// process on idle
|
||||
next_block(true);
|
||||
@@ -438,7 +536,11 @@ mod on_idle {
|
||||
// assert head item present
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
@@ -464,7 +566,7 @@ mod on_idle {
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_eq!(Queue::<T>::get(1), Some(DepositAmount::get()));
|
||||
|
||||
// process on idle
|
||||
next_block(true);
|
||||
@@ -475,28 +577,44 @@ mod on_idle {
|
||||
// assert head item present
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
@@ -529,30 +647,46 @@ mod on_idle {
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_eq!(Queue::<T>::get(1), Some(DepositAmount::get()));
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
})
|
||||
);
|
||||
|
||||
// when: a new era happens right before one is free.
|
||||
@@ -567,6 +701,7 @@ mod on_idle {
|
||||
stash: 1,
|
||||
// note era 0 is pruned to keep the vector length sane.
|
||||
checked: bounded_vec![3, 2, 1, 4],
|
||||
deposit: DepositAmount::get(),
|
||||
})
|
||||
);
|
||||
|
||||
@@ -602,13 +737,21 @@ mod on_idle {
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2]
|
||||
})
|
||||
);
|
||||
|
||||
// when
|
||||
@@ -618,13 +761,21 @@ mod on_idle {
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2]
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2]
|
||||
})
|
||||
);
|
||||
|
||||
// then we register a new era.
|
||||
@@ -636,14 +787,22 @@ mod on_idle {
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 4] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 4]
|
||||
})
|
||||
);
|
||||
|
||||
// progress to end
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 4, 1] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 4, 1]
|
||||
})
|
||||
);
|
||||
|
||||
// but notice that we don't care about era 0 instead anymore! we're done.
|
||||
@@ -669,7 +828,6 @@ mod on_idle {
|
||||
fn exposed_nominator_cannot_unstake() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
SlashPerEra::set(7);
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// create an exposed nominator in era 1
|
||||
@@ -686,6 +844,7 @@ mod on_idle {
|
||||
));
|
||||
assert_ok!(Staking::nominate(RuntimeOrigin::signed(exposed), vec![exposed]));
|
||||
|
||||
Balances::make_free_balance_be(&exposed, 100_000);
|
||||
// register the exposed one.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(exposed)));
|
||||
|
||||
@@ -693,23 +852,30 @@ mod on_idle {
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: exposed, checked: bounded_vec![3] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: exposed,
|
||||
checked: bounded_vec![3]
|
||||
})
|
||||
);
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: exposed, checked: bounded_vec![3, 2] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: exposed,
|
||||
checked: bounded_vec![3, 2]
|
||||
})
|
||||
);
|
||||
next_block(true);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
|
||||
assert_eq!(
|
||||
fast_unstake_events_since_last_call(),
|
||||
// we slash them by 21, since we checked 3 eras in total (3, 2, 1).
|
||||
vec![
|
||||
Event::Checking { stash: exposed, eras: vec![3] },
|
||||
Event::Checking { stash: exposed, eras: vec![2] },
|
||||
Event::Slashed { stash: exposed, amount: 3 * 7 }
|
||||
Event::Slashed { stash: exposed, amount: DepositAmount::get() }
|
||||
]
|
||||
);
|
||||
});
|
||||
@@ -721,7 +887,6 @@ mod on_idle {
|
||||
// same as the previous check, but we check 2 eras per block, and we make the exposed be
|
||||
// exposed in era 0, so that it is detected halfway in a check era.
|
||||
ErasToCheckPerBlock::<T>::put(2);
|
||||
SlashPerEra::set(7);
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// create an exposed nominator in era 1
|
||||
@@ -729,7 +894,7 @@ mod on_idle {
|
||||
pallet_staking::ErasStakers::<T>::mutate(0, VALIDATORS_PER_ERA, |expo| {
|
||||
expo.others.push(IndividualExposure { who: exposed, value: 0 as Balance });
|
||||
});
|
||||
Balances::make_free_balance_be(&exposed, 100);
|
||||
Balances::make_free_balance_be(&exposed, DepositAmount::get() + 100);
|
||||
assert_ok!(Staking::bond(
|
||||
RuntimeOrigin::signed(exposed),
|
||||
exposed,
|
||||
@@ -745,17 +910,21 @@ mod on_idle {
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: exposed, checked: bounded_vec![3, 2] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: exposed,
|
||||
checked: bounded_vec![3, 2]
|
||||
})
|
||||
);
|
||||
next_block(true);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
|
||||
assert_eq!(
|
||||
fast_unstake_events_since_last_call(),
|
||||
// we slash them by 28, since we checked 4 eras in total.
|
||||
// we slash them
|
||||
vec![
|
||||
Event::Checking { stash: exposed, eras: vec![3, 2] },
|
||||
Event::Slashed { stash: exposed, amount: 4 * 7 }
|
||||
Event::Slashed { stash: exposed, amount: DepositAmount::get() }
|
||||
]
|
||||
);
|
||||
});
|
||||
@@ -786,7 +955,7 @@ mod on_idle {
|
||||
|
||||
assert_eq!(
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![Event::Slashed { stash: 100, amount: 100 }]
|
||||
vec![Event::Slashed { stash: 100, amount: DepositAmount::get() }]
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -798,7 +967,7 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// create a new validator that 100% not exposed.
|
||||
Balances::make_free_balance_be(&42, 100);
|
||||
Balances::make_free_balance_be(&42, 100 + DepositAmount::get());
|
||||
assert_ok!(Staking::bond(RuntimeOrigin::signed(42), 42, 10, RewardDestination::Staked));
|
||||
assert_ok!(Staking::validate(RuntimeOrigin::signed(42), Default::default()));
|
||||
|
||||
@@ -809,7 +978,11 @@ mod on_idle {
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 42, checked: bounded_vec![3, 2, 1, 0] })
|
||||
Some(UnstakeRequest {
|
||||
deposit: DepositAmount::get(),
|
||||
stash: 42,
|
||||
checked: bounded_vec![3, 2, 1, 0]
|
||||
})
|
||||
);
|
||||
next_block(true);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
@@ -824,69 +997,3 @@ mod on_idle {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
mod signed_extension {
|
||||
use super::*;
|
||||
use sp_runtime::traits::SignedExtension;
|
||||
|
||||
const STAKING_CALL: crate::mock::RuntimeCall =
|
||||
crate::mock::RuntimeCall::Staking(pallet_staking::Call::<T>::chill {});
|
||||
|
||||
#[test]
|
||||
fn does_nothing_if_not_queued() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
assert!(PreventStakingOpsIfUnbonding::<T>::new()
|
||||
.pre_dispatch(&1, &STAKING_CALL, &Default::default(), Default::default())
|
||||
.is_ok());
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prevents_queued() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given: stash for 2 is 1.
|
||||
// when
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
|
||||
// then
|
||||
// stash can't.
|
||||
assert!(PreventStakingOpsIfUnbonding::<T>::new()
|
||||
.pre_dispatch(&1, &STAKING_CALL, &Default::default(), Default::default())
|
||||
.is_err());
|
||||
|
||||
// controller can't.
|
||||
assert!(PreventStakingOpsIfUnbonding::<T>::new()
|
||||
.pre_dispatch(&2, &STAKING_CALL, &Default::default(), Default::default())
|
||||
.is_err());
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prevents_head_stash() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given: stash for 2 is 1.
|
||||
// when
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
next_block(true);
|
||||
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
);
|
||||
|
||||
// then
|
||||
// stash can't
|
||||
assert!(PreventStakingOpsIfUnbonding::<T>::new()
|
||||
.pre_dispatch(&2, &STAKING_CALL, &Default::default(), Default::default())
|
||||
.is_err());
|
||||
|
||||
// controller can't
|
||||
assert!(PreventStakingOpsIfUnbonding::<T>::new()
|
||||
.pre_dispatch(&1, &STAKING_CALL, &Default::default(), Default::default())
|
||||
.is_err());
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user