Skip to content

Commit

Permalink
No unbonding when signer or next signer
Browse files Browse the repository at this point in the history
  • Loading branch information
JesseAbram committed Aug 26, 2024
1 parent 084a2b6 commit a3f6c12
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
63 changes: 59 additions & 4 deletions pallets/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ pub mod pallet {
NotNextSigner,
ReshareNotInProgress,
AlreadyConfirmed,
NoUnbodingWhenSigner,
NoUnbodingWhenNextSigner,
}

#[pallet::event]
Expand Down Expand Up @@ -397,9 +399,56 @@ pub mod pallet {
Ok(())
}

/// Wraps's substrate withdraw unbonded but clears extra state if fully unbonded
#[pallet::call_index(2)]
#[pallet::weight(<T as Config>::WeightInfo::withdraw_unbonded())]
pub fn unbonded(
origin: OriginFor<T>,
#[pallet::compact] value: BalanceOf<T>,
) -> DispatchResultWithPostInfo {
let controller = ensure_signed(origin.clone())?;
let ledger =
pallet_staking::Pallet::<T>::ledger(StakingAccount::Controller(controller.clone()))
.map_err(|_| Error::<T>::NoThresholdKey)?;

let validator_id = <T as pallet_session::Config>::ValidatorId::try_from(ledger.stash)
.or(Err(Error::<T>::InvalidValidatorId))?;

ensure!(!Self::signers().contains(&validator_id), Error::<T>::NoUnbodingWhenSigner);
ensure!(
!Self::next_signers().unwrap().next_signers.contains(&validator_id),
Error::<T>::NoUnbodingWhenNextSigner
);

pallet_staking::Pallet::<T>::unbond(origin, value)?;

Ok(().into())
}

#[pallet::call_index(3)]
#[pallet::weight(<T as Config>::WeightInfo::withdraw_unbonded())]
pub fn chill(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
let controller = ensure_signed(origin.clone())?;
let ledger =
pallet_staking::Pallet::<T>::ledger(StakingAccount::Controller(controller.clone()))
.map_err(|_| Error::<T>::NoThresholdKey)?;

let validator_id = <T as pallet_session::Config>::ValidatorId::try_from(ledger.stash)
.or(Err(Error::<T>::InvalidValidatorId))?;

ensure!(!Self::signers().contains(&validator_id), Error::<T>::NoUnbodingWhenSigner);
ensure!(
!Self::next_signers().unwrap().next_signers.contains(&validator_id),
Error::<T>::NoUnbodingWhenNextSigner
);

pallet_staking::Pallet::<T>::chill(origin)?;

Ok(().into())
}

/// Wraps's substrate withdraw unbonded but clears extra state if fully unbonded
#[pallet::call_index(4)]
#[pallet::weight(<T as Config>::WeightInfo::withdraw_unbonded())]
pub fn withdraw_unbonded(
origin: OriginFor<T>,
num_slashing_spans: u32,
Expand All @@ -412,6 +461,12 @@ pub mod pallet {
let validator_id = <T as pallet_session::Config>::ValidatorId::try_from(ledger.stash)
.or(Err(Error::<T>::InvalidValidatorId))?;

ensure!(!Self::signers().contains(&validator_id), Error::<T>::NoUnbodingWhenSigner);
ensure!(
!Self::next_signers().unwrap().next_signers.contains(&validator_id),
Error::<T>::NoUnbodingWhenNextSigner
);

pallet_staking::Pallet::<T>::withdraw_unbonded(origin, num_slashing_spans)?;
// TODO: do not allow unbonding of validator if not enough validators https://github.com/entropyxyz/entropy-core/issues/942
if pallet_staking::Pallet::<T>::bonded(&controller).is_none() {
Expand All @@ -429,7 +484,7 @@ pub mod pallet {
///
/// Note that - just like the original `validate()` extrinsic - the effects of this are
/// only applied in the following era.
#[pallet::call_index(3)]
#[pallet::call_index(5)]
#[pallet::weight(<T as Config>::WeightInfo::validate())]
pub fn validate(
origin: OriginFor<T>,
Expand Down Expand Up @@ -468,7 +523,7 @@ pub mod pallet {

/// Let a validator declare if their kvdb is synced or not synced
/// `synced`: State of validator's kvdb
#[pallet::call_index(4)]
#[pallet::call_index(6)]
#[pallet::weight(<T as Config>::WeightInfo::declare_synced())]
pub fn declare_synced(origin: OriginFor<T>, synced: bool) -> DispatchResult {
let who = ensure_signed(origin.clone())?;
Expand All @@ -478,7 +533,7 @@ pub mod pallet {
Ok(())
}

#[pallet::call_index(5)]
#[pallet::call_index(7)]
#[pallet::weight(({
<T as Config>::WeightInfo::confirm_key_reshare_confirmed(MAX_SIGNERS as u32)
.max(<T as Config>::WeightInfo::confirm_key_reshare_completed())
Expand Down
2 changes: 1 addition & 1 deletion pallets/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ impl pallet_parameters::Config for Test {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
let pallet_balances = pallet_balances::GenesisConfig::<Test> {
balances: vec![(1, 100), (2, 100), (3, 100), (4, 100)],
balances: vec![(1, 100), (2, 100), (3, 100), (4, 100), (7, 100), (8, 100)],
};
let pallet_staking_extension = pallet_staking_extension::GenesisConfig::<Test> {
// (ValidatorID, (AccountId, X25519PublicKey, TssServerURL))
Expand Down
26 changes: 26 additions & 0 deletions pallets/staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ fn it_will_not_allow_existing_tss_account_when_changing_threshold_account() {
fn it_deletes_when_no_bond_left() {
new_test_ext().execute_with(|| {
Signers::<Test>::put(vec![5, 6]);
NextSigners::<Test>::put(NextSignerInfo {
next_signers: vec![7, 8],
confirmations: vec![],
});
start_active_era(1);
assert_ok!(FrameStaking::bond(
RuntimeOrigin::signed(2),
Expand Down Expand Up @@ -311,6 +315,28 @@ fn it_deletes_when_no_bond_left() {
assert_eq!(Staking::threshold_to_stash(3), None);
// validator no longer synced
assert_eq!(Staking::is_validator_synced(2), false);

assert_ok!(FrameStaking::bond(
RuntimeOrigin::signed(7),
100u64,
pallet_staking::RewardDestination::Account(1),
));

assert_noop!(
Staking::withdraw_unbonded(RuntimeOrigin::signed(7), 0),
Error::<Test>::NoUnbodingWhenNextSigner
);

assert_ok!(FrameStaking::bond(
RuntimeOrigin::signed(8),
100u64,
pallet_staking::RewardDestination::Account(1),
));

assert_noop!(
Staking::withdraw_unbonded(RuntimeOrigin::signed(8), 0),
Error::<Test>::NoUnbodingWhenNextSigner
);
});
}

Expand Down
2 changes: 2 additions & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ impl Contains<RuntimeCall> for BaseCallFilter {
call,
RuntimeCall::Staking(pallet_staking::Call::withdraw_unbonded { .. })
| RuntimeCall::Staking(pallet_staking::Call::validate { .. })
| RuntimeCall::Staking(pallet_staking::Call::unbond { .. })
| RuntimeCall::Staking(pallet_staking::Call::chill { .. })
);
if is_paused || system_reject {
// no paused call
Expand Down

0 comments on commit a3f6c12

Please sign in to comment.