1use crate::cli::config::RethTransactionPoolConfig;
4use alloy_eips::eip1559::{ETHEREUM_BLOCK_GAS_LIMIT, MIN_PROTOCOL_BASE_FEE};
5use alloy_primitives::Address;
6use clap::Args;
7use reth_transaction_pool::{
8 blobstore::disk::DEFAULT_MAX_CACHED_BLOBS,
9 pool::{NEW_TX_LISTENER_BUFFER_SIZE, PENDING_TX_LISTENER_BUFFER_SIZE},
10 validate::DEFAULT_MAX_TX_INPUT_BYTES,
11 LocalTransactionConfig, PoolConfig, PriceBumpConfig, SubPoolLimit, DEFAULT_PRICE_BUMP,
12 DEFAULT_TXPOOL_ADDITIONAL_VALIDATION_TASKS, MAX_NEW_PENDING_TXS_NOTIFICATIONS,
13 REPLACE_BLOB_PRICE_BUMP, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER,
14 TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, TXPOOL_SUBPOOL_MAX_TXS_DEFAULT,
15};
16#[derive(Debug, Clone, Args, PartialEq, Eq)]
18#[command(next_help_heading = "TxPool")]
19pub struct TxPoolArgs {
20 #[arg(long = "txpool.pending-max-count", alias = "txpool.pending_max_count", default_value_t = TXPOOL_SUBPOOL_MAX_TXS_DEFAULT)]
22 pub pending_max_count: usize,
23 #[arg(long = "txpool.pending-max-size", alias = "txpool.pending_max_size", default_value_t = TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT)]
25 pub pending_max_size: usize,
26
27 #[arg(long = "txpool.basefee-max-count", alias = "txpool.basefee_max_count", default_value_t = TXPOOL_SUBPOOL_MAX_TXS_DEFAULT)]
29 pub basefee_max_count: usize,
30 #[arg(long = "txpool.basefee-max-size", alias = "txpool.basefee_max_size", default_value_t = TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT)]
32 pub basefee_max_size: usize,
33
34 #[arg(long = "txpool.queued-max-count", alias = "txpool.queued_max_count", default_value_t = TXPOOL_SUBPOOL_MAX_TXS_DEFAULT)]
36 pub queued_max_count: usize,
37 #[arg(long = "txpool.queued-max-size", alias = "txpool.queued_max_size", default_value_t = TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT)]
39 pub queued_max_size: usize,
40
41 #[arg(long = "txpool.max-account-slots", alias = "txpool.max_account_slots", default_value_t = TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER)]
43 pub max_account_slots: usize,
44
45 #[arg(long = "txpool.pricebump", default_value_t = DEFAULT_PRICE_BUMP)]
47 pub price_bump: u128,
48
49 #[arg(long = "txpool.minimal-protocol-fee", default_value_t = MIN_PROTOCOL_BASE_FEE)]
51 pub minimal_protocol_basefee: u64,
52
53 #[arg(long = "txpool.gas-limit", default_value_t = ETHEREUM_BLOCK_GAS_LIMIT)]
55 pub enforced_gas_limit: u64,
56
57 #[arg(long = "blobpool.pricebump", default_value_t = REPLACE_BLOB_PRICE_BUMP)]
59 pub blob_transaction_price_bump: u128,
60
61 #[arg(long = "txpool.max-tx-input-bytes", alias = "txpool.max_tx_input_bytes", default_value_t = DEFAULT_MAX_TX_INPUT_BYTES)]
63 pub max_tx_input_bytes: usize,
64
65 #[arg(long = "txpool.max-cached-entries", alias = "txpool.max_cached_entries", default_value_t = DEFAULT_MAX_CACHED_BLOBS)]
67 pub max_cached_entries: u32,
68
69 #[arg(long = "txpool.nolocals")]
71 pub no_locals: bool,
72 #[arg(long = "txpool.locals")]
74 pub locals: Vec<Address>,
75 #[arg(long = "txpool.no-local-transactions-propagation")]
77 pub no_local_transactions_propagation: bool,
78 #[arg(long = "txpool.additional-validation-tasks", alias = "txpool.additional_validation_tasks", default_value_t = DEFAULT_TXPOOL_ADDITIONAL_VALIDATION_TASKS)]
80 pub additional_validation_tasks: usize,
81
82 #[arg(long = "txpool.max-pending-txns", alias = "txpool.max_pending_txns", default_value_t = PENDING_TX_LISTENER_BUFFER_SIZE)]
84 pub pending_tx_listener_buffer_size: usize,
85
86 #[arg(long = "txpool.max-new-txns", alias = "txpool.max_new_txns", default_value_t = NEW_TX_LISTENER_BUFFER_SIZE)]
88 pub new_tx_listener_buffer_size: usize,
89
90 #[arg(long = "txpool.max-new-pending-txs-notifications", alias = "txpool.max-new-pending-txs-notifications", default_value_t = MAX_NEW_PENDING_TXS_NOTIFICATIONS)]
93 pub max_new_pending_txs_notifications: usize,
94}
95
96impl Default for TxPoolArgs {
97 fn default() -> Self {
98 Self {
99 pending_max_count: TXPOOL_SUBPOOL_MAX_TXS_DEFAULT,
100 pending_max_size: TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT,
101 basefee_max_count: TXPOOL_SUBPOOL_MAX_TXS_DEFAULT,
102 basefee_max_size: TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT,
103 queued_max_count: TXPOOL_SUBPOOL_MAX_TXS_DEFAULT,
104 queued_max_size: TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT,
105 max_account_slots: TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER,
106 price_bump: DEFAULT_PRICE_BUMP,
107 minimal_protocol_basefee: MIN_PROTOCOL_BASE_FEE,
108 enforced_gas_limit: ETHEREUM_BLOCK_GAS_LIMIT,
109 blob_transaction_price_bump: REPLACE_BLOB_PRICE_BUMP,
110 max_tx_input_bytes: DEFAULT_MAX_TX_INPUT_BYTES,
111 max_cached_entries: DEFAULT_MAX_CACHED_BLOBS,
112 no_locals: false,
113 locals: Default::default(),
114 no_local_transactions_propagation: false,
115 additional_validation_tasks: DEFAULT_TXPOOL_ADDITIONAL_VALIDATION_TASKS,
116 pending_tx_listener_buffer_size: PENDING_TX_LISTENER_BUFFER_SIZE,
117 new_tx_listener_buffer_size: NEW_TX_LISTENER_BUFFER_SIZE,
118 max_new_pending_txs_notifications: MAX_NEW_PENDING_TXS_NOTIFICATIONS,
119 }
120 }
121}
122
123impl RethTransactionPoolConfig for TxPoolArgs {
124 fn pool_config(&self) -> PoolConfig {
126 PoolConfig {
127 local_transactions_config: LocalTransactionConfig {
128 no_exemptions: self.no_locals,
129 local_addresses: self.locals.clone().into_iter().collect(),
130 propagate_local_transactions: !self.no_local_transactions_propagation,
131 },
132 pending_limit: SubPoolLimit {
133 max_txs: self.pending_max_count,
134 max_size: self.pending_max_size.saturating_mul(1024 * 1024),
135 },
136 basefee_limit: SubPoolLimit {
137 max_txs: self.basefee_max_count,
138 max_size: self.basefee_max_size.saturating_mul(1024 * 1024),
139 },
140 queued_limit: SubPoolLimit {
141 max_txs: self.queued_max_count,
142 max_size: self.queued_max_size.saturating_mul(1024 * 1024),
143 },
144 blob_limit: SubPoolLimit {
145 max_txs: self.queued_max_count,
146 max_size: self.queued_max_size.saturating_mul(1024 * 1024),
147 },
148 max_account_slots: self.max_account_slots,
149 price_bumps: PriceBumpConfig {
150 default_price_bump: self.price_bump,
151 replace_blob_tx_price_bump: self.blob_transaction_price_bump,
152 },
153 minimal_protocol_basefee: self.minimal_protocol_basefee,
154 gas_limit: self.enforced_gas_limit,
155 pending_tx_listener_buffer_size: self.pending_tx_listener_buffer_size,
156 new_tx_listener_buffer_size: self.new_tx_listener_buffer_size,
157 max_new_pending_txs_notifications: self.max_new_pending_txs_notifications,
158 }
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165 use clap::Parser;
166
167 #[derive(Parser)]
169 struct CommandParser<T: Args> {
170 #[command(flatten)]
171 args: T,
172 }
173
174 #[test]
175 fn txpool_args_default_sanity_test() {
176 let default_args = TxPoolArgs::default();
177 let args = CommandParser::<TxPoolArgs>::parse_from(["reth"]).args;
178 assert_eq!(args, default_args);
179 }
180
181 #[test]
182 fn txpool_parse_locals() {
183 let args = CommandParser::<TxPoolArgs>::parse_from([
184 "reth",
185 "--txpool.locals",
186 "0x0000000000000000000000000000000000000000",
187 ])
188 .args;
189 assert_eq!(args.locals, vec![Address::ZERO]);
190 }
191}