difftreelog
Adjust node and rpc to work with different runtimes
in: master
7 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11942,6 +11942,7 @@
"opal-runtime",
"pallet-ethereum",
"pallet-transaction-payment-rpc",
+ "pallet-transaction-payment-rpc-runtime-api",
"parity-scale-codec",
"parking_lot 0.11.2",
"polkadot-cli",
@@ -11988,7 +11989,9 @@
"substrate-prometheus-endpoint",
"unique-rpc",
"unique-runtime",
+ "unique-runtime-common",
"up-data-structs",
+ "up-rpc",
]
[[package]]
@@ -12003,12 +12006,11 @@
"futures 0.3.21",
"jsonrpc-core",
"jsonrpc-pubsub",
- "opal-runtime",
+ "pallet-common",
"pallet-ethereum",
"pallet-transaction-payment-rpc",
"pallet-transaction-payment-rpc-runtime-api",
"pallet-unique",
- "quartz-runtime",
"sc-client-api",
"sc-consensus-aura",
"sc-consensus-epochs",
@@ -12020,6 +12022,7 @@
"sc-rpc-api",
"sc-service",
"sc-transaction-pool",
+ "serde",
"sp-api",
"sp-block-builder",
"sp-blockchain",
@@ -12034,7 +12037,7 @@
"substrate-frame-rpc-system",
"tokio 0.2.25",
"uc-rpc",
- "unique-runtime",
+ "unique-runtime-common",
"up-rpc",
]
@@ -12118,10 +12121,13 @@
name = "unique-runtime-common"
version = "0.1.0"
dependencies = [
+ "fp-rpc",
"frame-support",
"frame-system",
+ "pallet-common",
"parity-scale-codec",
"scale-info",
+ "sp-consensus-aura",
"sp-core",
"sp-runtime",
]
node/cli/Cargo.tomldiffbeforeafterboth--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -238,6 +238,10 @@
################################################################################
# Local dependencies
+[dependencies.unique-runtime-common]
+default-features = false
+path = "../../runtime/common"
+
[dependencies.unique-runtime]
path = '../../runtime/unique'
optional = true
@@ -254,6 +258,13 @@
path = "../../primitives/data-structs"
default-features = false
+[dependencies.up-rpc]
+path = "../../primitives/rpc"
+
+[dependencies.pallet-transaction-payment-rpc-runtime-api]
+git = 'https://github.com/paritytech/substrate.git'
+branch = 'polkadot-v0.9.17'
+
################################################################################
# Package
@@ -295,7 +306,7 @@
unique-rpc = { default-features = false, path = "../rpc" }
[features]
-default = ["unique-runtime"]
+default = ["unique-runtime", "quartz-runtime", "opal-runtime"]
runtime-benchmarks = [
'unique-runtime/runtime-benchmarks',
'polkadot-service/runtime-benchmarks',
node/cli/src/chain_spec.rsdiffbeforeafterboth--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -24,20 +24,33 @@
use serde::{Deserialize, Serialize};
use serde_json::map::Map;
-#[cfg(feature = "unique-runtime")]
-use unique_runtime as runtime;
+use unique_runtime_common::types::*;
-#[cfg(feature = "quartz-runtime")]
-use quartz_runtime as runtime;
+/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
+pub type ChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;
-#[cfg(feature = "opal-runtime")]
-use opal_runtime as runtime;
+pub trait RuntimeIdentification {
+ fn is_unique(&self) -> bool;
+
+ fn is_quartz(&self) -> bool;
-use runtime::{*, opaque::*};
+ fn is_opal(&self) -> bool;
+}
-/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
-pub type ChainSpec = sc_service::GenericChainSpec<runtime::GenesisConfig, Extensions>;
+impl RuntimeIdentification for Box<dyn sc_service::ChainSpec> {
+ fn is_unique(&self) -> bool {
+ self.id().starts_with("unique")
+ }
+ fn is_quartz(&self) -> bool {
+ self.id().starts_with("quartz")
+ }
+
+ fn is_opal(&self) -> bool {
+ self.id().starts_with("opal")
+ }
+}
+
/// Helper function to generate a crypto pair from seed
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
TPublic::Pair::from_string(&format!("//{}", seed), None)
@@ -225,10 +238,12 @@
initial_authorities: Vec<AuraId>,
endowed_accounts: Vec<AccountId>,
id: ParaId,
-) -> GenesisConfig {
+) -> unique_runtime::GenesisConfig {
+ use unique_runtime::*;
+
GenesisConfig {
- system: runtime::SystemConfig {
- code: runtime::WASM_BINARY
+ system: SystemConfig {
+ code: WASM_BINARY
.expect("WASM binary was not build, please build it!")
.to_vec(),
},
@@ -245,9 +260,9 @@
key: Some(root_key),
},
vesting: VestingConfig { vesting: vec![] },
- parachain_info: runtime::ParachainInfoConfig { parachain_id: id },
+ parachain_info: ParachainInfoConfig { parachain_id: id },
parachain_system: Default::default(),
- aura: runtime::AuraConfig {
+ aura: AuraConfig {
authorities: initial_authorities,
},
aura_ext: Default::default(),
node/cli/src/command.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/>.1617// Original license18// This file is part of Substrate.1920// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd.21// SPDX-License-Identifier: Apache-2.02223// Licensed under the Apache License, Version 2.0 (the "License");24// you may not use this file except in compliance with the License.25// You may obtain a copy of the License at26//27// http://www.apache.org/licenses/LICENSE-2.028//29// Unless required by applicable law or agreed to in writing, software30// distributed under the License is distributed on an "AS IS" BASIS,31// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.32// See the License for the specific language governing permissions and33// limitations under the License.3435use crate::{36 chain_spec,37 cli::{Cli, RelayChainCli, Subcommand},38 service::{new_partial, ParachainRuntimeExecutor},39};40use codec::Encode;41use cumulus_primitives_core::ParaId;42use cumulus_client_service::genesis::generate_genesis_block;43use log::info;44use polkadot_parachain::primitives::AccountIdConversion;45use sc_cli::{46 ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams,47 NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli,48};49use sc_service::{50 config::{BasePath, PrometheusConfig},51};52use sp_core::hexdisplay::HexDisplay;53use sp_runtime::traits::Block as BlockT;54use std::{io::Write, net::SocketAddr};5556#[cfg(feature = "unique-runtime")]57use unique_runtime as runtime;5859#[cfg(feature = "quartz-runtime")]60use quartz_runtime as runtime;6162#[cfg(feature = "opal-runtime")]63use opal_runtime as runtime;6465use runtime::Block;6667fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {68 Ok(match id {69 "westend-local" => Box::new(chain_spec::local_testnet_westend_config()),70 "rococo-local" => Box::new(chain_spec::local_testnet_rococo_config()),71 "dev" => Box::new(chain_spec::development_config()),72 "" | "local" => Box::new(chain_spec::local_testnet_rococo_config()),73 path => Box::new(chain_spec::ChainSpec::from_json_file(74 std::path::PathBuf::from(path),75 )?),76 })77}7879impl SubstrateCli for Cli {80 // TODO use args81 fn impl_name() -> String {82 format!("{} Node", runtime::RUNTIME_NAME)83 }8485 fn impl_version() -> String {86 env!("SUBSTRATE_CLI_IMPL_VERSION").into()87 }88 // TODO use args89 fn description() -> String {90 format!(91 "{} Node\n\nThe command-line arguments provided first will be \92 passed to the parachain node, while the arguments provided after -- will be passed \93 to the relaychain node.\n\n\94 {} [parachain-args] -- [relaychain-args]",95 runtime::RUNTIME_NAME,96 Self::executable_name()97 )98 }99100 fn author() -> String {101 env!("CARGO_PKG_AUTHORS").into()102 }103104 //TODO use args105 fn support_url() -> String {106 "support@unique.network".into()107 }108109 fn copyright_start_year() -> i32 {110 2019111 }112113 fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {114 load_spec(id)115 }116117 fn native_runtime_version(_: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {118 &runtime::VERSION119 }120}121122impl SubstrateCli for RelayChainCli {123 // TODO use args124 fn impl_name() -> String {125 format!("{} Node", runtime::RUNTIME_NAME)126 }127128 fn impl_version() -> String {129 env!("SUBSTRATE_CLI_IMPL_VERSION").into()130 }131 // TODO use args132 fn description() -> String {133 format!(134 "{} Node\n\nThe command-line arguments provided first will be \135 passed to the parachain node, while the arguments provided after -- will be passed \136 to the relaychain node.\n\n\137 parachain-collator [parachain-args] -- [relaychain-args]",138 runtime::RUNTIME_NAME139 )140 }141142 fn author() -> String {143 env!("CARGO_PKG_AUTHORS").into()144 }145 // TODO use args146 fn support_url() -> String {147 "support@unique.network".into()148 }149150 fn copyright_start_year() -> i32 {151 2019152 }153154 fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {155 polkadot_cli::Cli::from_iter([RelayChainCli::executable_name()].iter()).load_spec(id)156 }157158 fn native_runtime_version(chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {159 polkadot_cli::Cli::native_runtime_version(chain_spec)160 }161}162163#[allow(clippy::borrowed_box)]164fn extract_genesis_wasm(chain_spec: &Box<dyn sc_service::ChainSpec>) -> Result<Vec<u8>> {165 let mut storage = chain_spec.build_storage()?;166167 storage168 .top169 .remove(sp_core::storage::well_known_keys::CODE)170 .ok_or_else(|| "Could not find wasm file in genesis state!".into())171}172173macro_rules! construct_async_run {174 (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{175 let runner = $cli.create_runner($cmd)?;176 runner.async_run(|$config| {177 let $components = new_partial::<178 _179 >(180 &$config,181 crate::service::parachain_build_import_queue,182 )?;183 let task_manager = $components.task_manager;184 { $( $code )* }.map(|v| (v, task_manager))185 })186 }}187}188189/// Parse command line arguments into service configuration.190pub fn run() -> Result<()> {191 let cli = Cli::from_args();192193 match &cli.subcommand {194 Some(Subcommand::BuildSpec(cmd)) => {195 let runner = cli.create_runner(cmd)?;196 runner.sync_run(|config| cmd.run(config.chain_spec, config.network))197 }198 Some(Subcommand::CheckBlock(cmd)) => {199 construct_async_run!(|components, cli, cmd, config| {200 Ok(cmd.run(components.client, components.import_queue))201 })202 }203 Some(Subcommand::ExportBlocks(cmd)) => {204 construct_async_run!(|components, cli, cmd, config| {205 Ok(cmd.run(components.client, config.database))206 })207 }208 Some(Subcommand::ExportState(cmd)) => {209 construct_async_run!(|components, cli, cmd, config| {210 Ok(cmd.run(components.client, config.chain_spec))211 })212 }213 Some(Subcommand::ImportBlocks(cmd)) => {214 construct_async_run!(|components, cli, cmd, config| {215 Ok(cmd.run(components.client, components.import_queue))216 })217 }218 Some(Subcommand::PurgeChain(cmd)) => {219 let runner = cli.create_runner(cmd)?;220221 runner.sync_run(|config| {222 let polkadot_cli = RelayChainCli::new(223 &config,224 [RelayChainCli::executable_name()]225 .iter()226 .chain(cli.relaychain_args.iter()),227 );228229 let polkadot_config = SubstrateCli::create_configuration(230 &polkadot_cli,231 &polkadot_cli,232 config.tokio_handle.clone(),233 )234 .map_err(|err| format!("Relay chain argument error: {}", err))?;235236 cmd.run(config, polkadot_config)237 })238 }239 Some(Subcommand::Revert(cmd)) => construct_async_run!(|components, cli, cmd, config| {240 Ok(cmd.run(components.client, components.backend))241 }),242 Some(Subcommand::ExportGenesisState(params)) => {243 let mut builder = sc_cli::LoggerBuilder::new("");244 builder.with_profiling(sc_tracing::TracingReceiver::Log, "");245 let _ = builder.init();246247 let spec = load_spec(¶ms.chain.clone().unwrap_or_default())?;248 let state_version = Cli::native_runtime_version(&spec).state_version();249 let block: Block = generate_genesis_block(&spec, state_version)?;250 let raw_header = block.header().encode();251 let output_buf = if params.raw {252 raw_header253 } else {254 format!("0x{:?}", HexDisplay::from(&block.header().encode())).into_bytes()255 };256257 if let Some(output) = ¶ms.output {258 std::fs::write(output, output_buf)?;259 } else {260 std::io::stdout().write_all(&output_buf)?;261 }262263 Ok(())264 }265 Some(Subcommand::ExportGenesisWasm(params)) => {266 let mut builder = sc_cli::LoggerBuilder::new("");267 builder.with_profiling(sc_tracing::TracingReceiver::Log, "");268 let _ = builder.init();269270 let raw_wasm_blob =271 extract_genesis_wasm(&cli.load_spec(¶ms.chain.clone().unwrap_or_default())?)?;272 let output_buf = if params.raw {273 raw_wasm_blob274 } else {275 format!("0x{:?}", HexDisplay::from(&raw_wasm_blob)).into_bytes()276 };277278 if let Some(output) = ¶ms.output {279 std::fs::write(output, output_buf)?;280 } else {281 std::io::stdout().write_all(&output_buf)?;282 }283284 Ok(())285 }286 Some(Subcommand::Benchmark(cmd)) => {287 if cfg!(feature = "runtime-benchmarks") {288 let runner = cli.create_runner(cmd)?;289290 runner.sync_run(|config| cmd.run::<Block, ParachainRuntimeExecutor>(config))291 } else {292 Err("Benchmarking wasn't enabled when building the node. \293 You can enable it with `--features runtime-benchmarks`."294 .into())295 }296 }297 None => {298 let runner = cli.create_runner(&cli.run.normalize())?;299300 runner.run_node_until_exit(|config| async move {301 let para_id = chain_spec::Extensions::try_get(&*config.chain_spec)302 .map(|e| e.para_id)303 .ok_or("Could not find parachain ID in chain-spec.")?;304305 let polkadot_cli = RelayChainCli::new(306 &config,307 [RelayChainCli::executable_name()]308 .iter()309 .chain(cli.relaychain_args.iter()),310 );311312 let id = ParaId::from(para_id);313314 let parachain_account =315 AccountIdConversion::<polkadot_primitives::v0::AccountId>::into_account(&id);316317 let state_version =318 RelayChainCli::native_runtime_version(&config.chain_spec).state_version();319 let block: Block = generate_genesis_block(&config.chain_spec, state_version)320 .map_err(|e| format!("{:?}", e))?;321 let genesis_state = format!("0x{:?}", HexDisplay::from(&block.header().encode()));322 let genesis_hash = format!("0x{:?}", HexDisplay::from(&block.header().hash().0));323324 let polkadot_config = SubstrateCli::create_configuration(325 &polkadot_cli,326 &polkadot_cli,327 config.tokio_handle.clone(),328 )329 .map_err(|err| format!("Relay chain argument error: {}", err))?;330331 info!("Parachain id: {:?}", id);332 info!("Parachain Account: {}", parachain_account);333 info!("Parachain genesis state: {}", genesis_state);334 info!("Parachain genesis hash: {}", genesis_hash);335 info!(336 "Is collating: {}",337 if config.role.is_authority() {338 "yes"339 } else {340 "no"341 }342 );343344 crate::service::start_node(config, polkadot_config, id)345 .await346 .map(|r| r.0)347 .map_err(Into::into)348 })349 }350 }351}352353impl DefaultConfigurationValues for RelayChainCli {354 fn p2p_listen_port() -> u16 {355 30334356 }357358 fn rpc_ws_listen_port() -> u16 {359 9945360 }361362 fn rpc_http_listen_port() -> u16 {363 9934364 }365366 fn prometheus_listen_port() -> u16 {367 9616368 }369}370371impl CliConfiguration<Self> for RelayChainCli {372 fn shared_params(&self) -> &SharedParams {373 self.base.base.shared_params()374 }375376 fn import_params(&self) -> Option<&ImportParams> {377 self.base.base.import_params()378 }379380 fn network_params(&self) -> Option<&NetworkParams> {381 self.base.base.network_params()382 }383384 fn keystore_params(&self) -> Option<&KeystoreParams> {385 self.base.base.keystore_params()386 }387388 fn base_path(&self) -> Result<Option<BasePath>> {389 Ok(self390 .shared_params()391 .base_path()392 .or_else(|| self.base_path.clone().map(Into::into)))393 }394395 fn rpc_http(&self, default_listen_port: u16) -> Result<Option<SocketAddr>> {396 self.base.base.rpc_http(default_listen_port)397 }398399 fn rpc_ipc(&self) -> Result<Option<String>> {400 self.base.base.rpc_ipc()401 }402403 fn rpc_ws(&self, default_listen_port: u16) -> Result<Option<SocketAddr>> {404 self.base.base.rpc_ws(default_listen_port)405 }406407 fn prometheus_config(408 &self,409 default_listen_port: u16,410 chain_spec: &Box<dyn ChainSpec>,411 ) -> Result<Option<PrometheusConfig>> {412 self.base413 .base414 .prometheus_config(default_listen_port, chain_spec)415 }416417 fn init<F>(418 &self,419 _support_url: &String,420 _impl_version: &String,421 _logger_hook: F,422 _config: &sc_service::Configuration,423 ) -> Result<()> {424 unreachable!("PolkadotCli is never initialized; qed");425 }426427 fn chain_id(&self, is_dev: bool) -> Result<String> {428 let chain_id = self.base.base.chain_id(is_dev)?;429430 Ok(if chain_id.is_empty() {431 self.chain_id.clone().unwrap_or_default()432 } else {433 chain_id434 })435 }436437 fn role(&self, is_dev: bool) -> Result<sc_service::Role> {438 self.base.base.role(is_dev)439 }440441 fn transaction_pool(&self) -> Result<sc_service::config::TransactionPoolOptions> {442 self.base.base.transaction_pool()443 }444445 fn state_cache_child_ratio(&self) -> Result<Option<usize>> {446 self.base.base.state_cache_child_ratio()447 }448449 fn rpc_methods(&self) -> Result<sc_service::config::RpcMethods> {450 self.base.base.rpc_methods()451 }452453 fn rpc_ws_max_connections(&self) -> Result<Option<usize>> {454 self.base.base.rpc_ws_max_connections()455 }456457 fn rpc_cors(&self, is_dev: bool) -> Result<Option<Vec<String>>> {458 self.base.base.rpc_cors(is_dev)459 }460461 fn default_heap_pages(&self) -> Result<Option<u64>> {462 self.base.base.default_heap_pages()463 }464465 fn force_authoring(&self) -> Result<bool> {466 self.base.base.force_authoring()467 }468469 fn disable_grandpa(&self) -> Result<bool> {470 self.base.base.disable_grandpa()471 }472473 fn max_runtime_instances(&self) -> Result<Option<usize>> {474 self.base.base.max_runtime_instances()475 }476477 fn announce_block(&self) -> Result<bool> {478 self.base.base.announce_block()479 }480481 fn telemetry_endpoints(482 &self,483 chain_spec: &Box<dyn ChainSpec>,484 ) -> Result<Option<sc_telemetry::TelemetryEndpoints>> {485 self.base.base.telemetry_endpoints(chain_spec)486 }487}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/>.1617// Original license18// This file is part of Substrate.1920// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd.21// SPDX-License-Identifier: Apache-2.02223// Licensed under the Apache License, Version 2.0 (the "License");24// you may not use this file except in compliance with the License.25// You may obtain a copy of the License at26//27// http://www.apache.org/licenses/LICENSE-2.028//29// Unless required by applicable law or agreed to in writing, software30// distributed under the License is distributed on an "AS IS" BASIS,31// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.32// See the License for the specific language governing permissions and33// limitations under the License.3435use crate::{36 chain_spec::{self, RuntimeIdentification},37 cli::{Cli, RelayChainCli, Subcommand},38 service::new_partial,39};4041#[cfg(feature = "unique-runtime")]42use crate::service::UniqueRuntimeExecutor;4344#[cfg(feature = "quartz-runtime")]45use crate::service::QuartzRuntimeExecutor;4647#[cfg(feature = "opal-runtime")]48use crate::service::OpalRuntimeExecutor;4950use codec::Encode;51use cumulus_primitives_core::ParaId;52use cumulus_client_service::genesis::generate_genesis_block;53use log::info;54use polkadot_parachain::primitives::AccountIdConversion;55use sc_cli::{56 ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams,57 NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli,58};59use sc_service::{60 config::{BasePath, PrometheusConfig},61};62use sp_core::hexdisplay::HexDisplay;63use sp_runtime::traits::Block as BlockT;64use std::{io::Write, net::SocketAddr};6566use unique_runtime_common::types::Block;6768macro_rules! no_runtime_err {69 ($chain_spec:expr) => {70 format!("No runtime valid runtime was found, chain id: {}",71 $chain_spec.id())72 };73}7475fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {76 Ok(match id {77 "westend-local" => Box::new(chain_spec::local_testnet_westend_config()),78 "rococo-local" => Box::new(chain_spec::local_testnet_rococo_config()),79 "dev" => Box::new(chain_spec::development_config()),80 "" | "local" => Box::new(chain_spec::local_testnet_rococo_config()),81 path => Box::new(chain_spec::ChainSpec::from_json_file(82 std::path::PathBuf::from(path),83 )?),84 })85}8687impl SubstrateCli for Cli {88 // TODO use args89 fn impl_name() -> String {90 "Unique Node".into()91 }9293 fn impl_version() -> String {94 env!("SUBSTRATE_CLI_IMPL_VERSION").into()95 }96 // TODO use args97 fn description() -> String {98 format!(99 "Unique Node\n\nThe command-line arguments provided first will be \100 passed to the parachain node, while the arguments provided after -- will be passed \101 to the relaychain node.\n\n\102 {} [parachain-args] -- [relaychain-args]",103 Self::executable_name()104 )105 }106107 fn author() -> String {108 env!("CARGO_PKG_AUTHORS").into()109 }110111 //TODO use args112 fn support_url() -> String {113 "support@unique.network".into()114 }115116 fn copyright_start_year() -> i32 {117 2019118 }119120 fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {121 load_spec(id)122 }123124 fn native_runtime_version(chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {125 #[cfg(feature = "unique-runtime")]126 if chain_spec.is_unique() {127 return &unique_runtime::VERSION;128 }129130 #[cfg(feature = "quartz-runtime")]131 if chain_spec.is_quartz() {132 return &quartz_runtime::VERSION;133 }134135 #[cfg(feature = "opal-runtime")]136 if chain_spec.is_opal() {137 return &opal_runtime::VERSION;138 }139140 panic!("{}", no_runtime_err!(chain_spec));141 }142}143144impl SubstrateCli for RelayChainCli {145 // TODO use args146 fn impl_name() -> String {147 "Unique Node".into()148 }149150 fn impl_version() -> String {151 env!("SUBSTRATE_CLI_IMPL_VERSION").into()152 }153 // TODO use args154 fn description() -> String {155 "Unique Node\n\nThe command-line arguments provided first will be \156 passed to the parachain node, while the arguments provided after -- will be passed \157 to the relaychain node.\n\n\158 parachain-collator [parachain-args] -- [relaychain-args]"159 .into()160 }161162 fn author() -> String {163 env!("CARGO_PKG_AUTHORS").into()164 }165 // TODO use args166 fn support_url() -> String {167 "support@unique.network".into()168 }169170 fn copyright_start_year() -> i32 {171 2019172 }173174 fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {175 polkadot_cli::Cli::from_iter([RelayChainCli::executable_name()].iter()).load_spec(id)176 }177178 fn native_runtime_version(chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {179 polkadot_cli::Cli::native_runtime_version(chain_spec)180 }181}182183#[allow(clippy::borrowed_box)]184fn extract_genesis_wasm(chain_spec: &Box<dyn sc_service::ChainSpec>) -> Result<Vec<u8>> {185 let mut storage = chain_spec.build_storage()?;186187 storage188 .top189 .remove(sp_core::storage::well_known_keys::CODE)190 .ok_or_else(|| "Could not find wasm file in genesis state!".into())191}192193macro_rules! construct_async_run {194 (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{195 let runner = $cli.create_runner($cmd)?;196197 #[cfg(feature = "unique-runtime")]198 if runner.config().chain_spec.is_unique() {199 return runner.async_run(|$config| {200 let $components = new_partial::<201 unique_runtime::RuntimeApi, UniqueRuntimeExecutor, _202 >(203 &$config,204 crate::service::parachain_build_import_queue,205 )?;206 let task_manager = $components.task_manager;207 { $( $code )* }.map(|v| (v, task_manager))208 });209 }210211 #[cfg(feature = "quartz-runtime")]212 if runner.config().chain_spec.is_quartz() {213 return runner.async_run(|$config| {214 let $components = new_partial::<215 quartz_runtime::RuntimeApi, QuartzRuntimeExecutor, _216 >(217 &$config,218 crate::service::parachain_build_import_queue,219 )?;220 let task_manager = $components.task_manager;221 { $( $code )* }.map(|v| (v, task_manager))222 });223 }224225 #[cfg(feature = "opal-runtime")]226 if runner.config().chain_spec.is_opal() {227 return runner.async_run(|$config| {228 let $components = new_partial::<229 opal_runtime::RuntimeApi, OpalRuntimeExecutor, _230 >(231 &$config,232 crate::service::parachain_build_import_queue,233 )?;234 let task_manager = $components.task_manager;235 { $( $code )* }.map(|v| (v, task_manager))236 });237 }238239 Err(no_runtime_err!(runner.config().chain_spec).into())240 }}241}242243/// Parse command line arguments into service configuration.244pub fn run() -> Result<()> {245 let cli = Cli::from_args();246247 match &cli.subcommand {248 Some(Subcommand::BuildSpec(cmd)) => {249 let runner = cli.create_runner(cmd)?;250 runner.sync_run(|config| cmd.run(config.chain_spec, config.network))251 }252 Some(Subcommand::CheckBlock(cmd)) => {253 construct_async_run!(|components, cli, cmd, config| {254 Ok(cmd.run(components.client, components.import_queue))255 })256 }257 Some(Subcommand::ExportBlocks(cmd)) => {258 construct_async_run!(|components, cli, cmd, config| {259 Ok(cmd.run(components.client, config.database))260 })261 }262 Some(Subcommand::ExportState(cmd)) => {263 construct_async_run!(|components, cli, cmd, config| {264 Ok(cmd.run(components.client, config.chain_spec))265 })266 }267 Some(Subcommand::ImportBlocks(cmd)) => {268 construct_async_run!(|components, cli, cmd, config| {269 Ok(cmd.run(components.client, components.import_queue))270 })271 }272 Some(Subcommand::PurgeChain(cmd)) => {273 let runner = cli.create_runner(cmd)?;274275 runner.sync_run(|config| {276 let polkadot_cli = RelayChainCli::new(277 &config,278 [RelayChainCli::executable_name()]279 .iter()280 .chain(cli.relaychain_args.iter()),281 );282283 let polkadot_config = SubstrateCli::create_configuration(284 &polkadot_cli,285 &polkadot_cli,286 config.tokio_handle.clone(),287 )288 .map_err(|err| format!("Relay chain argument error: {}", err))?;289290 cmd.run(config, polkadot_config)291 })292 }293 Some(Subcommand::Revert(cmd)) => construct_async_run!(|components, cli, cmd, config| {294 Ok(cmd.run(components.client, components.backend))295 }),296 Some(Subcommand::ExportGenesisState(params)) => {297 let mut builder = sc_cli::LoggerBuilder::new("");298 builder.with_profiling(sc_tracing::TracingReceiver::Log, "");299 let _ = builder.init();300301 let spec = load_spec(¶ms.chain.clone().unwrap_or_default())?;302 let state_version = Cli::native_runtime_version(&spec).state_version();303 let block: Block = generate_genesis_block(&spec, state_version)?;304 let raw_header = block.header().encode();305 let output_buf = if params.raw {306 raw_header307 } else {308 format!("0x{:?}", HexDisplay::from(&block.header().encode())).into_bytes()309 };310311 if let Some(output) = ¶ms.output {312 std::fs::write(output, output_buf)?;313 } else {314 std::io::stdout().write_all(&output_buf)?;315 }316317 Ok(())318 }319 Some(Subcommand::ExportGenesisWasm(params)) => {320 let mut builder = sc_cli::LoggerBuilder::new("");321 builder.with_profiling(sc_tracing::TracingReceiver::Log, "");322 let _ = builder.init();323324 let raw_wasm_blob =325 extract_genesis_wasm(&cli.load_spec(¶ms.chain.clone().unwrap_or_default())?)?;326 let output_buf = if params.raw {327 raw_wasm_blob328 } else {329 format!("0x{:?}", HexDisplay::from(&raw_wasm_blob)).into_bytes()330 };331332 if let Some(output) = ¶ms.output {333 std::fs::write(output, output_buf)?;334 } else {335 std::io::stdout().write_all(&output_buf)?;336 }337338 Ok(())339 }340 Some(Subcommand::Benchmark(cmd)) => {341 if cfg!(feature = "runtime-benchmarks") {342 let runner = cli.create_runner(cmd)?;343 runner.sync_run(|config| {344 #[cfg(feature = "unique-runtime")]345 if config.chain_spec.is_unique() {346 return cmd.run::<Block, UniqueRuntimeExecutor>(config);347 }348349 #[cfg(feature = "quartz-runtime")]350 if config.chain_spec.is_quartz() {351 return cmd.run::<Block, QuartzRuntimeExecutor>(config);352 }353354 #[cfg(feature = "opal-runtime")]355 if config.chain_spec.is_opal() {356 return cmd.run::<Block, OpalRuntimeExecutor>(config);357 }358359 Err(no_runtime_err!(config.chain_spec).into())360 })361 } else {362 Err("Benchmarking wasn't enabled when building the node. \363 You can enable it with `--features runtime-benchmarks`."364 .into())365 }366 }367 None => {368 let runner = cli.create_runner(&cli.run.normalize())?;369370 runner.run_node_until_exit(|config| async move {371 let para_id = chain_spec::Extensions::try_get(&*config.chain_spec)372 .map(|e| e.para_id)373 .ok_or("Could not find parachain ID in chain-spec.")?;374375 let polkadot_cli = RelayChainCli::new(376 &config,377 [RelayChainCli::executable_name()]378 .iter()379 .chain(cli.relaychain_args.iter()),380 );381382 let id = ParaId::from(para_id);383384 let parachain_account =385 AccountIdConversion::<polkadot_primitives::v0::AccountId>::into_account(&id);386387 let state_version =388 RelayChainCli::native_runtime_version(&config.chain_spec).state_version();389 let block: Block = generate_genesis_block(&config.chain_spec, state_version)390 .map_err(|e| format!("{:?}", e))?;391 let genesis_state = format!("0x{:?}", HexDisplay::from(&block.header().encode()));392 let genesis_hash = format!("0x{:?}", HexDisplay::from(&block.header().hash().0));393394 let polkadot_config = SubstrateCli::create_configuration(395 &polkadot_cli,396 &polkadot_cli,397 config.tokio_handle.clone(),398 )399 .map_err(|err| format!("Relay chain argument error: {}", err))?;400401 info!("Parachain id: {:?}", id);402 info!("Parachain Account: {}", parachain_account);403 info!("Parachain genesis state: {}", genesis_state);404 info!("Parachain genesis hash: {}", genesis_hash);405 info!(406 "Is collating: {}",407 if config.role.is_authority() {408 "yes"409 } else {410 "no"411 }412 );413414 #[cfg(feature = "unique-runtime")]415 if config.chain_spec.is_unique() {416 return crate::service::start_node::<417 unique_runtime::Runtime,418 unique_runtime::RuntimeApi,419 UniqueRuntimeExecutor,420 >(config, polkadot_config, id)421 .await422 .map(|r| r.0)423 .map_err(Into::into);424 }425426 #[cfg(feature = "quartz-runtime")]427 if config.chain_spec.is_quartz() {428 return crate::service::start_node::<429 quartz_runtime::Runtime,430 quartz_runtime::RuntimeApi,431 QuartzRuntimeExecutor,432 >(config, polkadot_config, id)433 .await434 .map(|r| r.0)435 .map_err(Into::into);436 }437438 #[cfg(feature = "opal-runtime")]439 if config.chain_spec.is_opal() {440 return crate::service::start_node::<441 opal_runtime::Runtime,442 opal_runtime::RuntimeApi,443 OpalRuntimeExecutor,444 >(config, polkadot_config, id)445 .await446 .map(|r| r.0)447 .map_err(Into::into);448 }449450 Err(no_runtime_err!(config.chain_spec).into())451 })452 }453 }454}455456impl DefaultConfigurationValues for RelayChainCli {457 fn p2p_listen_port() -> u16 {458 30334459 }460461 fn rpc_ws_listen_port() -> u16 {462 9945463 }464465 fn rpc_http_listen_port() -> u16 {466 9934467 }468469 fn prometheus_listen_port() -> u16 {470 9616471 }472}473474impl CliConfiguration<Self> for RelayChainCli {475 fn shared_params(&self) -> &SharedParams {476 self.base.base.shared_params()477 }478479 fn import_params(&self) -> Option<&ImportParams> {480 self.base.base.import_params()481 }482483 fn network_params(&self) -> Option<&NetworkParams> {484 self.base.base.network_params()485 }486487 fn keystore_params(&self) -> Option<&KeystoreParams> {488 self.base.base.keystore_params()489 }490491 fn base_path(&self) -> Result<Option<BasePath>> {492 Ok(self493 .shared_params()494 .base_path()495 .or_else(|| self.base_path.clone().map(Into::into)))496 }497498 fn rpc_http(&self, default_listen_port: u16) -> Result<Option<SocketAddr>> {499 self.base.base.rpc_http(default_listen_port)500 }501502 fn rpc_ipc(&self) -> Result<Option<String>> {503 self.base.base.rpc_ipc()504 }505506 fn rpc_ws(&self, default_listen_port: u16) -> Result<Option<SocketAddr>> {507 self.base.base.rpc_ws(default_listen_port)508 }509510 fn prometheus_config(511 &self,512 default_listen_port: u16,513 chain_spec: &Box<dyn ChainSpec>,514 ) -> Result<Option<PrometheusConfig>> {515 self.base516 .base517 .prometheus_config(default_listen_port, chain_spec)518 }519520 fn init<F>(521 &self,522 _support_url: &String,523 _impl_version: &String,524 _logger_hook: F,525 _config: &sc_service::Configuration,526 ) -> Result<()> {527 unreachable!("PolkadotCli is never initialized; qed");528 }529530 fn chain_id(&self, is_dev: bool) -> Result<String> {531 let chain_id = self.base.base.chain_id(is_dev)?;532533 Ok(if chain_id.is_empty() {534 self.chain_id.clone().unwrap_or_default()535 } else {536 chain_id537 })538 }539540 fn role(&self, is_dev: bool) -> Result<sc_service::Role> {541 self.base.base.role(is_dev)542 }543544 fn transaction_pool(&self) -> Result<sc_service::config::TransactionPoolOptions> {545 self.base.base.transaction_pool()546 }547548 fn state_cache_child_ratio(&self) -> Result<Option<usize>> {549 self.base.base.state_cache_child_ratio()550 }551552 fn rpc_methods(&self) -> Result<sc_service::config::RpcMethods> {553 self.base.base.rpc_methods()554 }555556 fn rpc_ws_max_connections(&self) -> Result<Option<usize>> {557 self.base.base.rpc_ws_max_connections()558 }559560 fn rpc_cors(&self, is_dev: bool) -> Result<Option<Vec<String>>> {561 self.base.base.rpc_cors(is_dev)562 }563564 fn default_heap_pages(&self) -> Result<Option<u64>> {565 self.base.base.default_heap_pages()566 }567568 fn force_authoring(&self) -> Result<bool> {569 self.base.base.force_authoring()570 }571572 fn disable_grandpa(&self) -> Result<bool> {573 self.base.base.disable_grandpa()574 }575576 fn max_runtime_instances(&self) -> Result<Option<usize>> {577 self.base.base.max_runtime_instances()578 }579580 fn announce_block(&self) -> Result<bool> {581 self.base.base.announce_block()582 }583584 fn telemetry_endpoints(585 &self,586 chain_spec: &Box<dyn ChainSpec>,587 ) -> Result<Option<sc_telemetry::TelemetryEndpoints>> {588 self.base.base.telemetry_endpoints(chain_spec)589 }590}node/cli/src/service.rsdiffbeforeafterboth--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -25,17 +25,8 @@
use futures::StreamExt;
use unique_rpc::overrides_handle;
-// Local Runtime Types
-#[cfg(feature = "unique-runtime")]
-use unique_runtime as runtime;
-
-#[cfg(feature = "quartz-runtime")]
-use quartz_runtime as runtime;
-#[cfg(feature = "opal-runtime")]
-use opal_runtime as runtime;
-
-use runtime::RuntimeApi;
+use serde::{Serialize, Deserialize};
// Cumulus Imports
use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};
@@ -71,18 +62,46 @@
pub type Block = sp_runtime::generic::Block<Header, sp_runtime::OpaqueExtrinsic>;
type Hash = sp_core::H256;
+use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index};
+
/// Native executor instance.
-pub struct ParachainRuntimeExecutor;
+pub struct UniqueRuntimeExecutor;
+pub struct QuartzRuntimeExecutor;
+pub struct OpalRuntimeExecutor;
+
+impl NativeExecutionDispatch for UniqueRuntimeExecutor {
+ type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
+
+ fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
+ unique_runtime::api::dispatch(method, data)
+ }
+
+ fn native_version() -> sc_executor::NativeVersion {
+ unique_runtime::native_version()
+ }
+}
+
+impl NativeExecutionDispatch for QuartzRuntimeExecutor {
+ type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
-impl NativeExecutionDispatch for ParachainRuntimeExecutor {
+ fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
+ unique_runtime::api::dispatch(method, data)
+ }
+
+ fn native_version() -> sc_executor::NativeVersion {
+ unique_runtime::native_version()
+ }
+}
+
+impl NativeExecutionDispatch for OpalRuntimeExecutor {
type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
- runtime::api::dispatch(method, data)
+ unique_runtime::api::dispatch(method, data)
}
fn native_version() -> sc_executor::NativeVersion {
- runtime::native_version()
+ unique_runtime::native_version()
}
}
@@ -106,9 +125,7 @@
)?))
}
-type ExecutorDispatch = ParachainRuntimeExecutor;
-
-type FullClient =
+type FullClient<RuntimeApi, ExecutorDispatch> =
sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;
type FullBackend = sc_service::TFullBackend<Block>;
type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
@@ -118,16 +135,16 @@
/// Use this macro if you don't actually need the full service, but just the builder in order to
/// be able to perform chain operations.
#[allow(clippy::type_complexity)]
-pub fn new_partial<BIQ>(
+pub fn new_partial<RuntimeApi, ExecutorDispatch, BIQ>(
config: &Configuration,
build_import_queue: BIQ,
) -> Result<
PartialComponents<
- FullClient,
+ FullClient<RuntimeApi, ExecutorDispatch>,
FullBackend,
FullSelectChain,
- sc_consensus::DefaultImportQueue<Block, FullClient>,
- sc_transaction_pool::FullPool<Block, FullClient>,
+ sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
+ sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
(
Option<Telemetry>,
Option<FilterPool>,
@@ -140,13 +157,21 @@
>
where
sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,
+ RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ + Send
+ + Sync
+ + 'static,
+ RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
BIQ: FnOnce(
- Arc<FullClient>,
+ Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
&Configuration,
Option<TelemetryHandle>,
&TaskManager,
- ) -> Result<sc_consensus::DefaultImportQueue<Block, FullClient>, sc_service::Error>,
+ ) -> Result<
+ sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
+ sc_service::Error,
+ >,
{
let _telemetry = config
.telemetry_endpoints
@@ -240,29 +265,50 @@
///
/// This is the actual implementation that is abstract over the executor and the runtime api.
#[sc_tracing::logging::prefix_logs_with("Parachain")]
-async fn start_node_impl<BIQ, BIC>(
+async fn start_node_impl<Runtime, RuntimeApi, ExecutorDispatch, BIQ, BIC>(
parachain_config: Configuration,
polkadot_config: Configuration,
id: ParaId,
build_import_queue: BIQ,
build_consensus: BIC,
-) -> sc_service::error::Result<(TaskManager, Arc<FullClient>)>
+) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>
where
sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,
+ Runtime: RuntimeInstance + Send + Sync + 'static,
+ <Runtime as RuntimeInstance>::CrossAccountId: Serialize,
+ for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,
+ RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ + Send
+ + Sync
+ + 'static,
+ RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
+ + fp_rpc::EthereumRuntimeRPCApi<Block>
+ + sp_session::SessionKeys<Block>
+ + sp_block_builder::BlockBuilder<Block>
+ + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
+ + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
+ + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
+ + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+ + sp_api::Metadata<Block>
+ + sp_offchain::OffchainWorkerApi<Block>
+ + cumulus_primitives_core::CollectCollationInfo<Block>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
BIQ: FnOnce(
- Arc<FullClient>,
+ Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
&Configuration,
Option<TelemetryHandle>,
&TaskManager,
- ) -> Result<sc_consensus::DefaultImportQueue<Block, FullClient>, sc_service::Error>,
+ ) -> Result<
+ sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
+ sc_service::Error,
+ >,
BIC: FnOnce(
- Arc<FullClient>,
+ Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
Option<&Registry>,
Option<TelemetryHandle>,
&TaskManager,
Arc<dyn RelayChainInterface>,
- Arc<sc_transaction_pool::FullPool<Block, FullClient>>,
+ Arc<sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>>,
Arc<NetworkService<Block, Hash>>,
SyncCryptoStorePtr,
bool,
@@ -274,7 +320,8 @@
let parachain_config = prepare_node_config(parachain_config);
- let params = new_partial::<BIQ>(¶chain_config, build_import_queue)?;
+ let params =
+ new_partial::<RuntimeApi, ExecutorDispatch, BIQ>(¶chain_config, build_import_queue)?;
let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =
params.other;
@@ -320,7 +367,7 @@
let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new(
task_manager.spawn_handle(),
- overrides_handle(client.clone()),
+ overrides_handle::<_, _, Runtime>(client.clone()),
50,
50,
));
@@ -346,10 +393,12 @@
fee_history_limit: 2048,
};
- Ok(unique_rpc::create_full::<_, _, _, _, RuntimeApi, _>(
- full_deps,
- subscription_executor.clone(),
- ))
+ Ok(
+ unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(
+ full_deps,
+ subscription_executor.clone(),
+ ),
+ )
});
task_manager.spawn_essential_handle().spawn(
@@ -436,12 +485,26 @@
}
/// Build the import queue for the the parachain runtime.
-pub fn parachain_build_import_queue(
- client: Arc<FullClient>,
+pub fn parachain_build_import_queue<RuntimeApi, ExecutorDispatch>(
+ client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
config: &Configuration,
telemetry: Option<TelemetryHandle>,
task_manager: &TaskManager,
-) -> Result<sc_consensus::DefaultImportQueue<Block, FullClient>, sc_service::Error> {
+) -> Result<
+ sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
+ sc_service::Error,
+>
+where
+ RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ + Send
+ + Sync
+ + 'static,
+ RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
+ + sp_block_builder::BlockBuilder<Block>
+ + sp_consensus_aura::AuraApi<Block, AuraId>
+ + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
+ ExecutorDispatch: NativeExecutionDispatch + 'static,
+{
let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
cumulus_client_consensus_aura::import_queue::<
@@ -475,12 +538,34 @@
}
/// Start a normal parachain node.
-pub async fn start_node(
+pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(
parachain_config: Configuration,
polkadot_config: Configuration,
id: ParaId,
-) -> sc_service::error::Result<(TaskManager, Arc<FullClient>)> {
- start_node_impl::<_, _>(
+) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>
+where
+ Runtime: RuntimeInstance + Send + Sync + 'static,
+ <Runtime as RuntimeInstance>::CrossAccountId: Serialize,
+ for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,
+ RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ + Send
+ + Sync
+ + 'static,
+ RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
+ + fp_rpc::EthereumRuntimeRPCApi<Block>
+ + sp_session::SessionKeys<Block>
+ + sp_block_builder::BlockBuilder<Block>
+ + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
+ + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
+ + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
+ + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+ + sp_api::Metadata<Block>
+ + sp_offchain::OffchainWorkerApi<Block>
+ + cumulus_primitives_core::CollectCollationInfo<Block>
+ + sp_consensus_aura::AuraApi<Block, AuraId>,
+ ExecutorDispatch: NativeExecutionDispatch + 'static,
+{
+ start_node_impl::<Runtime, RuntimeApi, ExecutorDispatch, _, _>(
parachain_config,
polkadot_config,
id,
node/rpc/Cargo.tomldiffbeforeafterboth--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -48,13 +48,16 @@
fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }
fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }
+pallet-common = { default-features = false, path = "../../pallets/common" }
+unique-runtime-common = { default-features = false, path = "../../runtime/common" }
pallet-unique = { path = "../../pallets/unique" }
uc-rpc = { path = "../../client/rpc" }
up-rpc = { path = "../../primitives/rpc" }
-unique-runtime = { path = "../../runtime/unique", optional = true }
-quartz-runtime = { path = "../../runtime/quartz", optional = true }
-opal-runtime = { path = "../../runtime/opal", optional = true }
+[dependencies.serde]
+features = ['derive']
+version = '1.0.130'
+
[features]
-default = ["unique-runtime"]
+default = []
std = []
node/rpc/src/lib.rsdiffbeforeafterboth--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -40,16 +40,9 @@
use sc_service::TransactionPool;
use std::{collections::BTreeMap, marker::PhantomData, sync::Arc};
-#[cfg(feature = "unique-runtime")]
-use unique_runtime as runtime;
-
-#[cfg(feature = "quartz-runtime")]
-use quartz_runtime as runtime;
-
-#[cfg(feature = "opal-runtime")]
-use opal_runtime as runtime;
-
-use runtime::opaque::{Hash, AccountId, CrossAccountId, Index, Block, BlockNumber, Balance};
+use unique_runtime_common::types::{
+ Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance,
+};
/// Public io handler for exporting into other modules
pub type IoHandler = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
@@ -100,29 +93,33 @@
pub block_data_cache: Arc<EthBlockDataCache<Block>>,
}
-struct AccountCodes<C, B> {
+struct AccountCodes<C, B, R> {
client: Arc<C>,
- _marker: PhantomData<B>,
+ _blk_marker: PhantomData<B>,
+ _runtime_marker: PhantomData<R>,
}
-impl<C, Block> AccountCodes<C, Block>
+impl<C, Block, R> AccountCodes<C, Block, R>
where
Block: sp_api::BlockT,
C: ProvideRuntimeApi<Block>,
+ R: RuntimeInstance,
{
fn new(client: Arc<C>) -> Self {
Self {
client,
- _marker: PhantomData,
+ _blk_marker: PhantomData,
+ _runtime_marker: PhantomData,
}
}
}
-impl<C, Block> fc_rpc::AccountCodeProvider<Block> for AccountCodes<C, Block>
+impl<C, Block, Runtime> fc_rpc::AccountCodeProvider<Block> for AccountCodes<C, Block, Runtime>
where
Block: sp_api::BlockT,
C: ProvideRuntimeApi<Block>,
- C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,
+ C::Api: up_rpc::UniqueApi<Block, <Runtime as RuntimeInstance>::CrossAccountId, AccountId>,
+ Runtime: RuntimeInstance,
{
fn code(&self, block: &sp_api::BlockId<Block>, account: sp_core::H160) -> Option<Vec<u8>> {
use up_rpc::UniqueApi;
@@ -134,22 +131,23 @@
}
}
-pub fn overrides_handle<C, BE>(client: Arc<C>) -> Arc<OverrideHandle<Block>>
+pub fn overrides_handle<C, BE, R>(client: Arc<C>) -> Arc<OverrideHandle<Block>>
where
C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,
C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,
C: Send + Sync + 'static,
C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
- C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,
+ C::Api: up_rpc::UniqueApi<Block, <R as RuntimeInstance>::CrossAccountId, AccountId>,
BE: Backend<Block> + 'static,
BE::State: StateBackend<BlakeTwo256>,
+ R: RuntimeInstance + Send + Sync + 'static,
{
let mut overrides_map = BTreeMap::new();
overrides_map.insert(
EthereumStorageSchema::V1,
Box::new(SchemaV1Override::new_with_code_provider(
client.clone(),
- Arc::new(AccountCodes::<C, Block>::new(client.clone())),
+ Arc::new(AccountCodes::<C, Block, R>::new(client.clone())),
)) as Box<dyn StorageOverride<_> + Send + Sync>,
);
overrides_map.insert(
@@ -170,7 +168,7 @@
}
/// Instantiate all Full RPC extensions.
-pub fn create_full<C, P, SC, CA, A, B>(
+pub fn create_full<C, P, SC, CA, R, A, B>(
deps: FullDeps<C, P, SC, CA>,
subscription_task_executor: SubscriptionTaskExecutor,
) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata>
@@ -184,11 +182,14 @@
// C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
- C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,
+ C::Api: up_rpc::UniqueApi<Block, <R as RuntimeInstance>::CrossAccountId, AccountId>,
B: sc_client_api::Backend<Block> + Send + Sync + 'static,
B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,
P: TransactionPool<Block = Block> + 'static,
CA: ChainApi<Block = Block> + 'static,
+ R: RuntimeInstance + Send + Sync + 'static,
+ <R as RuntimeInstance>::CrossAccountId: serde::Serialize,
+ for<'de> <R as RuntimeInstance>::CrossAccountId: serde::Deserialize<'de>,
{
use fc_rpc::{
EthApi, EthApiServer, EthDevSigner, EthFilterApi, EthFilterApiServer, EthPubSubApi,
@@ -235,13 +236,13 @@
signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);
}
- let overrides = overrides_handle(client.clone());
+ let overrides = overrides_handle::<_, _, R>(client.clone());
io.extend_with(EthApiServer::to_delegate(EthApi::new(
client.clone(),
pool.clone(),
graph,
- runtime::TransactionConverter,
+ <R as RuntimeInstance>::get_transaction_converter(),
network.clone(),
signers,
overrides.clone(),