Skip to content

Commit

Permalink
Refactor vote weight for further u128 fixes (paritytech#724)
Browse files Browse the repository at this point in the history
* Introduce Delta

* Add VoteWeightBase

* Upper bound of intention (paritytech#796)

* Add UpperBoundFactor

Close paritytech#672

* Check if the intention is nominating itself and add tests

* Add set_upper_bound_factor and build wasm

* Add LastRenominationOf (paritytech#794)

* Add LastRenominationOf

Close paritytech#692

* Fix renominate tests

* Build wasm

* genesis bitcoin (paritytech#799)

genesis runtime wasm

notice, do not copy wasm file into cli/src for develop!

* Add MaxUnbondEntriesPerIntention (paritytech#800)

* Add MaxUnbondEntriesPerIntention

Close paritytech#681

* Add test

* Nits

* Nit

* Pass tests

* Replace settle_amount() with settle_and_set_amount()

* Nit

* Build wasm

* Rename set_new_state to set_state

* Rebuild wasm
  • Loading branch information
liuchengxu authored Jul 30, 2019
1 parent 90c80e0 commit 5d2d59c
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 185 deletions.
Binary file not shown.
3 changes: 2 additions & 1 deletion xrml/xbootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ decl_storage! {
use xassets::{ChainT, Token, Chain, Asset};
use xspot::CurrencyPair;
use xmultisig::MultiSigPermission;
use xstaking::Delta;
use xbridge_features::H264;
use xsupport::error;

Expand Down Expand Up @@ -116,7 +117,7 @@ decl_storage! {
).unwrap();

xstaking::Module::<T>::bootstrap_refresh(&account_id, Some(url), Some(true), Some(validator_key), Some(memo));
xstaking::Module::<T>::bootstrap_update_vote_weight(&account_id, &account_id, value, true);
xstaking::Module::<T>::bootstrap_update_vote_weight(&account_id, &account_id, Delta::Add(value.as_()));

<xstaking::StakeWeight<T>>::insert(&account_id, value);
}
Expand Down
22 changes: 8 additions & 14 deletions xrml/xmining/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ impl<T: Trait> Module<T> {

fn apply_nominate(source: &T::AccountId, target: &T::AccountId, value: T::Balance) -> Result {
Self::staking_reserve(source, value)?;
Self::apply_update_vote_weight(source, target, value, true);
Self::apply_update_vote_weight(source, target, Delta::Add(value.as_()));
Self::deposit_event(RawEvent::Nominate(source.clone(), target.clone(), value));
Ok(())
}
Expand All @@ -538,8 +538,8 @@ impl<T: Trait> Module<T> {
value: T::Balance,
current_block: T::BlockNumber,
) -> Result {
Self::apply_update_vote_weight(who, from, value, false);
Self::apply_update_vote_weight(who, to, value, true);
Self::apply_update_vote_weight(who, from, Delta::Sub(value.as_()));
Self::apply_update_vote_weight(who, to, Delta::Add(value.as_()));
<LastRenominationOf<T>>::insert(who, current_block);
Ok(())
}
Expand Down Expand Up @@ -569,7 +569,7 @@ impl<T: Trait> Module<T> {
<NominationRecords<T>>::insert(&nr_key, record);
}

Self::apply_update_vote_weight(source, target, value, false);
Self::apply_update_vote_weight(source, target, Delta::Sub(value.as_()));

Self::deposit_event(RawEvent::Unnominate(freeze_until));

Expand Down Expand Up @@ -704,23 +704,17 @@ impl<T: Trait> Module<T> {
pub fn bootstrap_update_vote_weight(
source: &T::AccountId,
target: &T::AccountId,
value: T::Balance,
to_add: bool,
delta: Delta,
) {
Self::apply_update_vote_weight(source, target, value, to_add)
Self::apply_update_vote_weight(source, target, delta)
}

/// Actually update the vote weight and nomination balance of source and target.
fn apply_update_vote_weight(
source: &T::AccountId,
target: &T::AccountId,
value: T::Balance,
to_add: bool,
) {
fn apply_update_vote_weight(source: &T::AccountId, target: &T::AccountId, delta: Delta) {
let mut iprof = <Intentions<T>>::get(target);
let mut record = Self::nomination_record_of(source, target);

Self::update_vote_weight_both_way(&mut iprof, &mut record, value.as_(), to_add);
Self::update_vote_weight_both_way(&mut iprof, &mut record, &delta);

<Intentions<T>>::insert(target, iprof);
Self::mutate_nomination_record(source, target, record);
Expand Down
2 changes: 1 addition & 1 deletion xrml/xmining/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ pub fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
.unwrap();

XStaking::bootstrap_refresh(&intention, Some(url), Some(true), None, None);
XStaking::bootstrap_update_vote_weight(&intention, &intention, value, true);
XStaking::bootstrap_update_vote_weight(&intention, &intention, Delta::Add(value));
}

XAssets::pcx_issue(&1, 10).unwrap();
Expand Down
139 changes: 14 additions & 125 deletions xrml/xmining/staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ fn nominate_should_work() {

System::set_block_number(2);
XSession::check_rotate_session(System::block_number());
assert_ok!(XStaking::nominate(Origin::signed(1), 1.into(), 10, vec![]));
assert_ok!(XStaking::nominate(Origin::signed(2), 1.into(), 15, vec![]));

assert_eq!(XAssets::pcx_free_balance(&2), 20 - 15);
Expand Down Expand Up @@ -212,6 +213,7 @@ fn unnominate_should_work() {
XSession::check_rotate_session(System::block_number());

assert_ok!(XStaking::register(Origin::signed(1), b"name".to_vec(),));
assert_ok!(XStaking::nominate(Origin::signed(1), 1.into(), 10, vec![]));
assert_ok!(XStaking::nominate(Origin::signed(2), 1.into(), 15, vec![]));

System::set_block_number(2);
Expand Down Expand Up @@ -293,131 +295,9 @@ fn claim_should_work() {
assert_eq!(XAssets::pcx_free_balance(&2), 20);
System::set_block_number(3);
XSession::check_rotate_session(System::block_number());
assert_eq!(XAssets::pcx_free_balance(&2), 400000010);
assert_eq!(XAssets::pcx_free_balance(&2), 36363656);
assert_ok!(XStaking::claim(Origin::signed(2), 2.into()));
assert_eq!(XAssets::pcx_free_balance(&2), 4000000010);
});
}

#[test]
fn offline_should_slash_and_kick() {
// Test that an offline validator gets slashed and kicked
with_externalities(&mut new_test_ext(), || {
assert_eq!(XAssets::pcx_free_balance(&6), 30);
assert_ok!(XStaking::register(Origin::signed(6), b"name".to_vec(),));
assert_ok!(XStaking::refresh(
Origin::signed(6),
None,
Some(true),
None,
None
));

assert_ok!(XStaking::register(Origin::signed(10), b"name1".to_vec(),));
assert_ok!(XStaking::refresh(
Origin::signed(10),
None,
Some(true),
None,
None
));

assert_ok!(XStaking::register(Origin::signed(20), b"name2".to_vec(),));
assert_ok!(XStaking::refresh(
Origin::signed(20),
None,
Some(true),
None,
None
));

assert_ok!(XStaking::register(Origin::signed(30), b"name3".to_vec(),));
assert_ok!(XStaking::refresh(
Origin::signed(30),
None,
Some(true),
None,
None
));

assert_ok!(XStaking::register(Origin::signed(40), b"name4".to_vec(),));
assert_ok!(XStaking::refresh(
Origin::signed(40),
None,
Some(true),
None,
None
));

assert_ok!(XStaking::nominate(Origin::signed(1), 20.into(), 5, vec![]));
assert_ok!(XStaking::nominate(Origin::signed(2), 30.into(), 15, vec![]));
assert_ok!(XStaking::nominate(Origin::signed(3), 40.into(), 15, vec![]));
assert_ok!(XStaking::nominate(Origin::signed(4), 10.into(), 15, vec![]));

assert_eq!(XAccounts::intention_props_of(&6).is_active, true);
System::set_block_number(1);
XSession::check_rotate_session(System::block_number());

assert_ok!(XStaking::nominate(Origin::signed(4), 6.into(), 5, vec![]));
let jackpot_addr = XStaking::jackpot_accountid_for_unsafe(&6);
assert_eq!(XAssets::pcx_free_balance(&jackpot_addr), 0);

System::set_block_number(2);
XSession::check_rotate_session(System::block_number());

// Account 6 is a validator
assert_eq!(
XStaking::validators(),
vec![(40, 15), (30, 15), (10, 15), (20, 5), (6, 5)]
);
let mut total_active_stake = 15 + 15 + 15 + 5 + 5;
let mut rewards = 5_000_000_000 * 8 / 10;
let mut reward_of = Vec::new();
for (val, stakes) in XStaking::validators() {
let reward = rewards * stakes / total_active_stake;
reward_of.push((val, reward));
rewards -= reward;
total_active_stake -= stakes;
}
let reward = reward_of[4].1;
let jackpot1 = reward - reward / 10;
assert_eq!(XAssets::pcx_free_balance(&jackpot_addr), jackpot1);

System::set_block_number(3);
XSession::check_rotate_session(System::block_number());
// Validator 6 get slashed immediately
XStaking::on_offline_validator(&6);
assert_eq!(
XStaking::validators(),
vec![(40, 15), (30, 15), (10, 15), (20, 5), (6, 5)]
);

let mut total_active_stake = 15 + 15 + 15 + 5 + 5;
let mut rewards = 5_000_000_000 * 8 / 10;
let mut reward_of = Vec::new();
for (val, stakes) in XStaking::validators() {
let reward = rewards * stakes / total_active_stake;
reward_of.push((val, reward));
rewards -= reward;
total_active_stake -= stakes;
}
let reward = reward_of[4].1;
let jackpot2 = reward - reward / 10;
assert_eq!(
XAssets::pcx_free_balance(&jackpot_addr),
jackpot2 + jackpot1
);

System::set_block_number(4);
XSession::check_rotate_session(System::block_number());

// Validator 6 be kicked
assert_eq!(
XStaking::validators(),
vec![(40, 15), (30, 15), (10, 15), (20, 5)]
);
assert_eq!(XAssets::pcx_free_balance(&jackpot_addr), 0);
assert_eq!(XAccounts::intention_props_of(&2).is_active, false);
assert_eq!(XAssets::pcx_free_balance(&2), 363636383);
});
}

Expand Down Expand Up @@ -450,6 +330,8 @@ fn minimum_candidate_threshold_should_work() {
));

assert_ok!(XAssets::pcx_issue(&1, 5));

assert_ok!(XStaking::nominate(Origin::signed(6), 6.into(), 5, vec![]));
assert_ok!(XStaking::nominate(Origin::signed(1), 6.into(), 5, vec![]));

System::set_block_number(1);
Expand All @@ -468,6 +350,13 @@ fn minimum_candidate_threshold_should_work() {
);

assert_ok!(XAssets::pcx_issue(&1, 10 * 100_000_000));
assert_ok!(XAssets::pcx_issue(&6, 1_000_000_000));
assert_ok!(XStaking::nominate(
Origin::signed(6),
6.into(),
1_000_000_000,
vec![]
));
assert_ok!(XStaking::nominate(
Origin::signed(1),
6.into(),
Expand All @@ -494,8 +383,8 @@ fn minimum_candidate_threshold_should_work() {
vec![
(40, 4000000000),
(30, 3000000000),
(6, 2000000010),
(20, 2000000000),
(6, 1000000005),
(10, 1000000000)
]
);
Expand Down
35 changes: 33 additions & 2 deletions xrml/xmining/staking/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,47 @@ impl<AccountId: Default, Balance> OnReward<AccountId, Balance> for () {
fn reward(_: &Token, _: Balance) {}
}

pub trait VoteWeight<BlockNumber: As<u64>> {
pub trait VoteWeightBase<BlockNumber: As<u64>> {
fn amount(&self) -> u64;
fn set_amount(&mut self, value: u64, to_add: bool);
fn set_amount(&mut self, new: u64);

fn last_acum_weight(&self) -> u64;
fn set_last_acum_weight(&mut self, s: u64);

fn last_acum_weight_update(&self) -> u64;
fn set_last_acum_weight_update(&mut self, num: BlockNumber);
}

pub trait VoteWeight<BlockNumber: As<u64>>: VoteWeightBase<BlockNumber> {
/// Set the new amount after settling the change of nomination.
fn settle_and_set_amount(&mut self, delta: &Delta) {
let new = match *delta {
Delta::Add(x) => self.amount() + x,
Delta::Sub(x) => self.amount() - x,
};
self.set_amount(new);
}

/// Set new state on claim.
///
/// This action doesn't involve in a change of amount.
fn set_state_on_claim(&mut self, latest_acum_weight: u64, current_block: BlockNumber) {
self.set_last_acum_weight(latest_acum_weight);
self.set_last_acum_weight_update(current_block);
}

/// Set new state on nominate, unnominate and renominate.
///
/// This is similar to set_state_on_claim with the settlement of amount added.
fn set_state(&mut self, latest_acum_weight: u64, current_block: BlockNumber, delta: &Delta) {
self.set_last_acum_weight(latest_acum_weight);
self.set_last_acum_weight_update(current_block);
self.settle_and_set_amount(delta);
}

/// Unsafe settlement of latest_acum_weight.
///
/// FIXME: will be removed once the overflow issue is resolved.
fn latest_acum_weight(&self, current_block: BlockNumber) -> u64 {
self.last_acum_weight()
+ self.amount() * (current_block.as_() - self.last_acum_weight_update())
Expand Down
5 changes: 5 additions & 0 deletions xrml/xmining/staking/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ pub enum ClaimType {
PseduIntention(Token),
}

pub enum Delta {
Add(u64),
Sub(u64),
}

/// Intention mutable properties
#[derive(PartialEq, Eq, Clone, Encode, Decode, Default)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
Expand Down
Loading

0 comments on commit 5d2d59c

Please sign in to comment.