1
1
use {
2
+ agave_banking_stage_ingress_types:: BankingPacketBatch ,
3
+ assert_matches:: assert_matches,
2
4
crossbeam_channel:: unbounded,
3
5
itertools:: Itertools ,
4
6
log:: * ,
5
7
solana_core:: {
8
+ banking_stage:: unified_scheduler:: ensure_banking_stage_setup,
9
+ banking_trace:: BankingTracer ,
6
10
consensus:: {
7
11
heaviest_subtree_fork_choice:: HeaviestSubtreeForkChoice ,
8
12
progress_map:: { ForkProgress , ProgressMap } ,
@@ -14,22 +18,36 @@ use {
14
18
replay_stage:: ReplayStage ,
15
19
unfrozen_gossip_verified_vote_hashes:: UnfrozenGossipVerifiedVoteHashes ,
16
20
} ,
17
- solana_ledger:: genesis_utils:: create_genesis_config,
21
+ solana_entry:: entry:: Entry ,
22
+ solana_gossip:: cluster_info:: { ClusterInfo , Node } ,
23
+ solana_ledger:: {
24
+ blockstore:: Blockstore , create_new_tmp_ledger_auto_delete,
25
+ genesis_utils:: create_genesis_config, leader_schedule_cache:: LeaderScheduleCache ,
26
+ } ,
27
+ solana_perf:: packet:: to_packet_batches,
28
+ solana_poh:: poh_recorder:: create_test_recorder,
18
29
solana_runtime:: {
19
30
accounts_background_service:: AbsRequestSender , bank:: Bank , bank_forks:: BankForks ,
20
31
genesis_utils:: GenesisConfigInfo , installed_scheduler_pool:: SchedulingContext ,
21
32
prioritization_fee_cache:: PrioritizationFeeCache ,
22
33
} ,
23
34
solana_runtime_transaction:: runtime_transaction:: RuntimeTransaction ,
24
- solana_sdk:: { hash:: Hash , pubkey:: Pubkey , system_transaction, transaction:: Result } ,
35
+ solana_sdk:: {
36
+ hash:: Hash , pubkey:: Pubkey , signature:: Signer , signer:: keypair:: Keypair ,
37
+ system_transaction, transaction:: Result ,
38
+ } ,
39
+ solana_streamer:: socket:: SocketAddrSpace ,
25
40
solana_timings:: ExecuteTimings ,
26
- solana_unified_scheduler_logic:: Task ,
41
+ solana_unified_scheduler_logic:: { SchedulingMode , Task } ,
27
42
solana_unified_scheduler_pool:: {
28
- DefaultTaskHandler , HandlerContext , PooledScheduler , SchedulerPool , TaskHandler ,
43
+ DefaultSchedulerPool , DefaultTaskHandler , HandlerContext , PooledScheduler , SchedulerPool ,
44
+ SupportedSchedulingMode , TaskHandler ,
29
45
} ,
30
46
std:: {
31
47
collections:: HashMap ,
32
- sync:: { Arc , Mutex } ,
48
+ sync:: { atomic:: Ordering , Arc , Mutex } ,
49
+ thread:: sleep,
50
+ time:: Duration ,
33
51
} ,
34
52
} ;
35
53
@@ -185,3 +203,106 @@ fn test_scheduler_waited_by_drop_bank_service() {
185
203
// the scheduler used by the pruned_bank have been returned now.
186
204
assert_eq ! ( pool_raw. pooled_scheduler_count( ) , 1 ) ;
187
205
}
206
+
207
+ #[ test]
208
+ fn test_scheduler_producing_blocks ( ) {
209
+ solana_logger:: setup ( ) ;
210
+
211
+ let GenesisConfigInfo {
212
+ genesis_config,
213
+ mint_keypair,
214
+ ..
215
+ } = create_genesis_config ( 10_000 ) ;
216
+ let ( ledger_path, _blockhash) = create_new_tmp_ledger_auto_delete ! ( & genesis_config) ;
217
+ let blockstore = Arc :: new ( Blockstore :: open ( ledger_path. path ( ) ) . unwrap ( ) ) ;
218
+
219
+ // Setup bank_forks with block-producing unified scheduler enabled
220
+ let genesis_bank = Bank :: new_for_tests ( & genesis_config) ;
221
+ let bank_forks = BankForks :: new_rw_arc ( genesis_bank) ;
222
+ let ignored_prioritization_fee_cache = Arc :: new ( PrioritizationFeeCache :: new ( 0u64 ) ) ;
223
+ let genesis_bank = bank_forks. read ( ) . unwrap ( ) . working_bank_with_scheduler ( ) ;
224
+ genesis_bank. set_fork_graph_in_program_cache ( Arc :: downgrade ( & bank_forks) ) ;
225
+ let leader_schedule_cache = Arc :: new ( LeaderScheduleCache :: new_from_bank ( & genesis_bank) ) ;
226
+ let ( exit, poh_recorder, poh_service, signal_receiver) = create_test_recorder (
227
+ genesis_bank. clone ( ) ,
228
+ blockstore. clone ( ) ,
229
+ None ,
230
+ Some ( leader_schedule_cache) ,
231
+ ) ;
232
+ let pool = DefaultSchedulerPool :: new (
233
+ SupportedSchedulingMode :: Either ( SchedulingMode :: BlockProduction ) ,
234
+ None ,
235
+ None ,
236
+ None ,
237
+ None ,
238
+ ignored_prioritization_fee_cache,
239
+ poh_recorder. read ( ) . unwrap ( ) . new_recorder ( ) ,
240
+ ) ;
241
+ let channels = {
242
+ let banking_tracer = BankingTracer :: new_disabled ( ) ;
243
+ banking_tracer. create_channels_for_scheduler_pool ( & pool)
244
+ } ;
245
+ let cluster_info = {
246
+ let keypair = Arc :: new ( Keypair :: new ( ) ) ;
247
+ let node = Node :: new_localhost_with_pubkey ( & keypair. pubkey ( ) ) ;
248
+ Arc :: new ( ClusterInfo :: new (
249
+ node. info ,
250
+ keypair,
251
+ SocketAddrSpace :: Unspecified ,
252
+ ) )
253
+ } ;
254
+ ensure_banking_stage_setup ( & pool, & bank_forks, & channels, & cluster_info, & poh_recorder) ;
255
+ bank_forks. write ( ) . unwrap ( ) . install_scheduler_pool ( pool) ;
256
+
257
+ // Wait until genesis_bank reaches its tick height...
258
+ while poh_recorder. read ( ) . unwrap ( ) . bank ( ) . is_some ( ) {
259
+ sleep ( Duration :: from_millis ( 100 ) ) ;
260
+ }
261
+
262
+ // Create test tx
263
+ let tx = system_transaction:: transfer (
264
+ & mint_keypair,
265
+ & solana_pubkey:: new_rand ( ) ,
266
+ 1 ,
267
+ genesis_config. hash ( ) ,
268
+ ) ;
269
+ let banking_packet_batch = BankingPacketBatch :: new ( to_packet_batches ( & vec ! [ tx. clone( ) ; 1 ] , 1 ) ) ;
270
+ let tx = RuntimeTransaction :: from_transaction_for_tests ( tx) ;
271
+
272
+ // Crate tpu_bank
273
+ let tpu_bank = Bank :: new_from_parent ( genesis_bank. clone ( ) , & Pubkey :: default ( ) , 2 ) ;
274
+ let tpu_bank = bank_forks
275
+ . write ( )
276
+ . unwrap ( )
277
+ . insert_with_scheduling_mode ( SchedulingMode :: BlockProduction , tpu_bank) ;
278
+ poh_recorder
279
+ . write ( )
280
+ . unwrap ( )
281
+ . set_bank ( tpu_bank. clone_with_scheduler ( ) , false ) ;
282
+ tpu_bank. unblock_block_production ( ) ;
283
+ let tpu_bank = bank_forks. read ( ) . unwrap ( ) . working_bank_with_scheduler ( ) ;
284
+ assert_eq ! ( tpu_bank. transaction_count( ) , 0 ) ;
285
+
286
+ // Now, send transaction
287
+ channels
288
+ . unified_sender ( )
289
+ . send ( banking_packet_batch)
290
+ . unwrap ( ) ;
291
+
292
+ // Wait until tpu_bank reaches its tick height...
293
+ while poh_recorder. read ( ) . unwrap ( ) . bank ( ) . is_some ( ) {
294
+ sleep ( Duration :: from_millis ( 100 ) ) ;
295
+ }
296
+ assert_matches ! ( tpu_bank. wait_for_completed_scheduler( ) , Some ( ( Ok ( ( ) ) , _) ) ) ;
297
+
298
+ // Verify transactions are committed and poh-recorded
299
+ assert_eq ! ( tpu_bank. transaction_count( ) , 1 ) ;
300
+ assert_matches ! (
301
+ signal_receiver. into_iter( ) . find( |( _, ( entry, _) ) | !entry. is_tick( ) ) ,
302
+ Some ( ( _, ( Entry { transactions, ..} , _) ) ) if transactions == [ tx. to_versioned_transaction( ) ]
303
+ ) ;
304
+
305
+ // Stop things.
306
+ exit. store ( true , Ordering :: Relaxed ) ;
307
+ poh_service. join ( ) . unwrap ( ) ;
308
+ }
0 commit comments