referrerpolicy=no-referrer-when-downgrade

sc_transaction_pool/
transaction_pool_wrapper.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 wrapper. Provides a type for wrapping object providing actual implementation of
20//! transaction pool.
21
22use crate::{
23	builder::FullClientTransactionPool,
24	graph::{base_pool::Transaction, ExtrinsicFor, ExtrinsicHash},
25	ChainApi, FullChainApi, ReadyIteratorFor,
26};
27use async_trait::async_trait;
28use sc_transaction_pool_api::{
29	ChainEvent, ImportNotificationStream, LocalTransactionFor, LocalTransactionPool,
30	MaintainedTransactionPool, PoolStatus, ReadyTransactions, TransactionFor, TransactionPool,
31	TransactionSource, TransactionStatusStreamFor, TxHash, TxInvalidityReportMap,
32};
33use sp_runtime::traits::Block as BlockT;
34use std::{collections::HashMap, pin::Pin, sync::Arc};
35
36/// The wrapper for actual object providing implementation of TransactionPool.
37///
38/// This wraps actual implementation of the TransactionPool, e.g. fork-aware or single-state.
39pub struct TransactionPoolWrapper<Block, Client>(
40	pub Box<dyn FullClientTransactionPool<Block, Client>>,
41)
42where
43	Block: BlockT,
44	Client: sp_api::ProvideRuntimeApi<Block>
45		+ sc_client_api::BlockBackend<Block>
46		+ sc_client_api::blockchain::HeaderBackend<Block>
47		+ sp_runtime::traits::BlockIdTo<Block>
48		+ sp_blockchain::HeaderMetadata<Block, Error = sp_blockchain::Error>
49		+ 'static,
50	Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>;
51
52#[async_trait]
53impl<Block, Client> TransactionPool for TransactionPoolWrapper<Block, Client>
54where
55	Block: BlockT,
56	Client: sp_api::ProvideRuntimeApi<Block>
57		+ sc_client_api::BlockBackend<Block>
58		+ sc_client_api::blockchain::HeaderBackend<Block>
59		+ sp_runtime::traits::BlockIdTo<Block>
60		+ sp_blockchain::HeaderMetadata<Block, Error = sp_blockchain::Error>
61		+ 'static,
62	Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,
63{
64	type Block = Block;
65	type Hash = ExtrinsicHash<FullChainApi<Client, Block>>;
66	type InPoolTransaction = Transaction<
67		ExtrinsicHash<FullChainApi<Client, Block>>,
68		ExtrinsicFor<FullChainApi<Client, Block>>,
69	>;
70	type Error = <FullChainApi<Client, Block> as ChainApi>::Error;
71
72	async fn submit_at(
73		&self,
74		at: <Self::Block as BlockT>::Hash,
75		source: TransactionSource,
76		xts: Vec<TransactionFor<Self>>,
77	) -> Result<Vec<Result<TxHash<Self>, Self::Error>>, Self::Error> {
78		self.0.submit_at(at, source, xts).await
79	}
80
81	async fn submit_one(
82		&self,
83		at: <Self::Block as BlockT>::Hash,
84		source: TransactionSource,
85		xt: TransactionFor<Self>,
86	) -> Result<TxHash<Self>, Self::Error> {
87		self.0.submit_one(at, source, xt).await
88	}
89
90	async fn submit_and_watch(
91		&self,
92		at: <Self::Block as BlockT>::Hash,
93		source: TransactionSource,
94		xt: TransactionFor<Self>,
95	) -> Result<Pin<Box<TransactionStatusStreamFor<Self>>>, Self::Error> {
96		self.0.submit_and_watch(at, source, xt).await
97	}
98
99	async fn ready_at(
100		&self,
101		at: <Self::Block as BlockT>::Hash,
102	) -> ReadyIteratorFor<FullChainApi<Client, Block>> {
103		self.0.ready_at(at).await
104	}
105
106	fn ready(&self) -> Box<dyn ReadyTransactions<Item = Arc<Self::InPoolTransaction>> + Send> {
107		self.0.ready()
108	}
109
110	async fn report_invalid(
111		&self,
112		at: Option<<Self::Block as BlockT>::Hash>,
113		invalid_tx_errors: TxInvalidityReportMap<TxHash<Self>>,
114	) -> Vec<Arc<Self::InPoolTransaction>> {
115		self.0.report_invalid(at, invalid_tx_errors).await
116	}
117
118	fn futures(&self) -> Vec<Self::InPoolTransaction> {
119		self.0.futures()
120	}
121
122	fn status(&self) -> PoolStatus {
123		self.0.status()
124	}
125
126	fn import_notification_stream(&self) -> ImportNotificationStream<TxHash<Self>> {
127		self.0.import_notification_stream()
128	}
129
130	fn on_broadcasted(&self, propagations: HashMap<TxHash<Self>, Vec<String>>) {
131		self.0.on_broadcasted(propagations)
132	}
133
134	fn hash_of(&self, xt: &TransactionFor<Self>) -> TxHash<Self> {
135		self.0.hash_of(xt)
136	}
137
138	fn ready_transaction(&self, hash: &TxHash<Self>) -> Option<Arc<Self::InPoolTransaction>> {
139		self.0.ready_transaction(hash)
140	}
141
142	async fn ready_at_with_timeout(
143		&self,
144		at: <Self::Block as BlockT>::Hash,
145		timeout: std::time::Duration,
146	) -> ReadyIteratorFor<FullChainApi<Client, Block>> {
147		self.0.ready_at_with_timeout(at, timeout).await
148	}
149}
150
151#[async_trait]
152impl<Block, Client> MaintainedTransactionPool for TransactionPoolWrapper<Block, Client>
153where
154	Block: BlockT,
155	Client: sp_api::ProvideRuntimeApi<Block>
156		+ sc_client_api::BlockBackend<Block>
157		+ sc_client_api::blockchain::HeaderBackend<Block>
158		+ sp_runtime::traits::BlockIdTo<Block>
159		+ sp_blockchain::HeaderMetadata<Block, Error = sp_blockchain::Error>
160		+ 'static,
161	Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,
162{
163	async fn maintain(&self, event: ChainEvent<Self::Block>) {
164		self.0.maintain(event).await;
165	}
166}
167
168impl<Block, Client> LocalTransactionPool for TransactionPoolWrapper<Block, Client>
169where
170	Block: BlockT,
171	Client: sp_api::ProvideRuntimeApi<Block>
172		+ sc_client_api::BlockBackend<Block>
173		+ sc_client_api::blockchain::HeaderBackend<Block>
174		+ sp_runtime::traits::BlockIdTo<Block>
175		+ sp_blockchain::HeaderMetadata<Block, Error = sp_blockchain::Error>
176		+ 'static,
177	Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,
178{
179	type Block = Block;
180	type Hash = ExtrinsicHash<FullChainApi<Client, Block>>;
181	type Error = <FullChainApi<Client, Block> as ChainApi>::Error;
182
183	fn submit_local(
184		&self,
185		at: <Self::Block as BlockT>::Hash,
186		xt: LocalTransactionFor<Self>,
187	) -> Result<Self::Hash, Self::Error> {
188		self.0.submit_local(at, xt)
189	}
190}