diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 8796d04128..565a846bce 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -3444,6 +3444,7 @@ dependencies = [ "sc-basic-authorship", "sc-cli", "sc-client-api", + "sc-transaction-pool", "serde", "serde_json", "sp-consensus", diff --git a/substrate/bin/node/bench/Cargo.toml b/substrate/bin/node/bench/Cargo.toml index 0778909fa9..9b379209af 100644 --- a/substrate/bin/node/bench/Cargo.toml +++ b/substrate/bin/node/bench/Cargo.toml @@ -39,4 +39,5 @@ rand = { version = "0.7.2", features = ["small_rng"] } lazy_static = "1.4.0" parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } parity-db = { version = "0.1.2" } -futures = "0.3.1" +sc-transaction-pool = { version = "2.0.0-rc4", path = "../../../client/transaction-pool" } +futures = { version = "0.3.4", features = ["thread-pool"] } diff --git a/substrate/bin/node/bench/src/main.rs b/substrate/bin/node/bench/src/main.rs index 1182024711..96ef1d920c 100644 --- a/substrate/bin/node/bench/src/main.rs +++ b/substrate/bin/node/bench/src/main.rs @@ -25,6 +25,7 @@ mod simple_trie; mod state_sizes; mod tempdb; mod trie; +mod txpool; use structopt::StructOpt; @@ -37,6 +38,7 @@ use crate::{ import::ImportBenchmarkDescription, trie::{TrieReadBenchmarkDescription, TrieWriteBenchmarkDescription, DatabaseSize}, construct::ConstructionBenchmarkDescription, + txpool::PoolBenchmarkDescription, }; #[derive(Debug, StructOpt)] @@ -148,6 +150,7 @@ fn main() { size: SizeType::Large, database_type: BenchDataBaseType::RocksDb, }, + PoolBenchmarkDescription { database_type: BenchDataBaseType::RocksDb }, ); if opt.list { diff --git a/substrate/bin/node/bench/src/txpool.rs b/substrate/bin/node/bench/src/txpool.rs new file mode 100644 index 0000000000..8ac0633ae6 --- /dev/null +++ b/substrate/bin/node/bench/src/txpool.rs @@ -0,0 +1,106 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! Transaction pool integrated benchmarks. +//! +//! The goal of this benchmark is to figure out time needed to fill +//! the transaction pool for the next block. + +use std::{borrow::Cow, sync::Arc}; + +use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes, DatabaseType}; + +use sc_transaction_pool::{BasicPool, FullChainApi}; +use sp_runtime::generic::BlockId; +use sp_transaction_pool::{TransactionPool, TransactionSource}; + +use crate::core::{self, Path, Mode}; + +pub struct PoolBenchmarkDescription { + pub database_type: DatabaseType, +} + +pub struct PoolBenchmark { + database: BenchDb, +} + +impl core::BenchmarkDescription for PoolBenchmarkDescription { + fn path(&self) -> Path { + Path::new(&["node", "txpool"]) + } + + fn setup(self: Box) -> Box { + Box::new(PoolBenchmark { + database: BenchDb::with_key_types( + self.database_type, + 50_000, + KeyTypes::Sr25519, + ), + }) + } + + fn name(&self) -> Cow<'static, str> { + "Transaction pool benchmark".into() + } +} + +impl core::Benchmark for PoolBenchmark { + fn run(&mut self, mode: Mode) -> std::time::Duration { + let context = self.database.create_context(Profile::Wasm); + + let _ = context.client.runtime_version_at(&BlockId::Number(0)) + .expect("Failed to get runtime version") + .spec_version; + + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(3)); + } + + let executor = sp_core::testing::SpawnBlockingExecutor::new(); + let txpool = BasicPool::new_full( + Default::default(), + Arc::new(FullChainApi::new(context.client.clone(), None)), + None, + executor, + context.client.clone(), + ); + + let generated_transactions = self.database.block_content( + BlockType::RandomTransfersKeepAlive.to_content(Some(100)), + &context.client, + ).into_iter().collect::>(); + + let start = std::time::Instant::now(); + let submissions = generated_transactions.into_iter().map(|tx| { + txpool.submit_one( + &BlockId::Number(0), + TransactionSource::External, + tx, + ) + }); + futures::executor::block_on( + futures::future::join_all(submissions) + ); + let elapsed = start.elapsed(); + + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(1)); + } + elapsed + } +} diff --git a/substrate/bin/node/testing/src/bench.rs b/substrate/bin/node/testing/src/bench.rs index 507d3420d8..6f351a7001 100644 --- a/substrate/bin/node/testing/src/bench.rs +++ b/substrate/bin/node/testing/src/bench.rs @@ -456,7 +456,9 @@ impl BenchDb { ); BenchContext { - client: Arc::new(client), backend, db_guard: directory_guard, + client: Arc::new(client), + db_guard: directory_guard, + backend, } } }