Skip to content

Commit

Permalink
Add set_cmix_id extrinsic to Staking pallet
Browse files Browse the repository at this point in the history
  • Loading branch information
bernardo-xxnet committed Dec 16, 2021
1 parent 10bd140 commit e3677d7
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
41 changes: 41 additions & 0 deletions frame/staking/src/pallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,8 @@ pub mod pallet {
ValidatorMustHaveCmixId,
/// Validator commission is too low
ValidatorCommissionTooLow,
/// Stash account already has a CMIX ID
StashAlreadyHasCmixId,
}

#[pallet::hooks]
Expand Down Expand Up @@ -1608,6 +1610,45 @@ pub mod pallet {
Self::chill_stash(&stash);
Ok(())
}

/// Set the CMIX ID of a stash, if it doesn't have one already.
///
/// The dispatch origin for this call must be _Signed_ by the stash, not the controller.
///
/// # <weight>
/// - Independent of the arguments. Insignificant complexity.
/// ----------
/// Weight: O(1)
/// DB Weight:
/// - Read: Bonded, Ledger
/// - Write: Ledger
/// # </weight>
#[pallet::weight(T::WeightInfo::set_cmix_id())]
pub fn set_cmix_id(
origin: OriginFor<T>,
cmix_id: T::Hash,
) -> DispatchResult {
let stash = ensure_signed(origin)?;
let controller = Self::bonded(&stash).ok_or(Error::<T>::NotStash)?;

let mut ledger = <Ledger<T>>::get(&controller).ok_or(Error::<T>::NotController)?;

// Ensure cmix id is not set
if ledger.cmix_id.is_some() {
Err(Error::<T>::StashAlreadyHasCmixId)?
}

// Ensure cmix id is unique
if <CmixIds<T>>::contains_key(&cmix_id) {
Err(Error::<T>::ValidatorCmixIdNotUnique)?
}

// Set cmix id and write ledger
<CmixIds<T>>::insert(&cmix_id, ());
ledger.cmix_id = Some(cmix_id);
<Ledger<T>>::insert(&controller, &ledger);
Ok(())
}
}
}

Expand Down
11 changes: 11 additions & 0 deletions frame/staking/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub trait WeightInfo {
fn get_npos_targets(v: u32, ) -> Weight;
fn set_staking_limits() -> Weight;
fn chill_other() -> Weight;
fn set_cmix_id() -> Weight;
}

/// Weights for pallet_staking using the Substrate node and recommended hardware.
Expand Down Expand Up @@ -442,6 +443,11 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
.saturating_add(T::DbWeight::get().reads(11 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
fn set_cmix_id() -> Weight {
(83_389_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
}

// For backwards compatibility and tests
Expand Down Expand Up @@ -810,4 +816,9 @@ impl WeightInfo for () {
.saturating_add(RocksDbWeight::get().reads(11 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
fn set_cmix_id() -> Weight {
(83_389_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
}
73 changes: 73 additions & 0 deletions frame/staking/src/xx_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,79 @@ fn after_full_unbond_cmix_id_is_removed() {
})
}

#[test]
fn calling_set_cmix_id_correctly_stores_cmix_id() {
let stash_value = 100;
ExtBuilder::default()
.has_stakers(false)
.build_and_execute(|| {
let _ = Balances::make_free_balance_be(&10, stash_value);

// Can't call function if not bonded
assert_noop!(
Staking::set_cmix_id(Origin::signed(10), cmix_id(10u8).unwrap()),
Error::<Test>::NotStash,
);

// Bond account without cmix id
assert_ok!(Staking::bond(Origin::signed(10), 11, stash_value, None));

// Can't call function from controller
assert_noop!(
Staking::set_cmix_id(Origin::signed(11), cmix_id(10u8).unwrap()),
Error::<Test>::NotStash,
);

// Set cmix id
assert_ok!(Staking::set_cmix_id(Origin::signed(10), cmix_id(10u8).unwrap()));

// confirm cmix ID is correctly stored
assert!(CmixIds::<Test>::contains_key(&cmix_id(10u8).unwrap()));
})
}

#[test]
fn calling_set_cmix_id_stash_already_has_cmix_id_fails() {
let stash_value = 100;
ExtBuilder::default()
.has_stakers(false)
.build_and_execute(|| {
let _ = Balances::make_free_balance_be(&10, stash_value);

// bond first validator with cmix id
assert_ok!(Staking::bond(Origin::signed(10), 11, stash_value, cmix_id(10u8)));

// can't set cmix id, since it's already present
assert_noop!(
Staking::set_cmix_id(Origin::signed(10), cmix_id(11u8).unwrap()),
Error::<Test>::StashAlreadyHasCmixId,
);
})
}

#[test]
fn calling_set_cmix_id_with_existing_cmix_id_fails() {
let stash_value = 100;
ExtBuilder::default()
.has_stakers(false)
.build_and_execute(|| {
let _ = Balances::make_free_balance_be(&10, stash_value);
let _ = Balances::make_free_balance_be(&20, stash_value);

// bond first validator with cmix id
assert_ok!(Staking::bond(Origin::signed(10), 11, stash_value, cmix_id(10u8)));

// bond second validator without
assert_ok!(Staking::bond(Origin::signed(20), 21, stash_value, None));

// if second vaidator tries to set existing cmix id, fails with ValidatorCmixIdNotUnique
assert_noop!(
Staking::set_cmix_id(Origin::signed(20), cmix_id(10u8).unwrap()),
Error::<Test>::ValidatorCmixIdNotUnique,
);
})
}

////////////////////////////////////////
// Rewards Destination //
////////////////////////////////////////
Expand Down

0 comments on commit e3677d7

Please sign in to comment.