Skip to content

Commit

Permalink
Add docs about validator nickname (paritytech#225)
Browse files Browse the repository at this point in the history
* Add docs about Validator nickname

* Wrap too long lines

* Change ValidatorCount to 50

* Refactor: add chain_of() in xpallet_asset_registrar

* .

* Move DealWithFees to cli::impls
  • Loading branch information
liuchengxu authored Sep 7, 2020
1 parent 124a3d3 commit 959f11f
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 58 deletions.
2 changes: 1 addition & 1 deletion cli/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ fn testnet_genesis(
},
xpallet_mining_staking: Some(XStakingConfig {
validators,
validator_count: 1000,
validator_count: 50,
sessions_per_era: 12,
vesting_account: get_account_id_from_seed::<sr25519::Public>("vesting"),
glob_dist_ratio: (12, 88), // (Treasury, X-type Asset and Staking) = (12, 88)
Expand Down
29 changes: 27 additions & 2 deletions runtime/src/impls.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Some configurable implementations as associated type for the ChainX runtime.

use crate::{Authorship, Balances, NegativeImbalance};
use crate::{Authorship, Balances, NegativeImbalance, Runtime};
use chainx_primitives::Balance;
use frame_support::traits::{Currency, OnUnbalanced};
use frame_support::traits::{Currency, Imbalance, OnUnbalanced};
use sp_runtime::traits::Convert;

pub struct Author;
Expand All @@ -12,6 +12,31 @@ impl OnUnbalanced<NegativeImbalance> for Author {
}
}

pub struct DealWithFees;
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
fn on_nonzero_unbalanced(fees: NegativeImbalance) {
// for fees, 90% to the reward pot of author, 10% to author
let (to_reward_pot, to_author) = fees.ration(90, 10);

let to_author_numeric_amount = to_author.peek();
let to_reward_pot_numeric_amount = to_reward_pot.peek();

let author = <pallet_authorship::Module<Runtime>>::author();
let reward_pot = <xpallet_mining_staking::Module<Runtime>>::reward_pot_for(&author);

<pallet_balances::Module<Runtime>>::resolve_creating(&author, to_author);
<pallet_balances::Module<Runtime>>::resolve_creating(&reward_pot, to_reward_pot);
<frame_system::Module<Runtime>>::deposit_event(
xpallet_system::RawEvent::TransactionFeePaid(
author,
to_author_numeric_amount,
reward_pot,
to_reward_pot_numeric_amount,
),
);
}
}

/// Struct that handles the conversion of Balance -> `u64`. This is used for staking's election
/// calculation.
pub struct CurrencyToVoteHandler;
Expand Down
27 changes: 1 addition & 26 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub use xpallet_protocol::*;

/// Implementations of some helper traits passed into runtime modules as associated types.
pub mod impls;
use impls::CurrencyToVoteHandler;
use impls::{CurrencyToVoteHandler, DealWithFees};

/// Constant values used within the runtime.
pub mod constants;
Expand Down Expand Up @@ -394,31 +394,6 @@ parameter_types! {
}
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;

pub struct DealWithFees;
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
fn on_nonzero_unbalanced(fees: NegativeImbalance) {
// for fees, 90% to the reward pot of author, 10% to author
let (to_reward_pot, to_author) = fees.ration(90, 10);

let to_author_numeric_amount = to_author.peek();
let to_reward_pot_numeric_amount = to_reward_pot.peek();

let author = <pallet_authorship::Module<Runtime>>::author();
let reward_pot = <xpallet_mining_staking::Module<Runtime>>::reward_pot_for(&author);

<pallet_balances::Module<Runtime>>::resolve_creating(&author, to_author);
<pallet_balances::Module<Runtime>>::resolve_creating(&reward_pot, to_reward_pot);
<frame_system::Module<Runtime>>::deposit_event(
xpallet_system::RawEvent::TransactionFeePaid(
author,
to_author_numeric_amount,
reward_pot,
to_reward_pot_numeric_amount,
),
);
}
}

