Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
04af09b
txpool: API update: remove_invalid -> report_invalid
michalkucharczyk Nov 26, 2024
bf2dd1f
other modules updated
michalkucharczyk Nov 26, 2024
8c8e033
basic-authorship: updated
michalkucharczyk Nov 26, 2024
18ceac8
Cargo.lock updated
michalkucharczyk Nov 26, 2024
deb5c98
sketch
michalkucharczyk Nov 28, 2024
018f9d4
dropped_watcher: new fns are public
michalkucharczyk Nov 26, 2024
4aa24d3
dropped_watcher: improvement
michalkucharczyk Nov 26, 2024
9fe88a6
fatp: handling higher prio with full mempool
michalkucharczyk Nov 26, 2024
54ae11c
graph: fold_ready improved
michalkucharczyk Nov 26, 2024
a6882eb
graph: make some staff public
michalkucharczyk Nov 26, 2024
8d3dffe
tests added
michalkucharczyk Nov 26, 2024
70fd186
type removed
michalkucharczyk Nov 26, 2024
d3a1a7b
improvements
michalkucharczyk Nov 28, 2024
4246dac
make use of your brain
michalkucharczyk Nov 28, 2024
c203d72
fatp: pending actions now support removals
michalkucharczyk Nov 28, 2024
edb1257
validated_pool: SubmitOutcome
michalkucharczyk Nov 29, 2024
f778176
view/view_store: SubmitOutcome
michalkucharczyk Nov 29, 2024
a72b3f9
mempool: update_transaction stub
michalkucharczyk Nov 29, 2024
c411bb4
fatp: SubmitOutcome
michalkucharczyk Nov 29, 2024
7b461bf
fatp: todo added
michalkucharczyk Nov 29, 2024
8765d2c
single-state txpool: SubmitOutcome integration
michalkucharczyk Nov 29, 2024
e8ccd44
tests: SubmitOutcome fixes
michalkucharczyk Nov 29, 2024
6cca272
mempool: sizes fix
michalkucharczyk Nov 29, 2024
3b17a16
dropping transaction - size limit is properly obeyed now
michalkucharczyk Dec 3, 2024
4f767e5
merge / rebase fixes
michalkucharczyk Dec 4, 2024
6ba133e
mempool: prio is now locked option
michalkucharczyk Dec 4, 2024
46fa1fd
tests added + dead code cleanup
michalkucharczyk Dec 4, 2024
2221d7a
comments cleanup
michalkucharczyk Dec 4, 2024
0244ba0
tweaks
michalkucharczyk Jan 7, 2025
037e016
Merge remote-tracking branch 'origin/master' into mku-fatxpool-mempoo…
michalkucharczyk Jan 7, 2025
5d0283e
review comments
michalkucharczyk Jan 8, 2025
caca2e1
clippy
michalkucharczyk Jan 8, 2025
b86ef05
clean up
michalkucharczyk Jan 8, 2025
595c554
Merge remote-tracking branch 'origin/master' into mku-txpool-remove-i…
michalkucharczyk Jan 9, 2025
7471cc6
Merge remote-tracking branch 'polkadot-sdk-master-03/mku-fatxpool-mem…
michalkucharczyk Jan 9, 2025
61d7730
revalidate: use IndexMap to preserve order
michalkucharczyk Jan 13, 2025
c88d58b
implementation improvements + doc
michalkucharczyk Jan 13, 2025
8af640f
tests
michalkucharczyk Jan 13, 2025
0fad26c
wording
michalkucharczyk Jan 13, 2025
ccdb853
cleanup
michalkucharczyk Jan 13, 2025
1b09887
Cargo.lock updated
michalkucharczyk Jan 13, 2025
f1a1650
Update from michalkucharczyk running command 'prdoc --bump minor --au…
Jan 13, 2025
7ed1c82
Update prdoc/pr_6661.prdoc
michalkucharczyk Jan 13, 2025
4aa9bf0
Update prdoc/pr_6661.prdoc
michalkucharczyk Jan 13, 2025
2db11e5
Update prdoc/pr_6661.prdoc
michalkucharczyk Jan 13, 2025
f97ec19
deps
michalkucharczyk Jan 13, 2025
bac9d89
tests: minor improvements
michalkucharczyk Jan 14, 2025
7ef96d0
Merge remote-tracking branch 'origin/master' into mku-txpool-remove-i…
michalkucharczyk Jan 14, 2025
7081c59
test fixed
michalkucharczyk Jan 14, 2025
686a427
Apply suggestions from code review
michalkucharczyk Jan 15, 2025
4200ccc
Comment reviews applied
michalkucharczyk Jan 16, 2025
5bb5f8a
tests: fatp_invalid added
michalkucharczyk Jan 16, 2025
af464fa
more tests, fixes, docs updated
michalkucharczyk Jan 17, 2025
1f7280e
Merge remote-tracking branch 'origin/master' into mku-txpool-remove-i…
michalkucharczyk Jan 17, 2025
4d23a6f
Merge remote-tracking branch 'origin/master' into mku-txpool-remove-i…
michalkucharczyk Feb 3, 2025
562f30d
fix
michalkucharczyk Feb 3, 2025
8d63728
report_invalid: sp_blockchain::Error -> TransactionValidityError
michalkucharczyk Feb 3, 2025
4911864
Merge remote-tracking branch 'origin/master' into mku-txpool-remove-i…
michalkucharczyk Feb 4, 2025
44d55f3
merge fix
michalkucharczyk Feb 4, 2025
8d7334e
logging fixed - tracing
michalkucharczyk Feb 4, 2025
48214a3
Dropped(invalid) supported
michalkucharczyk Feb 5, 2025
bfec262
improved mempool revalidation
michalkucharczyk Feb 5, 2025
95c8ff2
view_store::report_invalid does not trigger event
michalkucharczyk Feb 5, 2025
37fb2e9
logging
michalkucharczyk Feb 5, 2025
50a4539
formatting
michalkucharczyk Feb 5, 2025
5b70ad9
mempool: remove_transaction -> remove_transactions
michalkucharczyk Feb 5, 2025
0e5fe6d
clippy
michalkucharczyk Feb 6, 2025
5e39d3f
clippy again
michalkucharczyk Feb 6, 2025
0910ead
Merge branch 'master' into mku-txpool-remove-invalid
michalkucharczyk Feb 11, 2025
6d7ccff
review comments
michalkucharczyk Feb 11, 2025
d30b6c0
fmt
michalkucharczyk Feb 11, 2025
cc03547
Merge branch 'master' into mku-txpool-remove-invalid
michalkucharczyk Feb 13, 2025
31c0b60
report_invalid: [tuple] -> TxInvalidityReportMap
michalkucharczyk Feb 13, 2025
9932bf6
do not drop future/stale event with single view
michalkucharczyk Feb 13, 2025
aa88716
Merge remote-tracking branch 'origin/master' into mku-txpool-remove-i…
michalkucharczyk Feb 13, 2025
6b41d93
view: unused function removed
michalkucharczyk Feb 13, 2025
8be5ef3
Cargo.lock
michalkucharczyk Feb 13, 2025
59e386a
Merge branch 'master' into mku-txpool-remove-invalid
michalkucharczyk Feb 14, 2025
024e21e
Merge branch 'master' into mku-txpool-remove-invalid
michalkucharczyk Feb 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions substrate/bin/node/bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ kitchensink-runtime = { workspace = true }
sc-client-api = { workspace = true, default-features = true }
sp-runtime = { workspace = true, default-features = true }
sp-state-machine = { workspace = true, default-features = true }
sp-blockchain = { workspace = true, default-features = true }
serde = { workspace = true, default-features = true }
serde_json = { workspace = true, default-features = true }
derive_more = { features = ["display"], workspace = true }
Expand Down
6 changes: 5 additions & 1 deletion substrate/bin/node/bench/src/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ impl sc_transaction_pool_api::TransactionPool for Transactions {
unimplemented!()
}

