From 31011a164ac2090f9609af710621a26d93cdd843 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Wed, 25 Sep 2024 17:20:17 +0200 Subject: [PATCH] chainspec --- Cargo.lock | 1 + node/Cargo.toml | 1 + node/src/chain_spec/mod.rs | 1 + node/src/chain_spec/paseo.rs | 291 +++++++++++++++++++++++++++++++++++ node/src/command.rs | 33 +++- node/src/service.rs | 16 +- runtime/paseo/src/lib.rs | 2 +- 7 files changed, 341 insertions(+), 4 deletions(-) create mode 100644 node/src/chain_spec/paseo.rs diff --git a/Cargo.lock b/Cargo.lock index d119768a..819ee96c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9741,6 +9741,7 @@ dependencies = [ "pallet-ismp-runtime-api", "pallet-transaction-payment-rpc", "parity-scale-codec", + "paseo-runtime", "polkadot-cli", "polkadot-primitives", "regionx-runtime-common", diff --git a/node/Cargo.toml b/node/Cargo.toml index 47474b87..16281cf1 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -19,6 +19,7 @@ serde_json = { workspace = true } # Local cocos-runtime = { workspace = true } +paseo-runtime = { workspace = true } regionx-runtime-common = { workspace = true } # Polytope Labs diff --git a/node/src/chain_spec/mod.rs b/node/src/chain_spec/mod.rs index b08d9a1b..e0c5af41 100644 --- a/node/src/chain_spec/mod.rs +++ b/node/src/chain_spec/mod.rs @@ -19,6 +19,7 @@ use sp_core::{Pair, Public}; use sp_runtime::traits::{IdentifyAccount, Verify}; pub mod cocos; +pub mod paseo; type AccountPublic = ::Signer; diff --git a/node/src/chain_spec/paseo.rs b/node/src/chain_spec/paseo.rs new file mode 100644 index 00000000..983f0488 --- /dev/null +++ b/node/src/chain_spec/paseo.rs @@ -0,0 +1,291 @@ +// This file is part of RegionX. +// +// RegionX 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. +// +// RegionX 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 RegionX. If not, see . + +use crate::chain_spec::{ + get_account_id_from_seed, get_collator_keys_from_seed, ChainSpec, Extensions, +}; +use cumulus_primitives_core::ParaId; +use orml_asset_registry::AssetMetadata; +use paseo_runtime::{REGX, REGX_EXISTENTIAL_DEPOSIT, ROC_EXISTENTIAL_DEPOSIT}; +use regionx_runtime_common::{ + assets::{AssetsStringLimit, RELAY_CHAIN_ASSET_ID}, + primitives::{AccountId, AuraId, Balance}, +}; +use sc_service::ChainType; +use sp_core::{sr25519, Encode}; +use xcm::opaque::lts::MultiLocation; + +/// The default XCM version to set in genesis config. +const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION; + +/// Generate the session keys from individual elements. +/// +/// The input must be a tuple of individual keys (a single arg for now since we have just one key). +pub fn session_keys(keys: AuraId) -> paseo_runtime::SessionKeys { + paseo_runtime::SessionKeys { aura: keys } +} + +pub fn paseo_config(id: u32) -> ChainSpec { + // Give your base currency a unit name and decimal places + let mut properties = sc_chain_spec::Properties::new(); + properties.insert("tokenSymbol".into(), "REGX".into()); + properties.insert("tokenDecimals".into(), 12.into()); + properties.insert("ss58Format".into(), 42.into()); + + ChainSpec::builder( + paseo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), + Extensions { relay_chain: "paseo".into(), para_id: id }, + ) + .with_name("RegionX (Paseo)") + .with_id("regionx-paseo") + .with_chain_type(ChainType::Live) + .with_genesis_config_patch(paseo_genesis(id.into())) + .with_protocol_id("regionx-paseo") + .with_properties(properties) + .build() +} + +pub fn development_config(id: u32) -> ChainSpec { + // Give your base currency a unit name and decimal places + let mut properties = sc_chain_spec::Properties::new(); + properties.insert("tokenSymbol".into(), "REGX".into()); + properties.insert("tokenDecimals".into(), 12.into()); + properties.insert("ss58Format".into(), 42.into()); + + ChainSpec::builder( + paseo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), + Extensions { + relay_chain: "rococo-local".into(), + // You MUST set this to the correct network! + para_id: id, + }, + ) + .with_name("RegionX (Paseo Development)") + .with_id("dev") + .with_chain_type(ChainType::Development) + .with_genesis_config_patch(testnet_genesis( + // initial collators. + vec![ + ( + get_account_id_from_seed::("Alice"), + get_collator_keys_from_seed("Alice"), + ), + ( + get_account_id_from_seed::("Bob"), + get_collator_keys_from_seed("Bob"), + ), + ], + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ], + get_account_id_from_seed::("Alice"), + id.into(), + )) + .with_protocol_id("regionx-dev") + .with_properties(properties) + .build() +} + +pub fn local_testnet_config(id: u32) -> ChainSpec { + // Give your base currency a unit name and decimal places + let mut properties = sc_chain_spec::Properties::new(); + properties.insert("tokenSymbol".into(), "REGX".into()); + properties.insert("tokenDecimals".into(), 12.into()); + properties.insert("ss58Format".into(), 42.into()); + + ChainSpec::builder( + paseo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), + Extensions { + relay_chain: "rococo-local".into(), + // You MUST set this to the correct network! + para_id: id, + }, + ) + .with_name("RegionX (Paseo Local)") + .with_id("regionx-paseo-local") + .with_chain_type(ChainType::Local) + .with_genesis_config_patch(testnet_genesis( + // initial collators. + vec![ + ( + get_account_id_from_seed::("Alice"), + get_collator_keys_from_seed("Alice"), + ), + ( + get_account_id_from_seed::("Bob"), + get_collator_keys_from_seed("Bob"), + ), + ], + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ], + get_account_id_from_seed::("Alice"), + id.into(), + )) + .with_protocol_id("regionx_paseo_local") + .with_properties(properties) + .build() +} + +fn paseo_genesis(id: ParaId) -> serde_json::Value { + serde_json::json!({ + "parachainInfo": { + "parachainId": id, + }, + "collatorSelection": { + "candidacyBond": 500 * REGX, + "invulnerables": [ + "5Gjj1GhDTyXjwk823TJsKMfv6DqtnwTwYyRZeygiWPQLv4vq" + ] + }, + "assetRegistry": { + "lastAssetId": RELAY_CHAIN_ASSET_ID, + "assets": vec![(RELAY_CHAIN_ASSET_ID, + AssetMetadata::::encode(&AssetMetadata{ + decimals: 12, + name: b"ROC".to_vec().try_into().expect("Invalid asset name"), + symbol: b"ROC".to_vec().try_into().expect("Invalid asset symbol"), + existential_deposit: ROC_EXISTENTIAL_DEPOSIT, + location: Some(MultiLocation::parent().into()), + additional: Default::default(), + }) + )] + }, + "sudo": { + // It should be needless to say that sudo is only available on the testnet. + "key": "5DADsnBXr5DXiEAjdJvruf6c7ZSUR8iXUTATQqJfheGLiEVm" + }, + "balances": { + "balances": [ + [ + "5DADsnBXr5DXiEAjdJvruf6c7ZSUR8iXUTATQqJfheGLiEVm", + 500_000 * REGX + ], + [ + "5F76zmFCUHBaSFoCecC54VCiZMpPWnRy4oPBrZpeLiuYRVCn", + 500_000 * REGX + ], + [ + "5DqwiiztGYq9P4jxG7RJJQWz4dMYREtbMrMSv62TwRAqVa1v", + 500_000 * REGX + ], + [ + "5FbSPQrNexY6dZ2JEVRguyqtrZbpD7qzRttXbiWKneagfEqr", + 500_000 * REGX + ], + [ + "5Gjj1GhDTyXjwk823TJsKMfv6DqtnwTwYyRZeygiWPQLv4vq", + 100_000 * REGX + ], + [ + "5HGe3UghLKPuYPAkzFWwfARkGmE5mJ4sjs5SF8xfvtiB7o4v", + 10_000 * REGX + ], + ] + }, + "technicalCommittee": { + "members": [ + "5DADsnBXr5DXiEAjdJvruf6c7ZSUR8iXUTATQqJfheGLiEVm", + "5DqwiiztGYq9P4jxG7RJJQWz4dMYREtbMrMSv62TwRAqVa1v", + "5FbSPQrNexY6dZ2JEVRguyqtrZbpD7qzRttXbiWKneagfEqr", + ] + }, + "session": { + "keys": [ + [ + "5Gjj1GhDTyXjwk823TJsKMfv6DqtnwTwYyRZeygiWPQLv4vq", + "5Gjj1GhDTyXjwk823TJsKMfv6DqtnwTwYyRZeygiWPQLv4vq", + { + "aura": "5Gjj1GhDTyXjwk823TJsKMfv6DqtnwTwYyRZeygiWPQLv4vq" + } + ] + ] + }, + "polkadotXcm": { + "safeXcmVersion": Some(SAFE_XCM_VERSION), + }, + }) +} + +fn testnet_genesis( + invulnerables: Vec<(AccountId, AuraId)>, + endowed_accounts: Vec, + root: AccountId, + id: ParaId, +) -> serde_json::Value { + serde_json::json!({ + "balances": { + "balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::>(), + }, + "parachainInfo": { + "parachainId": id, + }, + "collatorSelection": { + "invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::>(), + "candidacyBond": REGX_EXISTENTIAL_DEPOSIT * 16, + }, + "assetRegistry": { + "lastAssetId": RELAY_CHAIN_ASSET_ID, + "assets": vec![(RELAY_CHAIN_ASSET_ID, + AssetMetadata::::encode(&AssetMetadata{ + decimals: 12, + name: b"ROC".to_vec().try_into().expect("Invalid asset name"), + symbol: b"ROC".to_vec().try_into().expect("Invalid asset symbol"), + existential_deposit: ROC_EXISTENTIAL_DEPOSIT, + location: Some(MultiLocation::parent().into()), + additional: Default::default(), + }) + )] + }, + "session": { + "keys": invulnerables + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + session_keys(aura), // session keys + ) + }) + .collect::>(), + }, + "polkadotXcm": { + "safeXcmVersion": Some(SAFE_XCM_VERSION), + }, + "sudo": { "key": Some(root) } + }) +} diff --git a/node/src/command.rs b/node/src/command.rs index 8ae60a83..b120a1fa 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -29,11 +29,15 @@ use sp_runtime::traits::AccountIdConversion; use crate::{ chain_spec, cli::{Cli, RelayChainCli, Subcommand}, - service::{is_cocos, new_partial}, + service::{is_cocos, is_paseo, new_partial}, }; fn load_spec(id: &str) -> std::result::Result, String> { Ok(match id { + // TODO: Para Id + "regionx-paseo" => Box::new(chain_spec::paseo::paseo_config(2000)), + "regionx-paseo-dev" => Box::new(chain_spec::paseo::development_config(2000)), + "regionx-paseo-local" => Box::new(chain_spec::paseo::local_testnet_config(2000)), "cocos" => Box::new(chain_spec::cocos::cocos_config(4479)), "cocos-dev" | "dev" | "" => Box::new(chain_spec::cocos::development_config(2000)), "cocos-local" | "local" => Box::new(chain_spec::cocos::local_testnet_config(2000)), @@ -120,7 +124,15 @@ macro_rules! construct_async_run { (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{ let runner = $cli.create_runner($cmd)?; match runner.config().chain_spec.id() { - chain if is_cocos(chain) => { + chain if is_paseo(chain) => { + runner.async_run(|$config| { + let executor = sc_service::new_wasm_executor::(&$config); + let $components = new_partial::(&$config, executor)?; + let task_manager = $components.task_manager; + { $( $code )* }.map(|v| (v, task_manager)) + }) + }, + chain if is_cocos(chain) => { runner.async_run(|$config| { let executor = sc_service::new_wasm_executor::(&$config); let $components = new_partial::(&$config, executor)?; @@ -191,6 +203,11 @@ pub fn run() -> Result<()> { runner.sync_run(|config| { let executor = sc_service::new_wasm_executor::(&config); match config.chain_spec.id() { + chain if is_paseo(chain) => { + let partials = + new_partial::(&config, executor)?; + cmd.run(partials.client) + }, chain if is_cocos(chain) => { let partials = new_partial::(&config, executor)?; @@ -223,6 +240,11 @@ pub fn run() -> Result<()> { let executor = sc_service::new_wasm_executor::(&config); match config.chain_spec.id() { + chain if is_paseo(chain) => { + let partials = + new_partial::(&config, executor)?; + cmd.run(partials.client) + }, chain if is_cocos(chain) => { let partials = new_partial::(&config, executor)?; @@ -244,6 +266,13 @@ pub fn run() -> Result<()> { let executor = sc_service::new_wasm_executor::(&config); match config.chain_spec.id() { + chain if is_paseo(chain) => { + let partials = + new_partial::(&config, executor)?; + let db = partials.backend.expose_db(); + let storage = partials.backend.expose_storage(); + cmd.run(config, partials.client.clone(), db, storage) + }, chain if is_cocos(chain) => { let partials = new_partial::(&config, executor)?; diff --git a/node/src/service.rs b/node/src/service.rs index b812b645..6fe20f65 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -67,8 +67,13 @@ pub type Service = PartialComponents< (ParachainBlockImport, Option, Option), >; +pub fn is_paseo(id: &str) -> bool { + // Default to paseo + id.contains("paseo") || id.is_empty() +} + pub fn is_cocos(id: &str) -> bool { - id.contains("cocos") || id.is_empty() || id.contains("dev") || id.contains("local") + id.contains("cocos") } /// Starts a `ServiceBuilder` for a full service. @@ -471,6 +476,15 @@ pub async fn start_parachain_node( hwbench: Option, ) -> sc_service::error::Result { match parachain_config.chain_spec.id() { + chain if is_paseo(chain) => + start_node_impl::( + parachain_config, + polkadot_config, + collator_options, + para_id, + hwbench, + ) + .await, chain if is_cocos(chain) => start_node_impl::( parachain_config, diff --git a/runtime/paseo/src/lib.rs b/runtime/paseo/src/lib.rs index f9f4d78b..1fb44450 100644 --- a/runtime/paseo/src/lib.rs +++ b/runtime/paseo/src/lib.rs @@ -435,7 +435,7 @@ impl orml_asset_registry::Config for Runtime { parameter_types! { // TODO: Make sure this is reasonable - pub const TransactionByteFee: Balance = 20 * MICRO_REGX; + pub const TransactionByteFee: Balance = 50 * MICRO_REGX; } impl pallet_transaction_payment::Config for Runtime {