diff --git a/bridges/bin/millau-node/Cargo.toml b/bridges/bin/millau-node/Cargo.toml deleted file mode 100644 index 646841abdc..0000000000 --- a/bridges/bin/millau-node/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "millau-bridge-node" -description = "Substrate node compatible with Millau runtime" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2018" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -bridge-node = { path = "../node", default-features = false, features = ["millau"] } diff --git a/bridges/bin/millau/node/Cargo.toml b/bridges/bin/millau/node/Cargo.toml new file mode 100644 index 0000000000..a6dc223e84 --- /dev/null +++ b/bridges/bin/millau/node/Cargo.toml @@ -0,0 +1,54 @@ +[package] +name = "millau-bridge-node" +description = "Substrate node compatible with Millau runtime" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +build = "build.rs" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/parity-bridges-common/" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[dependencies] +jsonrpc-core = "15.0.0" +structopt = "0.3.17" + +# Bridge dependencies + +millau-runtime = { path = "../runtime" } + +# Substrate Dependencies + +frame-benchmarking = "2.0" +frame-benchmarking-cli = "2.0" +sc-basic-authorship = "0.8" +sc-cli = "0.8" +sc-client-api = "2.0" +sc-consensus = "0.8" +sc-consensus-aura = "0.8" +sc-executor = "0.8" +sc-finality-grandpa = "0.8" +sc-service = "0.8" +sc-rpc = "2.0" +sc-transaction-pool = "2.0" +sp-consensus = "0.8" +sp-consensus-aura = "0.8" +sp-core = "2.0" +sp-inherents = "2.0" +sp-finality-grandpa = "2.0" +sp-runtime = "2.0" +substrate-frame-rpc-system = "2.0" + +[build-dependencies] +build-script-utils = { package = "substrate-build-script-utils", version = "2.0" } +frame-benchmarking-cli = "2.0" +vergen = "3.1.0" + +[features] +default = [] + +# TODO: https://github.com/paritytech/parity-bridges-common/issues/390 +# I've left the feature flag here to test our CI configuration +runtime-benchmarks = [ + # "millau-runtime/runtime-benchmarks", +] diff --git a/bridges/bin/node/build.rs b/bridges/bin/millau/node/build.rs similarity index 100% rename from bridges/bin/node/build.rs rename to bridges/bin/millau/node/build.rs diff --git a/bridges/bin/millau/node/src/chain_spec.rs b/bridges/bin/millau/node/src/chain_spec.rs new file mode 100644 index 0000000000..df66c3318e --- /dev/null +++ b/bridges/bin/millau/node/src/chain_spec.rs @@ -0,0 +1,166 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +use millau_runtime::{ + AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, SessionConfig, SessionKeys, Signature, + SudoConfig, SystemConfig, WASM_BINARY, +}; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_core::{sr25519, Pair, Public}; +use sp_finality_grandpa::AuthorityId as GrandpaId; +use sp_runtime::traits::{IdentifyAccount, Verify}; + +/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. +pub type ChainSpec = sc_service::GenericChainSpec; + +/// The chain specification option. This is expected to come in from the CLI and +/// is little more than one of a number of alternatives which can easily be converted +/// from a string (`--chain=...`) into a `ChainSpec`. +#[derive(Clone, Debug)] +pub enum Alternative { + /// Whatever the current runtime is, with just Alice as an auth. + Development, + /// Whatever the current runtime is, with simple Alice/Bob/Charlie/Dave/Eve auths. + LocalTestnet, +} + +/// Helper function to generate a crypto pair from seed +pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +type AccountPublic = ::Signer; + +/// Helper function to generate an account ID from seed +pub fn get_account_id_from_seed(seed: &str) -> AccountId +where + AccountPublic: From<::Public>, +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + +/// Helper function to generate an authority key for Aura +pub fn get_authority_keys_from_seed(s: &str) -> (AccountId, AuraId, GrandpaId) { + ( + get_account_id_from_seed::(s), + get_from_seed::(s), + get_from_seed::(s), + ) +} + +impl Alternative { + /// Get an actual chain config from one of the alternatives. + pub(crate) fn load(self) -> Result { + Ok(match self { + Alternative::Development => ChainSpec::from_genesis( + "Development", + "dev", + sc_service::ChainType::Development, + || { + testnet_genesis( + vec![get_authority_keys_from_seed("Alice")], + get_account_id_from_seed::("Alice"), + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + ], + true, + ) + }, + vec![], + None, + None, + None, + None, + ), + Alternative::LocalTestnet => ChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + sc_service::ChainType::Local, + || { + testnet_genesis( + vec![ + get_authority_keys_from_seed("Alice"), + get_authority_keys_from_seed("Bob"), + get_authority_keys_from_seed("Charlie"), + get_authority_keys_from_seed("Dave"), + get_authority_keys_from_seed("Eve"), + ], + get_account_id_from_seed::("Alice"), + 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"), + ], + true, + ) + }, + vec![], + None, + None, + None, + None, + ), + }) + } +} + +fn session_keys(aura: AuraId, grandpa: GrandpaId) -> SessionKeys { + SessionKeys { aura, grandpa } +} + +fn testnet_genesis( + initial_authorities: Vec<(AccountId, AuraId, GrandpaId)>, + root_key: AccountId, + endowed_accounts: Vec, + _enable_println: bool, +) -> GenesisConfig { + GenesisConfig { + frame_system: Some(SystemConfig { + code: WASM_BINARY.to_vec(), + changes_trie_config: Default::default(), + }), + pallet_balances: Some(BalancesConfig { + balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), + }), + pallet_aura: Some(AuraConfig { + authorities: Vec::new(), + }), + pallet_grandpa: Some(GrandpaConfig { + authorities: Vec::new(), + }), + pallet_sudo: Some(SudoConfig { key: root_key }), + pallet_session: Some(SessionConfig { + keys: initial_authorities + .iter() + .map(|x| (x.0.clone(), x.0.clone(), session_keys(x.1.clone(), x.2.clone()))) + .collect::>(), + }), + } +} diff --git a/bridges/bin/node/src/cli.rs b/bridges/bin/millau/node/src/cli.rs similarity index 100% rename from bridges/bin/node/src/cli.rs rename to bridges/bin/millau/node/src/cli.rs diff --git a/bridges/bin/millau/node/src/command.rs b/bridges/bin/millau/node/src/command.rs new file mode 100644 index 0000000000..fcd107d1ee --- /dev/null +++ b/bridges/bin/millau/node/src/command.rs @@ -0,0 +1,161 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +use crate::cli::{Cli, Subcommand}; +use crate::service; +use crate::service::new_partial; +use millau_runtime::Block; +use sc_cli::{ChainSpec, Role, RuntimeVersion, SubstrateCli}; +use sc_service::PartialComponents; + +impl SubstrateCli for Cli { + fn impl_name() -> String { + "Millau Bridge Node".into() + } + + fn impl_version() -> String { + env!("CARGO_PKG_VERSION").into() + } + + fn description() -> String { + "Millau Bridge Node".into() + } + + fn author() -> String { + "Parity Technologies".into() + } + + fn support_url() -> String { + "https://github.com/paritytech/parity-bridges-common/".into() + } + + fn copyright_start_year() -> i32 { + 2019 + } + + fn executable_name() -> String { + "millau-bridge-node".into() + } + + fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { + &millau_runtime::VERSION + } + + fn load_spec(&self, id: &str) -> Result, String> { + Ok(Box::new( + match id { + "" | "dev" => crate::chain_spec::Alternative::Development, + "local" => crate::chain_spec::Alternative::LocalTestnet, + _ => return Err(format!("Unsupported chain specification: {}", id)), + } + .load()?, + )) + } +} + +/// Parse and run command line arguments +pub fn run() -> sc_cli::Result<()> { + let cli = Cli::from_args(); + + match &cli.subcommand { + Some(Subcommand::Benchmark(cmd)) => { + if cfg!(feature = "runtime-benchmarks") { + let runner = cli.create_runner(cmd)?; + + runner.sync_run(|config| cmd.run::(config)) + } else { + println!( + "Benchmarking wasn't enabled when building the node. \ + You can enable it with `--features runtime-benchmarks`." + ); + Ok(()) + } + } + Some(Subcommand::Key(cmd)) => cmd.run(), + Some(Subcommand::Sign(cmd)) => cmd.run(), + Some(Subcommand::Verify(cmd)) => cmd.run(), + Some(Subcommand::Vanity(cmd)) => cmd.run(), + Some(Subcommand::BuildSpec(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) + } + Some(Subcommand::CheckBlock(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + import_queue, + .. + } = new_partial(&config)?; + Ok((cmd.run(client, import_queue), task_manager)) + }) + } + Some(Subcommand::ExportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, task_manager, .. + } = new_partial(&config)?; + Ok((cmd.run(client, config.database), task_manager)) + }) + } + Some(Subcommand::ExportState(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, task_manager, .. + } = new_partial(&config)?; + Ok((cmd.run(client, config.chain_spec), task_manager)) + }) + } + Some(Subcommand::ImportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + import_queue, + .. + } = new_partial(&config)?; + Ok((cmd.run(client, import_queue), task_manager)) + }) + } + Some(Subcommand::PurgeChain(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.database)) + } + Some(Subcommand::Revert(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + backend, + .. + } = new_partial(&config)?; + Ok((cmd.run(client, backend), task_manager)) + }) + } + None => { + let runner = cli.create_runner(&cli.run)?; + runner.run_node_until_exit(|config| match config.role { + Role::Light => service::new_light(config), + _ => service::new_full(config), + }) + } + } +} diff --git a/bridges/bin/node/src/lib.rs b/bridges/bin/millau/node/src/lib.rs similarity index 100% rename from bridges/bin/node/src/lib.rs rename to bridges/bin/millau/node/src/lib.rs diff --git a/bridges/bin/millau-node/src/main.rs b/bridges/bin/millau/node/src/main.rs similarity index 85% rename from bridges/bin/millau-node/src/main.rs rename to bridges/bin/millau/node/src/main.rs index 6ce72ef75c..07ec88727d 100644 --- a/bridges/bin/millau-node/src/main.rs +++ b/bridges/bin/millau/node/src/main.rs @@ -18,7 +18,13 @@ #![warn(missing_docs)] -/// Run node. -fn main() -> bridge_node::Result { - bridge_node::run() +mod chain_spec; +#[macro_use] +mod service; +mod cli; +mod command; + +/// Run the Millau Node +fn main() -> sc_cli::Result<()> { + command::run() } diff --git a/bridges/bin/millau/node/src/service.rs b/bridges/bin/millau/node/src/service.rs new file mode 100644 index 0000000000..e2e83d5a72 --- /dev/null +++ b/bridges/bin/millau/node/src/service.rs @@ -0,0 +1,348 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +//! Service and ServiceFactory implementation. Specialized wrapper over substrate service. + +// ===================================================================================== +// ===================================================================================== +// ===================================================================================== +// UPDATE GUIDE: +// 1) replace everything with node-template/src/service.rs contents (found in main Substrate repo); +// 2) the only thing to keep from old code, is `rpc_extensions_builder` - we use our own custom RPCs; +// 3) fix compilation errors; +// 4) test :) +// ===================================================================================== +// ===================================================================================== +// ===================================================================================== + +use millau_runtime::{self, opaque::Block, RuntimeApi}; +use sc_client_api::{ExecutorProvider, RemoteBackend}; +use sc_executor::native_executor_instance; +pub use sc_executor::NativeExecutor; +use sc_finality_grandpa::{FinalityProofProvider as GrandpaFinalityProofProvider, SharedVoterState}; +use sc_service::{error::Error as ServiceError, Configuration, TaskManager}; +use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; +use sp_inherents::InherentDataProviders; +use std::sync::Arc; +use std::time::Duration; + +// Our native executor instance. +native_executor_instance!( + pub Executor, + millau_runtime::api::dispatch, + millau_runtime::native_version, + frame_benchmarking::benchmarking::HostFunctions, +); + +type FullClient = sc_service::TFullClient; +type FullBackend = sc_service::TFullBackend; +type FullSelectChain = sc_consensus::LongestChain; + +#[allow(clippy::type_complexity)] +pub fn new_partial( + config: &Configuration, +) -> Result< + sc_service::PartialComponents< + FullClient, + FullBackend, + FullSelectChain, + sp_consensus::DefaultImportQueue, + sc_transaction_pool::FullPool, + ( + sc_finality_grandpa::GrandpaBlockImport, + sc_finality_grandpa::LinkHalf, + ), + >, + ServiceError, +> { + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + + let (client, backend, keystore, task_manager) = sc_service::new_full_parts::(&config)?; + let client = Arc::new(client); + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.prometheus_registry(), + task_manager.spawn_handle(), + client.clone(), + ); + + let (grandpa_block_import, grandpa_link) = + sc_finality_grandpa::block_import(client.clone(), &(client.clone() as Arc<_>), select_chain.clone())?; + + let aura_block_import = + sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(grandpa_block_import.clone(), client.clone()); + + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>( + sc_consensus_aura::slot_duration(&*client)?, + aura_block_import, + Some(Box::new(grandpa_block_import.clone())), + None, + client.clone(), + inherent_data_providers.clone(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()), + )?; + + Ok(sc_service::PartialComponents { + client, + backend, + task_manager, + import_queue, + keystore, + select_chain, + transaction_pool, + inherent_data_providers, + other: (grandpa_block_import, grandpa_link), + }) +} + +/// Builds a new service for a full client. +pub fn new_full(config: Configuration) -> Result { + let sc_service::PartialComponents { + client, + backend, + mut task_manager, + import_queue, + keystore, + select_chain, + transaction_pool, + inherent_data_providers, + other: (block_import, grandpa_link), + } = new_partial(&config)?; + + let finality_proof_provider = GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); + + let (network, network_status_sinks, system_rpc_tx, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + on_demand: None, + block_announce_validator_builder: None, + finality_proof_request_builder: None, + finality_proof_provider: Some(finality_proof_provider), + })?; + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, + backend.clone(), + task_manager.spawn_handle(), + client.clone(), + network.clone(), + ); + } + + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let name = config.network.node_name.clone(); + let enable_grandpa = !config.disable_grandpa; + let prometheus_registry = config.prometheus_registry().cloned(); + let telemetry_connection_sinks = sc_service::TelemetryConnectionSinks::default(); + + let rpc_extensions_builder = { + use sc_rpc::DenyUnsafe; + use substrate_frame_rpc_system::{FullSystem, SystemApi}; + + let client = client.clone(); + let pool = transaction_pool.clone(); + + Box::new(move |_, _| { + let mut io = jsonrpc_core::IoHandler::default(); + io.extend_with(SystemApi::to_delegate(FullSystem::new( + client.clone(), + pool.clone(), + DenyUnsafe::No, + ))); + + io + }) + }; + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + network: network.clone(), + client: client.clone(), + keystore: keystore.clone(), + task_manager: &mut task_manager, + transaction_pool: transaction_pool.clone(), + telemetry_connection_sinks: telemetry_connection_sinks.clone(), + rpc_extensions_builder, + on_demand: None, + remote_blockchain: None, + backend, + network_status_sinks, + system_rpc_tx, + config, + })?; + + if role.is_authority() { + let proposer = + sc_basic_authorship::ProposerFactory::new(client.clone(), transaction_pool, prometheus_registry.as_ref()); + + let can_author_with = sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); + + let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>( + sc_consensus_aura::slot_duration(&*client)?, + client.clone(), + select_chain, + block_import, + proposer, + network.clone(), + inherent_data_providers.clone(), + force_authoring, + keystore.clone(), + can_author_with, + )?; + + // the AURA authoring task is considered essential, i.e. if it + // fails we take down the service with it. + task_manager.spawn_essential_handle().spawn_blocking("aura", aura); + } + + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore = if role.is_authority() { + Some(keystore as sp_core::traits::BareCryptoStorePtr) + } else { + None + }; + + let grandpa_config = sc_finality_grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_period: 512, + name: Some(name), + observer_enabled: false, + keystore, + is_authority: role.is_network_authority(), + }; + + if enable_grandpa { + // start the full GRANDPA voter + // NOTE: non-authorities could run the GRANDPA observer protocol, but at + // this point the full voter should provide better guarantees of block + // and vote data availability than the observer. The observer has not + // been tested extensively yet and having most nodes in a network run it + // could lead to finality stalls. + let grandpa_config = sc_finality_grandpa::GrandpaParams { + config: grandpa_config, + link: grandpa_link, + network, + inherent_data_providers, + telemetry_on_connect: Some(telemetry_connection_sinks.on_connect_stream()), + voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(), + prometheus_registry, + shared_voter_state: SharedVoterState::empty(), + }; + + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + task_manager + .spawn_essential_handle() + .spawn_blocking("grandpa-voter", sc_finality_grandpa::run_grandpa_voter(grandpa_config)?); + } else { + sc_finality_grandpa::setup_disabled_grandpa(client, &inherent_data_providers, network)?; + } + + network_starter.start_network(); + Ok(task_manager) +} + +/// Builds a new service for a light client. +pub fn new_light(config: Configuration) -> Result { + let (client, backend, keystore, mut task_manager, on_demand) = + sc_service::new_light_parts::(&config)?; + + let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light( + config.transaction_pool.clone(), + config.prometheus_registry(), + task_manager.spawn_handle(), + client.clone(), + on_demand.clone(), + )); + + let grandpa_block_import = sc_finality_grandpa::light_block_import( + client.clone(), + backend.clone(), + &(client.clone() as Arc<_>), + Arc::new(on_demand.checker().clone()) as Arc<_>, + )?; + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = finality_proof_import.create_finality_proof_request_builder(); + + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>( + sc_consensus_aura::slot_duration(&*client)?, + grandpa_block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + InherentDataProviders::new(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + sp_consensus::NeverCanAuthor, + )?; + + let finality_proof_provider = GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); + + let (network, network_status_sinks, system_rpc_tx, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + on_demand: Some(on_demand.clone()), + block_announce_validator_builder: None, + finality_proof_request_builder: Some(finality_proof_request_builder), + finality_proof_provider: Some(finality_proof_provider), + })?; + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, + backend.clone(), + task_manager.spawn_handle(), + client.clone(), + network.clone(), + ); + } + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + remote_blockchain: Some(backend.remote_blockchain()), + transaction_pool, + task_manager: &mut task_manager, + on_demand: Some(on_demand), + rpc_extensions_builder: Box::new(|_, _| ()), + telemetry_connection_sinks: sc_service::TelemetryConnectionSinks::default(), + config, + client, + keystore, + backend, + network, + network_status_sinks, + system_rpc_tx, + })?; + + network_starter.start_network(); + + Ok(task_manager) +} diff --git a/bridges/bin/millau-runtime/Cargo.toml b/bridges/bin/millau/runtime/Cargo.toml similarity index 85% rename from bridges/bin/millau-runtime/Cargo.toml rename to bridges/bin/millau/runtime/Cargo.toml index 85db10f4dc..039444b1e5 100644 --- a/bridges/bin/millau-runtime/Cargo.toml +++ b/bridges/bin/millau/runtime/Cargo.toml @@ -13,11 +13,11 @@ serde = { version = "1.0.115", optional = true, features = ["derive"] } # Bridge dependencies -bp-message-lane = { path = "../../primitives/message-lane", default-features = false } -bp-millau = { path = "../../primitives/millau", default-features = false } -pallet-bridge-call-dispatch = { path = "../../modules/call-dispatch", default-features = false } -pallet-message-lane = { path = "../../modules/message-lane", default-features = false } -pallet-shift-session-manager = { path = "../../modules/shift-session-manager", default-features = false } +bp-message-lane = { path = "../../../primitives/message-lane", default-features = false } +bp-millau = { path = "../../../primitives/millau", default-features = false } +pallet-bridge-call-dispatch = { path = "../../../modules/call-dispatch", default-features = false } +pallet-message-lane = { path = "../../../modules/message-lane", default-features = false } +pallet-shift-session-manager = { path = "../../../modules/shift-session-manager", default-features = false } # Substrate Dependencies diff --git a/bridges/bin/millau-runtime/build.rs b/bridges/bin/millau/runtime/build.rs similarity index 100% rename from bridges/bin/millau-runtime/build.rs rename to bridges/bin/millau/runtime/build.rs diff --git a/bridges/bin/millau-runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs similarity index 100% rename from bridges/bin/millau-runtime/src/lib.rs rename to bridges/bin/millau/runtime/src/lib.rs diff --git a/bridges/bin/rialto-node/Cargo.toml b/bridges/bin/rialto-node/Cargo.toml deleted file mode 100644 index 215cf60faa..0000000000 --- a/bridges/bin/rialto-node/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "rialto-bridge-node" -description = "Substrate node compatible with Rialto runtime" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2018" -license = "GPL-3.0-or-later WITH Classpath-exception-2.0" - -[dependencies] -bridge-node = { path = "../node", default-features = false, features = ["rialto"] } - -[features] -default = [] -runtime-benchmarks = [ - "bridge-node/runtime-benchmarks", -] diff --git a/bridges/bin/node/Cargo.toml b/bridges/bin/rialto/node/Cargo.toml similarity index 79% rename from bridges/bin/node/Cargo.toml rename to bridges/bin/rialto/node/Cargo.toml index 628ba75525..db4f2a093f 100644 --- a/bridges/bin/node/Cargo.toml +++ b/bridges/bin/rialto/node/Cargo.toml @@ -1,5 +1,6 @@ [package] -name = "bridge-node" +name = "rialto-bridge-node" +description = "Substrate node compatible with Rialto runtime" version = "0.1.0" authors = ["Parity Technologies "] edition = "2018" @@ -14,9 +15,8 @@ structopt = "0.3.17" # Bridge dependencies -millau-runtime = { path = "../millau-runtime", optional = true } -pallet-message-lane-rpc = { path = "../../modules/message-lane/rpc" } -rialto-runtime = { path = "../rialto-runtime", optional = true } +pallet-message-lane-rpc = { path = "../../../modules/message-lane/rpc" } +rialto-runtime = { path = "../runtime" } # Substrate Dependencies @@ -47,12 +47,6 @@ vergen = "3.1.0" [features] default = [] -millau = [ - "millau-runtime", -] -rialto = [ - "rialto-runtime", -] runtime-benchmarks = [ "rialto-runtime/runtime-benchmarks", ] diff --git a/bridges/bin/rialto/node/build.rs b/bridges/bin/rialto/node/build.rs new file mode 100644 index 0000000000..e9a10ff8ad --- /dev/null +++ b/bridges/bin/rialto/node/build.rs @@ -0,0 +1,25 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +use vergen::{generate_cargo_keys, ConstantsFlags}; + +const ERROR_MSG: &str = "Failed to generate metadata files"; + +fn main() { + generate_cargo_keys(ConstantsFlags::SHA_SHORT).expect(ERROR_MSG); + + build_script_utils::rerun_if_git_head_changed(); +} diff --git a/bridges/bin/node/src/chain_spec.rs b/bridges/bin/rialto/node/src/chain_spec.rs similarity index 100% rename from bridges/bin/node/src/chain_spec.rs rename to bridges/bin/rialto/node/src/chain_spec.rs diff --git a/bridges/bin/rialto/node/src/cli.rs b/bridges/bin/rialto/node/src/cli.rs new file mode 100644 index 0000000000..1149c4f910 --- /dev/null +++ b/bridges/bin/rialto/node/src/cli.rs @@ -0,0 +1,67 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +use sc_cli::RunCmd; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +pub struct Cli { + #[structopt(subcommand)] + pub subcommand: Option, + + #[structopt(flatten)] + pub run: RunCmd, +} + +/// Possible subcommands of the main binary. +#[derive(Debug, StructOpt)] +pub enum Subcommand { + /// Key management cli utilities + Key(sc_cli::KeySubcommand), + /// Verify a signature for a message, provided on STDIN, with a given (public or secret) key. + Verify(sc_cli::VerifyCmd), + + /// Generate a seed that provides a vanity address. + Vanity(sc_cli::VanityCmd), + + /// Sign a message, with a given (secret) key. + Sign(sc_cli::SignCmd), + + /// Build a chain specification. + BuildSpec(sc_cli::BuildSpecCmd), + + /// Validate blocks. + CheckBlock(sc_cli::CheckBlockCmd), + + /// Export blocks. + ExportBlocks(sc_cli::ExportBlocksCmd), + + /// Export the state of a given block into a chain spec. + ExportState(sc_cli::ExportStateCmd), + + /// Import blocks. + ImportBlocks(sc_cli::ImportBlocksCmd), + + /// Remove the whole chain. + PurgeChain(sc_cli::PurgeChainCmd), + + /// Revert the chain to a previous state. + Revert(sc_cli::RevertCmd), + + /// The custom benchmark subcommmand benchmarking runtime pallets. + #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")] + Benchmark(frame_benchmarking_cli::BenchmarkCmd), +} diff --git a/bridges/bin/node/src/command.rs b/bridges/bin/rialto/node/src/command.rs similarity index 84% rename from bridges/bin/node/src/command.rs rename to bridges/bin/rialto/node/src/command.rs index 7a7417c9a5..fb07b77cb0 100644 --- a/bridges/bin/node/src/command.rs +++ b/bridges/bin/rialto/node/src/command.rs @@ -14,22 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Bridges Common. - -// Parity Bridges Common 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. - -// Parity Bridges Common 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 Parity Bridges Common. If not, see . - use crate::cli::{Cli, Subcommand}; use crate::service; use crate::service::new_partial; @@ -39,7 +23,7 @@ use sc_service::PartialComponents; impl SubstrateCli for Cli { fn impl_name() -> String { - "Bridge Node".into() + "Rialto Bridge Node".into() } fn impl_version() -> String { @@ -47,7 +31,7 @@ impl SubstrateCli for Cli { } fn description() -> String { - "Bridge Node".into() + "Rialto Bridge Node".into() } fn author() -> String { @@ -63,7 +47,7 @@ impl SubstrateCli for Cli { } fn executable_name() -> String { - "bridge-node".into() + "rialto-bridge-node".into() } fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { diff --git a/bridges/bin/rialto-node/src/main.rs b/bridges/bin/rialto/node/src/main.rs similarity index 85% rename from bridges/bin/rialto-node/src/main.rs rename to bridges/bin/rialto/node/src/main.rs index 7e101de175..164afae2bb 100644 --- a/bridges/bin/rialto-node/src/main.rs +++ b/bridges/bin/rialto/node/src/main.rs @@ -18,7 +18,13 @@ #![warn(missing_docs)] -/// Run node. -fn main() -> bridge_node::Result { - bridge_node::run() +mod chain_spec; +#[macro_use] +mod service; +mod cli; +mod command; + +/// Run the Rialto Node +fn main() -> sc_cli::Result<()> { + command::run() } diff --git a/bridges/bin/node/src/service.rs b/bridges/bin/rialto/node/src/service.rs similarity index 100% rename from bridges/bin/node/src/service.rs rename to bridges/bin/rialto/node/src/service.rs diff --git a/bridges/bin/rialto-runtime/Cargo.toml b/bridges/bin/rialto/runtime/Cargo.toml similarity index 78% rename from bridges/bin/rialto-runtime/Cargo.toml rename to bridges/bin/rialto/runtime/Cargo.toml index 878dfc01b8..41dd0e9d67 100644 --- a/bridges/bin/rialto-runtime/Cargo.toml +++ b/bridges/bin/rialto/runtime/Cargo.toml @@ -15,17 +15,17 @@ serde = { version = "1.0.115", optional = true, features = ["derive"] } # Bridge dependencies -bp-currency-exchange = { path = "../../primitives/currency-exchange", default-features = false } -bp-eth-poa = { path = "../../primitives/ethereum-poa", default-features = false } -bp-header-chain = { path = "../../primitives/header-chain", default-features = false } -bp-message-lane = { path = "../../primitives/message-lane", default-features = false } -bp-millau = { path = "../../primitives/millau", default-features = false } -bp-rialto = { path = "../../primitives/rialto", default-features = false } -pallet-bridge-eth-poa = { path = "../../modules/ethereum", default-features = false } -pallet-bridge-call-dispatch = { path = "../../modules/call-dispatch", default-features = false } -pallet-bridge-currency-exchange = { path = "../../modules/currency-exchange", default-features = false } -pallet-message-lane = { path = "../../modules/message-lane", default-features = false } -pallet-shift-session-manager = { path = "../../modules/shift-session-manager", default-features = false } +bp-currency-exchange = { path = "../../../primitives/currency-exchange", default-features = false } +bp-eth-poa = { path = "../../../primitives/ethereum-poa", default-features = false } +bp-header-chain = { path = "../../../primitives/header-chain", default-features = false } +bp-message-lane = { path = "../../../primitives/message-lane", default-features = false } +bp-millau = { path = "../../../primitives/millau", default-features = false } +bp-rialto = { path = "../../../primitives/rialto", default-features = false } +pallet-bridge-eth-poa = { path = "../../../modules/ethereum", default-features = false } +pallet-bridge-call-dispatch = { path = "../../../modules/call-dispatch", default-features = false } +pallet-bridge-currency-exchange = { path = "../../../modules/currency-exchange", default-features = false } +pallet-message-lane = { path = "../../../modules/message-lane", default-features = false } +pallet-shift-session-manager = { path = "../../../modules/shift-session-manager", default-features = false } # Substrate Dependencies diff --git a/bridges/bin/rialto-runtime/build.rs b/bridges/bin/rialto/runtime/build.rs similarity index 100% rename from bridges/bin/rialto-runtime/build.rs rename to bridges/bin/rialto/runtime/build.rs diff --git a/bridges/bin/rialto-runtime/src/benches.rs b/bridges/bin/rialto/runtime/src/benches.rs similarity index 100% rename from bridges/bin/rialto-runtime/src/benches.rs rename to bridges/bin/rialto/runtime/src/benches.rs diff --git a/bridges/bin/rialto-runtime/src/exchange.rs b/bridges/bin/rialto/runtime/src/exchange.rs similarity index 100% rename from bridges/bin/rialto-runtime/src/exchange.rs rename to bridges/bin/rialto/runtime/src/exchange.rs diff --git a/bridges/bin/rialto-runtime/src/kovan.rs b/bridges/bin/rialto/runtime/src/kovan.rs similarity index 100% rename from bridges/bin/rialto-runtime/src/kovan.rs rename to bridges/bin/rialto/runtime/src/kovan.rs diff --git a/bridges/bin/rialto-runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs similarity index 100% rename from bridges/bin/rialto-runtime/src/lib.rs rename to bridges/bin/rialto/runtime/src/lib.rs diff --git a/bridges/bin/rialto-runtime/src/rialto.rs b/bridges/bin/rialto/runtime/src/rialto.rs similarity index 100% rename from bridges/bin/rialto-runtime/src/rialto.rs rename to bridges/bin/rialto/runtime/src/rialto.rs diff --git a/bridges/bin/scripts/init.sh b/bridges/bin/scripts/init.sh deleted file mode 100755 index 1405a41ef3..0000000000 --- a/bridges/bin/scripts/init.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e - -echo "*** Initializing WASM build environment" - -if [ -z $CI_PROJECT_NAME ] ; then - rustup update nightly - rustup update stable -fi - -rustup target add wasm32-unknown-unknown --toolchain nightly diff --git a/bridges/modules/ethereum-contract/builtin/Cargo.toml b/bridges/modules/ethereum-contract/builtin/Cargo.toml index b2adcfbf49..631bc24c44 100644 --- a/bridges/modules/ethereum-contract/builtin/Cargo.toml +++ b/bridges/modules/ethereum-contract/builtin/Cargo.toml @@ -15,7 +15,7 @@ log = "0.4.11" # Runtime/chain specific dependencies -rialto-runtime = { path = "../../../bin/rialto-runtime" } +rialto-runtime = { path = "../../../bin/rialto/runtime" } # Substrate Dependencies diff --git a/bridges/relays/ethereum/Cargo.toml b/bridges/relays/ethereum/Cargo.toml index d496aeff67..bc60e41b81 100644 --- a/bridges/relays/ethereum/Cargo.toml +++ b/bridges/relays/ethereum/Cargo.toml @@ -36,7 +36,7 @@ relay-ethereum-client = { path = "../ethereum-client" } relay-rialto-client = { path = "../rialto-client" } relay-substrate-client = { path = "../substrate-client" } relay-utils = { path = "../utils" } -rialto-runtime = { path = "../../bin/rialto-runtime" } +rialto-runtime = { path = "../../bin/rialto/runtime" } # Substrate Dependencies diff --git a/bridges/relays/millau-client/Cargo.toml b/bridges/relays/millau-client/Cargo.toml index cb98370d84..3bf0dc426f 100644 --- a/bridges/relays/millau-client/Cargo.toml +++ b/bridges/relays/millau-client/Cargo.toml @@ -13,7 +13,7 @@ relay-utils = { path = "../utils" } # Supported Chains -millau-runtime = { path = "../../bin/millau-runtime" } +millau-runtime = { path = "../../bin/millau/runtime" } # Substrate Dependencies diff --git a/bridges/relays/rialto-client/Cargo.toml b/bridges/relays/rialto-client/Cargo.toml index aec1262a00..2f4be18a66 100644 --- a/bridges/relays/rialto-client/Cargo.toml +++ b/bridges/relays/rialto-client/Cargo.toml @@ -13,7 +13,7 @@ relay-utils = { path = "../utils" } # Bridge dependencies -rialto-runtime = { path = "../../bin/rialto-runtime" } +rialto-runtime = { path = "../../bin/rialto/runtime" } # Substrate Dependencies