fn remove_invalid(&self, _hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>> {
fn report_invalid(
&self,
_at: Option<Self::Hash>,
_invalid_tx_errors: &[(TxHash<Self>, Option<sp_blockchain::Error>)],
) -> Vec<Arc<Self::InPoolTransaction>> {
Default::default()
}

Expand Down
4 changes: 2 additions & 2 deletions substrate/client/basic-authorship/src/basic_authorship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ where
target: LOG_TARGET,
"[{:?}] Invalid transaction: {} at: {}", pending_tx_hash, e, self.parent_hash
);
unqueue_invalid.push(pending_tx_hash);
unqueue_invalid.push((pending_tx_hash, Some(e)));
},
}
};
Expand All @@ -524,7 +524,7 @@ where
);
}

self.transaction_pool.remove_invalid(&unqueue_invalid);
self.transaction_pool.report_invalid(Some(self.parent_hash), &unqueue_invalid);
Ok(end_reason)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,12 @@ impl TransactionPool for MiddlewarePool {
Ok(watcher.boxed())
}

fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>> {
self.inner_pool.remove_invalid(hashes)
fn report_invalid(
&self,
at: Option<<Self::Block as BlockT>::Hash>,
invalid_tx_errors: &[(TxHash<Self>, Option<sp_blockchain::Error>)],
) -> Vec<Arc<Self::InPoolTransaction>> {
self.inner_pool.report_invalid(at, invalid_tx_errors)
}

fn status(&self) -> PoolStatus {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ where
}

// Best effort pool removal (tx can already be finalized).
pool.remove_invalid(&[broadcast_state.tx_hash]);
pool.report_invalid(None, &[(broadcast_state.tx_hash, None)]);
});

