From 8aa367c27a86794c5c08ecbc6feea574ce9e54e3 Mon Sep 17 00:00:00 2001
From: Jim Posen <jim.posen@gmail.com>
Date: Mon, 29 Jul 2019 17:06:13 +0200
Subject: [PATCH] Fix substrate factory CLI command (#3239)

* CLI execution flag for import-blocks and factory.

* Fix minimum_balance bug with CLI factory.
---
 substrate/Cargo.lock                          |  1 +
 substrate/core/cli/src/lib.rs                 |  9 ++++++--
 substrate/core/cli/src/params.rs              | 13 +++++++++++
 substrate/node/cli/Cargo.toml                 |  1 +
 substrate/node/cli/src/factory_impl.rs        | 10 ++++----
 substrate/node/cli/src/lib.rs                 | 23 +++++++++++++++++--
 .../transaction-factory/src/complex_mode.rs   |  9 ++------
 .../test-utils/transaction-factory/src/lib.rs |  7 +++---
 8 files changed, 54 insertions(+), 19 deletions(-)

diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index eb7a89e78c5..4b44d707371 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -2252,6 +2252,7 @@ dependencies = [
  "srml-contracts 2.0.0",
  "srml-finality-tracker 2.0.0",
  "srml-indices 2.0.0",
+ "srml-support 2.0.0",
  "srml-system 2.0.0",
  "srml-timestamp 2.0.0",
  "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/substrate/core/cli/src/lib.rs b/substrate/core/cli/src/lib.rs
index cc31af184ed..7cd7db88979 100644
--- a/substrate/core/cli/src/lib.rs
+++ b/substrate/core/cli/src/lib.rs
@@ -51,7 +51,7 @@ use params::{
 	NetworkConfigurationParams, MergeParameters, TransactionPoolParams,
 	NodeKeyParams, NodeKeyType, Cors,
 };
-pub use params::{NoCustom, CoreParams, SharedParams};
+pub use params::{NoCustom, CoreParams, SharedParams, ExecutionStrategy as ExecutionStrategyParam};
 pub use traits::{GetLogFilter, AugmentClap};
 use app_dirs::{AppInfo, AppDataType};
 use log::info;
@@ -639,7 +639,12 @@ where
 	E: IntoExit,
 	S: FnOnce(&str) -> Result<Option<ChainSpec<FactoryGenesis<F>>>, String>,
 {
-	let config = create_config_with_db_path::<F, _>(spec_factory, &cli.shared_params, version)?;
+	let mut config = create_config_with_db_path::<F, _>(spec_factory, &cli.shared_params, version)?;
+	config.execution_strategies = ExecutionStrategies {
+		importing: cli.execution.into(),
+		other: cli.execution.into(),
+		..Default::default()
+	};
 
 	let file: Box<dyn Read> = match cli.input {
 		Some(filename) => Box::new(File::open(filename)?),
diff --git a/substrate/core/cli/src/params.rs b/substrate/core/cli/src/params.rs
index 499c8b9ecac..e1018eb93a4 100644
--- a/substrate/core/cli/src/params.rs
+++ b/substrate/core/cli/src/params.rs
@@ -33,6 +33,7 @@ macro_rules! impl_get_log_filter {
 
 arg_enum! {
 	/// How to execute blocks
+	#[allow(missing_docs)]
 	#[derive(Debug, Clone, Copy)]
 	pub enum ExecutionStrategy {
 		Native,
@@ -610,6 +611,18 @@ pub struct ImportBlocksCmd {
 	#[allow(missing_docs)]
 	#[structopt(flatten)]
 	pub shared_params: SharedParams,
+
+	/// The means of execution used when calling into the runtime while importing blocks.
+	#[structopt(
+		long = "execution",
+		value_name = "STRATEGY",
+		raw(
+			possible_values = "&ExecutionStrategy::variants()",
+			case_insensitive = "true",
+			default_value = r#""NativeElseWasm""#
+		)
+	)]
+	pub execution: ExecutionStrategy,
 }
 
 impl_get_log_filter!(ImportBlocksCmd);
diff --git a/substrate/node/cli/Cargo.toml b/substrate/node/cli/Cargo.toml
index d3d48ebe015..f40ef95ada8 100644
--- a/substrate/node/cli/Cargo.toml
+++ b/substrate/node/cli/Cargo.toml
@@ -42,6 +42,7 @@ finality_tracker = { package = "srml-finality-tracker", path = "../../srml/final
 contracts = { package = "srml-contracts", path = "../../srml/contracts" }
 system = { package = "srml-system", path = "../../srml/system" }
 balances = { package = "srml-balances", path = "../../srml/balances" }
+support = { package = "srml-support", path = "../../srml/support", default-features = false }
 
 [dev-dependencies]
 babe = { package = "substrate-consensus-babe", path = "../../core/consensus/babe", features = ["test-helpers"] }
diff --git a/substrate/node/cli/src/factory_impl.rs b/substrate/node/cli/src/factory_impl.rs
index 182cf4080e4..2d812b35ca3 100644
--- a/substrate/node/cli/src/factory_impl.rs
+++ b/substrate/node/cli/src/factory_impl.rs
@@ -23,11 +23,13 @@ use rand::rngs::StdRng;
 
 use parity_codec::Decode;
 use keyring::sr25519::Keyring;
-use node_runtime::{Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall};
+use node_primitives::Hash;
+use node_runtime::{Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit};
 use primitives::{sr25519, crypto::Pair};
 use parity_codec::Encode;
 use sr_primitives::{generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension}};
 use substrate_service::ServiceFactory;
+use support::traits::Get;
 use transaction_factory::RuntimeAdapter;
 use transaction_factory::modes::Mode;
 use crate::service;
@@ -133,7 +135,7 @@ impl RuntimeAdapter for FactoryState<Number> {
 		sender: &Self::AccountId,
 		key: &Self::Secret,
 		destination: &Self::AccountId,
-		amount: &Self::Number,
+		amount: &Self::Balance,
 		prior_block_hash: &<Self::Block as BlockT>::Hash,
 	) -> <Self::Block as BlockT>::Extrinsic {
 		let index = self.extract_index(&sender, prior_block_hash);
@@ -161,9 +163,9 @@ impl RuntimeAdapter for FactoryState<Number> {
 		inherent
 	}
 
-	fn minimum_balance() -> Self::Number {
+	fn minimum_balance() -> Self::Balance {
 		// TODO get correct amount via api. See #2587.
-		1337
+		ExistentialDeposit::get()
 	}
 
 	fn master_account_id() -> Self::AccountId {
diff --git a/substrate/node/cli/src/lib.rs b/substrate/node/cli/src/lib.rs
index b18fa57411c..adf9d81fa7d 100644
--- a/substrate/node/cli/src/lib.rs
+++ b/substrate/node/cli/src/lib.rs
@@ -26,7 +26,7 @@ mod factory_impl;
 
 use tokio::prelude::Future;
 use tokio::runtime::{Builder as RuntimeBuilder, Runtime};
-pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams};
+pub use cli::{VersionInfo, IntoExit, NoCustom, SharedParams, ExecutionStrategyParam};
 use substrate_service::{ServiceFactory, Roles as ServiceRoles};
 use std::ops::Deref;
 use log::info;
@@ -34,6 +34,7 @@ use structopt::{StructOpt, clap::App};
 use cli::{AugmentClap, GetLogFilter};
 use crate::factory_impl::FactoryState;
 use transaction_factory::RuntimeAdapter;
+use client::ExecutionStrategies;
 
 /// The chain specification option.
 #[derive(Clone, Debug, PartialEq)]
@@ -102,6 +103,18 @@ pub struct FactoryCmd {
 	#[allow(missing_docs)]
 	#[structopt(flatten)]
 	pub shared_params: SharedParams,
+
+	/// The means of execution used when calling into the runtime while importing blocks.
+	#[structopt(
+		long = "execution",
+		value_name = "STRATEGY",
+		raw(
+			possible_values = "&ExecutionStrategyParam::variants()",
+			case_insensitive = "true",
+			default_value = r#""NativeElseWasm""#
+		)
+	)]
+	pub execution: ExecutionStrategyParam,
 }
 
 impl AugmentClap for FactoryCmd {
@@ -173,11 +186,17 @@ pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Resul
 
 	match &ret {
 		Ok(Some(CustomSubcommands::Factory(cli_args))) => {
-			let config = cli::create_config_with_db_path::<service::Factory, _>(
+			let mut config = cli::create_config_with_db_path::<service::Factory, _>(
 				load_spec,
 				&cli_args.shared_params,
 				&version,
 			)?;
+			config.execution_strategies = ExecutionStrategies {
+				importing: cli_args.execution.into(),
+				block_construction: cli_args.execution.into(),
+				other: cli_args.execution.into(),
+				..Default::default()
+			};
 
 			match ChainSpec::from(config.chain_spec.id()) {
 				Some(ref c) if c == &ChainSpec::Development || c == &ChainSpec::LocalTestnet => {},
diff --git a/substrate/test-utils/transaction-factory/src/complex_mode.rs b/substrate/test-utils/transaction-factory/src/complex_mode.rs
index 0d383c30256..66e209fc81b 100644
--- a/substrate/test-utils/transaction-factory/src/complex_mode.rs
+++ b/substrate/test-utils/transaction-factory/src/complex_mode.rs
@@ -83,13 +83,8 @@ where
 	let seed = factory_state.start_number() + factory_state.block_no();
 	let to = RA::gen_random_account_id(&seed);
 
-	let amount;
-	if factory_state.round() == RA::Number::zero() {
-		amount = RA::minimum_balance() * factory_state.rounds();
-	} else {
-		let rounds_left = factory_state.rounds() - factory_state.round();
-		amount = RA::minimum_balance() * rounds_left;
-	};
+	let rounds_left = factory_state.rounds() - factory_state.round();
+	let amount = RA::minimum_balance() * rounds_left.into();
 
 	let transfer = factory_state.transfer_extrinsic(
 		&from.0,
diff --git a/substrate/test-utils/transaction-factory/src/lib.rs b/substrate/test-utils/transaction-factory/src/lib.rs
index 61dbfab6584..747811433ab 100644
--- a/substrate/test-utils/transaction-factory/src/lib.rs
+++ b/substrate/test-utils/transaction-factory/src/lib.rs
@@ -21,7 +21,6 @@
 
 use std::collections::HashMap;
 use std::sync::Arc;
-use std::ops::Mul;
 use std::cmp::PartialOrd;
 use std::fmt::Display;
 
@@ -51,7 +50,7 @@ mod simple_modes;
 
 pub trait RuntimeAdapter {
 	type AccountId: Display;
-	type Balance: Display + Mul;
+	type Balance: Display + SimpleArithmetic + From<Self::Number>;
 	type Block: BlockT;
 	type Index: Copy;
 	type Number: Display + PartialOrd + SimpleArithmetic + Zero + One;
@@ -77,13 +76,13 @@ pub trait RuntimeAdapter {
 		sender: &Self::AccountId,
 		key: &Self::Secret,
 		destination: &Self::AccountId,
-		amount: &Self::Number,
+		amount: &Self::Balance,
 		prior_block_hash: &<Self::Block as BlockT>::Hash,
 	) -> <Self::Block as BlockT>::Extrinsic;
 
 	fn inherent_extrinsics(&self) -> InherentData;
 
-	fn minimum_balance() -> Self::Number;
+	fn minimum_balance() -> Self::Balance;
 	fn master_account_id() -> Self::AccountId;
 	fn master_account_secret() -> Self::Secret;
 	fn extract_index(&self, account_id: &Self::AccountId, block_hash: &<Self::Block as BlockT>::Hash) -> Self::Index;
-- 
GitLab