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

Clean stacking when unbonding all values (#154) #249

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
30 changes: 30 additions & 0 deletions srml/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,11 @@ decl_module! {
///
/// The dispatch origin for this call must be _Signed_ by the controller, not the stash.
///
/// After all pledged Ring and Kton are unbonded, the bonded accounts, namely stash and
/// controller, will also be unbonded. Once user want to bond again, the `bond` method
/// should be called. If there are still pledged Ring or Kton and user want to bond more
/// values, the `bond_extra` method should be called.
///
/// # <weight>
/// - Independent of the arguments. Limited but potentially exploitable complexity.
/// - Contains a limited number of reads.
Expand Down Expand Up @@ -877,6 +882,31 @@ decl_module! {
}
},
}

let StakingLedger {
active_ring,
active_kton,
stash,
..
} = ledger;

// all bonded rings and ktons is withdrawing, then remove Ledger to save storage
if active_ring.is_zero() && active_kton.is_zero() {
// TODO:
// These locks are still in the system, and should be removed after 14 days
//
// There two situations should be considered after the 14 days
// - the user never bond again, so the locks should be released.
// - the user is bonded again in the 14 days, so the after 14 days
// the lock should not be removed
//
// If the locks are not deleted, this lock will wast the storage in the future
// blocks.
//
// T::Ring::remove_lock(STAKING_ID, &stash);
// T::Kton::remove_lock(STAKING_ID, &stash);
Self::kill_stash(&stash);
}
}

// TODO: doc
Expand Down
134 changes: 28 additions & 106 deletions srml/staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1993,37 +1993,17 @@ fn bond_with_no_staked_value() {
RewardDestination::Controller,
0,
));
// assert_eq!(Ring::locks(&1)[0].amount, 5);

assert_ok!(Staking::unbond(Origin::signed(2), StakingBalances::RingBalance(5)));
assert_eq!(
Staking::ledger(2),
Some(StakingLedger {
stash: 1,
active_ring: 0,
active_deposit_ring: 0,
active_kton: 0,
deposit_items: vec![],
ring_staking_lock: StakingLock {
staking_amount: 0,
unbondings: vec![NormalLock { amount: 5, until: 60 }],
},
kton_staking_lock: Default::default(),
}),
);

Timestamp::set_timestamp(BondingDuration::get() - 1);

// Not yet removed.
assert!(Staking::ledger(2).is_some());
// assert_eq!(Ring::locks(&1)[0].amount, 5);
match Ring::locks(&1)[0].withdraw_lock.clone() {
WithdrawLock::Normal(_) => panic!("lock type error"),
WithdrawLock::WithStaking(lock) => assert_eq!(lock.staking_amount, 5),
}

Timestamp::set_timestamp(BondingDuration::get());
assert_ok!(Staking::unbond(Origin::signed(2), StakingBalances::RingBalance(5)));

// FIXME
// Poof. Account 1 is removed from the staking system.
// assert!(Staking::ledger(2).is_none());
// assert_eq!(Ring::locks(&1).len(), 0);
// unbond all, auto remove the ledger
assert_eq!(Staking::ledger(2), None);
});
}

Expand Down Expand Up @@ -2552,30 +2532,7 @@ fn time_deposit_ring_unbond_and_withdraw_automatically_should_work() {
reasons: WithdrawReasons::all(),
}],
);
assert_eq!(
Staking::ledger(controller).unwrap(),
StakingLedger {
stash,
active_ring: 0,
active_deposit_ring: 0,
active_kton: 0,
deposit_items: vec![],
ring_staking_lock: StakingLock {
staking_amount: 0,
unbondings: vec![
NormalLock {
amount: unbond_value,
until: BondingDuration::get(),
},
NormalLock {
amount: 1000 - unbond_value,
until: unbond_start + BondingDuration::get(),
},
],
},
kton_staking_lock: Default::default(),
},
);
assert_eq!(Staking::ledger(controller), None);

