1234567891011121314151617use 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;373839#[cfg(feature = "unique-runtime")]40pub type UniqueChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;414243#[cfg(feature = "quartz-runtime")]44pub type QuartzChainSpec = sc_service::GenericChainSpec<quartz_runtime::GenesisConfig, Extensions>;454647pub 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"))]7071const PARA_ID: u32 = 2095;7273#[cfg(feature = "unique-runtime")]7475const 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}119120121pub 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}126127128#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]129#[serde(deny_unknown_fields)]130pub struct Extensions {131 132 pub relay_chain: String,133 134 pub para_id: u32,135}136137impl Extensions {138 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;145146147pub 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 175 .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(), 203 acc, 204 SessionKeys { aura }, 205 )206 })207 .collect(),208 },209 aura: Default::default(),210 211212213 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 233 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 244 format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),245 ChainType::Local,246 move || {247 testnet_genesis!(248 default_runtime,249 250 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 262 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 280 vec![],281 282 None,283 284 None,285 None,286 287 Some(properties),288 289 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 307 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 318 format!("{}_local", default_runtime::RUNTIME_NAME).as_str(),319 ChainType::Local,320 move || {321 testnet_genesis!(322 default_runtime,323 324 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 336 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 354 vec![],355 356 None,357 358 None,359 None,360 361 Some(properties),362 363 Extensions {364 relay_chain: "westend-local".into(),365 para_id: PARA_ID,366 },367 )368}