forked from paritytech/substrate
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial staking integration (paritytech#127)
* Add initial staking module with only origin APIs defined * Add staking types * Add staking traits * Add vote_weight primitive * Add staking utils functions * Impl bond check * Fix ci * Impl rebond and unbond check * Impl partial apply_bond/rebond/unbond * unbonded chunks * Add ComputeVoteWeight trait * Impl Staking Claim * Impl apply_bond/rebond/unbond * Add staking module to runtime * Add mock * Possibly need a upgrade * Make staking test work after upgrading to rc4 * Add basic bond/rebond/unbond tests * Impl withdraw_unbonded * Fix rc4 migration * Nits * Be consistent with chainx primitives for VoteWeight trait * Improve the namings * Nits
- Loading branch information
1 parent
71481da
commit 4862016
Showing
16 changed files
with
1,751 additions
and
64 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "xp-staking" | ||
version = "0.1.0" | ||
authors = ["ChainX community <https://www.chainx.org>"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
# Substrate primitives | ||
sp-std = { git = "https://github.com/paritytech/substrate.git", tag = "v2.0.0-rc4", default-features = false } | ||
sp-runtime = { git = "https://github.com/paritytech/substrate.git", tag = "v2.0.0-rc4", default-features = false } | ||
|
||
# ChainX primitives | ||
chainx-primitives = { path = "../../primitives", default-features = false } | ||
|
||
[features] | ||
default = ["std"] | ||
std = [ | ||
"sp-std/std", | ||
"sp-runtime/std", | ||
|
||
"chainx-primitives/std", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
//! A crate which contains primitives that are useful for implementation that uses staking | ||
//! approaches in general. Definitions related to sessions, slashing, etc go here. | ||
|
||
mod vote_weight; | ||
|
||
pub use vote_weight::*; | ||
|
||
use chainx_primitives::AssetId; | ||
use sp_std::prelude::Vec; | ||
|
||
/// Simple index type with which we can count sessions. | ||
pub type SessionIndex = u32; | ||
|
||
/// Simple index type with which we can count unbonded entries. | ||
pub type UnbondedIndex = u32; | ||
|
||
/// Type for calculating staker's vote weight. | ||
pub type VoteWeight = u128; | ||
|
||
/// Type for measuring the non-validator entity's mining power. | ||
pub type MiningPower = u128; | ||
|
||
/// | ||
pub trait CollectAssetMiningInfo { | ||
/// | ||
fn collect_asset_mining_info() -> Vec<(AssetId, MiningPower)>; | ||
|
||
/// | ||
fn total_mining_power() -> MiningPower { | ||
Self::collect_asset_mining_info() | ||
.iter() | ||
.map(|(_, power)| power) | ||
.sum() | ||
} | ||
} | ||
|
||
impl CollectAssetMiningInfo for () { | ||
fn collect_asset_mining_info() -> Vec<(AssetId, MiningPower)> { | ||
Vec::new() | ||
} | ||
} | ||
|
||
/// Issue the fresh PCX to the non-validator mining entities. | ||
pub trait OnMinting<MiningEntity, Balance> { | ||
fn mint(_: &MiningEntity, _: Balance); | ||
} | ||
|
||
impl<MiningEntity, Balance> OnMinting<MiningEntity, Balance> for () { | ||
fn mint(_: &MiningEntity, _: Balance) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use crate::VoteWeight; | ||
use sp_std::result::Result; | ||
|
||
/// The getter and setter methods for the further vote weight processing. | ||
pub trait BaseVoteWeight<BlockNumber> { | ||
fn amount(&self) -> u128; | ||
fn set_amount(&mut self, new: u128); | ||
|
||
fn last_acum_weight(&self) -> VoteWeight; | ||
fn set_last_acum_weight(&mut self, s: VoteWeight); | ||
|
||
fn last_acum_weight_update(&self) -> u32; | ||
fn set_last_acum_weight_update(&mut self, num: BlockNumber); | ||
} | ||
|
||
#[derive(Clone, Copy, sp_runtime::RuntimeDebug)] | ||
pub enum Delta { | ||
Add(u128), | ||
Sub(u128), | ||
Zero, | ||
} | ||
|
||
/// General logic for stage changes of the vote weight operations. | ||
pub trait VoteWightTrait<BlockNumber>: BaseVoteWeight<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, | ||
Delta::Zero => return, | ||
}; | ||
self.set_amount(new); | ||
} | ||
|
||
/// This action doesn't involve in a change of amount, used for tokens module only. | ||
fn set_state_weight(&mut self, latest_acum_weight: VoteWeight, 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: VoteWeight, | ||
current_block: BlockNumber, | ||
delta: &Delta, | ||
) { | ||
self.set_state_weight(latest_acum_weight, current_block); | ||
self.settle_and_set_amount(delta); | ||
} | ||
} | ||
|
||
impl<BlockNumber, T: BaseVoteWeight<BlockNumber>> VoteWightTrait<BlockNumber> for T {} | ||
|
||
/// Formula: Latest Vote Weight = last_acum_weight(VoteWeight) + amount(u64) * duration(u64) | ||
pub type WeightFactors = (VoteWeight, u128, u32); | ||
|
||
pub struct ZeroVoteWeightError; | ||
|
||
pub trait ComputeVoteWeight<AccountId> { | ||
/// The entity that holds the funds of claimers. | ||
type Claimee; | ||
type Error: From<ZeroVoteWeightError>; | ||
|
||
fn claimer_weight_factors(_: &AccountId, _: &Self::Claimee, _: u32) -> WeightFactors; | ||
fn claimee_weight_factors(_: &Self::Claimee, _: u32) -> WeightFactors; | ||
|
||
fn settle_claimer_weight( | ||
who: &AccountId, | ||
target: &Self::Claimee, | ||
current_block: u32, | ||
) -> VoteWeight { | ||
Self::calc_latest_vote_weight(Self::claimer_weight_factors(who, target, current_block)) | ||
} | ||
|
||
fn settle_claimee_weight(target: &Self::Claimee, current_block: u32) -> VoteWeight { | ||
Self::calc_latest_vote_weight(Self::claimee_weight_factors(target, current_block)) | ||
} | ||
|
||
fn settle_weight_on_claim( | ||
who: &AccountId, | ||
target: &Self::Claimee, | ||
current_block: u32, | ||
) -> Result<(VoteWeight, VoteWeight), Self::Error> { | ||
let claimer_weight = Self::settle_claimer_weight(who, target, current_block); | ||
|
||
if claimer_weight == 0 { | ||
return Err(ZeroVoteWeightError.into()); | ||
} | ||
|
||
let claimee_weight = Self::settle_claimee_weight(target, current_block); | ||
|
||
Ok((claimer_weight, claimee_weight)) | ||
} | ||
|
||
fn calc_latest_vote_weight(weight_factors: WeightFactors) -> VoteWeight { | ||
let (last_acum_weight, amount, duration) = weight_factors; | ||
last_acum_weight + VoteWeight::from(amount) * VoteWeight::from(duration) | ||
} | ||
} | ||
|
||
pub trait Claim<AccountId> { | ||
type Claimee; | ||
type Error; | ||
|
||
fn claim(claimer: &AccountId, claimee: &Self::Claimee) -> Result<(), Self::Error>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.