Skip to content

Commit caf9993

Browse files
fatxpool: ChainApi is now async (#8875)
[`ChainApi`](https://github.com/paritytech/polkadot-sdk/blob/488072d245763fb059743bf32eea2f48d84054b3/substrate/client/transaction-pool/src/graph/pool.rs#L65-L66) is now `async_trait`, [`validate_transaction`](https://github.com/paritytech/polkadot-sdk/blob/488072d245763fb059743bf32eea2f48d84054b3/substrate/client/transaction-pool/src/graph/pool.rs#L78) and [`block_body`](https://github.com/paritytech/polkadot-sdk/blob/488072d245763fb059743bf32eea2f48d84054b3/substrate/client/transaction-pool/src/graph/pool.rs#L112) are now `async` methods. This is just cleanup - migrating from returning `Future` to `async` method --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 4a869b9 commit caf9993

File tree

8 files changed

+94
-89
lines changed

8 files changed

+94
-89
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

prdoc/pr_8875.prdoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
title: '`fatxpool`: `ChainApi` is now async'
2+
doc:
3+
- audience: Node Dev
4+
description: Internal `ChainApi` is now `async_trait`, `validate_transaction` and `block_body` are now `async` methods. This is just cleanup - migrating from returning `Future` to `async` method'.
5+
crates:
6+
- name: sc-transaction-pool
7+
bump: major

substrate/client/transaction-pool/benches/basics.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,10 @@
1616
// You should have received a copy of the GNU General Public License
1717
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818

19-
use criterion::{criterion_group, criterion_main, Criterion};
20-
19+
use async_trait::async_trait;
2120
use codec::Encode;
22-
use futures::{
23-
executor::block_on,
24-
future::{ready, Ready},
25-
};
21+
use criterion::{criterion_group, criterion_main, Criterion};
22+
use futures::executor::block_on;
2623
use sc_transaction_pool::*;
2724
use sp_blockchain::HashAndNumber;
2825
use sp_crypto_hashing::blake2_256;
@@ -55,31 +52,30 @@ fn to_tag(nonce: u64, from: AccountId) -> Tag {
5552
data.to_vec()
5653
}
5754

55+
#[async_trait]
5856
impl ChainApi for TestApi {
5957
type Block = Block;
6058
type Error = sc_transaction_pool_api::error::Error;
61-
type ValidationFuture = Ready<sc_transaction_pool_api::error::Result<TransactionValidity>>;
62-
type BodyFuture = Ready<sc_transaction_pool_api::error::Result<Option<Vec<Extrinsic>>>>;
6359

64-
fn validate_transaction(
60+
async fn validate_transaction(
6561
&self,
6662
at: <Self::Block as BlockT>::Hash,
6763
_: TransactionSource,
6864
uxt: Arc<<Self::Block as BlockT>::Extrinsic>,
6965
_: ValidateTransactionPriority,
70-
) -> Self::ValidationFuture {
66+
) -> Result<TransactionValidity, Self::Error> {
7167
let uxt = (*uxt).clone();
7268
let transfer = TransferData::try_from(&uxt)
7369
.expect("uxt is expected to be bench_call (carrying TransferData)");
7470
let nonce = transfer.nonce;
7571
let from = transfer.from;
7672

7773
match self.block_id_to_number(&BlockId::Hash(at)) {
78-
Ok(Some(num)) if num > 5 => return ready(Ok(Err(InvalidTransaction::Stale.into()))),
74+
Ok(Some(num)) if num > 5 => return Ok(Err(InvalidTransaction::Stale.into())),
7975
_ => {},
8076
}
8177

82-
ready(Ok(Ok(ValidTransaction {
78+
Ok(Ok(ValidTransaction {
8379
priority: 4,
8480
requires: if nonce > 1 && self.nonce_dependant {
8581
vec![to_tag(nonce - 1, from)]
@@ -89,15 +85,15 @@ impl ChainApi for TestApi {
8985
provides: vec![to_tag(nonce, from)],
9086
longevity: 10,
9187
propagate: true,
92-
})))
88+
}))
9389
}
9490

9591
fn validate_transaction_blocking(
9692
&self,
9793
_at: <Self::Block as BlockT>::Hash,
9894
_source: TransactionSource,
9995
_uxt: Arc<<Self::Block as BlockT>::Extrinsic>,
100-
) -> sc_transaction_pool_api::error::Result<TransactionValidity> {
96+
) -> Result<TransactionValidity, Self::Error> {
10197
unimplemented!();
10298
}
10399

@@ -128,8 +124,11 @@ impl ChainApi for TestApi {
128124
(blake2_256(&encoded).into(), encoded.len())
129125
}
130126

131-
fn block_body(&self, _id: <Self::Block as BlockT>::Hash) -> Self::BodyFuture {
132-
ready(Ok(None))
127+
async fn block_body(
128+
&self,
129+
_id: <Self::Block as BlockT>::Hash,
130+
) -> Result<Option<Vec<<Self::Block as BlockT>::Extrinsic>>, Self::Error> {
131+
Ok(None)
133132
}
134133

135134
fn block_header(

substrate/client/transaction-pool/src/common/api.rs

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ use crate::{
2323
graph::ValidateTransactionPriority,
2424
insert_and_log_throttled, LOG_TARGET, LOG_TARGET_STAT,
2525
};
26+
use async_trait::async_trait;
2627
use codec::Encode;
27-
use futures::future::{ready, Future, FutureExt, Ready};
28+
use futures::future::{Future, FutureExt};
2829
use prometheus_endpoint::Registry as PrometheusRegistry;
2930
use sc_client_api::{blockchain::HeaderBackend, BlockBackend};
3031
use sp_api::{ApiExt, ProvideRuntimeApi};
@@ -181,6 +182,7 @@ impl<Client, Block> FullChainApi<Client, Block> {
181182
}
182183
}
183184

185+
#[async_trait]
184186
impl<Client, Block> graph::ChainApi for FullChainApi<Client, Block>
185187
where
186188
Block: BlockT,
@@ -194,21 +196,21 @@ where
194196
{
195197
type Block = Block;
196198
type Error = error::Error;
197-
type ValidationFuture =
198-
Pin<Box<dyn Future<Output = error::Result<TransactionValidity>> + Send>>;
199-
type BodyFuture = Ready<error::Result<Option<Vec<<Self::Block as BlockT>::Extrinsic>>>>;
200199

201-
fn block_body(&self, hash: Block::Hash) -> Self::BodyFuture {
202-
ready(self.client.block_body(hash).map_err(error::Error::from))
200+
async fn block_body(
201+
&self,
202+
hash: Block::Hash,
203+
) -> Result<Option<Vec<<Self::Block as BlockT>::Extrinsic>>, Self::Error> {
204+
self.client.block_body(hash).map_err(error::Error::from)
203205
}
204206

205-
fn validate_transaction(
207+
async fn validate_transaction(
206208
&self,
207209
at: <Self::Block as BlockT>::Hash,
208210
source: TransactionSource,
209211
uxt: graph::ExtrinsicFor<Self>,
210212
validation_priority: ValidateTransactionPriority,
211-
) -> Self::ValidationFuture {
213+
) -> Result<TransactionValidity, Self::Error> {
212214
let start = Instant::now();
213215
let (tx, rx) = oneshot::channel();
214216
let client = self.client.clone();
@@ -228,39 +230,36 @@ where
228230
};
229231
let metrics = self.metrics.clone();
230232

231-
async move {
232-
metrics.report(|m| m.validations_scheduled.inc());
233-
234-
{
235-
validation_pool
236-
.send(
237-
async move {
238-
let res = validate_transaction_blocking(&*client, at, source, uxt);
239-
let _ = tx.send(res);
240-
metrics.report(|m| m.validations_finished.inc());
241-
}
242-
.boxed(),
243-
)
244-
.await
245-
.map_err(|e| Error::RuntimeApi(format!("Validation pool down: {:?}", e)))?;
246-
}
233+
metrics.report(|m| m.validations_scheduled.inc());
247234

248-
let validity = match rx.await {
249-
Ok(r) => r,
250-
Err(_) => Err(Error::RuntimeApi("Validation was canceled".into())),
251-
};
235+
{
236+
validation_pool
237+
.send(
238+
async move {
239+
let res = validate_transaction_blocking(&*client, at, source, uxt);
240+
let _ = tx.send(res);
241+
metrics.report(|m| m.validations_finished.inc());
242+
}
243+
.boxed(),
244+
)
245+
.await
246+
.map_err(|e| Error::RuntimeApi(format!("Validation pool down: {:?}", e)))?;
247+
}
252248

253-
insert_and_log_throttled!(
254-
Level::DEBUG,
255-
target:LOG_TARGET_STAT,
256-
prefix:prefix,
257-
stats,
258-
start.elapsed().into()
259-
);
249+
let validity = match rx.await {
250+
Ok(r) => r,
251+
Err(_) => Err(Error::RuntimeApi("Validation was canceled".into())),
252+
};
253+
254+
insert_and_log_throttled!(
255+
Level::DEBUG,
256+
target:LOG_TARGET_STAT,
257+
prefix:prefix,
258+
stats,
259+
start.elapsed().into()
260+
);
260261

261-
validity
262-
}
263-
.boxed()
262+
validity
264263
}
265264

266265
/// Validates a transaction by calling into the runtime.
@@ -271,21 +270,21 @@ where
271270
at: Block::Hash,
272271
source: TransactionSource,
273272
uxt: graph::ExtrinsicFor<Self>,
274-
) -> error::Result<TransactionValidity> {
273+
) -> Result<TransactionValidity, Self::Error> {
275274
validate_transaction_blocking(&*self.client, at, source, uxt)
276275
}
277276

278277
fn block_id_to_number(
279278
&self,
280279
at: &BlockId<Self::Block>,
281-
) -> error::Result<Option<graph::NumberFor<Self>>> {
280+
) -> Result<Option<graph::NumberFor<Self>>, Self::Error> {
282281
self.client.to_number(at).map_err(|e| Error::BlockIdConversion(e.to_string()))
283282
}
284283

285284
fn block_id_to_hash(
286285
&self,
287286
at: &BlockId<Self::Block>,
288-
) -> error::Result<Option<graph::BlockHash<Self>>> {
287+
) -> Result<Option<graph::BlockHash<Self>>, Self::Error> {
289288
self.client.to_hash(at).map_err(|e| Error::BlockIdConversion(e.to_string()))
290289
}
291290

substrate/client/transaction-pool/src/common/tests.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::{
2222
graph::{BlockHash, ChainApi, ExtrinsicFor, NumberFor, RawExtrinsicFor},
2323
ValidateTransactionPriority,
2424
};
25+
use async_trait::async_trait;
2526
use codec::Encode;
2627
use parking_lot::Mutex;
2728
use sc_transaction_pool_api::error;
@@ -69,20 +70,19 @@ impl TestApi {
6970
}
7071
}
7172

73+
#[async_trait]
7274
impl ChainApi for TestApi {
7375
type Block = Block;
7476
type Error = error::Error;
75-
type ValidationFuture = futures::future::Ready<error::Result<TransactionValidity>>;
76-
type BodyFuture = futures::future::Ready<error::Result<Option<Vec<Extrinsic>>>>;
7777

7878
/// Verify extrinsic at given block.
79-
fn validate_transaction(
79+
async fn validate_transaction(
8080
&self,
8181
at: <Self::Block as BlockT>::Hash,
8282
_source: TransactionSource,
8383
uxt: ExtrinsicFor<Self>,
8484
_: ValidateTransactionPriority,
85-
) -> Self::ValidationFuture {
85+
) -> Result<TransactionValidity, Self::Error> {
8686
let uxt = (*uxt).clone();
8787
self.validation_requests.lock().push(uxt.clone());
8888
let hash = self.hash_and_length(&uxt).0;
@@ -159,15 +159,15 @@ impl ChainApi for TestApi {
159159
_ => unimplemented!(),
160160
};
161161

162-
futures::future::ready(Ok(res))
162+
Ok(res)
163163
}
164164

165165
fn validate_transaction_blocking(
166166
&self,
167167
_at: <Self::Block as BlockT>::Hash,
168168
_source: TransactionSource,
169169
_uxt: Arc<<Self::Block as BlockT>::Extrinsic>,
170-
) -> error::Result<TransactionValidity> {
170+
) -> Result<TransactionValidity, Self::Error> {
171171
unimplemented!();
172172
}
173173

@@ -202,8 +202,11 @@ impl ChainApi for TestApi {
202202
(Hashing::hash(&encoded), len)
203203
}
204204

205-
fn block_body(&self, _id: <Self::Block as BlockT>::Hash) -> Self::BodyFuture {
206-
futures::future::ready(Ok(None))
205+
async fn block_body(
206+
&self,
207+
_id: <Self::Block as BlockT>::Hash,
208+
) -> Result<Option<Vec<<Self::Block as BlockT>::Extrinsic>>, Self::Error> {
209+
Ok(None)
207210
}
208211

209212
fn block_header(

substrate/client/transaction-pool/src/graph/pool.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818

1919
use crate::{common::tracing_log_xt::log_xt_trace, LOG_TARGET};
20-
use futures::{channel::mpsc::Receiver, Future};
20+
use async_trait::async_trait;
21+
use futures::channel::mpsc::Receiver;
2122
use indexmap::IndexMap;
2223
use sc_transaction_pool_api::error;
2324
use sp_blockchain::{HashAndNumber, TreeRoute};
@@ -74,27 +75,21 @@ pub enum ValidateTransactionPriority {
7475
}
7576

7677
/// Concrete extrinsic validation and query logic.
78+
#[async_trait]
7779
pub trait ChainApi: Send + Sync {
7880
/// Block type.
7981
type Block: BlockT;
8082
/// Error type.
8183
type Error: From<error::Error> + error::IntoPoolError;
82-
/// Validate transaction future.
83-
type ValidationFuture: Future<Output = Result<TransactionValidity, Self::Error>> + Send + Unpin;
84-
/// Body future (since block body might be remote)
85-
type BodyFuture: Future<Output = Result<Option<Vec<<Self::Block as traits::Block>::Extrinsic>>, Self::Error>>
86-
+ Unpin
87-
+ Send
88-
+ 'static;
8984

9085
/// Asynchronously verify extrinsic at given block.
91-
fn validate_transaction(
86+
async fn validate_transaction(
9287
&self,
9388
at: <Self::Block as BlockT>::Hash,
9489
source: TransactionSource,
9590
uxt: ExtrinsicFor<Self>,
9691
validation_priority: ValidateTransactionPriority,
97-
) -> Self::ValidationFuture;
92+
) -> Result<TransactionValidity, Self::Error>;
9893

9994
/// Synchronously verify given extrinsic at given block.
10095
///
@@ -123,7 +118,10 @@ pub trait ChainApi: Send + Sync {
123118
fn hash_and_length(&self, uxt: &RawExtrinsicFor<Self>) -> (ExtrinsicHash<Self>, usize);
124119

125120
/// Returns a block body given the block.
126-
fn block_body(&self, at: <Self::Block as BlockT>::Hash) -> Self::BodyFuture;
121+
async fn block_body(
122+
&self,
123+
at: <Self::Block as BlockT>::Hash,
124+
) -> Result<Option<Vec<<Self::Block as traits::Block>::Extrinsic>>, Self::Error>;
127125

128126
/// Returns a block header given the block id.
129127
fn block_header(

substrate/test-utils/runtime/transaction-pool/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ workspace = true
1515
targets = ["x86_64-unknown-linux-gnu"]
1616

1717
[dependencies]
18+
async-trait = { workspace = true }
1819
codec = { workspace = true, default-features = true }
1920
futures = { workspace = true }
2021
log = { workspace = true }

0 commit comments

Comments
 (0)