Skip to content

Commit

Permalink
Upper bound of intention (paritytech#796)
Browse files Browse the repository at this point in the history
* Add UpperBoundFactor

Close paritytech#672

* Check if the intention is nominating itself and add tests

* Add set_upper_bound_factor and build wasm
  • Loading branch information
atenjin committed Jul 29, 2019
1 parent 73f7860 commit 5c61543
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
Binary file not shown.
38 changes: 37 additions & 1 deletion xrml/xmining/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! Staking manager: Periodically determines the best set of validators.
#![cfg_attr(not(feature = "std"), no_std)]
#![recursion_limit = "128"]

mod mock;
mod reward;
Expand All @@ -28,9 +29,9 @@ use xaccounts::IntentionJackpotAccountIdFor;
use xassets::{AssetErr, Memo, Token};
use xr_primitives::{Name, XString, URL};
use xsession::SessionKeyUsability;
use xsupport::debug;
#[cfg(feature = "std")]
use xsupport::who;
use xsupport::{debug, error};

pub use self::traits::*;
pub use self::types::*;
Expand Down Expand Up @@ -76,6 +77,10 @@ decl_module! {
"Cannot nominate if greater than your avaliable free balance."
);

if !Self::is_nominating_intention_itself(&who, &target) {
Self::wont_reach_upper_bound(&target, value)?;
}

Self::apply_nominate(&who, &target, value)?;
}

Expand Down Expand Up @@ -106,6 +111,10 @@ decl_module! {
"Cannot renominate if greater than your current nomination."
);

if !Self::is_nominating_intention_itself(&who, &to) {
Self::wont_reach_upper_bound(&to, value)?;
}

Self::apply_renominate(&who, &from, &to, value)?;
}

Expand Down Expand Up @@ -287,6 +296,11 @@ decl_module! {
<MinimumCandidateThreshold<T>>::put(new);
}

/// Set the factor of intention's total nomination upper bond.
fn set_upper_bond_factor(new: u32) {
<UpperBoundFactor<T>>::put(new);
}

}
}

Expand Down Expand Up @@ -357,6 +371,9 @@ decl_storage! {

pub NominationRecords get(nomination_records): map (T::AccountId, T::AccountId) => Option<NominationRecord<T::Balance, T::BlockNumber>>;

/// The upper bound nominations of the intention that could absorb is up to the self-bonded.
pub UpperBoundFactor get(upper_bound_factor): u32 = 10u32;

/// Reported validators that did evil, reset per session.
pub EvilValidatorsPerSession get(evil_validators): Vec<T::AccountId>;

Expand Down Expand Up @@ -395,6 +412,10 @@ impl<T: Trait> Module<T> {
}
}

pub fn upper_bound_of(who: &T::AccountId) -> T::Balance {
Self::self_bonded_of(who) * T::Balance::sa(u64::from(Self::upper_bound_factor()))
}

pub fn total_nomination_of(intention: &T::AccountId) -> T::Balance {
<Intentions<T>>::get(intention).total_nomination
}
Expand Down Expand Up @@ -614,6 +635,21 @@ impl<T: Trait> Module<T> {
));
}

fn wont_reach_upper_bound(nominee: &T::AccountId, value: T::Balance) -> Result {
let total_nomination = Self::total_nomination_of(nominee);
let upper_bound = Self::upper_bound_of(nominee);
if total_nomination + value <= upper_bound {
Ok(())
} else {
error!("Fail to (re)nominate, upper bound of nominee({:?}) is {:?}, current total_nomination: {:?}, want to nominate: {:?}", nominee, upper_bound, total_nomination, value);
Err("Cannot (re)nominate if the target is reaching the upper bound of total nomination.")
}
}

fn is_nominating_intention_itself(nominator: &T::AccountId, nominee: &T::AccountId) -> bool {
Self::is_intention(nominator) && *nominator == *nominee
}

#[cfg(feature = "std")]
pub fn bootstrap_register(intention: &T::AccountId, name: Name) -> Result {
Self::apply_register(intention, name)
Expand Down
38 changes: 38 additions & 0 deletions xrml/xmining/staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,41 @@ fn minimum_candidate_threshold_should_work() {
);
});
}

#[test]
fn upper_bound_of_total_nomination_should_work() {
with_externalities(&mut new_test_ext(), || {
assert_ok!(XStaking::register(Origin::signed(1), b"name1".to_vec(),));
assert_ok!(XStaking::register(Origin::signed(2), b"name2".to_vec(),));

assert_noop!(
XStaking::nominate(Origin::signed(3), 1.into(), 5, vec![]),
"Cannot (re)nominate if the target is reaching the upper bound of total nomination."
);

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

assert_noop!(
XStaking::nominate(Origin::signed(3), 1.into(), 10, vec![]),
"Cannot (re)nominate if the target is reaching the upper bound of total nomination."
);

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

assert_ok!(XStaking::nominate(Origin::signed(2), 2.into(), 2, vec![]));
assert_ok!(XStaking::nominate(Origin::signed(3), 2.into(), 15, vec![]));

assert_ok!(XStaking::nominate(Origin::signed(1), 1.into(), 1, vec![]));
assert_noop!(
XStaking::renominate(Origin::signed(3), 2.into(), 1.into(), 10, vec![]),
"Cannot (re)nominate if the target is reaching the upper bound of total nomination."
);
assert_ok!(XStaking::renominate(
Origin::signed(3),
2.into(),
1.into(),
9,
vec![]
));
});
}

0 comments on commit 5c61543

Please sign in to comment.