// Keep track of this entry and the abortable handle.
Expand Down
6 changes: 3 additions & 3 deletions substrate/client/rpc/src/author/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,17 @@ where
let hashes = bytes_or_hash
.into_iter()
.map(|x| match x {
hash::ExtrinsicOrHash::Hash(h) => Ok(h),
hash::ExtrinsicOrHash::Hash(h) => Ok((h, None)),
hash::ExtrinsicOrHash::Extrinsic(bytes) => {
let xt = Decode::decode(&mut &bytes[..])?;
Ok(self.pool.hash_of(&xt))
Ok((self.pool.hash_of(&xt), None))
},
})
.collect::<Result<Vec<_>>>()?;

Ok(self
.pool
.remove_invalid(&hashes)
.report_invalid(None, &hashes)
.into_iter()
.map(|tx| tx.hash().clone())
.collect())
Expand Down
20 changes: 18 additions & 2 deletions substrate/client/transaction-pool/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,24 @@ pub trait TransactionPool: Send + Sync {
fn ready(&self) -> Box<dyn ReadyTransactions<Item = Arc<Self::InPoolTransaction>> + Send>;

// *** Block production
/// Remove transactions identified by given hashes (and dependent transactions) from the pool.
fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>>;
/// Reports invalid transactions to the transaction pool.
///
/// This function accepts an array of tuples, each containing a transaction hash and an
/// optional error encountered during the transaction execution at a specific (also optional)
/// block.
///
/// The transaction pool implementation decides which transactions to remove. Transactions
/// dependent on invalid ones will also be removed.
///
/// If the tuple's error is None, the transaction will be forcibly removed from the pool.
///
/// The optional `at` parameter provides additional context regarding the block where the error
/// occurred.
fn report_invalid(
&self,
at: Option<<Self::Block as BlockT>::Hash>,
invalid_tx_errors: &[(TxHash<Self>, Option<sp_blockchain::Error>)],
) -> Vec<Arc<Self::InPoolTransaction>>;

// *** logging
/// Get futures transaction list.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -675,18 +675,49 @@ where
.inspect_err(|_| mempool.remove(xt_hash))
}

