mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 22:51:03 +00:00
Add nominators option to chain-spec-builder (#8502)
* Add nominators option to chain-spec-builder * Update bin/utils/chain-spec-builder/src/main.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
@@ -23,9 +23,9 @@ use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519};
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use node_runtime::{
|
use node_runtime::{
|
||||||
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig,
|
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig,
|
||||||
DemocracyConfig,GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus,
|
DemocracyConfig, GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus,
|
||||||
StakingConfig, ElectionsConfig, IndicesConfig, SocietyConfig, SudoConfig, SystemConfig,
|
StakingConfig, ElectionsConfig, IndicesConfig, SocietyConfig, SudoConfig, SystemConfig,
|
||||||
TechnicalCommitteeConfig, wasm_binary_unwrap,
|
TechnicalCommitteeConfig, wasm_binary_unwrap, MAX_NOMINATIONS,
|
||||||
};
|
};
|
||||||
use node_runtime::Block;
|
use node_runtime::Block;
|
||||||
use node_runtime::constants::currency::*;
|
use node_runtime::constants::currency::*;
|
||||||
@@ -146,12 +146,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
|||||||
|
|
||||||
let endowed_accounts: Vec<AccountId> = vec![root_key.clone()];
|
let endowed_accounts: Vec<AccountId> = vec![root_key.clone()];
|
||||||
|
|
||||||
testnet_genesis(
|
testnet_genesis(initial_authorities, vec![], root_key, Some(endowed_accounts), false)
|
||||||
initial_authorities,
|
|
||||||
root_key,
|
|
||||||
Some(endowed_accounts),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Staging testnet config.
|
/// Staging testnet config.
|
||||||
@@ -214,6 +209,7 @@ pub fn testnet_genesis(
|
|||||||
ImOnlineId,
|
ImOnlineId,
|
||||||
AuthorityDiscoveryId,
|
AuthorityDiscoveryId,
|
||||||
)>,
|
)>,
|
||||||
|
initial_nominators: Vec<AccountId>,
|
||||||
root_key: AccountId,
|
root_key: AccountId,
|
||||||
endowed_accounts: Option<Vec<AccountId>>,
|
endowed_accounts: Option<Vec<AccountId>>,
|
||||||
enable_println: bool,
|
enable_println: bool,
|
||||||
@@ -234,11 +230,31 @@ pub fn testnet_genesis(
|
|||||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
initial_authorities.iter().for_each(|x|
|
// endow all authorities and nominators.
|
||||||
if !endowed_accounts.contains(&x.0) {
|
initial_authorities.iter().map(|x| &x.0).chain(initial_nominators.iter()).for_each(|x| {
|
||||||
endowed_accounts.push(x.0.clone())
|
if !endowed_accounts.contains(&x) {
|
||||||
|
endowed_accounts.push(x.clone())
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
|
// stakers: all validators and nominators.
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let stakers = initial_authorities
|
||||||
|
.iter()
|
||||||
|
.map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator))
|
||||||
|
.chain(initial_nominators.iter().map(|x| {
|
||||||
|
use rand::{seq::SliceRandom, Rng};
|
||||||
|
let limit = (MAX_NOMINATIONS as usize).min(initial_authorities.len());
|
||||||
|
let count = rng.gen::<usize>() % limit;
|
||||||
|
let nominations = initial_authorities
|
||||||
|
.as_slice()
|
||||||
|
.choose_multiple(&mut rng, count)
|
||||||
|
.into_iter()
|
||||||
|
.map(|choice| choice.0.clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
(x.clone(), x.clone(), STASH, StakerStatus::Nominator(nominations))
|
||||||
|
}))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let num_endowed_accounts = endowed_accounts.len();
|
let num_endowed_accounts = endowed_accounts.len();
|
||||||
|
|
||||||
@@ -271,11 +287,9 @@ pub fn testnet_genesis(
|
|||||||
pallet_staking: StakingConfig {
|
pallet_staking: StakingConfig {
|
||||||
validator_count: initial_authorities.len() as u32 * 2,
|
validator_count: initial_authorities.len() as u32 * 2,
|
||||||
minimum_validator_count: initial_authorities.len() as u32,
|
minimum_validator_count: initial_authorities.len() as u32,
|
||||||
stakers: initial_authorities.iter().map(|x| {
|
|
||||||
(x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)
|
|
||||||
}).collect(),
|
|
||||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||||
slash_reward_fraction: Perbill::from_percent(10),
|
slash_reward_fraction: Perbill::from_percent(10),
|
||||||
|
stakers,
|
||||||
.. Default::default()
|
.. Default::default()
|
||||||
},
|
},
|
||||||
pallet_democracy: DemocracyConfig::default(),
|
pallet_democracy: DemocracyConfig::default(),
|
||||||
@@ -335,6 +349,7 @@ fn development_config_genesis() -> GenesisConfig {
|
|||||||
vec![
|
vec![
|
||||||
authority_keys_from_seed("Alice"),
|
authority_keys_from_seed("Alice"),
|
||||||
],
|
],
|
||||||
|
vec![],
|
||||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
None,
|
None,
|
||||||
true,
|
true,
|
||||||
@@ -362,6 +377,7 @@ fn local_testnet_genesis() -> GenesisConfig {
|
|||||||
authority_keys_from_seed("Alice"),
|
authority_keys_from_seed("Alice"),
|
||||||
authority_keys_from_seed("Bob"),
|
authority_keys_from_seed("Bob"),
|
||||||
],
|
],
|
||||||
|
vec![],
|
||||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
@@ -395,6 +411,7 @@ pub(crate) mod tests {
|
|||||||
vec![
|
vec![
|
||||||
authority_keys_from_seed("Alice"),
|
authority_keys_from_seed("Alice"),
|
||||||
],
|
],
|
||||||
|
vec![],
|
||||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
|||||||
@@ -472,8 +472,7 @@ parameter_types! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl pallet_staking::Config for Runtime {
|
impl pallet_staking::Config for Runtime {
|
||||||
const MAX_NOMINATIONS: u32 =
|
const MAX_NOMINATIONS: u32 = MAX_NOMINATIONS;
|
||||||
<NposCompactSolution16 as sp_npos_elections::CompactSolution>::LIMIT as u32;
|
|
||||||
type Currency = Balances;
|
type Currency = Balances;
|
||||||
type UnixTime = Timestamp;
|
type UnixTime = Timestamp;
|
||||||
type CurrencyToVote = U128CurrencyToVote;
|
type CurrencyToVote = U128CurrencyToVote;
|
||||||
@@ -527,6 +526,9 @@ sp_npos_elections::generate_solution_type!(
|
|||||||
>(16)
|
>(16)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
pub const MAX_NOMINATIONS: u32 =
|
||||||
|
<NposCompactSolution16 as sp_npos_elections::CompactSolution>::LIMIT as u32;
|
||||||
|
|
||||||
impl pallet_election_provider_multi_phase::Config for Runtime {
|
impl pallet_election_provider_multi_phase::Config for Runtime {
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
type Currency = Balances;
|
type Currency = Balances;
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ enum ChainSpecBuilder {
|
|||||||
/// Authority key seed.
|
/// Authority key seed.
|
||||||
#[structopt(long, short, required = true)]
|
#[structopt(long, short, required = true)]
|
||||||
authority_seeds: Vec<String>,
|
authority_seeds: Vec<String>,
|
||||||
|
/// Active nominators (SS58 format), each backing a random subset of the aforementioned
|
||||||
|
/// authorities.
|
||||||
|
#[structopt(long, short, default_value = "0")]
|
||||||
|
nominator_accounts: Vec<String>,
|
||||||
/// Endowed account address (SS58 format).
|
/// Endowed account address (SS58 format).
|
||||||
#[structopt(long, short)]
|
#[structopt(long, short)]
|
||||||
endowed_accounts: Vec<String>,
|
endowed_accounts: Vec<String>,
|
||||||
@@ -57,6 +61,11 @@ enum ChainSpecBuilder {
|
|||||||
/// The number of authorities.
|
/// The number of authorities.
|
||||||
#[structopt(long, short)]
|
#[structopt(long, short)]
|
||||||
authorities: usize,
|
authorities: usize,
|
||||||
|
/// The number of nominators backing the aforementioned authorities.
|
||||||
|
///
|
||||||
|
/// Will nominate a random subset of `authorities`.
|
||||||
|
#[structopt(long, short, default_value = "0")]
|
||||||
|
nominators: usize,
|
||||||
/// The number of endowed accounts.
|
/// The number of endowed accounts.
|
||||||
#[structopt(long, short, default_value = "0")]
|
#[structopt(long, short, default_value = "0")]
|
||||||
endowed: usize,
|
endowed: usize,
|
||||||
@@ -87,6 +96,7 @@ impl ChainSpecBuilder {
|
|||||||
|
|
||||||
fn genesis_constructor(
|
fn genesis_constructor(
|
||||||
authority_seeds: &[String],
|
authority_seeds: &[String],
|
||||||
|
nominator_accounts: &[AccountId],
|
||||||
endowed_accounts: &[AccountId],
|
endowed_accounts: &[AccountId],
|
||||||
sudo_account: &AccountId,
|
sudo_account: &AccountId,
|
||||||
) -> chain_spec::GenesisConfig {
|
) -> chain_spec::GenesisConfig {
|
||||||
@@ -100,6 +110,7 @@ fn genesis_constructor(
|
|||||||
|
|
||||||
chain_spec::testnet_genesis(
|
chain_spec::testnet_genesis(
|
||||||
authorities,
|
authorities,
|
||||||
|
nominator_accounts.to_vec(),
|
||||||
sudo_account.clone(),
|
sudo_account.clone(),
|
||||||
Some(endowed_accounts.to_vec()),
|
Some(endowed_accounts.to_vec()),
|
||||||
enable_println,
|
enable_println,
|
||||||
@@ -108,26 +119,28 @@ fn genesis_constructor(
|
|||||||
|
|
||||||
fn generate_chain_spec(
|
fn generate_chain_spec(
|
||||||
authority_seeds: Vec<String>,
|
authority_seeds: Vec<String>,
|
||||||
|
nominator_accounts: Vec<String>,
|
||||||
endowed_accounts: Vec<String>,
|
endowed_accounts: Vec<String>,
|
||||||
sudo_account: String,
|
sudo_account: String,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let parse_account = |address: &String| {
|
let parse_account = |address: String| {
|
||||||
AccountId::from_string(address)
|
AccountId::from_string(&address)
|
||||||
.map_err(|err| format!("Failed to parse account address: {:?}", err))
|
.map_err(|err| format!("Failed to parse account address: {:?}", err))
|
||||||
};
|
};
|
||||||
|
|
||||||
let endowed_accounts = endowed_accounts
|
let nominator_accounts =
|
||||||
.iter()
|
nominator_accounts.into_iter().map(parse_account).collect::<Result<Vec<_>, String>>()?;
|
||||||
.map(parse_account)
|
|
||||||
.collect::<Result<Vec<_>, String>>()?;
|
|
||||||
|
|
||||||
let sudo_account = parse_account(&sudo_account)?;
|
let endowed_accounts =
|
||||||
|
endowed_accounts.into_iter().map(parse_account).collect::<Result<Vec<_>, String>>()?;
|
||||||
|
|
||||||
|
let sudo_account = parse_account(sudo_account)?;
|
||||||
|
|
||||||
let chain_spec = chain_spec::ChainSpec::from_genesis(
|
let chain_spec = chain_spec::ChainSpec::from_genesis(
|
||||||
"Custom",
|
"Custom",
|
||||||
"custom",
|
"custom",
|
||||||
sc_chain_spec::ChainType::Live,
|
sc_chain_spec::ChainType::Live,
|
||||||
move || genesis_constructor(&authority_seeds, &endowed_accounts, &sudo_account),
|
move || genesis_constructor(&authority_seeds, &nominator_accounts, &endowed_accounts, &sudo_account),
|
||||||
vec![],
|
vec![],
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@@ -186,6 +199,7 @@ fn generate_authority_keys_and_store(
|
|||||||
|
|
||||||
fn print_seeds(
|
fn print_seeds(
|
||||||
authority_seeds: &[String],
|
authority_seeds: &[String],
|
||||||
|
nominator_seeds: &[String],
|
||||||
endowed_seeds: &[String],
|
endowed_seeds: &[String],
|
||||||
sudo_seed: &str,
|
sudo_seed: &str,
|
||||||
) {
|
) {
|
||||||
@@ -201,6 +215,12 @@ fn print_seeds(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("{}", header.paint("Nominator seeds"));
|
||||||
|
|
||||||
|
for (n, seed) in nominator_seeds.iter().enumerate() {
|
||||||
|
println!("{} //{}", entry.paint(format!("nom-{}:", n)), seed);
|
||||||
|
}
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
if !endowed_seeds.is_empty() {
|
if !endowed_seeds.is_empty() {
|
||||||
@@ -220,34 +240,27 @@ fn print_seeds(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), String> {
|
fn main() -> Result<(), String> {
|
||||||
#[cfg(build_type="debug")]
|
#[cfg(build_type = "debug")]
|
||||||
println!(
|
println!(
|
||||||
"The chain spec builder builds a chain specification that includes a Substrate runtime compiled as WASM. To \
|
"The chain spec builder builds a chain specification that includes a Substrate runtime \
|
||||||
ensure proper functioning of the included runtime compile (or run) the chain spec builder binary in \
|
compiled as WASM. To ensure proper functioning of the included runtime compile (or run) \
|
||||||
`--release` mode.\n",
|
the chain spec builder binary in `--release` mode.\n",
|
||||||
);
|
);
|
||||||
|
|
||||||
let builder = ChainSpecBuilder::from_args();
|
let builder = ChainSpecBuilder::from_args();
|
||||||
let chain_spec_path = builder.chain_spec_path().to_path_buf();
|
let chain_spec_path = builder.chain_spec_path().to_path_buf();
|
||||||
|
|
||||||
let (authority_seeds, endowed_accounts, sudo_account) = match builder {
|
let (authority_seeds, nominator_accounts, endowed_accounts, sudo_account) = match builder {
|
||||||
ChainSpecBuilder::Generate { authorities, endowed, keystore_path, .. } => {
|
ChainSpecBuilder::Generate { authorities, nominators, endowed, keystore_path, .. } => {
|
||||||
let authorities = authorities.max(1);
|
let authorities = authorities.max(1);
|
||||||
let rand_str = || -> String {
|
let rand_str = || -> String { OsRng.sample_iter(&Alphanumeric).take(32).collect() };
|
||||||
OsRng.sample_iter(&Alphanumeric)
|
|
||||||
.take(32)
|
|
||||||
.collect()
|
|
||||||
};
|
|
||||||
|
|
||||||
let authority_seeds = (0..authorities).map(|_| rand_str()).collect::<Vec<_>>();
|
let authority_seeds = (0..authorities).map(|_| rand_str()).collect::<Vec<_>>();
|
||||||
|
let nominator_seeds = (0..nominators).map(|_| rand_str()).collect::<Vec<_>>();
|
||||||
let endowed_seeds = (0..endowed).map(|_| rand_str()).collect::<Vec<_>>();
|
let endowed_seeds = (0..endowed).map(|_| rand_str()).collect::<Vec<_>>();
|
||||||
let sudo_seed = rand_str();
|
let sudo_seed = rand_str();
|
||||||
|
|
||||||
print_seeds(
|
print_seeds(&authority_seeds, &nominator_seeds, &endowed_seeds, &sudo_seed);
|
||||||
&authority_seeds,
|
|
||||||
&endowed_seeds,
|
|
||||||
&sudo_seed,
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(keystore_path) = keystore_path {
|
if let Some(keystore_path) = keystore_path {
|
||||||
generate_authority_keys_and_store(
|
generate_authority_keys_and_store(
|
||||||
@@ -256,23 +269,37 @@ fn main() -> Result<(), String> {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let endowed_accounts = endowed_seeds.iter().map(|seed| {
|
let nominator_accounts = nominator_seeds
|
||||||
chain_spec::get_account_id_from_seed::<sr25519::Public>(seed)
|
.into_iter()
|
||||||
.to_ss58check()
|
.map(|seed| {
|
||||||
}).collect();
|
chain_spec::get_account_id_from_seed::<sr25519::Public>(&seed).to_ss58check()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let sudo_account = chain_spec::get_account_id_from_seed::<sr25519::Public>(&sudo_seed)
|
let endowed_accounts = endowed_seeds
|
||||||
.to_ss58check();
|
.into_iter()
|
||||||
|
.map(|seed| {
|
||||||
|
chain_spec::get_account_id_from_seed::<sr25519::Public>(&seed).to_ss58check()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
(authority_seeds, endowed_accounts, sudo_account)
|
let sudo_account =
|
||||||
},
|
chain_spec::get_account_id_from_seed::<sr25519::Public>(&sudo_seed).to_ss58check();
|
||||||
ChainSpecBuilder::New { authority_seeds, endowed_accounts, sudo_account, .. } => {
|
|
||||||
(authority_seeds, endowed_accounts, sudo_account)
|
(authority_seeds, nominator_accounts, endowed_accounts, sudo_account)
|
||||||
},
|
}
|
||||||
|
ChainSpecBuilder::New {
|
||||||
|
authority_seeds,
|
||||||
|
nominator_accounts,
|
||||||
|
endowed_accounts,
|
||||||
|
sudo_account,
|
||||||
|
..
|
||||||
|
} => (authority_seeds, nominator_accounts, endowed_accounts, sudo_account),
|
||||||
};
|
};
|
||||||
|
|
||||||
let json = generate_chain_spec(
|
let json = generate_chain_spec(
|
||||||
authority_seeds,
|
authority_seeds,
|
||||||
|
nominator_accounts,
|
||||||
endowed_accounts,
|
endowed_accounts,
|
||||||
sudo_account,
|
sudo_account,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user