send_and_confirm_transactions_in_parallel.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. use {
  2. solana_client::{
  3. nonblocking::tpu_client::TpuClient,
  4. rpc_config::RpcSendTransactionConfig,
  5. send_and_confirm_transactions_in_parallel::{
  6. send_and_confirm_transactions_in_parallel_blocking_v2, SendAndConfirmConfigV2,
  7. },
  8. },
  9. solana_commitment_config::CommitmentConfig,
  10. solana_keypair::Keypair,
  11. solana_message::Message,
  12. solana_native_token::LAMPORTS_PER_SOL,
  13. solana_net_utils::SocketAddrSpace,
  14. solana_pubkey::Pubkey,
  15. solana_rpc_client::rpc_client::RpcClient,
  16. solana_signer::Signer,
  17. solana_system_interface::instruction as system_instruction,
  18. solana_test_validator::TestValidator,
  19. std::sync::Arc,
  20. };
  21. const NUM_TRANSACTIONS: usize = 1000;
  22. fn create_messages(from: Pubkey, to: Pubkey) -> (Vec<Message>, u64) {
  23. let mut messages = vec![];
  24. let mut sum = 0u64;
  25. for i in 1..NUM_TRANSACTIONS {
  26. let amount_to_transfer = (i as u64).checked_mul(LAMPORTS_PER_SOL).unwrap();
  27. let ix = system_instruction::transfer(&from, &to, amount_to_transfer);
  28. let message = Message::new(&[ix], Some(&from));
  29. messages.push(message);
  30. sum = sum.checked_add(amount_to_transfer).unwrap();
  31. }
  32. (messages, sum)
  33. }
  34. #[test]
  35. fn test_send_and_confirm_transactions_in_parallel_without_tpu_client() {
  36. agave_logger::setup();
  37. let alice = Keypair::new();
  38. let test_validator =
  39. TestValidator::with_no_fees(alice.pubkey(), None, SocketAddrSpace::Unspecified);
  40. let bob_pubkey = solana_pubkey::new_rand();
  41. let alice_pubkey = alice.pubkey();
  42. let rpc_client = Arc::new(RpcClient::new(test_validator.rpc_url()));
  43. assert_eq!(
  44. rpc_client.get_version().unwrap().solana_core,
  45. solana_version::semver!()
  46. );
  47. let original_alice_balance = rpc_client.get_balance(&alice.pubkey()).unwrap();
  48. let (messages, sum) = create_messages(alice_pubkey, bob_pubkey);
  49. let txs_errors = send_and_confirm_transactions_in_parallel_blocking_v2(
  50. rpc_client.clone(),
  51. None,
  52. &messages,
  53. &[&alice],
  54. SendAndConfirmConfigV2 {
  55. with_spinner: false,
  56. resign_txs_count: Some(5),
  57. rpc_send_transaction_config: RpcSendTransactionConfig {
  58. skip_preflight: false,
  59. preflight_commitment: Some(CommitmentConfig::confirmed().commitment),
  60. encoding: None,
  61. max_retries: None,
  62. min_context_slot: None,
  63. },
  64. },
  65. );
  66. assert!(txs_errors.is_ok());
  67. assert!(txs_errors.unwrap().iter().all(|x| x.is_none()));
  68. assert_eq!(
  69. rpc_client
  70. .get_balance_with_commitment(&bob_pubkey, CommitmentConfig::processed())
  71. .unwrap()
  72. .value,
  73. sum
  74. );
  75. assert_eq!(
  76. rpc_client
  77. .get_balance_with_commitment(&alice_pubkey, CommitmentConfig::processed())
  78. .unwrap()
  79. .value,
  80. original_alice_balance - sum
  81. );
  82. }
  83. #[test]
  84. fn test_send_and_confirm_transactions_in_parallel_with_tpu_client() {
  85. agave_logger::setup();
  86. let alice = Keypair::new();
  87. let test_validator =
  88. TestValidator::with_no_fees(alice.pubkey(), None, SocketAddrSpace::Unspecified);
  89. let bob_pubkey = solana_pubkey::new_rand();
  90. let alice_pubkey = alice.pubkey();
  91. let rpc_client = Arc::new(RpcClient::new(test_validator.rpc_url()));
  92. assert_eq!(
  93. rpc_client.get_version().unwrap().solana_core,
  94. solana_version::semver!()
  95. );
  96. let original_alice_balance = rpc_client.get_balance(&alice.pubkey()).unwrap();
  97. let (messages, sum) = create_messages(alice_pubkey, bob_pubkey);
  98. let ws_url = test_validator.rpc_pubsub_url();
  99. let tpu_client_fut = TpuClient::new(
  100. "temp",
  101. rpc_client.get_inner_client().clone(),
  102. ws_url.as_str(),
  103. solana_client::tpu_client::TpuClientConfig::default(),
  104. );
  105. let tpu_client = rpc_client.runtime().block_on(tpu_client_fut).unwrap();
  106. let txs_errors = send_and_confirm_transactions_in_parallel_blocking_v2(
  107. rpc_client.clone(),
  108. Some(tpu_client),
  109. &messages,
  110. &[&alice],
  111. SendAndConfirmConfigV2 {
  112. with_spinner: false,
  113. resign_txs_count: Some(5),
  114. rpc_send_transaction_config: RpcSendTransactionConfig {
  115. skip_preflight: false,
  116. preflight_commitment: Some(CommitmentConfig::confirmed().commitment),
  117. encoding: None,
  118. max_retries: None,
  119. min_context_slot: None,
  120. },
  121. },
  122. );
  123. assert!(txs_errors.is_ok());
  124. assert!(txs_errors.unwrap().iter().all(|x| x.is_none()));
  125. assert_eq!(
  126. rpc_client
  127. .get_balance_with_commitment(&bob_pubkey, CommitmentConfig::processed())
  128. .unwrap()
  129. .value,
  130. sum
  131. );
  132. assert_eq!(
  133. rpc_client
  134. .get_balance_with_commitment(&alice_pubkey, CommitmentConfig::processed())
  135. .unwrap()
  136. .value,
  137. original_alice_balance - sum
  138. );
  139. }