Skip to content

Commit ab7c86b

Browse files
paritytech-release-backport-bot[bot]michalkucharczykgithub-actions[bot]bkchr
authored
[stable2506] Backport #9338 (#9438)
Backport #9338 into `stable2506` from michalkucharczyk. See the [documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md) on how to use this bot. <!-- # To be used by other automation, do not modify: original-pr-number: #${pull_number} --> Co-authored-by: Michal Kucharczyk <[email protected]> Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Bastian Köcher <[email protected]>
1 parent 03e07b6 commit ab7c86b

File tree

6 files changed

+221
-73
lines changed

6 files changed

+221
-73
lines changed

prdoc/pr_9338.prdoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
title: 'fatxpool: instant seal support'
2+
doc:
3+
- audience: Node Dev
4+
description: |-
5+
This PR introduces creation of view for known best block during instantiation of `fatxpool`. This is intended to fix an instant-seal nodes, where block building is triggered via transaction import.
6+
crates:
7+
- name: sc-transaction-pool
8+
bump: patch

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

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,23 @@ where
208208
ChainApi: graph::ChainApi<Block = Block> + 'static,
209209
<Block as BlockT>::Hash: Unpin,
210210
{
211+
// Injects a view for the given block to self.
212+
//
213+
// Helper for the pool new methods.
214+
fn inject_initial_view(self, initial_view_hash: Block::Hash) -> Self {
215+
if let Some(block_number) =
216+
self.api.block_id_to_number(&BlockId::Hash(initial_view_hash)).ok().flatten()
217+
{
218+
let at_best = HashAndNumber { number: block_number, hash: initial_view_hash };
219+
let tree_route =
220+
&TreeRoute::new(vec![at_best.clone()], 0).expect("tree route is correct; qed");
221+
let view = self.build_and_plug_view(None, &at_best, &tree_route);
222+
self.view_store.insert_new_view_sync(view.into(), &tree_route);
223+
trace!(target: LOG_TARGET, ?block_number, ?initial_view_hash, "fatp::injected initial view");
224+
};
225+
self
226+
}
227+
211228
/// Create new fork aware transaction pool with provided shared instance of `ChainApi` intended
212229
/// for tests.
213230
pub fn new_test(
@@ -304,7 +321,8 @@ where
304321
submit_and_watch_stats: DurationSlidingStats::new(Duration::from_secs(
305322
STAT_SLIDING_WINDOW,
306323
)),
307-
},
324+
}
325+
.inject_initial_view(best_block_hash),
308326
[combined_tasks, mempool_task],
309327
)
310328
}
@@ -461,6 +479,7 @@ where
461479
STAT_SLIDING_WINDOW,
462480
)),
463481
}
482+
.inject_initial_view(best_block_hash)
464483
}
465484

466485
/// Get access to the underlying api
@@ -1207,7 +1226,7 @@ where
12071226
}
12081227

12091228
let best_view = self.view_store.find_best_view(tree_route);
1210-
let new_view = self.build_new_view(best_view, hash_and_number, tree_route).await;
1229+
let new_view = self.build_and_update_view(best_view, hash_and_number, tree_route).await;
12111230

