Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Support Staking Payout to Any Account #6832

Merged
merged 2 commits into from
Aug 26, 2020
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
2 changes: 1 addition & 1 deletion frame/offences/benchmarking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn create_offender<T: Trait>(n: u32, nominators: u32) -> Result<Offender<T>, &'s
RawOrigin::Signed(nominator_stash.clone()).into(),
nominator_controller_lookup.clone(),
amount.clone(),
reward_destination,
reward_destination.clone(),
)?;

let selected_validators: Vec<LookupSourceOf<T>> = vec![controller_lookup.clone()];
Expand Down
15 changes: 10 additions & 5 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,16 +427,18 @@ pub enum StakerStatus<AccountId> {

/// A destination account for payment.
#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)]
pub enum RewardDestination {
pub enum RewardDestination<AccountId> {
/// Pay into the stash account, increasing the amount at stake accordingly.
Staked,
/// Pay into the stash account, not increasing the amount at stake.
Stash,
/// Pay into the controller account.
Controller,
/// Pay into a specified account.
Account(AccountId),
}

impl Default for RewardDestination {
impl<AccountId> Default for RewardDestination<AccountId> {
fn default() -> Self {
RewardDestination::Staked
}
Expand Down Expand Up @@ -1049,7 +1051,7 @@ decl_storage! {
=> Option<StakingLedger<T::AccountId, BalanceOf<T>>>;

/// Where the reward payment should be made. Keyed by stash.
pub Payee get(fn payee): map hasher(twox_64_concat) T::AccountId => RewardDestination;
pub Payee get(fn payee): map hasher(twox_64_concat) T::AccountId => RewardDestination<T::AccountId>;

/// The map from (wannabe) validator stash key to the preferences of that validator.
pub Validators get(fn validators):
Expand Down Expand Up @@ -1496,7 +1498,7 @@ decl_module! {
pub fn bond(origin,
controller: <T::Lookup as StaticLookup>::Source,
#[compact] value: BalanceOf<T>,
payee: RewardDestination,
payee: RewardDestination<T::AccountId>,
) {
let stash = ensure_signed(origin)?;

Expand Down Expand Up @@ -1830,7 +1832,7 @@ decl_module! {
/// - Write: Payee
/// # </weight>
#[weight = 11 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 1)]
fn set_payee(origin, payee: RewardDestination) {
fn set_payee(origin, payee: RewardDestination<T::AccountId>) {
gavofyork marked this conversation as resolved.
Show resolved Hide resolved
let controller = ensure_signed(origin)?;
let ledger = Self::ledger(&controller).ok_or(Error::<T>::NotController)?;
let stash = &ledger.stash;
Expand Down Expand Up @@ -2488,6 +2490,9 @@ impl<T: Trait> Module<T> {
Self::update_ledger(&controller, &l);
r
}),
RewardDestination::Account(dest_account) => {
Some(T::Currency::deposit_creating(&dest_account, amount))
}
}
}

Expand Down
38 changes: 32 additions & 6 deletions frame/staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4359,7 +4359,7 @@ fn test_payout_stakers() {
// We also test that `payout_extra_nominators` works.
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
let balance = 1000;
// Create three validators:
// Create a validator:
bond_validator(11, 10, balance); // Default(64)

// Create nominators, targeting stash of validators
Expand Down Expand Up @@ -4597,15 +4597,12 @@ fn on_initialize_weight_is_correct() {
});
}


#[test]
fn payout_creates_controller() {
// Here we will test validator can set `max_nominators_payout` and it works.
// We also test that `payout_extra_nominators` works.
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
let balance = 1000;
// Create three validators:
bond_validator(11, 10, balance); // Default(64)
// Create a validator:
bond_validator(11, 10, balance);

// Create a stash/controller pair
bond_nominator(1234, 1337, 100, vec![11]);
Expand All @@ -4626,3 +4623,32 @@ fn payout_creates_controller() {
assert!(Balances::free_balance(1337) > 0);
})
}

#[test]
fn payout_to_any_account_works() {
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
let balance = 1000;
// Create a validator:
bond_validator(11, 10, balance); // Default(64)

// Create a stash/controller pair
bond_nominator(1234, 1337, 100, vec![11]);

// Update payout location
assert_ok!(Staking::set_payee(Origin::signed(1337), RewardDestination::Account(42)));

// Reward Destination account doesn't exist
assert_eq!(Balances::free_balance(42), 0);

mock::start_era(1);
Staking::reward_by_ids(vec![(11, 1)]);
// Compute total payout now for whole duration as other parameter won't change
let total_payout_0 = current_total_payout_for_duration(3 * 1000);
assert!(total_payout_0 > 100); // Test is meaningful if reward something
mock::start_era(2);
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1));

// Payment is successful
assert!(Balances::free_balance(42) > 0);
})
}