assert_err!(
Ring::transfer(Origin::signed(stash), controller, 1),
Expand Down Expand Up @@ -3999,7 +3956,8 @@ fn xavier_q2() {
}

#[test]
fn xavier_q3() {
fn bond_values_then_unbond_all_then_bond_again() {
// The Kton part
ExtBuilder::default().build().execute_with(|| {
let stash = 123;
let controller = 456;
Expand All @@ -4013,6 +3971,7 @@ fn xavier_q3() {
RewardDestination::Stash,
0,
));

assert_eq!(Timestamp::get(), 1);
assert_eq!(
Staking::ledger(controller).unwrap(),
Expand All @@ -4029,38 +3988,22 @@ fn xavier_q3() {
},
}
);
// println!("Locks: {:#?}", Kton::locks(stash));
// println!("StakingLedger: {:#?}", Staking::ledger(controller));
// println!();

// all values are unbond
assert_ok!(Staking::unbond(
Origin::signed(controller),
StakingBalances::KtonBalance(5)
));
assert_eq!(
Staking::ledger(controller).unwrap(),
StakingLedger {
stash: 123,
active_ring: 0,
active_deposit_ring: 0,
active_kton: 0,
deposit_items: vec![],
ring_staking_lock: Default::default(),
kton_staking_lock: StakingLock {
staking_amount: 0,
unbondings: vec![NormalLock { amount: 5, until: 61 }],
},
}
);
// println!("Locks: {:#?}", Kton::locks(stash));
// println!("StakingLedger: {:#?}", Staking::ledger(controller));
// println!();
assert_eq!(Staking::ledger(controller), None);

// bond again
Timestamp::set_timestamp(61);
assert_ok!(Staking::bond_extra(
assert_ok!(Staking::bond(
Origin::signed(stash),
controller,
StakingBalances::KtonBalance(1),
0
RewardDestination::Stash,
0,
));
assert_eq!(Timestamp::get(), 61);
assert_eq!(
Expand All @@ -4074,15 +4017,13 @@ fn xavier_q3() {
ring_staking_lock: Default::default(),
kton_staking_lock: StakingLock {
staking_amount: 1,
unbondings: vec![NormalLock { amount: 5, until: 61 }],
unbondings: vec![],
},
}
);
// println!("Locks: {:#?}", Kton::locks(stash));
// println!("StakingLedger: {:#?}", Staking::ledger(controller));
// println!();
});

// The Ring part
ExtBuilder::default().build().execute_with(|| {
let stash = 123;
let controller = 456;
Expand Down Expand Up @@ -4112,38 +4053,22 @@ fn xavier_q3() {
kton_staking_lock: Default::default(),
}
);
// println!("Locks: {:#?}", Ring::locks(stash));
// println!("StakingLedger: {:#?}", Staking::ledger(controller));
// println!();

// all values are unbond
assert_ok!(Staking::unbond(
Origin::signed(controller),
StakingBalances::RingBalance(5),
));
assert_eq!(
Staking::ledger(controller).unwrap(),
StakingLedger {
stash: 123,
active_ring: 0,
active_deposit_ring: 0,
active_kton: 0,
deposit_items: vec![],
ring_staking_lock: StakingLock {
staking_amount: 0,
unbondings: vec![NormalLock { amount: 5, until: 61 }],
},
kton_staking_lock: Default::default(),
}
);
// println!("Locks: {:#?}", Ring::locks(stash));
// println!("StakingLedger: {:#?}", Staking::ledger(controller));
// println!();
assert_eq!(Staking::ledger(controller), None);

// bond again
Timestamp::set_timestamp(61);
assert_ok!(Staking::bond_extra(
assert_ok!(Staking::bond(
Origin::signed(stash),
controller,
StakingBalances::RingBalance(1),
0
RewardDestination::Stash,
0,
));
assert_eq!(Timestamp::get(), 61);
assert_eq!(
Expand All @@ -4156,14 +4081,11 @@ fn xavier_q3() {
deposit_items: vec![],
ring_staking_lock: StakingLock {
staking_amount: 1,
unbondings: vec![NormalLock { amount: 5, until: 61 }],
unbondings: vec![],
},
kton_staking_lock: Default::default(),
}
);
// println!("Locks: {:#?}", Ring::locks(stash));
// println!("StakingLedger: {:#?}", Staking::ledger(controller));
// println!();
});
}

Expand Down