feat: add txpool metrics (#584)

* feat(metrics): `Metrics` derive macro

* rename metrics to metrics-derive

* use fully qualified fmt path

* metric vec with capacity

* favor metrics over simple scope attr, simplify code

* pull metric description from doc comment

* rm debug log

* add more docs and sample usage

* link to metrics macros

* add tests for metrics derive macro

* clippy

* Fix doc of headers_unexpected_errors field of HeaderMetrics

* Add tx pool metrics struct and metrics updates in code

* Format file

* Update metrics doc

* Add some comments

* Format file

* Refactor metrics describers for consistency

* Format files

* Fix broken import

* Apply metrics macro to TxPoolMetrics

* Remove unused imports

* Remove unused commented code

* Remove files

Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
This commit is contained in:
Mariano A. Nicolini
2022-12-27 12:44:41 -03:00
committed by GitHub
parent 1c3d704244
commit c2b19cecef
6 changed files with 77 additions and 32 deletions

50
Cargo.lock generated
View File

@ -521,9 +521,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.0.29" version = "4.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"clap_derive", "clap_derive",
@ -1282,7 +1282,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-core" name = "ethers-core"
version = "1.0.2" version = "1.0.2"
source = "git+https://github.com/gakonst/ethers-rs#612cce016cb90de049495bb3c23c360787beb4b1" source = "git+https://github.com/gakonst/ethers-rs#799f752e55e80aa8d6357321d4f5f7ebf66daa8a"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"bytes", "bytes",
@ -1308,7 +1308,7 @@ dependencies = [
[[package]] [[package]]
name = "ethers-providers" name = "ethers-providers"
version = "1.0.2" version = "1.0.2"
source = "git+https://github.com/gakonst/ethers-rs#612cce016cb90de049495bb3c23c360787beb4b1" source = "git+https://github.com/gakonst/ethers-rs#799f752e55e80aa8d6357321d4f5f7ebf66daa8a"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"auto_impl", "auto_impl",
@ -2056,9 +2056,9 @@ checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e"
[[package]] [[package]]
name = "is-terminal" name = "is-terminal"
version = "0.4.1" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
dependencies = [ dependencies = [
"hermit-abi 0.2.6", "hermit-abi 0.2.6",
"io-lifetimes", "io-lifetimes",
@ -2300,9 +2300,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.138" version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]] [[package]]
name = "libloading" name = "libloading"
@ -2631,11 +2631,11 @@ dependencies = [
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.14.0" version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [ dependencies = [
"hermit-abi 0.1.19", "hermit-abi 0.2.6",
"libc", "libc",
] ]
@ -2855,9 +2855,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]] [[package]]
name = "pest" name = "pest"
version = "2.5.1" version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" checksum = "0f6e86fb9e7026527a0d46bc308b841d73170ef8f443e1807f6ef88526a816d4"
dependencies = [ dependencies = [
"thiserror", "thiserror",
"ucd-trie", "ucd-trie",
@ -2966,9 +2966,9 @@ dependencies = [
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "0.3.18" version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81bdd679d533107e090c2704a35982fc06302e30898e63ffa26a81155c012e92" checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b"
[[package]] [[package]]
name = "postcard" name = "postcard"
@ -3311,7 +3311,7 @@ dependencies = [
name = "reth" name = "reth"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clap 4.0.29", "clap 4.0.32",
"confy", "confy",
"dirs-next", "dirs-next",
"eyre", "eyre",
@ -3854,9 +3854,11 @@ dependencies = [
"bitflags", "bitflags",
"fnv", "fnv",
"futures-util", "futures-util",
"metrics",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"paste", "paste",
"rand 0.8.5", "rand 0.8.5",
"reth-metrics-derive",
"reth-primitives", "reth-primitives",
"serde", "serde",
"thiserror", "thiserror",
@ -3867,7 +3869,7 @@ dependencies = [
[[package]] [[package]]
name = "revm" name = "revm"
version = "2.3.1" version = "2.3.1"
source = "git+https://github.com/bluealloy/revm?branch=main#488ef8ab62f433b1b434d2d81bc744a2db8f735f" source = "git+https://github.com/bluealloy/revm?branch=main#85f2b549631e597f2199ff4b5d58e5fb1c66ea4d"
dependencies = [ dependencies = [
"arrayref", "arrayref",
"auto_impl", "auto_impl",
@ -3887,7 +3889,7 @@ dependencies = [
[[package]] [[package]]
name = "revm_precompiles" name = "revm_precompiles"
version = "1.1.2" version = "1.1.2"
source = "git+https://github.com/bluealloy/revm?branch=main#488ef8ab62f433b1b434d2d81bc744a2db8f735f" source = "git+https://github.com/bluealloy/revm?branch=main#85f2b549631e597f2199ff4b5d58e5fb1c66ea4d"
dependencies = [ dependencies = [
"bytes", "bytes",
"hashbrown 0.13.1", "hashbrown 0.13.1",
@ -4000,9 +4002,9 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.36.5" version = "0.36.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"errno", "errno",
@ -4231,18 +4233,18 @@ checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.151" version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.151" version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@ -26,6 +26,10 @@ futures-util = "0.3"
parking_lot = "0.12" parking_lot = "0.12"
tokio = { version = "1", default-features = false, features = ["sync"] } tokio = { version = "1", default-features = false, features = ["sync"] }
# rpc/metrics
metrics = "0.20.1"
reth-metrics-derive = { path = "../metrics/metrics-derive" }
# misc # misc
aquamarine = "0.1" # docs aquamarine = "0.1" # docs
thiserror = "1.0" thiserror = "1.0"

View File

@ -101,6 +101,7 @@ use tokio::sync::mpsc::Receiver;
mod config; mod config;
pub mod error; pub mod error;
mod identifier; mod identifier;
pub mod metrics;
mod ordering; mod ordering;
pub mod pool; pub mod pool;
mod traits; mod traits;

View File

@ -0,0 +1,16 @@
//! Transaction pool metrics.
use metrics::Counter;
use reth_metrics_derive::Metrics;
/// Transaction pool metrics
#[derive(Metrics)]
#[metrics(scope = "transaction_pool")]
pub struct TxPoolMetrics {
/// Number of transactions inserted in the pool
pub(crate) inserted_transactions: Counter,
/// Number of invalid transactions
pub(crate) invalid_transactions: Counter,
/// Number of removed transactions from the pool
pub(crate) removed_transactions: Counter,
}

View File

@ -3,6 +3,7 @@ use crate::{
config::MAX_ACCOUNT_SLOTS_PER_SENDER, config::MAX_ACCOUNT_SLOTS_PER_SENDER,
error::PoolError, error::PoolError,
identifier::{SenderId, TransactionId}, identifier::{SenderId, TransactionId},
metrics::TxPoolMetrics,
pool::{ pool::{
best::BestTransactions, best::BestTransactions,
parked::{BasefeeOrd, ParkedPool, QueuedOrd}, parked::{BasefeeOrd, ParkedPool, QueuedOrd},
@ -85,6 +86,8 @@ pub struct TxPool<T: TransactionOrdering> {
basefee_pool: ParkedPool<BasefeeOrd<T::Transaction>>, basefee_pool: ParkedPool<BasefeeOrd<T::Transaction>>,
/// All transactions in the pool. /// All transactions in the pool.
all_transactions: AllTransactions<T::Transaction>, all_transactions: AllTransactions<T::Transaction>,
/// Transaction pool metrics
metrics: TxPoolMetrics,
} }
// === impl TxPool === // === impl TxPool ===
@ -99,6 +102,7 @@ impl<T: TransactionOrdering> TxPool<T> {
basefee_pool: Default::default(), basefee_pool: Default::default(),
all_transactions: AllTransactions::new(config.max_account_slots), all_transactions: AllTransactions::new(config.max_account_slots),
config, config,
metrics: Default::default(),
} }
} }
@ -161,6 +165,8 @@ impl<T: TransactionOrdering> TxPool<T> {
// Remove all transaction that were included in the block // Remove all transaction that were included in the block
for tx_hash in &event.mined_transactions { for tx_hash in &event.mined_transactions {
self.remove_transaction_by_hash(tx_hash); self.remove_transaction_by_hash(tx_hash);
// Update removed transactions metric
self.metrics.removed_transactions.increment(1);
} }
// Apply the state changes to the total set of transactions which triggers sub-pool updates. // Apply the state changes to the total set of transactions which triggers sub-pool updates.
@ -215,6 +221,8 @@ impl<T: TransactionOrdering> TxPool<T> {
match self.all_transactions.insert_tx(tx, on_chain_balance, on_chain_nonce) { match self.all_transactions.insert_tx(tx, on_chain_balance, on_chain_nonce) {
Ok(InsertOk { transaction, move_to, replaced_tx, updates, .. }) => { Ok(InsertOk { transaction, move_to, replaced_tx, updates, .. }) => {
self.add_new_transaction(transaction.clone(), replaced_tx, move_to); self.add_new_transaction(transaction.clone(), replaced_tx, move_to);
// Update inserted transactions metric
self.metrics.inserted_transactions.increment(1);
let UpdateOutcome { promoted, discarded, removed } = self.process_updates(updates); let UpdateOutcome { promoted, discarded, removed } = self.process_updates(updates);
// This transaction was moved to the pending pool. // This transaction was moved to the pending pool.
@ -231,14 +239,23 @@ impl<T: TransactionOrdering> TxPool<T> {
Ok(res) Ok(res)
} }
Err(InsertErr::Underpriced { existing, .. }) => { Err(e) => {
Err(PoolError::ReplacementUnderpriced(existing)) // Update invalid transactions metric
} self.metrics.invalid_transactions.increment(1);
Err(InsertErr::ProtocolFeeCapTooLow { transaction, fee_cap }) => { match e {
Err(PoolError::ProtocolFeeCapTooLow(*transaction.hash(), fee_cap)) InsertErr::Underpriced { existing, .. } => {
} Err(PoolError::ReplacementUnderpriced(existing))
Err(InsertErr::ExceededSenderTransactionsCapacity { transaction }) => { }
Err(PoolError::SpammerExceededCapacity(transaction.sender(), *transaction.hash())) InsertErr::ProtocolFeeCapTooLow { transaction, fee_cap } => {
Err(PoolError::ProtocolFeeCapTooLow(*transaction.hash(), fee_cap))
}
InsertErr::ExceededSenderTransactionsCapacity { transaction } => {
Err(PoolError::SpammerExceededCapacity(
transaction.sender(),
*transaction.hash(),
))
}
}
} }
} }
} }

View File

@ -64,6 +64,11 @@ How the metrics are exposed to the end-user is determined by the CLI.
- `stages.headers.unexpected_errors`: Number of unexpected errors while requesting headers - `stages.headers.unexpected_errors`: Number of unexpected errors while requesting headers
- `stages.headers.request_time`: Elapsed time of successful header requests - `stages.headers.request_time`: Elapsed time of successful header requests
#### Transaction Pool
- `transaction_pool.inserted_transactions`: Number of transactions inserted in the pool
- `transaction_pool.invalid_transactions`: Number of invalid transactions
- `transaction_pool.removed_transactions`: Number of removed transactions from the pool
[metrics]: https://docs.rs/metrics [metrics]: https://docs.rs/metrics
[metrics.Key]: https://docs.rs/metrics/latest/metrics/struct.Key.html [metrics.Key]: https://docs.rs/metrics/latest/metrics/struct.Key.html
[metrics.KeyName]: https://docs.rs/metrics/latest/metrics/struct.KeyName.html [metrics.KeyName]: https://docs.rs/metrics/latest/metrics/struct.KeyName.html