diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 45fc16bca77c1b5b6c176a25c6292cb9ce75d7b6..ecc37e9d158a7ef258de612bb02d85a94ad9cc83 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -3437,7 +3437,6 @@ dependencies = [ "node-primitives", "node-rpc", "node-runtime", - "node-transaction-factory", "pallet-authority-discovery", "pallet-balances", "pallet-contracts", @@ -3763,24 +3762,6 @@ dependencies = [ "wabt", ] -[[package]] -name = "node-transaction-factory" -version = "0.8.0-dev" -dependencies = [ - "log", - "parity-scale-codec", - "sc-block-builder", - "sc-cli", - "sc-client-api", - "sc-service", - "sp-api", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-runtime", -] - [[package]] name = "nodrop" version = "0.1.14" diff --git a/substrate/Cargo.toml b/substrate/Cargo.toml index 3882e96611e05a1986c05b4f939eebbb307cdd9d..d9ee8709d1334f7ffbab48f02028a94f79b5e295 100644 --- a/substrate/Cargo.toml +++ b/substrate/Cargo.toml @@ -12,7 +12,6 @@ members = [ "bin/node/rpc", "bin/node/runtime", "bin/node/testing", - "bin/node/transaction-factory", "bin/utils/subkey", "bin/utils/chain-spec-builder", "client/api", diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index e1e93dea3f38eb6fa48769558364ca18dd12e1ee..5b23a989cd0bf648fb9da61ff2b2e22ccf067e27 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -97,7 +97,6 @@ node-executor = { version = "2.0.0-dev", path = "../executor" } # CLI-specific dependencies sc-cli = { version = "0.8.0-dev", optional = true, path = "../../../client/cli" } frame-benchmarking-cli = { version = "2.0.0-dev", optional = true, path = "../../../utils/frame/benchmarking-cli" } -node-transaction-factory = { version = "0.8.0-dev", optional = true, path = "../transaction-factory" } node-inspect = { version = "0.8.0-dev", optional = true, path = "../inspect" } # WASM-specific dependencies @@ -126,7 +125,6 @@ platforms = "0.2.1" [build-dependencies] structopt = { version = "0.3.8", optional = true } -node-transaction-factory = { version = "0.8.0-dev", optional = true, path = "../transaction-factory" } node-inspect = { version = "0.8.0-dev", optional = true, path = "../inspect" } frame-benchmarking-cli = { version = "2.0.0-dev", optional = true, path = "../../../utils/frame/benchmarking-cli" } substrate-build-script-utils = { version = "2.0.0-dev", optional = true, path = "../../../utils/build-script-utils" } @@ -147,7 +145,6 @@ browser = [ cli = [ "node-executor/wasmi-errno", "node-inspect", - "node-transaction-factory", "sc-cli", "frame-benchmarking-cli", "sc-service/db", diff --git a/substrate/bin/node/cli/src/cli.rs b/substrate/bin/node/cli/src/cli.rs index 44b18fd716337c0857ebdf50f442001db12034c0..fa9a43ee6841ca88302810ecb81b6d1bed5f77c0 100644 --- a/substrate/bin/node/cli/src/cli.rs +++ b/substrate/bin/node/cli/src/cli.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see <http://www.gnu.org/licenses/>. -use sc_cli::{ImportParams, RunCmd, SharedParams}; +use sc_cli::RunCmd; use structopt::StructOpt; /// An overarching CLI command definition. @@ -34,13 +34,6 @@ pub enum Subcommand { /// A set of base subcommands handled by `sc_cli`. #[structopt(flatten)] Base(sc_cli::Subcommand), - /// The custom factory subcommmand for manufacturing transactions. - #[structopt( - name = "factory", - about = "Manufactures num transactions from Alice to random accounts. \ - Only supported for development or local testnet." - )] - Factory(FactoryCmd), /// The custom inspect subcommmand for decoding blocks and extrinsics. #[structopt( @@ -53,24 +46,3 @@ pub enum Subcommand { #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")] Benchmark(frame_benchmarking_cli::BenchmarkCmd), } - -/// The `factory` command used to generate transactions. -/// Please note: this command currently only works on an empty database! -#[derive(Debug, StructOpt, Clone)] -pub struct FactoryCmd { - /// Number of blocks to generate. - #[structopt(long = "blocks", default_value = "1")] - pub blocks: u32, - - /// Number of transactions to push per block. - #[structopt(long = "transactions", default_value = "8")] - pub transactions: u32, - - #[allow(missing_docs)] - #[structopt(flatten)] - pub shared_params: SharedParams, - - #[allow(missing_docs)] - #[structopt(flatten)] - pub import_params: ImportParams, -} diff --git a/substrate/bin/node/cli/src/command.rs b/substrate/bin/node/cli/src/command.rs index ab7d6ea65e8c276b3f1aaba552960265a3abd0f1..91c6298c9fd5c5751dab747d23d0d46d3e1a15d0 100644 --- a/substrate/bin/node/cli/src/command.rs +++ b/substrate/bin/node/cli/src/command.rs @@ -14,12 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see <http://www.gnu.org/licenses/>. -use crate::{chain_spec, factory_impl::FactoryState, service, Cli, FactoryCmd, Subcommand}; +use crate::{chain_spec, service, Cli, Subcommand}; use node_executor::Executor; use node_runtime::{Block, RuntimeApi}; -use node_transaction_factory::RuntimeAdapter; -use sc_cli::{CliConfiguration, ImportParams, Result, SharedParams, SubstrateCli}; -use sc_service::Configuration; +use sc_cli::{Result, SubstrateCli}; impl SubstrateCli for Cli { fn impl_name() -> &'static str { @@ -94,11 +92,6 @@ pub fn run() -> Result<()> { Ok(()) } } - Some(Subcommand::Factory(cmd)) => { - let runner = cli.create_runner(cmd)?; - - runner.sync_run(|config| cmd.run(config)) - } Some(Subcommand::Base(subcommand)) => { let runner = cli.create_runner(subcommand)?; @@ -106,44 +99,3 @@ pub fn run() -> Result<()> { } } } - -impl CliConfiguration for FactoryCmd { - fn shared_params(&self) -> &SharedParams { - &self.shared_params - } - - fn import_params(&self) -> Option<&ImportParams> { - Some(&self.import_params) - } -} - -impl FactoryCmd { - fn run(&self, config: Configuration) -> Result<()> { - match config.chain_spec.id() { - "dev" | "local" => {} - _ => return Err("Factory is only supported for development and local testnet.".into()), - } - - // Setup tracing. - if let Some(tracing_targets) = self.import_params.tracing_targets.as_ref() { - let subscriber = sc_tracing::ProfilingSubscriber::new( - self.import_params.tracing_receiver.into(), - tracing_targets, - ); - if let Err(e) = tracing::subscriber::set_global_default(subscriber) { - return Err(format!("Unable to set global default subscriber {}", e).into()); - } - } - - let factory_state = FactoryState::new(self.blocks, self.transactions); - - let service_builder = new_full_start!(config).0; - node_transaction_factory::factory( - factory_state, - service_builder.client(), - service_builder - .select_chain() - .expect("The select_chain is always initialized by new_full_start!; qed"), - ) - } -} diff --git a/substrate/bin/node/cli/src/factory_impl.rs b/substrate/bin/node/cli/src/factory_impl.rs deleted file mode 100644 index bc7653538247f05c33381516be2a756463dc3c2a..0000000000000000000000000000000000000000 --- a/substrate/bin/node/cli/src/factory_impl.rs +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>. - -//! Implementation of the transaction factory trait, which enables -//! using the cli to manufacture transactions and distribute them -//! to accounts. - -use rand::{Rng, SeedableRng}; -use rand::rngs::StdRng; - -use codec::{Encode, Decode}; -use sp_keyring::sr25519::Keyring; -use node_runtime::{ - Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit, - MinimumPeriod -}; -use node_primitives::Signature; -use sp_core::{sr25519, crypto::Pair}; -use sp_runtime::{ - generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension, Verify, IdentifyAccount} -}; -use node_transaction_factory::RuntimeAdapter; -use sp_inherents::InherentData; -use sp_timestamp; -use sp_finality_tracker; - -type AccountPublic = <Signature as Verify>::Signer; - -pub struct FactoryState<N> { - blocks: u32, - transactions: u32, - block_number: N, - index: u32, -} - -type Number = <<node_primitives::Block as BlockT>::Header as HeaderT>::Number; - -impl<Number> FactoryState<Number> { - fn build_extra(index: node_primitives::Index, phase: u64) -> node_runtime::SignedExtra { - ( - frame_system::CheckVersion::new(), - frame_system::CheckGenesis::new(), - frame_system::CheckEra::from(Era::mortal(256, phase)), - frame_system::CheckNonce::from(index), - frame_system::CheckWeight::new(), - pallet_transaction_payment::ChargeTransactionPayment::from(0), - ) - } -} - -impl RuntimeAdapter for FactoryState<Number> { - type AccountId = node_primitives::AccountId; - type Balance = node_primitives::Balance; - type Block = node_primitives::Block; - type Phase = sp_runtime::generic::Phase; - type Secret = sr25519::Pair; - type Index = node_primitives::Index; - - type Number = Number; - - fn new( - blocks: u32, - transactions: u32, - ) -> FactoryState<Self::Number> { - FactoryState { - blocks, - transactions, - block_number: 0, - index: 0, - } - } - - fn block_number(&self) -> u32 { - self.block_number - } - - fn blocks(&self) -> u32 { - self.blocks - } - - fn transactions(&self) -> u32 { - self.transactions - } - - fn set_block_number(&mut self, value: u32) { - self.block_number = value; - } - - fn transfer_extrinsic( - &mut self, - sender: &Self::AccountId, - key: &Self::Secret, - destination: &Self::AccountId, - amount: &Self::Balance, - version: u32, - genesis_hash: &<Self::Block as BlockT>::Hash, - prior_block_hash: &<Self::Block as BlockT>::Hash, - ) -> <Self::Block as BlockT>::Extrinsic { - let phase = self.block_number() as Self::Phase; - let extra = Self::build_extra(self.index, phase); - self.index += 1; - - sign::<Self>(CheckedExtrinsic { - signed: Some((sender.clone(), extra)), - function: Call::Balances( - BalancesCall::transfer( - pallet_indices::address::Address::Id(destination.clone().into()), - (*amount).into() - ) - ) - }, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), ())) - } - - fn inherent_extrinsics(&self) -> InherentData { - let timestamp = (self.block_number as u64 + 1) * MinimumPeriod::get(); - - let mut inherent = InherentData::new(); - inherent.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) - .expect("Failed putting timestamp inherent"); - inherent.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &self.block_number) - .expect("Failed putting finalized number inherent"); - inherent - } - - fn minimum_balance() -> Self::Balance { - ExistentialDeposit::get() - } - - fn master_account_id() -> Self::AccountId { - Keyring::Alice.to_account_id() - } - - fn master_account_secret() -> Self::Secret { - Keyring::Alice.pair() - } - - /// Generates a random `AccountId` from `seed`. - fn gen_random_account_id(seed: u32) -> Self::AccountId { - let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(seed)); - AccountPublic::from(pair.public()).into_account() - } - - /// Generates a random `Secret` from `seed`. - fn gen_random_account_secret(seed: u32) -> Self::Secret { - let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(seed)); - pair - } -} - -fn gen_seed_bytes(seed: u32) -> [u8; 32] { - let mut rng: StdRng = SeedableRng::seed_from_u64(seed as u64); - - let mut seed_bytes = [0u8; 32]; - for i in 0..32 { - seed_bytes[i] = rng.gen::<u8>(); - } - seed_bytes -} - -/// Creates an `UncheckedExtrinsic` containing the appropriate signature for -/// a `CheckedExtrinsics`. -fn sign<RA: RuntimeAdapter>( - xt: CheckedExtrinsic, - key: &sr25519::Pair, - additional_signed: <SignedExtra as SignedExtension>::AdditionalSigned, -) -> <RA::Block as BlockT>::Extrinsic { - let s = match xt.signed { - Some((signed, extra)) => { - let payload = (xt.function, extra.clone(), additional_signed); - let signature = payload.using_encoded(|b| { - if b.len() > 256 { - key.sign(&sp_io::hashing::blake2_256(b)) - } else { - key.sign(b) - } - }).into(); - UncheckedExtrinsic { - signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), - function: payload.0, - } - } - None => UncheckedExtrinsic { - signature: None, - function: xt.function, - }, - }; - - let e = Encode::encode(&s); - Decode::decode(&mut &e[..]).expect("Failed to decode signed unchecked extrinsic") -} diff --git a/substrate/bin/node/cli/src/lib.rs b/substrate/bin/node/cli/src/lib.rs index 1e2c790bfa7d21a8857ba1bf2f90a3a419701585..3c49f9176f15b96df4bd4ae87ea407b713f340e1 100644 --- a/substrate/bin/node/cli/src/lib.rs +++ b/substrate/bin/node/cli/src/lib.rs @@ -37,8 +37,6 @@ mod browser; #[cfg(feature = "cli")] mod cli; #[cfg(feature = "cli")] -mod factory_impl; -#[cfg(feature = "cli")] mod command; #[cfg(feature = "browser")] diff --git a/substrate/bin/node/cli/tests/factory.rs b/substrate/bin/node/cli/tests/factory.rs deleted file mode 100644 index 2930cd52e2e16e497d197849a9833d492c3868d7..0000000000000000000000000000000000000000 --- a/substrate/bin/node/cli/tests/factory.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>. - -#![cfg(unix)] - -use assert_cmd::cargo::cargo_bin; -use std::process::{Command, Stdio}; -use tempfile::tempdir; - -mod common; - -#[test] -fn factory_works() { - let base_path = tempdir().expect("could not create a temp dir"); - - let status = Command::new(cargo_bin("substrate")) - .stdout(Stdio::null()) - .args(&["factory", "--dev", "-d"]) - .arg(base_path.path()) - .status() - .unwrap(); - assert!(status.success()); - - // Make sure that the `dev` chain folder exists & `db` - assert!(base_path.path().join("chains/dev/").exists()); - assert!(base_path.path().join("chains/dev/db").exists()); -} diff --git a/substrate/bin/node/transaction-factory/Cargo.toml b/substrate/bin/node/transaction-factory/Cargo.toml deleted file mode 100644 index 5aa803a7e18ee4d7702b6d9939ac8df2df6acb74..0000000000000000000000000000000000000000 --- a/substrate/bin/node/transaction-factory/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "node-transaction-factory" -version = "0.8.0-dev" -authors = ["Parity Technologies <admin@parity.io>"] -edition = "2018" -license = "GPL-3.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } -sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } -sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -log = "0.4.8" -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } diff --git a/substrate/bin/node/transaction-factory/src/lib.rs b/substrate/bin/node/transaction-factory/src/lib.rs deleted file mode 100644 index 44cb178be15ae3d8d73a49db5ef8c2717c8c1855..0000000000000000000000000000000000000000 --- a/substrate/bin/node/transaction-factory/src/lib.rs +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>. - -//! Simple transaction factory which distributes tokens from a master -//! account to a specified number of newly created accounts. -//! -//! The factory currently only works on an empty database! - -use std::collections::HashMap; -use std::sync::Arc; -use std::cmp::PartialOrd; -use std::fmt::Display; - -use log::info; - -use sp_block_builder::BlockBuilder; -use sc_block_builder::BlockBuilderProvider; -use sp_api::{ProvideRuntimeApi, ApiExt, CallApiAt, TransactionFor}; -use sp_consensus::{ - BlockOrigin, BlockImportParams, InherentData, - ForkChoiceStrategy, SelectChain -}; -use sp_consensus::block_import::BlockImport; -use codec::{Decode, Encode}; -use sp_runtime::generic::BlockId; -use sp_runtime::traits::{ - Block as BlockT, Header as HeaderT, AtLeast32Bit, One, Zero, -}; -use sp_blockchain::HeaderBackend; - -pub trait RuntimeAdapter { - type AccountId: Display; - type Balance: Display + AtLeast32Bit + From<Self::Number>; - type Block: BlockT; - type Index: Copy; - type Number: Display + PartialOrd + AtLeast32Bit + Zero + One; - type Phase: Copy; - type Secret; - - fn new(blocks: u32, transactions: u32) -> Self; - - fn blocks(&self) -> u32; - fn transactions(&self) -> u32; - - fn block_number(&self) -> u32; - fn set_block_number(&mut self, value: u32); - - fn transfer_extrinsic( - &mut self, - sender: &Self::AccountId, - key: &Self::Secret, - destination: &Self::AccountId, - amount: &Self::Balance, - version: u32, - genesis_hash: &<Self::Block as BlockT>::Hash, - prior_block_hash: &<Self::Block as BlockT>::Hash, - ) -> <Self::Block as BlockT>::Extrinsic; - - fn inherent_extrinsics(&self) -> InherentData; - - fn minimum_balance() -> Self::Balance; - fn master_account_id() -> Self::AccountId; - fn master_account_secret() -> Self::Secret; - - fn gen_random_account_id(seed: u32) -> Self::AccountId; - fn gen_random_account_secret(seed: u32) -> Self::Secret; -} - -/// Manufactures transactions. The exact amount depends on `num` and `rounds`. -pub fn factory<Backend, Block, Client, Sc, RA>( - mut factory_state: RA, - client: &Arc<Client>, - select_chain: &Sc, -) -> sc_cli::Result<()> - where - Backend: sc_client_api::backend::Backend<Block> + Send, - Block: BlockT, - Client: BlockBuilderProvider<Backend, Block, Client> + CallApiAt<Block, Error = sp_blockchain::Error> - + ProvideRuntimeApi<Block> + HeaderBackend<Block>, - Client::Api: BlockBuilder<Block, Error = sp_blockchain::Error> + ApiExt<Block, StateBackend = Backend::State>, - Sc: SelectChain<Block>, - RA: RuntimeAdapter<Block = Block>, - Block::Hash: From<sp_core::H256>, - for<'a> &'a Client: BlockImport<Block, Transaction = TransactionFor<Client, Block>>, -{ - let best_header: Result<<Block as BlockT>::Header, sc_cli::Error> = - select_chain.best_chain().map_err(|e| format!("{:?}", e).into()); - let mut best_hash = best_header?.hash(); - let mut best_block_id = BlockId::<Block>::hash(best_hash); - let version = client.runtime_version_at(&best_block_id)?.spec_version; - let genesis_hash = client.hash(Zero::zero())? - .expect("Genesis block always exists; qed").into(); - - while factory_state.block_number() < factory_state.blocks() { - let from = (RA::master_account_id(), RA::master_account_secret()); - let amount = RA::minimum_balance(); - - let inherents = RA::inherent_extrinsics(&factory_state); - let inherents = client.runtime_api().inherent_extrinsics(&best_block_id, inherents) - .expect("Failed to create inherent extrinsics"); - - let tx_per_block = factory_state.transactions(); - - let mut block = client.new_block(Default::default()).expect("Failed to create new block"); - - for tx_num in 0..tx_per_block { - let seed = tx_num * (factory_state.block_number() + 1); - let to = RA::gen_random_account_id(seed); - - let transfer = factory_state.transfer_extrinsic( - &from.0, - &from.1, - &to, - &amount, - version, - &genesis_hash, - &best_hash, - ); - - info!("Pushing transfer {}/{} to {} into block.", tx_num + 1, tx_per_block, to); - - block.push( - Decode::decode(&mut &transfer.encode()[..]) - .expect("Failed to decode transfer extrinsic") - ).expect("Failed to push transfer extrinsic into block"); - } - - for inherent in inherents { - block.push(inherent).expect("Failed ..."); - } - - let block = block.build().expect("Failed to bake block").block; - - factory_state.set_block_number(factory_state.block_number() + 1); - - info!( - "Created block {} with hash {}.", - factory_state.block_number(), - best_hash, - ); - - best_hash = block.header().hash(); - best_block_id = BlockId::<Block>::hash(best_hash); - - let mut import = BlockImportParams::new(BlockOrigin::File, block.header().clone()); - import.body = Some(block.extrinsics().to_vec()); - import.fork_choice = Some(ForkChoiceStrategy::LongestChain); - (&**client).import_block(import, HashMap::new()).expect("Failed to import block"); - - info!("Imported block at {}", factory_state.block_number()); - } - - Ok(()) -}