/// Intended to remove transactions identified by the given hashes, and any dependent
/// transactions, from the pool. In current implementation this function only outputs the error.
/// Seems that API change is needed here to make this call reasonable.
// todo [#5491]: api change? we need block hash here (assuming we need it at all - could be
// useful for verification for debugging purposes).
fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>> {
if !hashes.is_empty() {
log::debug!(target: LOG_TARGET, "fatp::remove_invalid {}", hashes.len());
log_xt_trace!(target:LOG_TARGET, hashes, "[{:?}] fatp::remove_invalid");
self.metrics
.report(|metrics| metrics.removed_invalid_txs.inc_by(hashes.len() as _));
}
// /// Intended to remove transactions identified by the given hashes, and any dependent
// /// transactions, from the pool. In current implementation this function only outputs the
// error. /// Seems that API change is needed here to make this call reasonable.
// // todo [#5491]: api change? we need block hash here (assuming we need it at all - could be
// // useful for verification for debugging purposes).
// fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>> {
// if !hashes.is_empty() {
// log::debug!(target: LOG_TARGET, "fatp::remove_invalid {}", hashes.len());
// log_xt_trace!(target:LOG_TARGET, hashes, "[{:?}] fatp::remove_invalid");
// self.metrics
// .report(|metrics| metrics.removed_invalid_txs.inc_by(hashes.len() as _));
// }
// Default::default()
// }

/// Reports invalid transactions to the transaction pool.
///
/// This function takes an array of tuples, each consisting of a transaction hash and the
/// corresponding error that occurred during transaction execution at given block.
///
/// The transaction pool implementation will determine which transactions should be
/// removed from the pool. Transactions that depend on invalid transactions will also
/// be removed.
fn report_invalid(
&self,
at: Option<<Self::Block as BlockT>::Hash>,
invalid_tx_errors: &[(TxHash<Self>, Option<sp_blockchain::Error>)],
) -> Vec<Arc<Self::InPoolTransaction>> {
self.metrics
.report(|metrics| metrics.reported_invalid_txs.inc_by(invalid_tx_errors.len() as _));

let removed = self.view_store.report_invalid(at, invalid_tx_errors);

self.metrics
.report(|metrics| metrics.removed_invalid_txs.inc_by(removed.len() as _));

// todo (after merging / rebasing)

// depending on error:
// - handle cloned view with view_store replacements
// - remove resulting hashes from mempool and collect Arc<Transaction>
// - send notification using listener (should this be done in view_store)

Default::default()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub struct Metrics {
/// Total number of unwatched transactions in txpool.
pub unwatched_txs: Gauge<U64>,
/// Total number of transactions reported as invalid.
pub reported_invalid_txs: Counter<U64>,
/// Total number of transactions removed as invalid.
pub removed_invalid_txs: Counter<U64>,
/// Total number of finalized transactions.
pub finalized_txs: Counter<U64>,
Expand Down Expand Up @@ -99,10 +101,17 @@ impl MetricsRegistrant for Metrics {
)?,
registry,
)?,
reported_invalid_txs: register(
Counter::new(
"substrate_sub_txpool_reported_invalid_txs_total",
"Total number of transactions reported as invalid.",
)?,
registry,
)?,
removed_invalid_txs: register(
Counter::new(
"substrate_sub_txpool_removed_invalid_txs_total",
"Total number of transactions reported as invalid.",
"Total number of transactions removed as invalid.",
)?,
registry,
)?,
Expand Down
11 changes: 9 additions & 2 deletions substrate/client/transaction-pool/src/fork_aware_txpool/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use super::metrics::MetricsLink as PrometheusMetrics;
use crate::{
common::log_xt::log_xt_trace,
graph::{
self, watcher::Watcher, ExtrinsicFor, ExtrinsicHash, IsValidator, ValidatedTransaction,
ValidatedTransactionFor,
self, watcher::Watcher, ExtrinsicFor, ExtrinsicHash, IsValidator, TransactionFor,
ValidatedTransaction, ValidatedTransactionFor,
},
LOG_TARGET,
};
Expand Down Expand Up @@ -455,4 +455,11 @@ where
);
}
}

