diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 51bf1481f7fc..5c14d4e05b87 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -10,41 +10,27 @@ crate-type = ["cdylib", "rlib"] [dependencies] log = "0.4.8" -tokio = "0.1.22" futures = { version = "0.3.1", features = ["compat"] } futures01 = { package = "futures", version = "0.1.29" } structopt = "=0.3.7" -cli = { package = "sc-cli", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } service = { package = "polkadot-service", path = "../service", default-features = false } -libp2p = { version = "0.13.1", default-features = false, optional = true } -wasm-bindgen = { version = "0.2.55", optional = true } -wasm-bindgen-futures = { version = "0.4.5", optional = true } -console_log = { version = "0.1.2", optional = true } -console_error_panic_hook = { version = "0.1.1", optional = true } -js-sys = { version = "0.3.22", optional = true } -kvdb-web = { version = "0.1.1", optional = true } -substrate-service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", optional = true, default-features = false } -substrate-network = { package = "sc-network", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", optional = true } +tokio = { version = "0.1.22", optional = true } -# Imported just for the `wasm-bindgen` feature -rand = { version = "0.7", features = ["wasm-bindgen"], optional = true } -rand6 = { package = "rand", version = "0.6.5", features = ["wasm-bindgen"], optional = true } +wasm-bindgen = { version = "0.2.57", optional = true } +wasm-bindgen-futures = { version = "0.4.7", optional = true } +browser-utils = { package = "browser-utils", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", optional = true } +substrate-service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", optional = true, default-features = false } [features] -default = [ "wasmtime", "rocksdb" ] -wasmtime = [ "cli/wasmtime" ] +default = [ "wasmtime", "rocksdb", "cli" ] +wasmtime = [ "sc-cli/wasmtime" ] rocksdb = [ "service/rocksdb" ] +cli = [ "tokio" ] browser = [ - "libp2p", "wasm-bindgen", - "console_error_panic_hook", "wasm-bindgen-futures", - "console_log", - "js-sys", - "kvdb-web", + "browser-utils", "substrate-service", - "substrate-network", - "rand", - "rand6", ] diff --git a/cli/src/browser.rs b/cli/src/browser.rs index 27c60a2d6cb4..32b03fcc8842 100644 --- a/cli/src/browser.rs +++ b/cli/src/browser.rs @@ -15,51 +15,28 @@ // along with Substrate. If not, see . use crate::ChainSpec; -use futures01::{prelude::*, sync::oneshot, sync::mpsc}; -use libp2p::wasm_ext; -use log::{debug, info}; -use std::sync::Arc; -use service::{AbstractService, Roles as ServiceRoles}; -use substrate_service::{RpcSession, Configuration, config::DatabaseConfig}; +use log::info; +use substrate_service::Configuration; use wasm_bindgen::prelude::*; -use futures::{compat::*, TryFutureExt as _, TryStreamExt as _, FutureExt as _}; +use service::CustomConfiguration; /// Starts the client. /// /// You must pass a libp2p transport that supports . #[wasm_bindgen] -pub async fn start_client(wasm_ext: wasm_ext::ffi::Transport) -> Result { +pub async fn start_client(wasm_ext: browser_utils::Transport) -> Result { start_inner(wasm_ext) .await .map_err(|err| JsValue::from_str(&err.to_string())) } -async fn start_inner(wasm_ext: wasm_ext::ffi::Transport) -> Result> { - console_error_panic_hook::set_once(); - console_log::init_with_level(log::Level::Info); +async fn start_inner(wasm_ext: browser_utils::Transport) -> Result> { + browser_utils::set_console_error_panic_hook(); + browser_utils::init_console_log(log::Level::Info)?; - // Build the configuration to pass to the service. - let config = { - let wasm_ext = wasm_ext::ExtTransport::new(wasm_ext); - let chain_spec = ChainSpec::Kusama.load().map_err(|e| format!("{:?}", e))?; - let mut config = Configuration::::default_with_spec_and_base_path(chain_spec, None); - config.network.transport = substrate_network::config::TransportConfig::Normal { - wasm_external_transport: Some(wasm_ext.clone()), - allow_private_ipv4: true, - enable_mdns: false, - }; - config.telemetry_external_transport = Some(wasm_ext); - config.roles = ServiceRoles::LIGHT; - config.name = "Browser node".to_string(); - config.database = { - let db = kvdb_web::Database::open("polkadot".into(), 10) - .await - .unwrap(); - DatabaseConfig::Custom(Arc::new(db)) - }; - config.keystore_path = Some(std::path::PathBuf::from("/")); - config - }; + let chain_spec = ChainSpec::Kusama.load().map_err(|e| format!("{:?}", e))?; + let config: Configuration = browser_utils::browser_configuration(wasm_ext, chain_spec) + .await?; info!("Polkadot browser node"); info!(" version {}", config.full_version()); @@ -76,105 +53,7 @@ async fn start_inner(wasm_ext: wasm_ext::ffi::Transport) -> Result(); - wasm_bindgen_futures::spawn_local(futures01::future::poll_fn(move || { - loop { - match rpc_send_rx.poll() { - Ok(Async::Ready(Some(message))) => { - let fut = service.rpc_query(&message.session, &message.rpc_json); - let _ = message.send_back.send(Box::new(fut)); - }, - Ok(Async::NotReady) => break, - Err(_) | Ok(Async::Ready(None)) => return Ok(Async::Ready(())), - } - } - - loop { - match service.poll().map_err(|_| ())? { - Async::Ready(()) => return Ok(Async::Ready(())), - Async::NotReady => break - } - } - - Ok::<_, ()>(Async::NotReady) - }).compat().map(drop)); - - Ok(Client { - rpc_send_tx, - }) -} - -/// A running client. -#[wasm_bindgen] -pub struct Client { - rpc_send_tx: mpsc::UnboundedSender, -} - -struct RpcMessage { - rpc_json: String, - session: RpcSession, - send_back: oneshot::Sender, Error = ()> + Unpin>>, -} - -#[wasm_bindgen] -impl Client { - /// Allows starting an RPC request. Returns a `Promise` containing the result of that request. - #[wasm_bindgen(js_name = "rpcSend")] - pub fn rpc_send(&mut self, rpc: &str) -> js_sys::Promise { - let rpc_session = RpcSession::new(mpsc::channel(1).0); - let (tx, rx) = oneshot::channel(); - let _ = self.rpc_send_tx.unbounded_send(RpcMessage { - rpc_json: rpc.to_owned(), - session: rpc_session, - send_back: tx, - }); - let fut = rx - .compat() - .map_err(|_| ()) - .and_then(|fut| fut.compat()) - .map_ok(|s| JsValue::from_str(&s.unwrap_or(String::new()))) - .map_err(|_| JsValue::NULL); - wasm_bindgen_futures::future_to_promise(fut) - } - - /// Subscribes to an RPC pubsub endpoint. - #[wasm_bindgen(js_name = "rpcSubscribe")] - pub fn rpc_subscribe(&mut self, rpc: &str, callback: js_sys::Function) { - let (tx, rx) = mpsc::channel(4); - let rpc_session = RpcSession::new(tx); - let (fut_tx, fut_rx) = oneshot::channel(); - let _ = self.rpc_send_tx.unbounded_send(RpcMessage { - rpc_json: rpc.to_owned(), - session: rpc_session.clone(), - send_back: fut_tx, - }); - let fut_rx = fut_rx - .compat() - .map_err(|_| ()) - .and_then(|fut| fut.compat()) - .map(drop); - wasm_bindgen_futures::spawn_local(fut_rx); - wasm_bindgen_futures::spawn_local(rx - .compat() - .try_for_each(move |s| { - match callback.call1(&callback, &JsValue::from_str(&s)) { - Ok(_) => futures::future::ready(Ok(())), - Err(_) => futures::future::ready(Err(())), - } - }) - .then(move |_| { - // We need to keep `rpc_session` alive. - debug!("RPC subscription has ended"); - drop(rpc_session); - futures::future::ready(()) - }) - ); - } + Ok(browser_utils::start_client(service)) } diff --git a/cli/src/lib.rs b/cli/src/lib.rs index aa7ff96c743e..c8555ac8dc31 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -27,6 +27,7 @@ use chain_spec::ChainSpec; use futures::{ Future, FutureExt, TryFutureExt, future::select, channel::oneshot, compat::Future01CompatExt, }; +#[cfg(feature = "cli")] use tokio::runtime::Runtime; use log::info; use structopt::StructOpt; @@ -36,8 +37,8 @@ pub use service::{ WrappedExecutor }; -pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams}; -pub use cli::{display_role, error}; +pub use sc_cli::{VersionInfo, IntoExit, NoCustom, SharedParams}; +pub use sc_cli::{display_role, error}; /// Load the `ChainSpec` for the given `id`. pub fn load_spec(id: &str) -> Result, String> { @@ -53,8 +54,8 @@ enum PolkadotSubCommands { ValidationWorker(ValidationWorkerCommand), } -impl cli::GetSharedParams for PolkadotSubCommands { - fn shared_params(&self) -> Option<&cli::SharedParams> { None } +impl sc_cli::GetSharedParams for PolkadotSubCommands { + fn shared_params(&self) -> Option<&sc_cli::SharedParams> { None } } #[derive(Debug, StructOpt, Clone)] @@ -70,8 +71,9 @@ struct PolkadotSubParams { } /// Parses polkadot specific CLI arguments and run the service. -pub fn run(exit: E, version: cli::VersionInfo) -> error::Result<()> { - let cmd = cli::parse_and_prepare::( +#[cfg(feature = "cli")] +pub fn run(exit: E, version: sc_cli::VersionInfo) -> error::Result<()> { + let cmd = sc_cli::parse_and_prepare::( &version, "parity-polkadot", std::env::args(), @@ -79,7 +81,7 @@ pub fn run(exit: E, version: cli::VersionInfo) -> error::Result<()> // Preload spec to select native runtime let spec = match cmd.shared_params() { - Some(params) => Some(cli::load_spec(params, &load_spec)?), + Some(params) => Some(sc_cli::load_spec(params, &load_spec)?), None => None, }; if spec.as_ref().map_or(false, |c| c.is_kusama()) { @@ -100,10 +102,11 @@ pub fn run(exit: E, version: cli::VersionInfo) -> error::Result<()> } /// Execute the given `cmd` with the given runtime. +#[cfg(feature = "cli")] fn execute_cmd_with_runtime( exit: X, - version: &cli::VersionInfo, - cmd: cli::ParseAndPrepare, + version: &sc_cli::VersionInfo, + cmd: sc_cli::ParseAndPrepare, spec: Option, ) -> error::Result<()> where @@ -120,7 +123,7 @@ where // Use preloaded spec let load_spec = |_: &str| Ok(spec); match cmd { - cli::ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, + sc_cli::ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, |exit, _cli_args, custom_args, mut config| { info!("{}", version.name); info!(" version {}", config.full_version()); @@ -154,17 +157,17 @@ where ), }.map_err(|e| format!("{:?}", e)) }), - cli::ParseAndPrepare::BuildSpec(cmd) => cmd.run::(load_spec), - cli::ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config| + sc_cli::ParseAndPrepare::BuildSpec(cmd) => cmd.run::(load_spec), + sc_cli::ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config| Ok(service::new_chain_ops::(config)?), load_spec, exit), - cli::ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config| + sc_cli::ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config| Ok(service::new_chain_ops::(config)?), load_spec, exit), - cli::ParseAndPrepare::CheckBlock(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config| + sc_cli::ParseAndPrepare::CheckBlock(cmd) => cmd.run_with_builder::<_, _, _, _, _, _, _>(|config| Ok(service::new_chain_ops::(config)?), load_spec, exit), - cli::ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), - cli::ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<_, _, _, _, _, _>(|config| + sc_cli::ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), + sc_cli::ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder::<_, _, _, _, _, _>(|config| Ok(service::new_chain_ops::(config)?), load_spec), - cli::ParseAndPrepare::CustomCommand(PolkadotSubCommands::ValidationWorker(args)) => { + sc_cli::ParseAndPrepare::CustomCommand(PolkadotSubCommands::ValidationWorker(args)) => { if cfg!(feature = "browser") { Err(error::Error::Input("Cannot run validation worker in browser".into())) } else { @@ -177,6 +180,7 @@ where } /// Run the given `service` using the `runtime` until it exits or `e` fires. +#[cfg(feature = "cli")] pub fn run_until_exit( mut runtime: Runtime, service: impl AbstractService, @@ -185,7 +189,7 @@ pub fn run_until_exit( let (exit_send, exit) = oneshot::channel(); let executor = runtime.executor(); - let informant = cli::informant::build(&service); + let informant = sc_cli::informant::build(&service); let future = select(exit, informant) .map(|_| Ok(())) .compat(); diff --git a/network/src/tests/mod.rs b/network/src/tests/mod.rs index cd00c6de9a5b..32efa1dadc11 100644 --- a/network/src/tests/mod.rs +++ b/network/src/tests/mod.rs @@ -57,10 +57,6 @@ impl Context for TestContext { } } - fn send_consensus(&mut self, _who: PeerId, _consensus: Vec) { - unimplemented!() - } - fn send_chain_specific(&mut self, who: PeerId, message: Vec) { self.messages.push((who, message)) } diff --git a/runtime/common/src/claims.rs b/runtime/common/src/claims.rs index e69c74df1a70..a2bef829fa9d 100644 --- a/runtime/common/src/claims.rs +++ b/runtime/common/src/claims.rs @@ -317,6 +317,7 @@ mod tests { impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); + type OnReapAccount = System; type OnNewAccount = (); type Event = (); type DustRemoval = (); @@ -335,6 +336,7 @@ mod tests { type Currency = Balances; type Prefix = Prefix; } + type System = system::Module; type Balances = balances::Module; type Claims = Module; diff --git a/runtime/common/src/crowdfund.rs b/runtime/common/src/crowdfund.rs index 891616706168..393f48733693 100644 --- a/runtime/common/src/crowdfund.rs +++ b/runtime/common/src/crowdfund.rs @@ -554,6 +554,7 @@ mod tests { impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); + type OnReapAccount = System; type OnNewAccount = (); type Event = (); type DustRemoval = (); diff --git a/runtime/common/src/parachains.rs b/runtime/common/src/parachains.rs index 02f7a728cedf..0a552ab4056d 100644 --- a/runtime/common/src/parachains.rs +++ b/runtime/common/src/parachains.rs @@ -1023,6 +1023,7 @@ mod tests { impl balances::Trait for Test { type Balance = Balance; type OnFreeBalanceZero = (); + type OnReapAccount = System; type OnNewAccount = (); type Event = (); type DustRemoval = (); diff --git a/runtime/common/src/registrar.rs b/runtime/common/src/registrar.rs index 431a3b3d201e..510b5424b51e 100644 --- a/runtime/common/src/registrar.rs +++ b/runtime/common/src/registrar.rs @@ -647,6 +647,7 @@ mod tests { impl balances::Trait for Test { type Balance = Balance; type OnFreeBalanceZero = (); + type OnReapAccount = System; type OnNewAccount = (); type Event = (); type DustRemoval = (); diff --git a/runtime/common/src/slots.rs b/runtime/common/src/slots.rs index 06250198189b..566162180377 100644 --- a/runtime/common/src/slots.rs +++ b/runtime/common/src/slots.rs @@ -874,6 +874,7 @@ mod tests { impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); + type OnReapAccount = System; type OnNewAccount = (); type Event = (); type DustRemoval = (); diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 21ab324233f4..2ca9187ea60c 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -174,6 +174,7 @@ pub type DealWithFees = SplitTwoWays< impl balances::Trait for Runtime { type Balance = Balance; type OnFreeBalanceZero = Staking; + type OnReapAccount = System; type OnNewAccount = Indices; type Event = Event; type DustRemoval = (); diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index b3bae29aa4ca..055d62245785 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -178,6 +178,7 @@ pub type DealWithFees = SplitTwoWays< impl balances::Trait for Runtime { type Balance = Balance; type OnFreeBalanceZero = Staking; + type OnReapAccount = System; type OnNewAccount = Indices; type Event = Event; type DustRemoval = (); diff --git a/service/Cargo.toml b/service/Cargo.toml index c1fc9c73611b..7df37b4171e9 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -35,7 +35,7 @@ consensus_common = { package = "sp-consensus", git = "https://github.com/parityt grandpa = { package = "sc-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } grandpa_primitives = { package = "sp-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } -service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } +service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } telemetry = { package = "sc-telemetry", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }