瀏覽代碼

agave-validator: add args tests for run (part 6) (#7620)

* init

* --rpc-send-retry-ms

* --rpc-send-batch-size

* --rpc-send-batch-ms

* --rpc-send-default-max-retries

* --rpc-send-service-max-retries

* --rpc-send-transaction-retry-pool-max-size

* --rpc-send-transaction-tpu-peer

* leader_forward_count

* move the comparison into the args parsing (1)

* move the comparison into the args parsing (2)

* use run_args.send_transaction_service_config directly

* remove useless default

* rename var: rpc_send_batch_send_rate_ms -> batch_send_rate_ms

* rename var: rpc_send_retry_rate_ms -> retry_rate_ms

* more test cases

* use crate::commands::Error

* lint

* batch_size

* default_max_retries

* service_max_retries

* retry_pool_max_size

* lint
Yihau Chen 2 月之前
父節點
當前提交
279f1eed10

+ 1 - 1
send-transaction-service/src/send_transaction_service.rs

@@ -122,7 +122,7 @@ struct ProcessTransactionsResult {
     last_sent_time: Option<Instant>,
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq)]
 pub struct Config {
     pub retry_rate_ms: u64,
     pub leader_forward_count: u64,

+ 8 - 1
validator/src/commands/run/args.rs

@@ -26,7 +26,7 @@ use {
     solana_rpc::{rpc::JsonRpcConfig, rpc_pubsub_service::PubSubConfig},
     solana_runtime::snapshot_utils::{SnapshotVersion, SUPPORTED_ARCHIVE_COMPRESSION},
     solana_send_transaction_service::send_transaction_service::{
-        MAX_BATCH_SEND_RATE_MS, MAX_TRANSACTION_BATCH_SIZE,
+        Config as SendTransactionServiceConfig, MAX_BATCH_SEND_RATE_MS, MAX_TRANSACTION_BATCH_SIZE,
     },
     solana_signer::Signer,
     solana_streamer::socket::SocketAddrSpace,
@@ -62,6 +62,7 @@ pub mod json_rpc_config;
 pub mod pub_sub_config;
 pub mod rpc_bigtable_config;
 pub mod rpc_bootstrap_config;
+pub mod send_transaction_config;
 
 #[derive(Debug, PartialEq)]
 pub struct RunArgs {
@@ -74,6 +75,7 @@ pub struct RunArgs {
     pub blockstore_options: BlockstoreOptions,
     pub json_rpc_config: JsonRpcConfig,
     pub pub_sub_config: PubSubConfig,
+    pub send_transaction_service_config: SendTransactionServiceConfig,
 }
 
 impl FromClapArgMatches for RunArgs {
@@ -123,6 +125,9 @@ impl FromClapArgMatches for RunArgs {
             blockstore_options: BlockstoreOptions::from_clap_arg_match(matches)?,
             json_rpc_config: JsonRpcConfig::from_clap_arg_match(matches)?,
             pub_sub_config: PubSubConfig::from_clap_arg_match(matches)?,
+            send_transaction_service_config: SendTransactionServiceConfig::from_clap_arg_match(
+                matches,
+            )?,
         })
     }
 }
@@ -1752,6 +1757,7 @@ mod tests {
                         solana_rpc::rpc_pubsub_service::DEFAULT_QUEUE_CAPACITY_ITEMS,
                     ..PubSubConfig::default_for_tests()
                 },
+                send_transaction_service_config: SendTransactionServiceConfig::default(),
             }
         }
     }
@@ -1768,6 +1774,7 @@ mod tests {
                 blockstore_options: self.blockstore_options.clone(),
                 json_rpc_config: self.json_rpc_config.clone(),
                 pub_sub_config: self.pub_sub_config.clone(),
+                send_transaction_service_config: self.send_transaction_service_config.clone(),
             }
         }
     }

+ 324 - 0
validator/src/commands/run/args/send_transaction_config.rs

