Skip to content

Commit

Permalink
Endow the root account some balances (paritytech#374)
Browse files Browse the repository at this point in the history
* Endow root account 100PCX

.

* Rename to BalanceSet as balances also has this :(

* Rename to initialize_legacy_validators() to make it more explicit

* Increase minimal penalty

* Add two tech members

* Complete tech members

* Add immortal validators

* Add set_immortals()

* Ensure new immortabls are all validators

* New weights for set_minimum_penalty() and set_sessions_per_era()

* Ignore immortals for passing the tests

* Add mainnet bootnodes

* Fix build_wasm.sh
  • Loading branch information
liuchengxu authored Nov 23, 2020
1 parent 895496c commit 238f824
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 55 deletions.
39 changes: 27 additions & 12 deletions cli/src/chain_spec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2019-2020 ChainX Project Authors. Licensed under GPL-3.0.

use std::collections::BTreeMap;
use std::convert::TryInto;

use hex_literal::hex;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -381,7 +382,11 @@ pub fn mainnet_config() -> Result<ChainSpec, String> {
"chainx",
ChainType::Live,
constructor,
bootnodes![], // FIXME Add mainnet bootnodes
bootnodes![
"/dns/p2p.1.chainx.org/tcp/20222/p2p/12D3KooWMMGD6eyLDgoTPnmGrawn9gkjtsZGLACJXqVCUbe6R6bD",
"/dns/p2p.2.chainx.org/tcp/20222/p2p/12D3KooWC1tFLBFVw47S2nfD7Nzhg5hBMUvsnz4nqpr82zfTYWaH",
"/dns/p2p.3.chainx.org/tcp/20222/p2p/12D3KooWPthFY8xDDyM5X9PWZwNfioqP5EShiTKyVv5899H22WBT",
],
Some(
TelemetryEndpoints::new(vec![
(CHAINX_TELEMETRY_URL.to_string(), 0),
Expand Down Expand Up @@ -568,7 +573,8 @@ fn build_genesis(
}),
xpallet_genesis_builder: Some(XGenesisBuilderConfig {
params: crate::genesis::genesis_builder_params(),
total_endowed,
initial_authorities_endowed: total_endowed,
root_endowed: 0,
}),
}
}
Expand All @@ -584,26 +590,33 @@ fn mainnet_genesis(
) -> GenesisConfig {
// 1000 PCX
const STAKING_LOCKED: Balance = 100_000 * DOLLARS;
// 100 PCX
const ROOT_ENDOWED: Balance = 10_000 * DOLLARS;

let (assets, assets_restrictions) = init_assets(assets);

let initial_authorities_len = initial_authorities.len();

let tech_comm_members = initial_authorities
.iter()
.map(|((validator, _), _, _, _, _)| validator)
.take((initial_authorities_len + 1) / 2)
.cloned()
.collect::<Vec<_>>();
let tech_comm_members: Vec<AccountId> = vec![
// 5C7VzhPqJsLXcyJmX71ZEt7GdkAMTxHNPwh6BSb8thgBbQU1
hex!["0221ce7c4a0b771faaf0bbae23c3a1965348cb5257611313a73c3d4a53599509"].into(),
// 5D7F1AJoDwuCvZZKEggeGk2brxYty9mkamUcFHyshYBnbWs3
hex!["2e2b928d39b7a9c8688509927e17031001fab604557db093ead5069474e0584e"].into(),
// 5HG5CswZ6X39BYqt8Dc8e4Cn2HieGnnUiG39ddGn2oq5G36W
hex!["e5d8bb656b124beb40990ef9346c441f888981ec7e0d4c55c9c72c176aec5290"].into(),
];

let balances = initial_authorities
let mut balances = initial_authorities
.iter()
.map(|((validator, _), _, _, _, _)| validator)
.cloned()
.map(|validator| (validator, STAKING_LOCKED))
.collect::<Vec<_>>();

let total_endowed = initial_authorities_len as Balance * STAKING_LOCKED;
// 100 PCX to root account for paying the transaction fee.
balances.push((root_key.clone(), ROOT_ENDOWED));

let initial_authorities_endowed = initial_authorities_len as Balance * STAKING_LOCKED;

let validators = initial_authorities
.clone()
Expand Down Expand Up @@ -695,7 +708,8 @@ fn mainnet_genesis(
vesting_account,
glob_dist_ratio: (12, 88), // (Treasury, X-type Asset and Staking) = (12, 88)
mining_ratio: (10, 90), // (Asset Mining, Staking) = (10, 90)
minimum_penalty: 2 * DOLLARS,
minimum_penalty: 100 * DOLLARS,
candidate_requirement: (100 * DOLLARS, 1_000 * DOLLARS), // Minimum value (self_bonded, total_bonded) to be a validator candidate
..Default::default()
}),
xpallet_mining_asset: Some(XMiningAssetConfig {
Expand All @@ -707,7 +721,8 @@ fn mainnet_genesis(
}),
xpallet_genesis_builder: Some(XGenesisBuilderConfig {
params: crate::genesis::genesis_builder_params(),
total_endowed,
root_endowed: ROOT_ENDOWED,
initial_authorities_endowed,
}),
}
}
3 changes: 2 additions & 1 deletion scripts/build_wasm.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#!/usr/bin/env bash
docker run --rm -it -e PACKAGE=chainx-runtime -v $PWD:/build -v /tmp/cargo:/cargo-home chainx/srtool:nightly-2020-09-30

docker run --rm -it -e PACKAGE=chainx-runtime -v $PWD:/build -v /tmp/cargo:/cargo-home chainxorg/srtool:nightly-2020-09-30
2 changes: 1 addition & 1 deletion xpallets/assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ decl_event!(
/// Some balances of an asset were destoryed. [asset_id, who, amount]
Destroyed(AssetId, AccountId, Balance),
/// Set asset balance of an account by root. [asset_id, who, asset_type, amount]
SetBalance(AssetId, AccountId, AssetType, Balance),
BalanceSet(AssetId, AccountId, AssetType, Balance),
}
);

Expand Down
2 changes: 1 addition & 1 deletion xpallets/assets/src/trigger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl<T: Trait> AssetChangedTrigger<T> {
type_: AssetType,
value: BalanceOf<T>,
) -> DispatchResult {
Module::<T>::deposit_event(Event::<T>::SetBalance(*id, who.clone(), type_, value));
Module::<T>::deposit_event(Event::<T>::BalanceSet(*id, who.clone(), type_, value));
T::OnAssetChanged::on_set_balance(id, who, type_, value)?;
Ok(())
}
Expand Down
17 changes: 10 additions & 7 deletions xpallets/genesis-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ decl_storage! {
trait Store for Module<T: Trait> as XGenesisBuilder {}
add_extra_genesis {
config(params): AllParams<T::AccountId, T::Balance, AssetBalanceOf<T>, StakingBalanceOf<T>>;
config(total_endowed): T::Balance;
config(root_endowed): T::Balance;
config(initial_authorities_endowed): T::Balance;
build(|config| {
use crate::genesis::{xassets, balances, xstaking, xmining_asset};

let now = std::time::Instant::now();

balances::initialize::<T>(&config.params.balances, config.total_endowed);
balances::initialize::<T>(&config.params.balances, config.root_endowed, config.initial_authorities_endowed);
xassets::initialize::<T>(&config.params.xassets);
xstaking::initialize::<T>(&config.params.xstaking);
xmining_asset::initialize::<T>(&config.params.xmining_asset);
Expand Down Expand Up @@ -68,7 +69,8 @@ mod genesis {

pub fn initialize<T: Trait>(
params: &BalancesParams<T::AccountId, T::Balance>,
total_endowed: T::Balance,
root_endowed: T::Balance,
initial_authorities_endowed: T::Balance,
) {
let BalancesParams {
free_balances,
Expand Down Expand Up @@ -100,9 +102,10 @@ mod genesis {

for FreeBalanceInfo { who, free } in free_balances {
if *who == *legacy_council {
set_free_balance(&treasury_account, free);
let treasury_free = *free - root_endowed;
set_free_balance(&treasury_account, &treasury_free);
} else if *who == *legacy_team {
let vesting_free = *free - total_endowed;
let vesting_free = *free - initial_authorities_endowed;
set_free_balance(&vesting_account, &vesting_free);
} else if let Some(validator) = validator_for::<T, _>(who, legacy_pots.iter()) {
let new_pot = xpallet_mining_staking::Module::<T>::reward_pot_for(validator);
Expand Down Expand Up @@ -144,7 +147,7 @@ mod genesis {
let genesis_validators = validators.iter().map(|v| v.who.clone()).collect::<Vec<_>>();

// Firstly register the genesis validators.
xpallet_mining_staking::Module::<T>::initialize_validators(validators)
xpallet_mining_staking::Module::<T>::initialize_legacy_validators(validators)
.expect("Failed to initialize genesis staking validators");

// Then mock the validator bond themselves and set the vote weights.
Expand All @@ -166,7 +169,7 @@ mod genesis {
nominator, nominee, *weight,
);
// Skip the validator self-bonding as it has already been processed
// in initialize_validators()
// in initialize_legacy_validators()
if *nominee == *nominator {
continue;
}
Expand Down
14 changes: 14 additions & 0 deletions xpallets/mining/staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,20 @@ benchmarks! {
verify {
assert_eq!(ValidatorBondingDuration::<T>::get(), c.into());
}

set_minimum_penalty {
let c = 1000u32;
}: _(RawOrigin::Root, c.into())
verify {
assert_eq!(MinimumPenalty::<T>::get(), c.into());
}

set_sessions_per_era {
let c = 1000u32;
}: _(RawOrigin::Root, c)
verify {
assert_eq!(SessionsPerEra::get(), c);
}
}

#[cfg(test)]
Expand Down
33 changes: 32 additions & 1 deletion xpallets/mining/staking/src/election.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<T: Trait> Module<T> {
///
/// Otherwise the candidate will be **forced to be chilled**.
fn meet_candidate_threshold(who: &T::AccountId) -> bool {
let BondRequirement { self_bonded, total } = Self::validator_bond_requirement();
let BondRequirement { self_bonded, total } = Self::validator_candidate_requirement();
let threshold_satisfied =
Self::validator_self_bonded(who) >= self_bonded && Self::total_votes_of(who) >= total;

Expand Down Expand Up @@ -82,6 +82,37 @@ impl<T: Trait> Module<T> {
.map(|(_, v)| v)
.collect::<Vec<_>>();

// Remove the immortals once Sudo is removed.
if let Some(immortals) = Self::immortals() {
// since the genesis validators have the same votes, it's ok to not sort them.
let unwanted_losers = immortals
.iter()
.filter(|i| !validators.contains(i))
.collect::<Vec<_>>();

// If we are here, the returned validators are not ensured to be sorted.
if !unwanted_losers.is_empty() {
let mut validators_without_immortals = validators
.into_iter()
.filter(|v| !immortals.contains(v))
.collect::<Vec<_>>();

for _ in unwanted_losers {
if !validators_without_immortals.is_empty() {
// Pop out the validator with fewest votes.
validators_without_immortals.pop();
}
}

let mut validators =
Vec::with_capacity(validators_without_immortals.len() + immortals.len());
validators.extend_from_slice(&validators_without_immortals);
validators.extend_from_slice(&immortals);

return Some(validators);
}
}

// Always return Some(new_validators).
Some(validators)
}
Expand Down
43 changes: 36 additions & 7 deletions xpallets/mining/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ decl_storage! {
u32 = DEFAULT_MAXIMUM_VALIDATOR_COUNT;

/// Minimum value (self_bonded, total_bonded) to be a candidate of validator election.
pub ValidatorCandidateRequirement get(fn validator_bond_requirement):
pub ValidatorCandidateRequirement get(fn validator_candidate_requirement):
BondRequirement<BalanceOf<T>>;

/// The length of a staking era in sessions.
Expand Down Expand Up @@ -199,14 +199,18 @@ decl_storage! {

/// Minimum penalty for each slash.
pub MinimumPenalty get(fn minimum_penalty) config(): BalanceOf<T>;

/// Immortal validators will always be elected if any.
///
/// Immortals will be intialized from the genesis validators.
Immortals get(fn immortals): Option<Vec<T::AccountId>>;
}

add_extra_genesis {
// Staking validators are used for initializing the genesis easier in tests.
// For the mainnet genesis, use `Module::<T>::initialize_validators()`.
config(validators): Vec<(T::AccountId, ReferralId, BalanceOf<T>)>;
config(glob_dist_ratio): (u32, u32);
config(mining_ratio): (u32, u32);
config(candidate_requirement): (BalanceOf<T>, BalanceOf<T>);
build(|config: &GenesisConfig<T>| {
assert!(config.glob_dist_ratio.0 + config.glob_dist_ratio.1 > 0);
assert!(config.mining_ratio.0 + config.mining_ratio.1 > 0);
Expand All @@ -218,6 +222,17 @@ decl_storage! {
asset: config.mining_ratio.0,
staking: config.mining_ratio.1,
});
ValidatorCandidateRequirement::<T>::put(BondRequirement {
self_bonded: config.candidate_requirement.0,
total: config.candidate_requirement.1,
});
Immortals::<T>::put(
config
.validators
.iter()
.map(|(validator, _, _)| validator.clone())
.collect::<Vec<_>>(),
);

for (validator, referral_id, balance) in &config.validators {
assert!(
Expand Down Expand Up @@ -491,18 +506,31 @@ decl_module! {
ValidatorBondingDuration::<T>::put(new);
}

// FIXME: add to WeightInfo once it's stable.
#[weight = 10_000_000]
#[weight = T::WeightInfo::set_minimum_penalty()]
fn set_minimum_penalty(origin, #[compact] new: BalanceOf<T>) {
ensure_root(origin)?;
MinimumPenalty::<T>::put(new);
}

#[weight = 10_000_000]
#[weight = T::WeightInfo::set_sessions_per_era()]
fn set_sessions_per_era(origin, #[compact] new: SessionIndex) {
ensure_root(origin)?;
SessionsPerEra::put(new);
}

#[weight = 10_000_000]
fn set_immortals(origin, new: Vec<T::AccountId>) {
ensure_root(origin)?;
ensure!(
new.iter().find(|&v| !Self::is_validator(v)).is_none(),
Error::<T>::NotValidator
);
if new.is_empty() {
Immortals::<T>::kill()
} else {
Immortals::<T>::put(new);
}
}
}
}

Expand Down Expand Up @@ -551,8 +579,9 @@ impl<T: Trait> xpallet_support::traits::Validator<T::AccountId> for Module<T> {
}

impl<T: Trait> Module<T> {
/// Initializes the validators exported from ChainX 1.0.
#[cfg(feature = "std")]
pub fn initialize_validators(
pub fn initialize_legacy_validators(
validators: &[xp_genesis_builder::ValidatorInfo<T::AccountId, BalanceOf<T>>],
) -> DispatchResult {
for xp_genesis_builder::ValidatorInfo {
Expand Down
2 changes: 2 additions & 0 deletions xpallets/mining/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ impl ExtBuilder {
ext.execute_with(|| {
System::set_block_number(1);
Timestamp::set_timestamp(INIT_TIMESTAMP);
// Just ignore the immortals for tests.
XStaking::set_immortals(Origin::root(), vec![]).unwrap();
});

ext
Expand Down
Loading

0 comments on commit 238f824

Please sign in to comment.