Skip to content

Commit 7231580

Browse files
paritytech-release-backport-bot[bot]michalkucharczykEgorPopelyaev
authored
[stable2506] Backport #9189 (#9464)
Backport #9189 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: Egor_P <[email protected]>
1 parent 411c502 commit 7231580

File tree

4 files changed

+232
-68
lines changed

4 files changed

+232
-68
lines changed

prdoc/pr_9189.prdoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
title: '`fatxpool`: avoid premature revalidation of transactions'
2+
doc:
3+
- audience: Node Dev
4+
description: |-
5+
After this PR transactions will be revalidated in mempool on finalized blocks only if height of finalized block is greater then the height of the block at which transactions was originally submitted.
6+
crates:
7+
- name: sc-transaction-pool
8+
bump: minor

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

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -737,10 +737,20 @@ where
737737
) -> Result<Pin<Box<TransactionStatusStreamFor<Self>>>, ChainApi::Error> {
738738
let xt = Arc::from(xt);
739739

740-
let insertion = match self.mempool.push_watched(source, xt.clone()).await {
740+
let at_number = self
741+
.api
742+
.block_id_to_number(&BlockId::Hash(at))
743+
.ok()
744+
.flatten()
745+
.unwrap_or_default()
746+
.into()
747+
.as_u64();
748+
749+
let insertion = match self.mempool.push_watched(source, at_number, xt.clone()).await {
741750
Ok(result) => result,
742751
Err(TxPoolApiError::ImmediatelyDropped) =>
743-
self.attempt_transaction_replacement(source, true, xt.clone()).await?,
752+
self.attempt_transaction_replacement(source, at_number, true, xt.clone())
753+
.await?,
744754
Err(e) => return Err(e.into()),
745755
};
746756

@@ -764,9 +774,18 @@ where
764774
/// Refer to [`Self::submit_at`]
765775
async fn submit_at_inner(
766776
&self,
777+
at: Block::Hash,
767778
source: TransactionSource,
768779
xts: Vec<TransactionFor<Self>>,
769780
) -> Result<Vec<Result<TxHash<Self>, ChainApi::Error>>, ChainApi::Error> {
781+
let at_number = self
782+
.api
783+
.block_id_to_number(&BlockId::Hash(at))
784+
.ok()
785+
.flatten()
786+
.unwrap_or_default()
787+
.into()
788+
.as_u64();
770789
let view_store = self.view_store.clone();
771790
trace!(
772791
target: LOG_TARGET,
@@ -776,7 +795,7 @@ where
776795
);
777796
log_xt_trace!(target: LOG_TARGET, xts.iter().map(|xt| self.tx_hash(xt)), "fatp::submit_at");
778797
let xts = xts.into_iter().map(Arc::from).collect::<Vec<_>>();
779-
let mempool_results = self.mempool.extend_unwatched(source, &xts).await;
798+
let mempool_results = self.mempool.extend_unwatched(source, at_number, &xts).await;
780799

781800
if view_store.is_empty() {
782801
return Ok(mempool_results
@@ -792,7 +811,7 @@ where
792811
.map(|(result, xt)| async move {
793812
match result {
794813
Err(TxPoolApiError::ImmediatelyDropped) =>
795-
self.attempt_transaction_replacement(source, false, xt).await,
814+
self.attempt_transaction_replacement(source, at_number, false, xt).await,
796815
_ => result,
797816
}
798817
})
@@ -940,7 +959,7 @@ where
940959
/// are reduced to single result. Refer to `reduce_multiview_result` for more details.
941960
async fn submit_at(
942961
&self,
943-
_: <Self::Block as BlockT>::Hash,
962+
at: <Self::Block as BlockT>::Hash,
944963
source: TransactionSource,
945964
xts: Vec<TransactionFor<Self>>,
946965
) -> Result<Vec<Result<TxHash<Self>, Self::Error>>, Self::Error> {
@@ -952,9 +971,7 @@ where
952971
"fatp::submit_at"
953972
);
954973
log_xt_trace!(target: LOG_TARGET, xts.iter().map(|xt| self.tx_hash(xt)), "fatp::submit_at");
955-
956-
let result = self.submit_at_inner(source, xts).await;
957-
974+
let result = self.submit_at_inner(at, source, xts).await;
958975
insert_and_log_throttled!(
959976
Level::DEBUG,
960977
target:LOG_TARGET_STAT,
@@ -1148,7 +1165,7 @@ where
11481165

11491166
fn submit_local(
11501167
&self,
1151-
_at: Block::Hash,
1168+
at: Block::Hash,
11521169
xt: sc_transaction_pool_api::LocalTransactionFor<Self>,
11531170
) -> Result<Self::Hash, Self::Error> {
11541171
trace!(
@@ -1157,12 +1174,20 @@ where
11571174
"fatp::submit_local"
11581175
);
11591176
let xt = Arc::from(xt);
1177+
let at_number = self
1178+
.api
1179+
.block_id_to_number(&BlockId::Hash(at))
1180+
.ok()
1181+
.flatten()
1182+
.unwrap_or_default()
1183+
.into()
1184+
.as_u64();
11601185

11611186
// note: would be nice to get rid of sync methods one day. See: #8912
11621187
let result = self
11631188
.mempool
11641189
.clone()
1165-
.extend_unwatched_sync(TransactionSource::Local, vec![xt.clone()])
1190+
.extend_unwatched_sync(TransactionSource::Local, at_number, vec![xt.clone()])
11661191
.remove(0);
11671192

11681193
let insertion = match result {
@@ -1847,6 +1872,7 @@ where
18471872
async fn attempt_transaction_replacement(
18481873
&self,
18491874
source: TransactionSource,
1875+
at_number: u64,
18501876
watched: bool,
18511877
xt: ExtrinsicFor<ChainApi>,
18521878
) -> Result<InsertionInfo<ExtrinsicHash<ChainApi>>, TxPoolApiError> {
@@ -1874,8 +1900,10 @@ where
18741900
return Err(TxPoolApiError::ImmediatelyDropped)
18751901
};
18761902

1877-
let insertion_info =
1878-
self.mempool.try_insert_with_replacement(xt, priority, source, watched).await?;
1903+
let insertion_info = self
1904+
.mempool
1905+
.try_insert_with_replacement(xt, priority, source, at_number, watched)
1906+
.await?;
18791907
self.post_attempt_transaction_replacement(xt_hash, insertion_info)
18801908
}
18811909

@@ -1886,29 +1914,31 @@ where
18861914
watched: bool,
18871915
xt: ExtrinsicFor<ChainApi>,
18881916
) -> Result<InsertionInfo<ExtrinsicHash<ChainApi>>, TxPoolApiError> {
1889-
let at = self
1917+
let HashAndNumber { number: at_number, hash: at_hash } = self
18901918
.view_store
18911919
.most_recent_view
18921920
.read()
18931921
.as_ref()
18941922
.ok_or(TxPoolApiError::ImmediatelyDropped)?
1895-
.at
1896-
.hash;
1923+
.at;
18971924

18981925
let ValidTransaction { priority, .. } = self
18991926
.api
1900-
.validate_transaction_blocking(at, TransactionSource::Local, Arc::from(xt.clone()))
1927+
.validate_transaction_blocking(at_hash, TransactionSource::Local, Arc::from(xt.clone()))
19011928
.map_err(|_| TxPoolApiError::ImmediatelyDropped)?
19021929
.map_err(|e| match e {
19031930
TransactionValidityError::Invalid(i) => TxPoolApiError::InvalidTransaction(i),
19041931
TransactionValidityError::Unknown(u) => TxPoolApiError::UnknownTransaction(u),
19051932
})?;
19061933
let xt_hash = self.hash_of(&xt);
19071934

1908-
let insertion_info = self
1909-
.mempool
1910-
.clone()
1911-
.try_insert_with_replacement_sync(xt, priority, source, watched)?;
1935+
let insertion_info = self.mempool.clone().try_insert_with_replacement_sync(
1936+
xt,
1937+
priority,
1938+
source,
1939+
at_number.into().as_u64(),
1940+
watched,
1941+
)?;
19121942
self.post_attempt_transaction_replacement(xt_hash, insertion_info)
19131943
}
19141944

0 commit comments

Comments
 (0)