@@ -0,0 +1,324 @@
+use {
+    crate::commands::{Error, FromClapArgMatches, Result},
+    clap::{value_t, ArgMatches},
+    solana_send_transaction_service::send_transaction_service::{
+        Config as SendTransactionServiceConfig, MAX_TRANSACTION_SENDS_PER_SECOND,
+    },
+};
+
+impl FromClapArgMatches for SendTransactionServiceConfig {
+    fn from_clap_arg_match(matches: &ArgMatches) -> Result<Self> {
+        let batch_send_rate_ms = value_t!(matches, "rpc_send_transaction_batch_ms", u64)?;
+        let retry_rate_ms = value_t!(matches, "rpc_send_transaction_retry_ms", u64)?;
+        if batch_send_rate_ms > retry_rate_ms {
+            return Err(Error::Dynamic(Box::<dyn std::error::Error>::from(format!(
+                "the specified rpc-send-batch-ms ({batch_send_rate_ms}) is invalid, it must be <= \
+                 rpc-send-retry-ms ({retry_rate_ms})"
+            ))));
+        }
+
+        let batch_size = value_t!(matches, "rpc_send_transaction_batch_size", usize)?;
+        let millis_per_second = 1000;
+        let tps = batch_size as u64 * millis_per_second / batch_send_rate_ms;
+        if tps > MAX_TRANSACTION_SENDS_PER_SECOND {
+            return Err(Error::Dynamic(Box::<dyn std::error::Error>::from(format!(
+                "either the specified rpc-send-batch-size ({batch_size}) or rpc-send-batch-ms \
+                 ({batch_send_rate_ms}) is invalid, 'rpc-send-batch-size * 1000 / \
+                 rpc-send-batch-ms' must be smaller than ({MAX_TRANSACTION_SENDS_PER_SECOND}) .",
+            ))));
+        }
+
+        let tpu_peers = matches
+            .values_of("rpc_send_transaction_tpu_peer")
+            .map(|values| values.map(solana_net_utils::parse_host_port).collect())
+            .transpose()
+            .map_err(|e| {
+                Error::Dynamic(Box::<dyn std::error::Error>::from(format!(
+                    "Invalid tpu peer address: {e}",
+                )))
+            })?;
+
+        let default_max_retries =
+            value_t!(matches, "rpc_send_transaction_default_max_retries", usize).ok();
+
+        let service_max_retries =
+            value_t!(matches, "rpc_send_transaction_service_max_retries", usize)?;
+
+        let retry_pool_max_size =
+            value_t!(matches, "rpc_send_transaction_retry_pool_max_size", usize)?;
+
+        let rpc_send_transaction_also_leader =
+            matches.is_present("rpc_send_transaction_also_leader");
+        let leader_forward_count = if tpu_peers.is_some() && !rpc_send_transaction_also_leader {
+            // rpc-sts is configured to send only to specific tpu peers. disable leader forwards
+            0
+        } else {
+            value_t!(matches, "rpc_send_transaction_leader_forward_count", u64)?
+        };
+
+        Ok(SendTransactionServiceConfig {
+            retry_rate_ms,
+            batch_size,
+            batch_send_rate_ms,
+            default_max_retries,
+            service_max_retries,
+            retry_pool_max_size,
+            tpu_peers,
+            leader_forward_count,
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use {
+        super::*,
+        crate::commands::run::args::{
+            tests::verify_args_struct_by_command_run_with_identity_setup, RunArgs,
+        },
+        std::net::{Ipv4Addr, SocketAddr},
+    };
+
+    #[test]
+    fn verify_args_struct_by_command_run_with_retry_rate_ms() {
+        let default_run_args = RunArgs::default();
+        let expected_args = RunArgs {
+            send_transaction_service_config: SendTransactionServiceConfig {
+                retry_rate_ms: 99999,
+                ..default_run_args.send_transaction_service_config.clone()
+            },
+            ..default_run_args.clone()
+        };
+        verify_args_struct_by_command_run_with_identity_setup(
+            default_run_args,
+            vec!["--rpc-send-retry-ms", "99999"],
+            expected_args,
+        );
+    }
+
+    #[test]
+    fn verify_args_struct_by_command_run_with_batch_size() {
+        {
+            let default_run_args = RunArgs::default();
+            let expected_args = RunArgs {
+                send_transaction_service_config: SendTransactionServiceConfig {
+                    batch_size: 1,
+                    ..default_run_args.send_transaction_service_config.clone()
+                },
+                ..default_run_args.clone()
+            };
+            verify_args_struct_by_command_run_with_identity_setup(
+                default_run_args,
+                vec!["--rpc-send-batch-size", "1"],
+                expected_args,
+            );
+        }
+
+        {
+            let default_run_args = RunArgs::default();
+            let expected_args = RunArgs {
+                send_transaction_service_config: SendTransactionServiceConfig {
+                    batch_size: 999,
+                    batch_send_rate_ms: 1000,
+                    ..default_run_args.send_transaction_service_config.clone()
+                },
+                ..default_run_args.clone()
+            };
+            verify_args_struct_by_command_run_with_identity_setup(
+                default_run_args,
+                vec![
+                    "--rpc-send-batch-size",
+                    "999",
+                    "--rpc-send-batch-ms",
+                    "1000",
+                ],
+                expected_args,
+            );
+        }
+    }
+
+    #[test]
+    fn verify_args_struct_by_command_run_with_batch_send_rate_ms() {
+        let default_run_args = RunArgs::default();
+        let expected_args = RunArgs {
+            send_transaction_service_config: SendTransactionServiceConfig {
+                batch_send_rate_ms: 1999,
+                ..default_run_args.send_transaction_service_config.clone()
+            },
+            ..default_run_args.clone()
+        };
+        verify_args_struct_by_command_run_with_identity_setup(
+            default_run_args,
+            vec!["--rpc-send-batch-ms", "1999"],
+            expected_args,
+        );
+    }
+
+    #[test]
+    fn verify_args_struct_by_command_run_with_default_max_retries() {
+        let default_run_args = RunArgs::default();
+        let expected_args = RunArgs {
+            send_transaction_service_config: SendTransactionServiceConfig {
+                default_max_retries: Some(9999),
+                ..default_run_args.send_transaction_service_config.clone()
+            },
+            ..default_run_args.clone()
+        };
+        verify_args_struct_by_command_run_with_identity_setup(
+            default_run_args,
+            vec!["--rpc-send-default-max-retries", "9999"],
+            expected_args,
+        );
+    }
+
+    #[test]
+    fn verify_args_struct_by_command_run_with_service_max_retries() {
+        let default_run_args = RunArgs::default();
+        let expected_args = RunArgs {
+            send_transaction_service_config: SendTransactionServiceConfig {
+                service_max_retries: 9999,
+                ..default_run_args.send_transaction_service_config.clone()
+            },
+            ..default_run_args.clone()
+        };
+        verify_args_struct_by_command_run_with_identity_setup(
+            default_run_args,
+            vec!["--rpc-send-service-max-retries", "9999"],
+            expected_args,
+        );
+    }
+
+    #[test]
+    fn verify_args_struct_by_command_run_with_retry_pool_max_size() {
+        let default_run_args = RunArgs::default();
+        let expected_args = RunArgs {
+            send_transaction_service_config: SendTransactionServiceConfig {
+                retry_pool_max_size: 9999,
+                ..default_run_args.send_transaction_service_config.clone()
+            },
+            ..default_run_args.clone()
+        };
+        verify_args_struct_by_command_run_with_identity_setup(
+            default_run_args,
+            vec!["--rpc-send-transaction-retry-pool-max-size", "9999"],
+            expected_args,
+        );
+    }
+
+    #[test]
+    fn verify_args_struct_by_command_run_with_tpu_peers() {
+        // single tpu peer
+        {
+            let default_run_args = RunArgs::default();
+            let expected_args = RunArgs {
+                send_transaction_service_config: SendTransactionServiceConfig {
+                    tpu_peers: Some(vec![SocketAddr::from((Ipv4Addr::LOCALHOST, 8000))]),
+                    leader_forward_count: 0, // see SendTransactionServiceConfig::from_clap_arg_match for more details
+                    ..default_run_args.send_transaction_service_config.clone()
+                },
+                ..default_run_args.clone()
+            };
+            verify_args_struct_by_command_run_with_identity_setup(
+                default_run_args,
+                vec!["--rpc-send-transaction-tpu-peer", "127.0.0.1:8000"],
+                expected_args,
+            );
+        }
+
+        // multiple tpu peers
+        {
+            let default_run_args = RunArgs::default();
+            let expected_args = RunArgs {
+                send_transaction_service_config: SendTransactionServiceConfig {
+                    tpu_peers: Some(vec![
+                        SocketAddr::from((Ipv4Addr::LOCALHOST, 8000)),
+                        SocketAddr::from((Ipv4Addr::LOCALHOST, 8001)),
+                        SocketAddr::from((Ipv4Addr::LOCALHOST, 8002)),
+                    ]),
+                    leader_forward_count: 0, // see SendTransactionServiceConfig::from_clap_arg_match for more details
+                    ..default_run_args.send_transaction_service_config.clone()
+                },
+                ..default_run_args.clone()
+            };
+            verify_args_struct_by_command_run_with_identity_setup(
+                default_run_args,
+                vec![
+                    "--rpc-send-transaction-tpu-peer",
+                    "127.0.0.1:8000",
+                    "--rpc-send-transaction-tpu-peer",
+                    "127.0.0.1:8001",
+                    "--rpc-send-transaction-tpu-peer",
+                    "127.0.0.1:8002",
+                ],
+                expected_args,
+            );
+        }
+    }
+
+    #[test]
+    fn verify_args_struct_by_command_run_with_rpc_send_transaction_leader_forward_count() {
+        // rpc-send-transaction-leader-forward-count
+        {
+            let default_run_args = RunArgs::default();
+            let expected_args = RunArgs {
+                send_transaction_service_config: SendTransactionServiceConfig {
+                    leader_forward_count: 100,
+                    ..default_run_args.send_transaction_service_config.clone()
+                },
+                ..default_run_args.clone()
+            };
+            verify_args_struct_by_command_run_with_identity_setup(
+                default_run_args,
+                vec!["--rpc-send-leader-count", "100"],
+                expected_args,
+            );
+        }
+
+        // rpc-send-transaction-leader-forward-count + rpc-send-transaction-tpu-peer
+        {
+            let default_run_args = RunArgs::default();
+            let expected_args = RunArgs {
+                send_transaction_service_config: SendTransactionServiceConfig {
+                    leader_forward_count: 0,
+                    tpu_peers: Some(vec![SocketAddr::from((Ipv4Addr::LOCALHOST, 8000))]),
+                    ..default_run_args.send_transaction_service_config.clone()
+                },
+                ..default_run_args.clone()
+            };
+            verify_args_struct_by_command_run_with_identity_setup(
+                default_run_args,
+                vec![
+                    "--rpc-send-transaction-tpu-peer",
+                    "127.0.0.1:8000",
+                    "--rpc-send-leader-count",
+                    "100",
+                ],
+                expected_args,
+            );
+        }
+
+        // rpc-send-transaction-leader-forward-count + rpc-send-transaction-also-leader + rpc-send-transaction-tpu-peer
+        {
+            let default_run_args = RunArgs::default();
+            let expected_args = RunArgs {
+                send_transaction_service_config: SendTransactionServiceConfig {
+                    tpu_peers: Some(vec![SocketAddr::from((Ipv4Addr::LOCALHOST, 8000))]),
+                    leader_forward_count: 100,
+                    ..default_run_args.send_transaction_service_config.clone()
+                },
+                ..default_run_args.clone()
+            };
+            verify_args_struct_by_command_run_with_identity_setup(
+                default_run_args,
+                vec![
+                    "--rpc-send-transaction-tpu-peer",
+                    "127.0.0.1:8000",
+                    "--rpc-send-transaction-also-leader",
+                    "--rpc-send-leader-count",
+                    "100",
+                ],
+                expected_args,
+            );
+        }
+    }
+}

+ 1 - 68
validator/src/commands/run/execute.rs

@@ -59,7 +59,6 @@ use {
             self, ArchiveFormat, SnapshotInterval, SnapshotVersion, BANK_SNAPSHOTS_DIR,
         },
     },
-    solana_send_transaction_service::send_transaction_service,
     solana_signer::Signer,
     solana_streamer::quic::{QuicServerParams, DEFAULT_TPU_COALESCE},
     solana_tpu_client::tpu_client::DEFAULT_TPU_ENABLE_UDP,
@@ -87,8 +86,6 @@ pub enum Operation {
     Run,
 }
 
-const MILLIS_PER_SECOND: u64 = 1000;
-
 pub fn execute(
     matches: &ArgMatches,
     solana_version: &str,
@@ -460,48 +457,6 @@ pub fn execute(
     let starting_with_geyser_plugins: bool = on_start_geyser_plugin_config_files.is_some()
         || matches.is_present("geyser_plugin_always_enabled");
 
-    let rpc_send_retry_rate_ms = value_t_or_exit!(matches, "rpc_send_transaction_retry_ms", u64);
-    let rpc_send_batch_size = value_t_or_exit!(matches, "rpc_send_transaction_batch_size", usize);
-    let rpc_send_batch_send_rate_ms =
-        value_t_or_exit!(matches, "rpc_send_transaction_batch_ms", u64);
-
-    if rpc_send_batch_send_rate_ms > rpc_send_retry_rate_ms {
-        Err(format!(
-            "the specified rpc-send-batch-ms ({rpc_send_batch_send_rate_ms}) is invalid, it must \
-             be <= rpc-send-retry-ms ({rpc_send_retry_rate_ms})"
-        ))?;
-    }
-
-    let tps = rpc_send_batch_size as u64 * MILLIS_PER_SECOND / rpc_send_batch_send_rate_ms;
-    if tps > send_transaction_service::MAX_TRANSACTION_SENDS_PER_SECOND {
-        Err(format!(
-            "either the specified rpc-send-batch-size ({}) or rpc-send-batch-ms ({}) is invalid, \
-             'rpc-send-batch-size * 1000 / rpc-send-batch-ms' must be smaller than ({}) .",
-            rpc_send_batch_size,
-            rpc_send_batch_send_rate_ms,
-            send_transaction_service::MAX_TRANSACTION_SENDS_PER_SECOND
-        ))?;
-    }
-    let rpc_send_transaction_tpu_peers = matches
-        .values_of("rpc_send_transaction_tpu_peer")
-        .map(|values| {
-            values
-                .map(solana_net_utils::parse_host_port)
-                .collect::<Result<Vec<SocketAddr>, String>>()
-        })
-        .transpose()
-        .map_err(|err| {
-            format!("failed to parse rpc send-transaction-service tpu peer address: {err}")
-        })?;
-    let rpc_send_transaction_also_leader = matches.is_present("rpc_send_transaction_also_leader");
-    let leader_forward_count =
-        if rpc_send_transaction_tpu_peers.is_some() && !rpc_send_transaction_also_leader {
-            // rpc-sts is configured to send only to specific tpu peers. disable leader forwards
-            0
-        } else {
-            value_t_or_exit!(matches, "rpc_send_transaction_leader_forward_count", u64)
-        };
-
     let xdp_interface = matches.value_of("retransmit_xdp_interface");
     let xdp_zero_copy = matches.is_present("retransmit_xdp_zero_copy");
     let retransmit_xdp = matches.value_of("retransmit_xdp_cpu_cores").map(|cpus| {
@@ -607,29 +562,7 @@ pub fn execute(
         generator_config: None,
         contact_debug_interval,
         contact_save_interval: DEFAULT_CONTACT_SAVE_INTERVAL_MILLIS,
-        send_transaction_service_config: send_transaction_service::Config {
-            retry_rate_ms: rpc_send_retry_rate_ms,
-            leader_forward_count,
-            default_max_retries: value_t!(
-                matches,
-                "rpc_send_transaction_default_max_retries",
-                usize
-            )
-            .ok(),
-            service_max_retries: value_t_or_exit!(
-                matches,
-                "rpc_send_transaction_service_max_retries",
-                usize
-            ),
-            batch_send_rate_ms: rpc_send_batch_send_rate_ms,
-            batch_size: rpc_send_batch_size,
-            retry_pool_max_size: value_t_or_exit!(
-                matches,
-                "rpc_send_transaction_retry_pool_max_size",
-                usize
-            ),
-            tpu_peers: rpc_send_transaction_tpu_peers,
-        },
+        send_transaction_service_config: run_args.send_transaction_service_config,
         no_poh_speed_test: matches.is_present("no_poh_speed_test"),
         no_os_memory_stats_reporting: matches.is_present("no_os_memory_stats_reporting"),
         no_os_network_stats_reporting: matches.is_present("no_os_network_stats_reporting"),