impl pallet_transaction_payment::Trait for Runtime {
type Currency = Balances;
type OnTransactionPayment = DealWithFees;
Expand Down
1 change: 1 addition & 0 deletions scripts/chainx-js/chainx_types_manual.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"remaining": "RpcBalance",
"executed_indices": "Vec<TradingHistoryIndex>",
"already_filled": "RpcBalance",
"reserved_balance": "RpcBalance",
"last_update_at": "BlockNumber"
},
"TotalAssetInfoForRpc": {
Expand Down
1 change: 1 addition & 0 deletions scripts/chainx-js/res/chainx_types.json
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@
"remaining": "RpcBalance",
"executedIndices": "Vec<TradingHistoryIndex>",
"alreadyFilled": "RpcBalance",
"reservedBalance": "RpcBalance",
"lastUpdateAt": "BlockNumber"
},
"TotalAssetInfoForRpc": {
Expand Down
7 changes: 7 additions & 0 deletions xpallets/assets-registrar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,13 @@ impl<T: Trait> Module<T> {
Self::asset_online(asset_id).is_some()
}

/// Returns the chain of given asset `asset_id`.
pub fn chain_of(asset_id: &AssetId) -> result::Result<Chain, DispatchError> {
Self::asset_info_of(asset_id)
.map(|info| info.chain())
.ok_or_else(|| Error::<T>::AssetDoesNotExist.into())
}

/// Returns the asset info of given `id`.
pub fn get_asset_info(id: &AssetId) -> result::Result<AssetInfo, DispatchError> {
if let Some(asset) = Self::asset_info_of(id) {
Expand Down
90 changes: 65 additions & 25 deletions xpallets/gateway/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,13 @@ decl_module! {
fn deposit_event() = default;

#[weight = <T as Trait>::WeightInfo::withdraw()]
pub fn withdraw(origin, #[compact] asset_id: AssetId, #[compact] value: BalanceOf<T>, addr: AddrStr, ext: Memo) -> DispatchResult {
pub fn withdraw(
origin,
#[compact] asset_id: AssetId,
#[compact] value: BalanceOf<T>,
addr: AddrStr,
ext: Memo
) -> DispatchResult {
let who = ensure_signed(origin)?;
Self::apply_withdraw(who, asset_id, value, addr, ext)
}
Expand All @@ -115,33 +121,50 @@ decl_module! {

// trustees
#[weight = <T as Trait>::WeightInfo::setup_trustee()]
pub fn setup_trustee(origin, chain: Chain, about: Text, hot_entity: Vec<u8>, cold_entity: Vec<u8>) -> DispatchResult {
pub fn setup_trustee(
origin,
chain: Chain,
about: Text,
hot_entity: Vec<u8>,
cold_entity: Vec<u8>
) -> DispatchResult {
let who = ensure_signed(origin)?;
ensure!(T::Validator::is_validator(&who), Error::<T>::NotValidator);
Self::setup_trustee_impl(who, chain, about, hot_entity, cold_entity)
}

/// use for trustee multisig addr
#[weight = <T as Trait>::WeightInfo::transition_trustee_session(new_trustees.len() as u32)]
pub fn transition_trustee_session(origin, chain: Chain, new_trustees: Vec<T::AccountId>) -> DispatchResult {
pub fn transition_trustee_session(
origin,
chain: Chain,
new_trustees: Vec<T::AccountId>
) -> DispatchResult {
match ensure_signed(origin.clone()) {
Ok(who) => {
if who != Self::trustee_multisig_addr(chain) {
return Err(Error::<T>::InvalidMultisig.into());
}
()
},
Err(_) => {
ensure_root(origin)?;
},
};

info!("[transition_trustee_session_by_root]|try to transition trustee|chain:{:?}|new_trustees:{:?}", chain, new_trustees);
info!(
"[transition_trustee_session_by_root]|try to transition trustee|chain:{:?}|new_trustees:{:?}",
chain,
new_trustees
);
Self::transition_trustee_session_impl(chain, new_trustees)
}

#[weight = <T as Trait>::WeightInfo::set_withdrawal_state()]
pub fn set_withdrawal_state(origin, #[compact] withdrawal_id: u32, state: WithdrawalState) -> DispatchResult {
pub fn set_withdrawal_state(
origin,
#[compact] withdrawal_id: u32,
state: WithdrawalState
) -> DispatchResult {
let from = ensure_signed(origin)?;

let map = Self::trustee_multisigs();
Expand All @@ -161,7 +184,12 @@ decl_module! {
}

#[weight = 0]
pub fn force_set_binding(origin, chain: Chain, who: <T::Lookup as StaticLookup>::Source, binded: <T::Lookup as StaticLookup>::Source) -> DispatchResult {
pub fn force_set_binding(
origin,
chain: Chain,
who: <T::Lookup as StaticLookup>::Source,
binded: <T::Lookup as StaticLookup>::Source
) -> DispatchResult {
ensure_root(origin)?;
let who = T::Lookup::lookup(who)?;
let binded = T::Lookup::lookup(binded)?;
Expand All @@ -178,35 +206,50 @@ decl_storage! {

/// trustee basal info config
pub TrusteeInfoConfigOf get(fn trustee_info_config): map hasher(twox_64_concat) Chain => TrusteeInfoConfig;

/// when generate trustee, auto generate a new session number, increase the newest trustee addr, can't modify by user
pub TrusteeSessionInfoLen get(fn trustee_session_info_len): map hasher(twox_64_concat) Chain => u32 = 0;

pub TrusteeSessionInfoOf get(fn trustee_session_info_of):
double_map hasher(twox_64_concat) Chain, hasher(twox_64_concat) u32 => Option<GenericTrusteeSessionInfo<T::AccountId>>;
double_map hasher(twox_64_concat) Chain, hasher(twox_64_concat) u32
=> Option<GenericTrusteeSessionInfo<T::AccountId>>;

pub TrusteeIntentionPropertiesOf get(fn trustee_intention_props_of):
double_map hasher(blake2_128_concat) T::AccountId, hasher(twox_64_concat) Chain => Option<GenericTrusteeIntentionProps>;
double_map hasher(blake2_128_concat) T::AccountId, hasher(twox_64_concat) Chain
=> Option<GenericTrusteeIntentionProps>;

pub AddressBinding:
double_map hasher(twox_64_concat) Chain, hasher(blake2_128_concat) ChainAddress => Option<T::AccountId>;
double_map hasher(twox_64_concat) Chain, hasher(blake2_128_concat) ChainAddress
=> Option<T::AccountId>;

pub BoundAddressOf:
double_map hasher(blake2_128_concat) T::AccountId, hasher(twox_64_concat) Chain => Vec<ChainAddress>;
double_map hasher(blake2_128_concat) T::AccountId, hasher(twox_64_concat) Chain
=> Vec<ChainAddress>;

pub ChannelBindingOf get(fn channel_binding_of):
double_map hasher(blake2_128_concat) T::AccountId, hasher(twox_64_concat) Chain => Option<T::AccountId>;
double_map hasher(blake2_128_concat) T::AccountId, hasher(twox_64_concat) Chain
=> Option<T::AccountId>;
}
add_extra_genesis {
config(trustees): Vec<(Chain, TrusteeInfoConfig, Vec<(T::AccountId, Text, Vec<u8>, Vec<u8>)>)>;
build(|config| {
for (chain, info_config, trustee_infos) in config.trustees.iter() {
let mut trustees = vec![];
let mut trustees = Vec::with_capacity(trustee_infos.len());
for (who, about, hot, cold) in trustee_infos.iter() {
Module::<T>::setup_trustee_impl(who.clone(), *chain, about.clone(), hot.clone(), cold.clone()).expect("must success");
Module::<T>::setup_trustee_impl(
who.clone(),
*chain,
about.clone(),
hot.clone(),
cold.clone(),
)
.expect("setup trustee can not fail; qed");
trustees.push(who.clone());
}
// config set should before transitino
TrusteeInfoConfigOf::insert(chain, info_config.clone());
Module::<T>::transition_trustee_session_impl(*chain, trustees).expect("must success in genesis");
Module::<T>::transition_trustee_session_impl(*chain, trustees)
.expect("trustee session transition can not fail; qed");
}
})
}
Expand Down Expand Up @@ -235,9 +278,7 @@ impl<T: Trait> Module<T> {
pub fn withdrawal_limit(
asset_id: &AssetId,
) -> result::Result<WithdrawalLimit<BalanceOf<T>>, DispatchError> {
let info = xpallet_assets_registrar::Module::<T>::asset_info_of(&asset_id)
.ok_or(xpallet_assets_registrar::Error::<T>::AssetDoesNotExist)?;
let chain = info.chain();
let chain = xpallet_assets_registrar::Module::<T>::chain_of(asset_id)?;
match chain {
Chain::Bitcoin => T::Bitcoin::withdrawal_limit(&asset_id),
_ => Err(Error::<T>::NotSupportedChain.into()),
Expand All @@ -252,8 +293,7 @@ impl<T: Trait> Module<T> {
) -> DispatchResult {
ext.check_validity()?;

let info = xpallet_assets_registrar::Module::<T>::get_asset_info(&asset_id)?;
let chain = info.chain();
let chain = xpallet_assets_registrar::Module::<T>::chain_of(&asset_id)?;
match chain {
Chain::Bitcoin => {
// bitcoin do not need memo
Expand Down Expand Up @@ -326,10 +366,10 @@ impl<T: Trait> Module<T> {
);
return Err(Error::<T>::DuplicatedAccountId.into());
}
let mut props = vec![];
let mut props = Vec::with_capacity(new_trustees.len());
for accountid in new_trustees.into_iter() {
let p = Self::trustee_intention_props_of(&accountid, chain).ok_or_else(|| {
error!("[transition_trustee_session]|not all candidate has registered as a trustee yet|who:{:?}", accountid);
error!("[transition_trustee_session]|some candidate has not registered as a trustee|who:{:?}", accountid);
Error::<T>::NotRegistered
})?;
props.push((accountid, p));
Expand Down Expand Up @@ -385,11 +425,11 @@ impl<T: Trait> Module<T> {
let multi_addr =
T::DetermineMultisigAddress::calc_multisig(&info.trustee_list, info.threshold);

// not allow different chain has same multi-address
// Each chain must have a distinct multisig address,
// duplicated multisig address is not allowed.
let find_duplicated = Self::trustee_multisigs()
.into_iter()
.find(|(c, multisig)| &multi_addr == multisig && c == &chain)
.is_some();
.any(|(c, multisig)| multi_addr == multisig && c == chain);
if find_duplicated {
return Err(Error::<T>::InvalidMultisig.into());
}
Expand Down
22 changes: 18 additions & 4 deletions xpallets/mining/staking/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
//! # Staking Module
//!
//! ## Terminology
//!
//! - Validator nickname: The nickname, a.k.a, Validator name in ChainX 1.0, is
//! exclusively used as the ReferralId for getting some reward(10% of the
//! total dividend) in Asset Mining because the depositor marks this
//! validator as its referral when doing the deposit.
//! Validator nickname and ReferralId is interchangeable in various scenarios.

#![cfg_attr(not(feature = "std"), no_std)]

Expand Down Expand Up @@ -374,7 +382,6 @@ decl_module! {

ensure!(current_block > locked_until, Error::<T>::UnbondedWithdrawalNotYetDue);

// apply withdraw_unbonded
Self::apply_unlock_unbonded_withdrawal(&sender, value);

unbonded_chunks.swap_remove(unbonded_index as usize);
Expand Down Expand Up @@ -423,16 +430,23 @@ decl_module! {
}

/// Register to be a validator for the origin account.
///
/// The reason for using `validator_nickname` instead of `referral_id` as
/// the variable name is when we interact with this interface from outside
/// we can take this as the nickname of validator, which possibly
/// can help reduce some misunderstanding for these unfamiliar with
/// the referral mechanism in Asset Mining. In the context of codebase, we
/// always use the concept of referral id.
#[weight = T::WeightInfo::register()]
pub fn register(origin, referral_id: ReferralId) {
pub fn register(origin, validator_nickname: ReferralId) {
let sender = ensure_signed(origin)?;
Self::check_referral_id(&referral_id)?;
Self::check_referral_id(&validator_nickname)?;
ensure!(!Self::is_validator(&sender), Error::<T>::AlreadyValidator);
ensure!(
(Self::validator_set().count() as u32) < MaximumValidatorCount::get(),
Error::<T>::TooManyValidators
);
Self::apply_register(&sender, referral_id);
Self::apply_register(&sender, validator_nickname);
}

#[weight = T::WeightInfo::set_validator_count()]
Expand Down

0 comments on commit 959f11f

Please sign in to comment.