referrerpolicy=no-referrer-when-downgrade

node_bench/
txpool.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Transaction pool integrated benchmarks.
20//!
21//! The goal of this benchmark is to figure out time needed to fill
22//! the transaction pool for the next block.
23
24use std::borrow::Cow;
25
26use node_testing::bench::{BenchDb, BlockType, DatabaseType, KeyTypes};
27
28use sc_transaction_pool::BasicPool;
29use sc_transaction_pool_api::{TransactionPool, TransactionSource};
30
31use crate::core::{self, Mode, Path};
32
33pub struct PoolBenchmarkDescription {
34	pub database_type: DatabaseType,
35}
36
37pub struct PoolBenchmark {
38	database: BenchDb,
39}
40
41impl core::BenchmarkDescription for PoolBenchmarkDescription {
42	fn path(&self) -> Path {
43		Path::new(&["node", "txpool"])
44	}
45
46	fn setup(self: Box<Self>) -> Box<dyn core::Benchmark> {
47		Box::new(PoolBenchmark {
48			database: BenchDb::with_key_types(self.database_type, 50_000, KeyTypes::Sr25519),
49		})
50	}
51
52	fn name(&self) -> Cow<'static, str> {
53		"Transaction pool benchmark".into()
54	}
55}
56
57impl core::Benchmark for PoolBenchmark {
58	fn run(&mut self, mode: Mode) -> std::time::Duration {
59		let context = self.database.create_context();
60		let genesis_hash = context.client.chain_info().genesis_hash;
61
62		let _ = context
63			.client
64			.runtime_version_at(genesis_hash)
65			.expect("Failed to get runtime version")
66			.spec_version;
67
68		if mode == Mode::Profile {
69			std::thread::park_timeout(std::time::Duration::from_secs(3));
70		}
71
72		let executor = sp_core::testing::TaskExecutor::new();
73		let txpool = BasicPool::new_full(
74			Default::default(),
75			true.into(),
76			None,
77			executor,
78			context.client.clone(),
79		);
80
81		let generated_transactions = self
82			.database
83			.block_content(
84				BlockType::RandomTransfersKeepAlive.to_content(Some(100)),
85				&context.client,
86			)
87			.into_iter()
88			.collect::<Vec<_>>();
89
90		let start = std::time::Instant::now();
91		let submissions = generated_transactions
92			.into_iter()
93			.map(|tx| txpool.submit_one(genesis_hash, TransactionSource::External, tx));
94		futures::executor::block_on(futures::future::join_all(submissions));
95		let elapsed = start.elapsed();
96
97		if mode == Mode::Profile {
98			std::thread::park_timeout(std::time::Duration::from_secs(1));
99		}
100		elapsed
101	}
102}