bench_tps.rs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #![allow(clippy::arithmetic_side_effects)]
  2. use {
  3. serial_test::serial,
  4. solana_account::{Account, AccountSharedData},
  5. solana_bench_tps::{
  6. bench::{do_bench_tps, generate_and_fund_keypairs},
  7. cli::{Config, InstructionPaddingConfig},
  8. send_batch::generate_durable_nonce_accounts,
  9. },
  10. solana_commitment_config::CommitmentConfig,
  11. solana_connection_cache::connection_cache::NewConnectionConfig,
  12. solana_core::validator::ValidatorConfig,
  13. solana_faucet::faucet::run_local_faucet_for_tests,
  14. solana_fee_calculator::FeeRateGovernor,
  15. solana_keypair::Keypair,
  16. solana_local_cluster::{
  17. cluster::Cluster,
  18. local_cluster::{ClusterConfig, LocalCluster},
  19. validator_configs::make_identical_validator_configs,
  20. },
  21. solana_net_utils::SocketAddrSpace,
  22. solana_quic_client::{QuicConfig, QuicConnectionManager},
  23. solana_rent::Rent,
  24. solana_rpc::rpc::JsonRpcConfig,
  25. solana_rpc_client::rpc_client::RpcClient,
  26. solana_signer::Signer,
  27. solana_test_validator::TestValidatorGenesis,
  28. solana_tpu_client::tpu_client::{TpuClient, TpuClientConfig},
  29. std::{sync::Arc, time::Duration},
  30. };
  31. fn program_account(program_data: &[u8]) -> AccountSharedData {
  32. AccountSharedData::from(Account {
  33. lamports: Rent::default().minimum_balance(program_data.len()).min(1),
  34. data: program_data.to_vec(),
  35. owner: solana_sdk_ids::bpf_loader::id(),
  36. executable: true,
  37. rent_epoch: 0,
  38. })
  39. }
  40. fn test_bench_tps_local_cluster(config: Config) {
  41. let additional_accounts = vec![(
  42. spl_instruction_padding_interface::ID,
  43. program_account(include_bytes!("fixtures/spl_instruction_padding.so")),
  44. )];
  45. agave_logger::setup();
  46. let faucet_keypair = Keypair::new();
  47. let faucet_pubkey = faucet_keypair.pubkey();
  48. let faucet_addr = run_local_faucet_for_tests(
  49. faucet_keypair,
  50. None, /* per_time_cap */
  51. 0, /* port */
  52. );
  53. const NUM_NODES: usize = 1;
  54. let cluster = LocalCluster::new(
  55. &mut ClusterConfig {
  56. node_stakes: vec![999_990; NUM_NODES],
  57. mint_lamports: 200_000_000,
  58. validator_configs: make_identical_validator_configs(
  59. &ValidatorConfig {
  60. rpc_config: JsonRpcConfig {
  61. faucet_addr: Some(faucet_addr),
  62. ..JsonRpcConfig::default_for_test()
  63. },
  64. ..ValidatorConfig::default_for_test()
  65. },
  66. NUM_NODES,
  67. ),
  68. additional_accounts,
  69. ..ClusterConfig::default()
  70. },
  71. SocketAddrSpace::Unspecified,
  72. );
  73. cluster.transfer(&cluster.funding_keypair, &faucet_pubkey, 100_000_000);
  74. let client = Arc::new(
  75. cluster
  76. .build_validator_tpu_quic_client(cluster.entry_point_info.pubkey())
  77. .unwrap_or_else(|err| {
  78. panic!("Could not create TpuClient with Quic Cache {err:?}");
  79. }),
  80. );
  81. let lamports_per_account = 100;
  82. let keypair_count = config.tx_count * config.keypair_multiplier;
  83. let keypairs = generate_and_fund_keypairs(
  84. client.clone(),
  85. &config.id,
  86. keypair_count,
  87. lamports_per_account,
  88. false,
  89. false,
  90. )
  91. .unwrap();
  92. let _total = do_bench_tps(client, config, keypairs, None);
  93. #[cfg(not(debug_assertions))]
  94. assert!(_total > 100);
  95. }
  96. fn test_bench_tps_test_validator(config: Config) {
  97. agave_logger::setup();
  98. let mint_keypair = Keypair::new();
  99. let mint_pubkey = mint_keypair.pubkey();
  100. let faucet_addr = run_local_faucet_for_tests(
  101. mint_keypair,
  102. None, /* per_time_cap */
  103. 0, /* port */
  104. );
  105. let test_validator = TestValidatorGenesis::default()
  106. .fee_rate_governor(FeeRateGovernor::new(0, 0))
  107. .rent(Rent {
  108. lamports_per_byte_year: 1,
  109. exemption_threshold: 1.0,
  110. ..Rent::default()
  111. })
  112. .faucet_addr(Some(faucet_addr))
  113. .add_program(
  114. "spl_instruction_padding",
  115. spl_instruction_padding_interface::ID,
  116. )
  117. .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified)
  118. .expect("validator start failed");
  119. let rpc_client = Arc::new(RpcClient::new_with_commitment(
  120. test_validator.rpc_url(),
  121. CommitmentConfig::processed(),
  122. ));
  123. let websocket_url = test_validator.rpc_pubsub_url();
  124. let client = Arc::new(
  125. TpuClient::new(
  126. "tpu_client_quic_bench_tps",
  127. rpc_client,
  128. &websocket_url,
  129. TpuClientConfig::default(),
  130. QuicConnectionManager::new_with_connection_config(QuicConfig::new().unwrap()),
  131. )
  132. .expect("Should build Quic Tpu Client."),
  133. );
  134. let lamports_per_account = 1000;
  135. let keypair_count = config.tx_count * config.keypair_multiplier;
  136. let keypairs = generate_and_fund_keypairs(
  137. client.clone(),
  138. &config.id,
  139. keypair_count,
  140. lamports_per_account,
  141. false,
  142. false,
  143. )
  144. .unwrap();
  145. let nonce_keypairs = if config.use_durable_nonce {
  146. Some(generate_durable_nonce_accounts(client.clone(), &keypairs))
  147. } else {
  148. None
  149. };
  150. let _total = do_bench_tps(client, config, keypairs, nonce_keypairs);
  151. #[cfg(not(debug_assertions))]
  152. assert!(_total > 100);
  153. }
  154. #[test]
  155. #[serial]
  156. fn test_bench_tps_local_cluster_solana() {
  157. test_bench_tps_local_cluster(Config {
  158. tx_count: 100,
  159. duration: Duration::from_secs(10),
  160. ..Config::default()
  161. });
  162. }
  163. #[test]
  164. #[serial]
  165. fn test_bench_tps_tpu_client() {
  166. test_bench_tps_test_validator(Config {
  167. tx_count: 100,
  168. duration: Duration::from_secs(10),
  169. ..Config::default()
  170. });
  171. }
  172. #[test]
  173. #[serial]
  174. fn test_bench_tps_tpu_client_nonce() {
  175. test_bench_tps_test_validator(Config {
  176. tx_count: 100,
  177. duration: Duration::from_secs(10),
  178. use_durable_nonce: true,
  179. ..Config::default()
  180. });
  181. }
  182. #[test]
  183. #[serial]
  184. fn test_bench_tps_local_cluster_with_padding() {
  185. test_bench_tps_local_cluster(Config {
  186. tx_count: 100,
  187. duration: Duration::from_secs(10),
  188. instruction_padding_config: Some(InstructionPaddingConfig {
  189. program_id: spl_instruction_padding_interface::ID,
  190. data_size: 0,
  191. }),
  192. ..Config::default()
  193. });
  194. }
  195. #[test]
  196. #[serial]
  197. fn test_bench_tps_tpu_client_with_padding() {
  198. test_bench_tps_test_validator(Config {
  199. tx_count: 100,
  200. duration: Duration::from_secs(10),
  201. instruction_padding_config: Some(InstructionPaddingConfig {
  202. program_id: spl_instruction_padding_interface::ID,
  203. data_size: 0,
  204. }),
  205. ..Config::default()
  206. });
  207. }