pub(crate) fn remove_invalid(
&self,
hashes: &[ExtrinsicHash<ChainApi>],
) -> Vec<TransactionFor<ChainApi>> {
self.pool.validated_pool().remove_invalid(hashes)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@ use futures::prelude::*;
use itertools::Itertools;
use parking_lot::RwLock;
use sc_transaction_pool_api::{error::Error as PoolError, PoolStatus, TransactionSource};
use sp_blockchain::TreeRoute;
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
use sp_blockchain::{ApplyExtrinsicFailed, Error as BlockchainError, TreeRoute};
use sp_runtime::{
generic::BlockId,
traits::Block as BlockT,
transaction_validity::{InvalidTransaction, TransactionValidityError},
};
use std::{collections::HashMap, sync::Arc, time::Instant};

/// The helper structure encapsulates all the views.
Expand Down Expand Up @@ -484,4 +488,45 @@ where
futures::future::join_all(finish_revalidation_futures).await;
log::trace!(target:LOG_TARGET,"finish_background_revalidations took {:?}", start.elapsed());
}

pub(crate) fn report_invalid(
&self,
at: Option<Block::Hash>,
invalid_tx_errors: &[(ExtrinsicHash<ChainApi>, Option<BlockchainError>)],
) -> Vec<ExtrinsicHash<ChainApi>> {
let mut remove_from_view = vec![];
let mut remove_from_pool = vec![];

invalid_tx_errors.iter().for_each(|(hash, e)| match e {
Some(BlockchainError::ApplyExtrinsicFailed(ApplyExtrinsicFailed::Validity(
TransactionValidityError::Invalid(
InvalidTransaction::Future | InvalidTransaction::Stale,
),
))) => {
remove_from_view.push(*hash);
},
_ => {
remove_from_pool.push(*hash);
},
});

at.inspect(|at| {
self.get_view_at(*at, true)
.map(|(view, _)| view.remove_invalid(&remove_from_view[..]))
.unwrap_or_default();
});

//todo: duplicated code - we need to remove subtree from every view
// let active_views = self.active_views.read();
// let inactive_views = self.inactive_views.read();
// active_views
// .iter()
// .chain(inactive_views.iter())
// .filter(|(_, view)| view.is_imported(&xt_hash))
// .for_each(|(_, view)| {
// view.remove_subtree(xt_hash, replaced_with);
// });

remove_from_pool
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,13 @@ where
Ok(watcher.into_stream().boxed())
}

fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>> {
let removed = self.pool.validated_pool().remove_invalid(hashes);
fn report_invalid(
&self,
_at: Option<<Self::Block as BlockT>::Hash>,
invalid_tx_errors: &[(TxHash<Self>, Option<sp_blockchain::Error>)],
) -> Vec<Arc<Self::InPoolTransaction>> {
let hashes = invalid_tx_errors.iter().map(|(hash, _)| *hash).collect::<Vec<_>>();
let removed = self.pool.validated_pool().remove_invalid(&hashes[..]);
self.metrics
.report(|metrics| metrics.validations_invalid.inc_by(removed.len() as u64));
removed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,12 @@ where
self.0.ready()
}

fn remove_invalid(&self, hashes: &[TxHash<Self>]) -> Vec<Arc<Self::InPoolTransaction>> {
self.0.remove_invalid(hashes)
fn report_invalid(
&self,
at: Option<<Self::Block as BlockT>::Hash>,
invalid_tx_errors: &[(TxHash<Self>, Option<sp_blockchain::Error>)],
) -> Vec<Arc<Self::InPoolTransaction>> {
self.0.report_invalid(at, invalid_tx_errors)
}

fn futures(&self) -> Vec<Self::InPoolTransaction> {
Expand Down