difftreelog
feat(collator-selection) opal only
in: master
10 files changed
node/cli/src/chain_spec.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};18use sc_service::ChainType;19use sp_core::{sr25519, Pair, Public};20use sp_runtime::traits::{IdentifyAccount, Verify};21use std::collections::BTreeMap;2223use serde::{Deserialize, Serialize};24use serde_json::map::Map;2526use up_common::types::opaque::*;27use up_common::constants::EXISTENTIAL_DEPOSIT;2829#[cfg(feature = "unique-runtime")]30pub use unique_runtime as default_runtime;3132#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]33pub use quartz_runtime as default_runtime;3435#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]36pub use opal_runtime as default_runtime;3738/// The `ChainSpec` parameterized for the unique runtime.39#[cfg(feature = "unique-runtime")]40pub type UniqueChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;4142/// The `ChainSpec` parameterized for the quartz runtime.43#[cfg(feature = "quartz-runtime")]44pub type QuartzChainSpec = sc_service::GenericChainSpec<quartz_runtime::GenesisConfig, Extensions>;4546/// The `ChainSpec` parameterized for the opal runtime.47pub type OpalChainSpec = sc_service::GenericChainSpec<opal_runtime::GenesisConfig, Extensions>;4849#[cfg(feature = "unique-runtime")]50pub type DefaultChainSpec = UniqueChainSpec;5152#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]53pub type DefaultChainSpec = QuartzChainSpec;5455#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]56pub type DefaultChainSpec = OpalChainSpec;5758pub enum RuntimeId {59 #[cfg(feature = "unique-runtime")]60 Unique,6162 #[cfg(feature = "quartz-runtime")]63 Quartz,6465 Opal,66 Unknown(String),67}6869#[cfg(not(feature = "unique-runtime"))]70/// PARA_ID for Opal/Quartz71const PARA_ID: u32 = 2095;7273#[cfg(feature = "unique-runtime")]74/// PARA_ID for Unique75const PARA_ID: u32 = 2037;7677pub trait RuntimeIdentification {78 fn runtime_id(&self) -> RuntimeId;79}8081impl RuntimeIdentification for Box<dyn sc_service::ChainSpec> {82 fn runtime_id(&self) -> RuntimeId {83 #[cfg(feature = "unique-runtime")]84 if self.id().starts_with("unique") || self.id().starts_with("unq") {85 return RuntimeId::Unique;86 }8788 #[cfg(feature = "quartz-runtime")]89 if self.id().starts_with("quartz") || self.id().starts_with("qtz") {90 return RuntimeId::Quartz;91 }9293 if self.id().starts_with("opal") || self.id() == "dev" || self.id() == "local_testnet" {94 return RuntimeId::Opal;95 }9697 RuntimeId::Unknown(self.id().into())98 }99}100101pub enum ServiceId {102 Prod,103 Dev,104}105106pub trait ServiceIdentification {107 fn service_id(&self) -> ServiceId;108}109110impl ServiceIdentification for Box<dyn sc_service::ChainSpec> {111 fn service_id(&self) -> ServiceId {112 if self.id().ends_with("dev") {113 ServiceId::Dev114 } else {115 ServiceId::Prod116 }117 }118}119120/// Helper function to generate a crypto pair from seed121pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {122 TPublic::Pair::from_string(&format!("//{}", seed), None)123 .expect("static values are valid; qed")124 .public()125}126127/// The extensions for the [`DefaultChainSpec`].128#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]129#[serde(deny_unknown_fields)]130pub struct Extensions {131 /// The relay chain of the Parachain.132 pub relay_chain: String,133 /// The id of the Parachain.134 pub para_id: u32,135}136137impl Extensions {138 /// Try to get the extension from the given `ChainSpec`.139 pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {140 sc_chain_spec::get_extension(chain_spec.extensions())141 }142}143144type AccountPublic = <Signature as Verify>::Signer;145146/// Helper function to generate an account ID from seed147pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId148where149 AccountPublic: From<<TPublic::Pair as Pair>::Public>,150{151 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()152}153154macro_rules! testnet_genesis {155 (156 $runtime:path,157 $root_key:expr,158 $initial_invulnerables:expr,159 $endowed_accounts:expr,160 $id:expr161 ) => {{162 use $runtime::*;163164 GenesisConfig {165 system: SystemConfig {166 code: WASM_BINARY167 .expect("WASM binary was not build, please build it!")168 .to_vec(),169 },170 balances: BalancesConfig {171 balances: $endowed_accounts172 .iter()173 .cloned()174 // 1e13 UNQ175 .map(|k| (k, 1 << 100))176 .collect(),177 },178 treasury: Default::default(),179 tokens: TokensConfig { balances: vec![] },180 sudo: SudoConfig {181 key: Some($root_key),182 },183 vesting: VestingConfig { vesting: vec![] },184 parachain_info: ParachainInfoConfig {185 parachain_id: $id.into(),186 },187 parachain_system: Default::default(),188 collator_selection: CollatorSelectionConfig {189 invulnerables: $initial_invulnerables190 .iter()191 .cloned()192 .map(|(acc, _)| acc)193 .collect(),194 candidacy_bond: EXISTENTIAL_DEPOSIT * 16,195 ..Default::default()196 },197 session: SessionConfig {198 keys: $initial_invulnerables199 .into_iter()200 .map(|(acc, aura)| {201 (202 acc.clone(), // account id203 acc, // validator id204 SessionKeys { aura }, // session keys205 )206 })207 .collect(),208 },209 aura: Default::default(),210 /*aura: AuraConfig {211 authorities: $initial_authorities,212 },*/213 aura_ext: Default::default(),214 evm: EVMConfig {215 accounts: BTreeMap::new(),216 },217 ethereum: EthereumConfig {},218 }219 }};220}221222pub fn development_config() -> DefaultChainSpec {223 let mut properties = Map::new();224 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());225 properties.insert("tokenDecimals".into(), 18.into());226 properties.insert(227 "ss58Format".into(),228 default_runtime::SS58Prefix::get().into(),229 );230231 DefaultChainSpec::from_genesis(232 // Name233 format!(234 "{}{}",235 default_runtime::RUNTIME_NAME.to_uppercase(),236 if cfg!(feature = "unique-runtime") {237 ""238 } else {239 " by UNIQUE"240 }241 )242 .as_str(),243 // ID244 format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),245 ChainType::Local,246 move || {247 testnet_genesis!(248 default_runtime,249 // Sudo account250 get_account_id_from_seed::<sr25519::Public>("Alice"),251 vec![252 (253 get_account_id_from_seed::<sr25519::Public>("Alice"),254 get_from_seed::<AuraId>("Alice"),255 ),256 (257 get_account_id_from_seed::<sr25519::Public>("Bob"),258 get_from_seed::<AuraId>("Bob"),259 ),260 ],261 // Pre-funded accounts262 vec![263 get_account_id_from_seed::<sr25519::Public>("Alice"),264 get_account_id_from_seed::<sr25519::Public>("Bob"),265 get_account_id_from_seed::<sr25519::Public>("Charlie"),266 get_account_id_from_seed::<sr25519::Public>("Dave"),267 get_account_id_from_seed::<sr25519::Public>("Eve"),268 get_account_id_from_seed::<sr25519::Public>("Ferdie"),269 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),270 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),271 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),272 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),273 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),274 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),275 ],276 PARA_ID277 )278 },279 // Bootnodes280 vec![],281 // Telemetry282 None,283 // Protocol ID284 None,285 None,286 // Properties287 Some(properties),288 // Extensions289 Extensions {290 relay_chain: "rococo-dev".into(),291 para_id: PARA_ID,292 },293 )294}295296pub fn local_testnet_config() -> DefaultChainSpec {297 let mut properties = Map::new();298 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());299 properties.insert("tokenDecimals".into(), 18.into());300 properties.insert(301 "ss58Format".into(),302 default_runtime::SS58Prefix::get().into(),303 );304305 DefaultChainSpec::from_genesis(306 // Name307 format!(308 "{}{}",309 default_runtime::RUNTIME_NAME.to_uppercase(),310 if cfg!(feature = "unique-runtime") {311 ""312 } else {313 " by UNIQUE"314 }315 )316 .as_str(),317 // ID318 format!("{}_local", default_runtime::RUNTIME_NAME).as_str(),319 ChainType::Local,320 move || {321 testnet_genesis!(322 default_runtime,323 // Sudo account324 get_account_id_from_seed::<sr25519::Public>("Alice"),325 vec![326 (327 get_account_id_from_seed::<sr25519::Public>("Alice"),328 get_from_seed::<AuraId>("Alice"),329 ),330 (331 get_account_id_from_seed::<sr25519::Public>("Bob"),332 get_from_seed::<AuraId>("Bob"),333 ),334 ],335 // Pre-funded accounts336 vec![337 get_account_id_from_seed::<sr25519::Public>("Alice"),338 get_account_id_from_seed::<sr25519::Public>("Bob"),339 get_account_id_from_seed::<sr25519::Public>("Charlie"),340 get_account_id_from_seed::<sr25519::Public>("Dave"),341 get_account_id_from_seed::<sr25519::Public>("Eve"),342 get_account_id_from_seed::<sr25519::Public>("Ferdie"),343 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),344 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),345 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),346 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),347 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),348 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),349 ],350 PARA_ID351 )352 },353 // Bootnodes354 vec![],355 // Telemetry356 None,357 // Protocol ID358 None,359 None,360 // Properties361 Some(properties),362 // Extensions363 Extensions {364 relay_chain: "westend-local".into(),365 para_id: PARA_ID,366 },367 )368}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};18use sc_service::ChainType;19use sp_core::{sr25519, Pair, Public};20use sp_runtime::traits::{IdentifyAccount, Verify};21use std::collections::BTreeMap;2223use serde::{Deserialize, Serialize};24use serde_json::map::Map;2526use up_common::types::opaque::*;27use up_common::constants::CANDIDACY_BOND;2829#[cfg(feature = "unique-runtime")]30pub use unique_runtime as default_runtime;3132#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]33pub use quartz_runtime as default_runtime;3435#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]36pub use opal_runtime as default_runtime;3738/// The `ChainSpec` parameterized for the unique runtime.39#[cfg(feature = "unique-runtime")]40pub type UniqueChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;4142/// The `ChainSpec` parameterized for the quartz runtime.43#[cfg(feature = "quartz-runtime")]44pub type QuartzChainSpec = sc_service::GenericChainSpec<quartz_runtime::GenesisConfig, Extensions>;4546/// The `ChainSpec` parameterized for the opal runtime.47pub type OpalChainSpec = sc_service::GenericChainSpec<opal_runtime::GenesisConfig, Extensions>;4849#[cfg(feature = "unique-runtime")]50pub type DefaultChainSpec = UniqueChainSpec;5152#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]53pub type DefaultChainSpec = QuartzChainSpec;5455#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]56pub type DefaultChainSpec = OpalChainSpec;5758pub enum RuntimeId {59 #[cfg(feature = "unique-runtime")]60 Unique,6162 #[cfg(feature = "quartz-runtime")]63 Quartz,6465 Opal,66 Unknown(String),67}6869#[cfg(not(feature = "unique-runtime"))]70/// PARA_ID for Opal/Quartz71const PARA_ID: u32 = 2095;7273#[cfg(feature = "unique-runtime")]74/// PARA_ID for Unique75const PARA_ID: u32 = 2037;7677pub trait RuntimeIdentification {78 fn runtime_id(&self) -> RuntimeId;79}8081impl RuntimeIdentification for Box<dyn sc_service::ChainSpec> {82 fn runtime_id(&self) -> RuntimeId {83 #[cfg(feature = "unique-runtime")]84 if self.id().starts_with("unique") || self.id().starts_with("unq") {85 return RuntimeId::Unique;86 }8788 #[cfg(feature = "quartz-runtime")]89 if self.id().starts_with("quartz") || self.id().starts_with("qtz") {90 return RuntimeId::Quartz;91 }9293 if self.id().starts_with("opal") || self.id() == "dev" || self.id() == "local_testnet" {94 return RuntimeId::Opal;95 }9697 RuntimeId::Unknown(self.id().into())98 }99}100101pub enum ServiceId {102 Prod,103 Dev,104}105106pub trait ServiceIdentification {107 fn service_id(&self) -> ServiceId;108}109110impl ServiceIdentification for Box<dyn sc_service::ChainSpec> {111 fn service_id(&self) -> ServiceId {112 if self.id().ends_with("dev") {113 ServiceId::Dev114 } else {115 ServiceId::Prod116 }117 }118}119120/// Helper function to generate a crypto pair from seed121pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {122 TPublic::Pair::from_string(&format!("//{}", seed), None)123 .expect("static values are valid; qed")124 .public()125}126127/// The extensions for the [`DefaultChainSpec`].128#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]129#[serde(deny_unknown_fields)]130pub struct Extensions {131 /// The relay chain of the Parachain.132 pub relay_chain: String,133 /// The id of the Parachain.134 pub para_id: u32,135}136137impl Extensions {138 /// Try to get the extension from the given `ChainSpec`.139 pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {140 sc_chain_spec::get_extension(chain_spec.extensions())141 }142}143144type AccountPublic = <Signature as Verify>::Signer;145146/// Helper function to generate an account ID from seed147pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId148where149 AccountPublic: From<<TPublic::Pair as Pair>::Public>,150{151 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()152}153154#[cfg(not(any(feature = "unique-runtime", feature = "quartz-runtime")))]155macro_rules! testnet_genesis {156 (157 $runtime:path,158 $root_key:expr,159 $initial_invulnerables:expr,160 $endowed_accounts:expr,161 $id:expr162 ) => {{163 use $runtime::*;164165 GenesisConfig {166 system: SystemConfig {167 code: WASM_BINARY168 .expect("WASM binary was not build, please build it!")169 .to_vec(),170 },171 balances: BalancesConfig {172 balances: $endowed_accounts173 .iter()174 .cloned()175 // 1e13 UNQ176 .map(|k| (k, 1 << 100))177 .collect(),178 },179 treasury: Default::default(),180 tokens: TokensConfig { balances: vec![] },181 sudo: SudoConfig {182 key: Some($root_key),183 },184 vesting: VestingConfig { vesting: vec![] },185 parachain_info: ParachainInfoConfig {186 parachain_id: $id.into(),187 },188 parachain_system: Default::default(),189 collator_selection: CollatorSelectionConfig {190 invulnerables: $initial_invulnerables191 .iter()192 .cloned()193 .map(|(acc, _)| acc)194 .collect(),195 candidacy_bond: CANDIDACY_BOND,196 ..Default::default()197 },198 session: SessionConfig {199 keys: $initial_invulnerables200 .into_iter()201 .map(|(acc, aura)| {202 (203 acc.clone(), // account id204 acc, // validator id205 SessionKeys { aura }, // session keys206 )207 })208 .collect(),209 },210 aura: Default::default(),211 aura_ext: Default::default(),212 evm: EVMConfig {213 accounts: BTreeMap::new(),214 },215 ethereum: EthereumConfig {},216 }217 }};218}219220#[cfg(any(feature = "unique-runtime", feature = "quartz-runtime"))]221macro_rules! testnet_genesis {222 (223 $runtime:path,224 $root_key:expr,225 $initial_invulnerables:expr,226 $endowed_accounts:expr,227 $id:expr228 ) => {{229 use $runtime::*;230231 GenesisConfig {232 system: SystemConfig {233 code: WASM_BINARY234 .expect("WASM binary was not build, please build it!")235 .to_vec(),236 },237 balances: BalancesConfig {238 balances: $endowed_accounts239 .iter()240 .cloned()241 // 1e13 UNQ242 .map(|k| (k, 1 << 100))243 .collect(),244 },245 treasury: Default::default(),246 tokens: TokensConfig { balances: vec![] },247 sudo: SudoConfig {248 key: Some($root_key),249 },250 vesting: VestingConfig { vesting: vec![] },251 parachain_info: ParachainInfoConfig {252 parachain_id: $id.into(),253 },254 parachain_system: Default::default(),255 aura: AuraConfig {256 authorities: $initial_invulnerables257 .into_iter()258 .map(|(_, aura)| aura)259 .collect(),260 },261 aura_ext: Default::default(),262 evm: EVMConfig {263 accounts: BTreeMap::new(),264 },265 ethereum: EthereumConfig {},266 }267 }};268}269270pub fn development_config() -> DefaultChainSpec {271 let mut properties = Map::new();272 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());273 properties.insert("tokenDecimals".into(), 18.into());274 properties.insert(275 "ss58Format".into(),276 default_runtime::SS58Prefix::get().into(),277 );278279 DefaultChainSpec::from_genesis(280 // Name281 format!(282 "{}{}",283 default_runtime::RUNTIME_NAME.to_uppercase(),284 if cfg!(feature = "unique-runtime") {285 ""286 } else {287 " by UNIQUE"288 }289 )290 .as_str(),291 // ID292 format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),293 ChainType::Local,294 move || {295 testnet_genesis!(296 default_runtime,297 // Sudo account298 get_account_id_from_seed::<sr25519::Public>("Alice"),299 vec![300 (301 get_account_id_from_seed::<sr25519::Public>("Alice"),302 get_from_seed::<AuraId>("Alice"),303 ),304 (305 get_account_id_from_seed::<sr25519::Public>("Bob"),306 get_from_seed::<AuraId>("Bob"),307 ),308 ],309 // Pre-funded accounts310 vec![311 get_account_id_from_seed::<sr25519::Public>("Alice"),312 get_account_id_from_seed::<sr25519::Public>("Bob"),313 get_account_id_from_seed::<sr25519::Public>("Charlie"),314 get_account_id_from_seed::<sr25519::Public>("Dave"),315 get_account_id_from_seed::<sr25519::Public>("Eve"),316 get_account_id_from_seed::<sr25519::Public>("Ferdie"),317 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),318 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),319 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),320 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),321 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),322 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),323 ],324 PARA_ID325 )326 },327 // Bootnodes328 vec![],329 // Telemetry330 None,331 // Protocol ID332 None,333 None,334 // Properties335 Some(properties),336 // Extensions337 Extensions {338 relay_chain: "rococo-dev".into(),339 para_id: PARA_ID,340 },341 )342}343344pub fn local_testnet_config() -> DefaultChainSpec {345 let mut properties = Map::new();346 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());347 properties.insert("tokenDecimals".into(), 18.into());348 properties.insert(349 "ss58Format".into(),350 default_runtime::SS58Prefix::get().into(),351 );352353 DefaultChainSpec::from_genesis(354 // Name355 format!(356 "{}{}",357 default_runtime::RUNTIME_NAME.to_uppercase(),358 if cfg!(feature = "unique-runtime") {359 ""360 } else {361 " by UNIQUE"362 }363 )364 .as_str(),365 // ID366 format!("{}_local", default_runtime::RUNTIME_NAME).as_str(),367 ChainType::Local,368 move || {369 testnet_genesis!(370 default_runtime,371 // Sudo account372 get_account_id_from_seed::<sr25519::Public>("Alice"),373 vec![374 (375 get_account_id_from_seed::<sr25519::Public>("Alice"),376 get_from_seed::<AuraId>("Alice"),377 ),378 (379 get_account_id_from_seed::<sr25519::Public>("Bob"),380 get_from_seed::<AuraId>("Bob"),381 ),382 ],383 // Pre-funded accounts384 vec![385 get_account_id_from_seed::<sr25519::Public>("Alice"),386 get_account_id_from_seed::<sr25519::Public>("Bob"),387 get_account_id_from_seed::<sr25519::Public>("Charlie"),388 get_account_id_from_seed::<sr25519::Public>("Dave"),389 get_account_id_from_seed::<sr25519::Public>("Eve"),390 get_account_id_from_seed::<sr25519::Public>("Ferdie"),391 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),392 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),393 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),394 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),395 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),396 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),397 ],398 PARA_ID399 )400 },401 // Bootnodes402 vec![],403 // Telemetry404 None,405 // Protocol ID406 None,407 None,408 // Properties409 Some(properties),410 // Extensions411 Extensions {412 relay_chain: "westend-local".into(),413 para_id: PARA_ID,414 },415 )416}primitives/common/src/constants.rsdiffbeforeafterboth--- a/primitives/common/src/constants.rs
+++ b/primitives/common/src/constants.rs
@@ -41,7 +41,10 @@
pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE;
pub const UNIQUE: Balance = 100 * CENTIUNIQUE;
+/// Minimum balance required to create or keep an account open.
pub const EXISTENTIAL_DEPOSIT: u128 = 0;
+/// Amount of Balance reserved for candidate registration.
+pub const CANDIDACY_BOND: u128 = EXISTENTIAL_DEPOSIT;
// Targeting 0.1 UNQ per transfer
pub const WEIGHT_TO_FEE_COEFF: u32 = /*<weight2fee>*/207_163_598/*</weight2fee>*/;
runtime/common/config/pallets/collator_selection.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/config/pallets/collator_selection.rs
@@ -0,0 +1,78 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+use frame_support::{parameter_types, PalletId};
+use frame_system::EnsureRoot;
+use crate::{
+ AccountId, BlockNumber, Runtime, RuntimeEvent, Balances, Aura, Session, SessionKeys,
+ CollatorSelection,
+};
+use up_common::constants::*;
+
+parameter_types! {
+ pub const SessionPeriod: BlockNumber = HOURS;
+ pub const SessionOffset: BlockNumber = 0;
+}
+
+impl pallet_session::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+ type ValidatorId = <Self as frame_system::Config>::AccountId;
+ // we don't have stash and controller, thus we don't need the convert as well.
+ type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
+ type ShouldEndSession = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
+ type NextSessionRotation = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
+ type SessionManager = CollatorSelection;
+ // Essentially just Aura, but lets be pedantic.
+ type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
+ type Keys = SessionKeys;
+ type WeightInfo = pallet_session::weights::SubstrateWeight<Self>; // ();
+}
+
+parameter_types! {
+ pub const UncleGenerations: u32 = 0;
+}
+
+impl pallet_authorship::Config for Runtime {
+ type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
+ type UncleGenerations = UncleGenerations;
+ type FilterUncle = ();
+ type EventHandler = CollatorSelection;
+}
+
+parameter_types! {
+ pub const PotId: PalletId = PalletId(*b"PotStake");
+ pub const MaxCandidates: u32 = 1000;
+ pub const MinCandidates: u32 = 5;
+ pub const MaxInvulnerables: u32 = 100;
+}
+
+impl pallet_collator_selection::Config for Runtime {
+ type RuntimeEvent = RuntimeEvent;
+ type Currency = Balances;
+ // We allow root only to execute privileged collator selection operations.
+ type UpdateOrigin = EnsureRoot<AccountId>;
+ type PotId = PotId;
+ type MaxCandidates = MaxCandidates;
+ type MinCandidates = MinCandidates;
+ type MaxInvulnerables = MaxInvulnerables;
+ // todo:collator kick threshold should be in storage and configured only by root -- or rather UpdateOrigin
+ // Should be a multiple of session or things will get inconsistent.
+ type KickThreshold = SessionPeriod;
+ type ValidatorId = <Self as frame_system::Config>::AccountId;
+ type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
+ type ValidatorRegistration = Session;
+ type WeightInfo = ();
+}
runtime/common/config/pallets/mod.rsdiffbeforeafterboth--- a/runtime/common/config/pallets/mod.rs
+++ b/runtime/common/config/pallets/mod.rs
@@ -46,6 +46,9 @@
#[cfg(feature = "app-promotion")]
pub mod app_promotion;
+#[cfg(feature = "collator-selection")]
+pub mod collator_selection;
+
parameter_types! {
pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();
pub const CollectionCreationPrice: Balance = 2 * UNIQUE;
runtime/common/config/substrate.rsdiffbeforeafterboth--- a/runtime/common/config/substrate.rs
+++ b/runtime/common/config/substrate.rs
@@ -34,7 +34,7 @@
};
use crate::{
runtime_common::DealWithFees, Runtime, RuntimeEvent, RuntimeCall, RuntimeOrigin, PalletInfo,
- System, Balances, Treasury, SS58Prefix, Aura, Session, SessionKeys, CollatorSelection, Version,
+ System, Balances, Treasury, SS58Prefix, Version,
};
use up_common::{types::*, constants::*};
@@ -215,58 +215,4 @@
type AuthorityId = AuraId;
type DisabledValidators = ();
type MaxAuthorities = MaxAuthorities;
-}
-
-parameter_types! {
- pub const SessionPeriod: BlockNumber = HOURS;
- pub const SessionOffset: BlockNumber = 0;
-}
-
-impl pallet_session::Config for Runtime {
- type RuntimeEvent = RuntimeEvent;
- type ValidatorId = <Self as frame_system::Config>::AccountId;
- // we don't have stash and controller, thus we don't need the convert as well.
- type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
- type ShouldEndSession = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
- type NextSessionRotation = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
- type SessionManager = CollatorSelection;
- // Essentially just Aura, but lets be pedantic.
- type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
- type Keys = SessionKeys;
- type WeightInfo = pallet_session::weights::SubstrateWeight<Self>; // ();
-}
-
-parameter_types! {
- pub const UncleGenerations: u32 = 0;
-}
-
-impl pallet_authorship::Config for Runtime {
- type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
- type UncleGenerations = UncleGenerations;
- type FilterUncle = ();
- type EventHandler = CollatorSelection;
-}
-
-parameter_types! {
- pub const PotId: PalletId = PalletId(*b"PotStake");
- pub const MaxCandidates: u32 = 1000;
- pub const MinCandidates: u32 = 5;
- pub const MaxInvulnerables: u32 = 100;
-}
-
-impl pallet_collator_selection::Config for Runtime {
- type RuntimeEvent = RuntimeEvent;
- type Currency = Balances;
- // We allow root only to execute privileged collator selection operations.
- type UpdateOrigin = EnsureRoot<AccountId>;
- type PotId = PotId;
- type MaxCandidates = MaxCandidates;
- type MinCandidates = MinCandidates;
- type MaxInvulnerables = MaxInvulnerables;
- // Should be a multiple of session or things will get inconsistent.
- type KickThreshold = SessionPeriod;
- type ValidatorId = <Self as frame_system::Config>::AccountId;
- type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
- type ValidatorRegistration = Session;
- type WeightInfo = ();
}
runtime/common/construct_runtime/mod.rsdiffbeforeafterboth--- a/runtime/common/construct_runtime/mod.rs
+++ b/runtime/common/construct_runtime/mod.rs
@@ -32,9 +32,15 @@
ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned} = 20,
ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21,
+ #[runtimes(opal)]
Authorship: pallet_authorship::{Pallet, Call, Storage} = 22,
+
+ #[runtimes(opal)]
CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event<T>, Config<T>} = 23,
+
+ #[runtimes(opal)]
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>} = 24,
+
Aura: pallet_aura::{Pallet, Config<T>} = 25,
AuraExt: cumulus_pallet_aura_ext::{Pallet, Config} = 26,
runtime/common/mod.rsdiffbeforeafterboth--- a/runtime/common/mod.rs
+++ b/runtime/common/mod.rs
@@ -180,154 +180,166 @@
pub struct AuraToCollatorSelection;
impl frame_support::traits::OnRuntimeUpgrade for AuraToCollatorSelection {
fn on_runtime_upgrade() -> Weight {
- use frame_support::{BoundedVec, storage::migration};
- use sp_runtime::{
- traits::{OpaqueKeys, Saturating},
- RuntimeAppPublic,
- };
- use pallet_session::SessionManager;
- use up_common::constants::EXISTENTIAL_DEPOSIT;
- use crate::config::substrate::MaxInvulnerables;
-
- let mut weight = <Runtime as frame_system::Config>::DbWeight::get().reads(1);
+ #[cfg(feature = "collator-selection")]
+ {
+ use frame_support::{BoundedVec, storage::migration};
+ use sp_runtime::{
+ traits::{OpaqueKeys, Saturating},
+ RuntimeAppPublic,
+ };
+ use pallet_session::SessionManager;
+ use up_common::constants::CANDIDACY_BOND;
+ use crate::config::pallets::collator_selection::MaxInvulnerables;
- let version =
- migration::get_storage_value::<()>(b"AuraToCollatorSelection", b"StorageVersion", &[]);
-
- let should_upgrade = match version {
- None => true,
- Some(_) => false,
- };
+ let mut weight = <Runtime as frame_system::Config>::DbWeight::get().reads(1);
- if should_upgrade {
- log::info!(
- target: "runtime::aura_to_collator_selection",
- "Running migration of Aura authorities to Collator Selection invulnerables"
+ let version = migration::get_storage_value::<()>(
+ b"AuraToCollatorSelection",
+ b"StorageVersion",
+ &[],
);
- let invulnerables = pallet_aura::Pallet::<Runtime>::authorities()
- .iter()
- .cloned()
- .filter_map(|authority_id| {
- weight.saturating_accrue(<Runtime as frame_system::Config>::DbWeight::get().reads_writes(1, 1));
- let vec = authority_id.clone().to_raw_vec();
- let slice = vec.as_slice();
- let array: Option<[u8; 32]> = match slice.try_into() {
- Ok(a) => Some(a),
- Err(_) => {
- log::error!("Failed to convert an Aura authority to a Collator Selection invulnerable: {:?}", authority_id);
- None
- },
- };
- array.map(|a| (AccountId::from(a), authority_id))
- })
- .collect::<Vec<_>>();
+ let should_upgrade = match version {
+ None => true,
+ Some(_) => false,
+ };
+
+ if should_upgrade {
+ log::info!(
+ target: "runtime::aura_to_collator_selection",
+ "Running migration of Aura authorities to Collator Selection invulnerables"
+ );
- let bounded_invulnerables = BoundedVec::<_, MaxInvulnerables>::try_from(
- invulnerables
+ let invulnerables = pallet_aura::Pallet::<Runtime>::authorities()
.iter()
.cloned()
- .map(|(acc, _)| acc)
- .collect::<Vec<_>>(),
- )
- .expect("Existing collators/invulnerables are more than MaxInvulnerables");
+ .filter_map(|authority_id| {
+ weight.saturating_accrue(<Runtime as frame_system::Config>::DbWeight::get().reads_writes(1, 1));
+ let vec = authority_id.clone().to_raw_vec();
+ let slice = vec.as_slice();
+ let array: Option<[u8; 32]> = match slice.try_into() {
+ Ok(a) => Some(a),
+ Err(_) => {
+ log::error!("Failed to convert an Aura authority to a Collator Selection invulnerable: {:?}", authority_id);
+ None
+ },
+ };
+ array.map(|a| (AccountId::from(a), authority_id))
+ })
+ .collect::<Vec<_>>();
- <pallet_collator_selection::Invulnerables<Runtime>>::put(bounded_invulnerables);
- <pallet_collator_selection::DesiredCandidates<Runtime>>::put(0);
- <pallet_collator_selection::CandidacyBond<Runtime>>::put(EXISTENTIAL_DEPOSIT * 16);
+ let bounded_invulnerables = BoundedVec::<_, MaxInvulnerables>::try_from(
+ invulnerables
+ .iter()
+ .cloned()
+ .map(|(acc, _)| acc)
+ .collect::<Vec<_>>(),
+ )
+ .expect("Existing collators/invulnerables are more than MaxInvulnerables");
+
+ <pallet_collator_selection::Invulnerables<Runtime>>::put(bounded_invulnerables);
+ <pallet_collator_selection::DesiredCandidates<Runtime>>::put(0);
+ <pallet_collator_selection::CandidacyBond<Runtime>>::put(CANDIDACY_BOND);
- let keys = invulnerables
- .into_iter()
- .map(|(acc, aura)| {
- (
- acc.clone(), // account id
- acc, // validator id
- SessionKeys { aura: aura.clone() }, // session keys
- )
- })
- .collect::<Vec<_>>();
+ let keys = invulnerables
+ .into_iter()
+ .map(|(acc, aura)| {
+ (
+ acc.clone(), // account id
+ acc, // validator id
+ SessionKeys { aura: aura.clone() }, // session keys
+ )
+ })
+ .collect::<Vec<_>>();
- for (account, val, keys) in keys.iter().cloned() {
- for id in <Runtime as pallet_session::Config>::Keys::key_ids() {
- <pallet_session::KeyOwner<Runtime>>::insert((*id, keys.get_raw(*id)), &val)
- }
- <pallet_session::NextKeys<Runtime>>::insert(&val, &keys);
- // todo exercise caution, the following is taken from genesis
- if frame_system::Pallet::<Runtime>::inc_consumers_without_limit(&account).is_err() {
- log::warn!(
- "We have entered an error with incrementing consumers without limit during the migration"
- );
- // This will leak a provider reference, however it only happens once (at
- // genesis) so it's really not a big deal and we assume that the user wants to
- // do this since it's the only way a non-endowed account can contain a session
- // key.
- frame_system::Pallet::<Runtime>::inc_providers(&account);
+ for (account, val, keys) in keys.iter().cloned() {
+ for id in <Runtime as pallet_session::Config>::Keys::key_ids() {
+ <pallet_session::KeyOwner<Runtime>>::insert((*id, keys.get_raw(*id)), &val)
+ }
+ <pallet_session::NextKeys<Runtime>>::insert(&val, &keys);
+ // todo exercise caution, the following is taken from genesis
+ if frame_system::Pallet::<Runtime>::inc_consumers_without_limit(&account)
+ .is_err()
+ {
+ log::warn!(
+ "We have entered an error with incrementing consumers without limit during the migration"
+ );
+ // This will leak a provider reference, however it only happens once (at
+ // genesis) so it's really not a big deal and we assume that the user wants to
+ // do this since it's the only way a non-endowed account can contain a session
+ // key.
+ frame_system::Pallet::<Runtime>::inc_providers(&account);
+ }
}
- }
- let initial_validators_0 =
- <Runtime as pallet_session::Config>::SessionManager::new_session(0).unwrap_or_else(
- || {
- frame_support::print(
- "No initial validator provided by `SessionManager`, use \
- session config keys to generate initial validator set.",
- );
- keys.iter().map(|x| x.1.clone()).collect()
- },
- );
- /*assert!(
- !initial_validators_0.is_empty(),
- "Empty validator set for session 0 in (pseudo) genesis block!"
- );*/
+ let initial_validators_0 =
+ <Runtime as pallet_session::Config>::SessionManager::new_session(0)
+ .unwrap_or_else(|| {
+ frame_support::print(
+ "No initial validator provided by `SessionManager`, use \
+ session config keys to generate initial validator set.",
+ );
+ keys.iter().map(|x| x.1.clone()).collect()
+ });
+ /*assert!(
+ !initial_validators_0.is_empty(),
+ "Empty validator set for session 0 in (pseudo) genesis block!"
+ );*/
- let initial_validators_1 =
- <Runtime as pallet_session::Config>::SessionManager::new_session(1)
- .unwrap_or_else(|| initial_validators_0.clone());
- /*assert!(
- !initial_validators_1.is_empty(),
- "Empty validator set for session 1 in (pseudo) genesis block!"
- );*/
+ let initial_validators_1 =
+ <Runtime as pallet_session::Config>::SessionManager::new_session(1)
+ .unwrap_or_else(|| initial_validators_0.clone());
+ /*assert!(
+ !initial_validators_1.is_empty(),
+ "Empty validator set for session 1 in (pseudo) genesis block!"
+ );*/
- let queued_keys: Vec<_> = initial_validators_1
- .iter()
- .cloned()
- .map(|v| {
- (
- v.clone(),
- <pallet_session::NextKeys<Runtime>>::get(&v)
- .expect("Validator in session 1 missing keys!"),
- )
- })
- .collect();
+ let queued_keys: Vec<_> = initial_validators_1
+ .iter()
+ .cloned()
+ .map(|v| {
+ (
+ v.clone(),
+ <pallet_session::NextKeys<Runtime>>::get(&v)
+ .expect("Validator in session 1 missing keys!"),
+ )
+ })
+ .collect();
- // Tell everyone about the genesis session keys -- Aura must've already initialized it
- //<Runtime as pallet_session::Config>::SessionHandler::on_genesis_session::<<Runtime as pallet_session::Config>::Keys>(&queued_keys);
+ // Tell everyone about the genesis session keys -- Aura must've already initialized it
+ //<Runtime as pallet_session::Config>::SessionHandler::on_genesis_session::<<Runtime as pallet_session::Config>::Keys>(&queued_keys);
+
+ <pallet_session::Validators<Runtime>>::put(initial_validators_0);
+ <pallet_session::QueuedKeys<Runtime>>::put(queued_keys);
- <pallet_session::Validators<Runtime>>::put(initial_validators_0);
- <pallet_session::QueuedKeys<Runtime>>::put(queued_keys);
+ <Runtime as pallet_session::Config>::SessionManager::start_session(0);
- <Runtime as pallet_session::Config>::SessionManager::start_session(0);
+ log::info!(
+ target: "runtime::aura_to_collator_selection",
+ "Migration of Aura authorities to Collator Selection invulnerables is complete."
+ );
- log::info!(
- target: "runtime::aura_to_collator_selection",
- "Migration of Aura authorities to Collator Selection invulnerables is complete."
- );
+ migration::put_storage_value::<()>(
+ b"AuraToCollatorSelection",
+ b"StorageVersion",
+ &[],
+ (),
+ );
- migration::put_storage_value::<()>(
- b"AuraToCollatorSelection",
- b"StorageVersion",
- &[],
- (),
- );
+ weight += <Runtime as frame_system::Config>::DbWeight::get().writes(1)
+ } else {
+ log::info!(
+ target: "runtime::aura_to_collator_selection",
+ "The storage migration has already been flagged as complete. No migration needs to be done.",
+ );
+ }
- weight += <Runtime as frame_system::Config>::DbWeight::get().writes(1)
- } else {
- log::info!(
- target: "runtime::aura_to_collator_selection",
- "The storage migration has already been flagged as complete. No migration needs to be done.",
- );
+ weight
}
- weight
+ #[cfg(not(feature = "collator-selection"))]
+ {
+ Weight::zero()
+ }
}
}
runtime/opal/Cargo.tomldiffbeforeafterboth--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -173,13 +173,14 @@
"pallet-foreign-assets/std",
]
limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
-opal-runtime = ['refungible', 'rmrk', 'app-promotion', 'foreign-assets']
+opal-runtime = ['refungible', 'rmrk', 'app-promotion', 'foreign-assets', 'collator-selection']
refungible = []
scheduler = []
rmrk = []
foreign-assets = []
app-promotion = []
+collator-selection = []
################################################################################
# Substrate Dependencies
runtime/quartz/Cargo.tomldiffbeforeafterboth--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -177,6 +177,7 @@
scheduler = []
rmrk = []
foreign-assets = []
+collator-selection = []
################################################################################
# Substrate Dependencies
runtime/unique/Cargo.tomldiffbeforeafterboth--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -178,6 +178,7 @@
scheduler = []
rmrk = []
foreign-assets = []
+collator-selection = []
################################################################################
# Substrate Dependencies