mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 12:11:09 +00:00
Subsystems memory tracking: 1. Transaction pool (#4822)
* update sp-runtime * total update * usage informant * update to crates.io version * update Cargo.lock * update dummy update * fix todo * cleanup * avoid custom impl * Update client/transaction-pool/graph/src/future.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * remove another custom impl * remove another custom impl * add kb in report * update Cargo.lock * review suggestions * --amend * --amend * bump parity-util-mem to 0.5.0 * bumps * update macro and versions * add to grafana * naming Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
This commit is contained in:
@@ -84,7 +84,7 @@ pub struct PruneStatus<Hash, Ex> {
|
||||
|
||||
/// Immutable transaction
|
||||
#[cfg_attr(test, derive(Clone))]
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[derive(PartialEq, Eq, parity_util_mem::MallocSizeOf)]
|
||||
pub struct Transaction<Hash, Extrinsic> {
|
||||
/// Raw extrinsic representing that transaction.
|
||||
pub data: Extrinsic,
|
||||
@@ -209,7 +209,7 @@ const RECENTLY_PRUNED_TAGS: usize = 2;
|
||||
/// as-is for the second time will fail or produce unwanted results.
|
||||
/// Most likely it is required to revalidate them and recompute set of
|
||||
/// required tags.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, parity_util_mem::MallocSizeOf)]
|
||||
pub struct BasePool<Hash: hash::Hash + Eq, Ex> {
|
||||
reject_future_transactions: bool,
|
||||
future: FutureTransactions<Hash, Ex>,
|
||||
@@ -846,6 +846,33 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_track_heap_size() {
|
||||
let mut pool = pool();
|
||||
pool.import(Transaction {
|
||||
data: vec![5u8; 1024],
|
||||
bytes: 1,
|
||||
hash: 5,
|
||||
priority: 5u64,
|
||||
valid_till: 64u64,
|
||||
requires: vec![],
|
||||
provides: vec![vec![0], vec![4]],
|
||||
propagate: true,
|
||||
}).expect("import 1 should be ok");
|
||||
pool.import(Transaction {
|
||||
data: vec![3u8; 1024],
|
||||
bytes: 1,
|
||||
hash: 7,
|
||||
priority: 5u64,
|
||||
valid_till: 64u64,
|
||||
requires: vec![],
|
||||
provides: vec![vec![2], vec![7]],
|
||||
propagate: true,
|
||||
}).expect("import 2 should be ok");
|
||||
|
||||
assert!(parity_util_mem::malloc_size(&pool) > 5000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_remove_invalid_transactions() {
|
||||
// given
|
||||
|
||||
@@ -29,6 +29,7 @@ use sp_runtime::transaction_validity::{
|
||||
|
||||
use crate::base_pool::Transaction;
|
||||
|
||||
#[derive(parity_util_mem::MallocSizeOf)]
|
||||
/// Transaction with partially satisfied dependencies.
|
||||
pub struct WaitingTransaction<Hash, Ex> {
|
||||
/// Transaction details.
|
||||
@@ -109,7 +110,7 @@ impl<Hash, Ex> WaitingTransaction<Hash, Ex> {
|
||||
///
|
||||
/// Contains transactions that are still awaiting for some other transactions that
|
||||
/// could provide a tag that they require.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, parity_util_mem::MallocSizeOf)]
|
||||
pub struct FutureTransactions<Hash: hash::Hash + Eq, Ex> {
|
||||
/// tags that are not yet provided by any transaction and we await for them
|
||||
wanted_tags: HashMap<Tag, HashSet<Hash>>,
|
||||
@@ -243,3 +244,30 @@ impl<Hash: hash::Hash + Eq + Clone, Ex> FutureTransactions<Hash, Ex> {
|
||||
self.waiting.values().fold(0, |acc, tx| acc + tx.transaction.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn can_track_heap_size() {
|
||||
let mut future = FutureTransactions::default();
|
||||
future.import(WaitingTransaction {
|
||||
transaction: Transaction {
|
||||
data: vec![0u8; 1024],
|
||||
bytes: 1,
|
||||
hash: 1,
|
||||
priority: 1,
|
||||
valid_till: 2,
|
||||
requires: vec![vec![1], vec![2]],
|
||||
provides: vec![vec![3], vec![4]],
|
||||
propagate: true,
|
||||
}.into(),
|
||||
missing_tags: vec![vec![1u8], vec![2u8]].into_iter().collect(),
|
||||
imported_at: std::time::Instant::now(),
|
||||
});
|
||||
|
||||
// data is at least 1024!
|
||||
assert!(parity_util_mem::malloc_size(&future) > 1024);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,16 @@ pub struct Pool<B: ChainApi> {
|
||||
validated_pool: Arc<ValidatedPool<B>>,
|
||||
}
|
||||
|
||||
impl<B: ChainApi> parity_util_mem::MallocSizeOf for Pool<B>
|
||||
where
|
||||
B::Hash: parity_util_mem::MallocSizeOf,
|
||||
ExtrinsicFor<B>: parity_util_mem::MallocSizeOf,
|
||||
{
|
||||
fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize {
|
||||
self.validated_pool.size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: ChainApi> Pool<B> {
|
||||
/// Create a new transaction pool.
|
||||
pub fn new(options: Options, api: Arc<B>) -> Self {
|
||||
|
||||
@@ -36,7 +36,7 @@ use crate::base_pool::Transaction;
|
||||
/// An in-pool transaction reference.
|
||||
///
|
||||
/// Should be cheap to clone.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, parity_util_mem::MallocSizeOf)]
|
||||
pub struct TransactionRef<Hash, Ex> {
|
||||
/// The actual transaction data.
|
||||
pub transaction: Arc<Transaction<Hash, Ex>>,
|
||||
@@ -74,7 +74,7 @@ impl<Hash, Ex> PartialEq for TransactionRef<Hash, Ex> {
|
||||
}
|
||||
impl<Hash, Ex> Eq for TransactionRef<Hash, Ex> {}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, parity_util_mem::MallocSizeOf)]
|
||||
pub struct ReadyTx<Hash, Ex> {
|
||||
/// A reference to a transaction
|
||||
pub transaction: TransactionRef<Hash, Ex>,
|
||||
@@ -104,7 +104,7 @@ Hence every hash retrieved from `provided_tags` is always present in `ready`;
|
||||
qed
|
||||
"#;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, parity_util_mem::MallocSizeOf)]
|
||||
pub struct ReadyTransactions<Hash: hash::Hash + Eq, Ex> {
|
||||
/// Insertion id
|
||||
insertion_id: u64,
|
||||
@@ -676,6 +676,24 @@ mod tests {
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_report_heap_size() {
|
||||
let mut ready = ReadyTransactions::default();
|
||||
let tx = Transaction {
|
||||
data: vec![5],
|
||||
bytes: 1,
|
||||
hash: 5,
|
||||
priority: 1,
|
||||
valid_till: u64::max_value(), // use the max_value() here for testing.
|
||||
requires: vec![],
|
||||
provides: vec![],
|
||||
propagate: true,
|
||||
};
|
||||
import(&mut ready, tx).unwrap();
|
||||
|
||||
assert!(parity_util_mem::malloc_size(&ready) > 200);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_order_refs() {
|
||||
let mut id = 1;
|
||||
|
||||
@@ -74,6 +74,17 @@ pub(crate) struct ValidatedPool<B: ChainApi> {
|
||||
rotator: PoolRotator<ExHash<B>>,
|
||||
}
|
||||
|
||||
impl<B: ChainApi> parity_util_mem::MallocSizeOf for ValidatedPool<B>
|
||||
where
|
||||
B::Hash: parity_util_mem::MallocSizeOf,
|
||||
ExtrinsicFor<B>: parity_util_mem::MallocSizeOf,
|
||||
{
|
||||
fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize {
|
||||
// other entries insignificant or non-primary references
|
||||
self.pool.size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: ChainApi> ValidatedPool<B> {
|
||||
/// Create a new transaction pool.
|
||||
pub fn new(options: Options, api: Arc<B>) -> Self {
|
||||
|
||||
Reference in New Issue
Block a user