12121231
if let Some(view) = new_view {
12131232
{
@@ -1298,26 +1317,17 @@ where
12981317
/// If `origin_view` is provided, the new view will be cloned from it. Otherwise an empty view
12991318
/// will be created.
13001319
///
1301-
/// The new view will be updated with transactions from the tree_route and the mempool, all
1302-
/// required events will be triggered, it will be inserted to the view store.
1303-
///
13041320
/// This method will also update multi-view listeners with newly created view.
1305-
async fn build_new_view(
1321+
///
1322+
/// The new view will not be inserted into the view store.
1323+
fn build_and_plug_view(
13061324
&self,
13071325
origin_view: Option<Arc<View<ChainApi>>>,
13081326
at: &HashAndNumber<Block>,
13091327
tree_route: &TreeRoute<Block>,
1310-
) -> Option<Arc<View<ChainApi>>> {
1328+
) -> View<ChainApi> {
13111329
let enter = Instant::now();
1312-
debug!(
1313-
target: LOG_TARGET,
1314-
?at,
1315-
origin_view_at = ?origin_view.as_ref().map(|v| v.at.clone()),
1316-
?tree_route,
1317-
"build_new_view"
1318-
);
1319-
1320-
let (mut view, view_dropped_stream, view_aggregated_stream) =
1330+
let (view, view_dropped_stream, view_aggregated_stream) =
13211331
if let Some(origin_view) = origin_view {
13221332
let (mut view, view_dropped_stream, view_aggragated_stream) =
13231333
View::new_from_other(&origin_view, at);
@@ -1346,7 +1356,6 @@ where
13461356
"build_new_view::clone_view"
13471357
);
13481358

1349-
let start = Instant::now();
13501359
// 1. Capture all import notification from the very beginning, so first register all
13511360
//the listeners.
13521361
self.import_notification_sink.add_view(
@@ -1361,6 +1370,34 @@ where
13611370
self.view_store
13621371
.listener
13631372
.add_view_aggregated_stream(view.at.hash, view_aggregated_stream.boxed());
1373+
1374+
view
1375+
}
1376+
1377+
/// Builds and updates a new view.
1378+
///
1379+
/// This functio uses [`Self::build_new_view`] to create or clone new view.
1380+
///
1381+
/// The new view will be updated with transactions from the tree_route and the mempool, all
1382+
/// required events will be triggered, it will be inserted to the view store (respecting all
1383+
/// pre-insertion actions).
1384+
async fn build_and_update_view(
1385+
&self,
1386+
origin_view: Option<Arc<View<ChainApi>>>,
1387+
at: &HashAndNumber<Block>,
1388+
tree_route: &TreeRoute<Block>,
1389+
) -> Option<Arc<View<ChainApi>>> {
1390+
let start = Instant::now();
1391+
debug!(
1392+
target: LOG_TARGET,
1393+
?at,
1394+
origin_view_at = ?origin_view.as_ref().map(|v| v.at.clone()),
1395+
?tree_route,
1396+
"build_new_view"
1397+
);
1398+
1399+
let mut view = self.build_and_plug_view(origin_view, at, tree_route);
1400+
13641401
// sync the transactions statuses and referencing views in all the listeners with newly
13651402
// cloned view.
13661403
view.pool.validated_pool().retrigger_notifications();
@@ -1396,7 +1433,7 @@ where
13961433

13971434
debug!(
13981435
target: LOG_TARGET,
1399-
duration = ?enter.elapsed(),
1436+
duration = ?start.elapsed(),
14001437
?at,
14011438
"build_new_view"
14021439
);

substrate/client/transaction-pool/src/fork_aware_txpool/view_store.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -526,13 +526,7 @@ where
526526

527527
/// Inserts new view into the view store.
528528
///
529-
/// All the views associated with the blocks which are on enacted path (including common
530-
/// ancestor) will be:
531-
/// - moved to the inactive views set (`inactive_views`),
532-
/// - removed from the multi view listeners.
533-
///
534-
/// The `most_recent_view` is updated with the reference to the newly inserted view.
535-
///
529+
/// Refer to [`Self::insert_new_view_sync`] more details.
536530
/// If there are any pending tx replacments, they are applied to the new view.
537531
#[instrument(level = Level::TRACE, skip_all, target = "txpool", name = "view_store::insert_new_view")]
538532
pub(super) async fn insert_new_view(
@@ -543,7 +537,29 @@ where
543537
self.apply_pending_tx_replacements(view.clone()).await;
544538

545539
let start = Instant::now();
540+
self.insert_new_view_sync(view, tree_route);
546541

542+
debug!(
543+
target: LOG_TARGET,
544+
inactive_views = ?self.inactive_views.read().keys(),
545+
duration = ?start.elapsed(),
546+
"insert_new_view"
547+
);
548+
}
549+
550+
/// Inserts new view into the view store.
551+
///
552+
/// All the views associated with the blocks which are on enacted path (including common
553+
/// ancestor) will be:
554+
/// - moved to the inactive views set (`inactive_views`),
555+
/// - removed from the multi view listeners.
556+
///
557+
/// The `most_recent_view` is updated with the reference to the newly inserted view.
558+
pub(super) fn insert_new_view_sync(
559+
&self,
560+
view: Arc<View<ChainApi>>,
561+
tree_route: &TreeRoute<Block>,
562+
) {
547563
//note: most_recent_view must be synced with changes in in/active_views.
548564
{
549565
let mut most_recent_view_lock = self.most_recent_view.write();
@@ -561,12 +577,6 @@ where
561577
active_views.insert(view.at.hash, view.clone());
562578
most_recent_view_lock.replace(view.clone());
563579
};
564-
debug!(
565-
target: LOG_TARGET,
566-
inactive_views = ?self.inactive_views.read().keys(),
567-
duration = ?start.elapsed(),
568-
"insert_new_view"
569-
);
570580
}
571581

572582
/// Returns an optional reference to the view at given hash.

0 commit comments

Comments
 (0)