17
17
histogram:: Histogram ,
18
18
itertools:: Itertools ,
19
19
min_max_heap:: MinMaxHeap ,
20
- solana_client:: { connection_cache:: get_connection, tpu_connection:: TpuConnection } ,
20
+ solana_client:: {
21
+ connection_cache:: get_connection, tpu_connection:: TpuConnection ,
22
+ udp_client:: UdpTpuConnection ,
23
+ } ,
21
24
solana_entry:: entry:: hash_transactions,
22
25
solana_gossip:: { cluster_info:: ClusterInfo , contact_info:: ContactInfo } ,
23
26
solana_ledger:: blockstore_processor:: TransactionStatusSender ,
@@ -147,6 +150,8 @@ pub struct BankingStageStats {
147
150
rebuffered_packets_count : AtomicUsize ,
148
151
consumed_buffered_packets_count : AtomicUsize ,
149
152
end_of_slot_filtered_invalid_count : AtomicUsize ,
153
+ forwarded_transaction_count : AtomicUsize ,
154
+ forwarded_vote_count : AtomicUsize ,
150
155
batch_packet_indexes_len : Histogram ,
151
156
152
157
// Timing
@@ -201,6 +206,8 @@ impl BankingStageStats {
201
206
. unprocessed_packet_conversion_elapsed
202
207
. load ( Ordering :: Relaxed )
203
208
+ self . transaction_processing_elapsed . load ( Ordering :: Relaxed )
209
+ + self . forwarded_transaction_count . load ( Ordering :: Relaxed ) as u64
210
+ + self . forwarded_vote_count . load ( Ordering :: Relaxed ) as u64
204
211
+ self . batch_packet_indexes_len . entries ( )
205
212
}
206
213
@@ -264,6 +271,16 @@ impl BankingStageStats {
264
271
. swap( 0 , Ordering :: Relaxed ) as i64 ,
265
272
i64
266
273
) ,
274
+ (
275
+ "forwarded_transaction_count" ,
276
+ self . forwarded_transaction_count. swap( 0 , Ordering :: Relaxed ) as i64 ,
277
+ i64
278
+ ) ,
279
+ (
280
+ "forwarded_vote_count" ,
281
+ self . forwarded_vote_count. swap( 0 , Ordering :: Relaxed ) as i64 ,
282
+ i64
283
+ ) ,
267
284
(
268
285
"consume_buffered_packets_elapsed" ,
269
286
self . consume_buffered_packets_elapsed
@@ -489,10 +506,26 @@ impl BankingStage {
489
506
/// Forwards all valid, unprocessed packets in the buffer, up to a rate limit. Returns
490
507
/// the number of successfully forwarded packets in second part of tuple
491
508
fn forward_buffered_packets (
492
- tpu_forwards : & std:: net:: SocketAddr ,
509
+ forward_option : & ForwardOption ,
510
+ cluster_info : & ClusterInfo ,
511
+ poh_recorder : & Arc < Mutex < PohRecorder > > ,
493
512
packets : Vec < & Packet > ,
494
513
data_budget : & DataBudget ,
514
+ banking_stage_stats : & BankingStageStats ,
495
515
) -> ( std:: result:: Result < ( ) , TransportError > , usize ) {
516
+ let addr = match forward_option {
517
+ ForwardOption :: NotForward => return ( Ok ( ( ) ) , 0 ) ,
518
+ ForwardOption :: ForwardTransaction => {
519
+ next_leader_tpu_forwards ( cluster_info, poh_recorder)
520
+ }
521
+
522
+ ForwardOption :: ForwardTpuVote => next_leader_tpu_vote ( cluster_info, poh_recorder) ,
523
+ } ;
524
+ let addr = match addr {
525
+ Some ( addr) => addr,
526
+ None => return ( Ok ( ( ) ) , 0 ) ,
527
+ } ;
528
+
496
529
const INTERVAL_MS : u64 = 100 ;
497
530
const MAX_BYTES_PER_SECOND : usize = 10_000 * 1200 ;
498
531
const MAX_BYTES_PER_INTERVAL : usize = MAX_BYTES_PER_SECOND * INTERVAL_MS as usize / 1000 ;
@@ -525,7 +558,20 @@ impl BankingStage {
525
558
526
559
let mut measure = Measure :: start ( "banking_stage-forward-us" ) ;
527
560
528
- let conn = get_connection ( tpu_forwards) ;
561
+ let conn = if let ForwardOption :: ForwardTpuVote = forward_option {
562
+ // The vote must be forwarded using only UDP. Let's get the UDP connection.
563
+ banking_stage_stats
564
+ . forwarded_vote_count
565
+ . fetch_add ( packet_vec_len, Ordering :: Relaxed ) ;
566
+ Arc :: new ( UdpTpuConnection :: new_from_addr ( addr) . into ( ) )
567
+ } else {
568
+ // All other transactions can be forwarded using QUIC, get_connection() will use
569
+ // system wide setting to pick the correct connection object.
570
+ banking_stage_stats
571
+ . forwarded_transaction_count
572
+ . fetch_add ( packet_vec_len, Ordering :: Relaxed ) ;
573
+ get_connection ( & addr)
574
+ } ;
529
575
let res = conn. send_wire_transaction_batch_async ( packet_vec) ;
530
576
531
577
measure. stop ( ) ;
@@ -908,6 +954,7 @@ impl BankingStage {
908
954
false ,
909
955
data_budget,
910
956
slot_metrics_tracker,
957
+ banking_stage_stats,
911
958
)
912
959
} ,
913
960
( ) ,
@@ -926,6 +973,7 @@ impl BankingStage {
926
973
true ,
927
974
data_budget,
928
975
slot_metrics_tracker,
976
+ banking_stage_stats,
929
977
)
930
978
} ,
931
979
( ) ,
@@ -945,29 +993,26 @@ impl BankingStage {
945
993
hold : bool ,
946
994
data_budget : & DataBudget ,
947
995
slot_metrics_tracker : & mut LeaderSlotMetricsTracker ,
996
+ banking_stage_stats : & BankingStageStats ,
948
997
) {
949
- let addr = match forward_option {
950
- ForwardOption :: NotForward => {
951
- if !hold {
952
- buffered_packet_batches. clear ( ) ;
953
- }
954
- return ;
955
- }
956
- ForwardOption :: ForwardTransaction => {
957
- next_leader_tpu_forwards ( cluster_info, poh_recorder)
998
+ if let ForwardOption :: NotForward = forward_option {
999
+ if !hold {
1000
+ buffered_packet_batches. clear ( ) ;
958
1001
}
959
- ForwardOption :: ForwardTpuVote => next_leader_tpu_vote ( cluster_info, poh_recorder) ,
960
- } ;
961
- let addr = match addr {
962
- Some ( addr) => addr,
963
- None => return ,
964
- } ;
1002
+ return ;
1003
+ }
965
1004
966
1005
let forwardable_packets =
967
1006
Self :: filter_valid_packets_for_forwarding ( buffered_packet_batches. iter ( ) ) ;
968
1007
let forwardable_packets_len = forwardable_packets. len ( ) ;
969
- let ( _forward_result, sucessful_forwarded_packets_count) =
970
- Self :: forward_buffered_packets ( & addr, forwardable_packets, data_budget) ;
1008
+ let ( _forward_result, sucessful_forwarded_packets_count) = Self :: forward_buffered_packets (
1009
+ forward_option,
1010
+ cluster_info,
1011
+ poh_recorder,
1012
+ forwardable_packets,
1013
+ data_budget,
1014
+ banking_stage_stats,
1015
+ ) ;
971
1016
let failed_forwarded_packets_count =
972
1017
forwardable_packets_len. saturating_sub ( sucessful_forwarded_packets_count) ;
973
1018
@@ -4072,6 +4117,7 @@ mod tests {
4072
4117
vec ! [ deserialized_packet. clone( ) ] . into_iter ( ) ,
4073
4118
1 ,
4074
4119
) ;
4120
+ let stats = BankingStageStats :: default ( ) ;
4075
4121
BankingStage :: handle_forwarding (
4076
4122
& ForwardOption :: ForwardTransaction ,
4077
4123
& cluster_info,
@@ -4080,6 +4126,7 @@ mod tests {
4080
4126
true ,
4081
4127
& data_budget,
4082
4128
& mut LeaderSlotMetricsTracker :: new ( 0 ) ,
4129
+ & stats,
4083
4130
) ;
4084
4131
4085
4132
recv_socket
@@ -4179,6 +4226,7 @@ mod tests {
4179
4226
] ;
4180
4227
4181
4228
for ( name, forward_option, hold, expected_ids, expected_num_unprocessed) in test_cases {
4229
+ let stats = BankingStageStats :: default ( ) ;
4182
4230
BankingStage :: handle_forwarding (
4183
4231
& forward_option,
4184
4232
& cluster_info,
@@ -4187,6 +4235,7 @@ mod tests {
4187
4235
hold,
4188
4236
& DataBudget :: default ( ) ,
4189
4237
& mut LeaderSlotMetricsTracker :: new ( 0 ) ,
4238
+ & stats,
4190
4239
) ;
4191
4240
4192
4241
recv_socket
0 commit comments