Skip to content

Commit 0d3de56

Browse files
committed
Add test: test_scheduler_producing_blocks()
1 parent 8935353 commit 0d3de56

File tree

3 files changed

+139
-5
lines changed

3 files changed

+139
-5
lines changed

core/src/banking_trace.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,18 @@ pub struct Channels {
186186
}
187187

188188
impl Channels {
189+
#[cfg(feature = "dev-context-only-utils")]
190+
pub fn unified_sender(&self) -> &BankingPacketSender {
191+
let unified_sender = &self.non_vote_sender;
192+
assert!(unified_sender
193+
.sender
194+
.same_channel(&self.tpu_vote_sender.sender));
195+
assert!(unified_sender
196+
.sender
197+
.same_channel(&self.gossip_vote_sender.sender));
198+
unified_sender
199+
}
200+
189201
pub(crate) fn unified_receiver(&self) -> &BankingPacketReceiver {
190202
let unified_receiver = &self.non_vote_receiver;
191203
assert!(unified_receiver.same_channel(&self.tpu_vote_receiver));

core/tests/unified_scheduler.rs

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use {
2+
agave_banking_stage_ingress_types::BankingPacketBatch,
3+
assert_matches::assert_matches,
24
crossbeam_channel::unbounded,
35
itertools::Itertools,
46
log::*,
57
solana_core::{
8+
banking_stage::unified_scheduler::ensure_banking_stage_setup,
9+
banking_trace::BankingTracer,
610
consensus::{
711
heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice,
812
progress_map::{ForkProgress, ProgressMap},
@@ -14,22 +18,36 @@ use {
1418
replay_stage::ReplayStage,
1519
unfrozen_gossip_verified_vote_hashes::UnfrozenGossipVerifiedVoteHashes,
1620
},
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,
1829
solana_runtime::{
1930
accounts_background_service::AbsRequestSender, bank::Bank, bank_forks::BankForks,
2031
genesis_utils::GenesisConfigInfo, installed_scheduler_pool::SchedulingContext,
2132
prioritization_fee_cache::PrioritizationFeeCache,
2233
},
2334
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,
2540
solana_timings::ExecuteTimings,
26-
solana_unified_scheduler_logic::Task,
41+
solana_unified_scheduler_logic::{SchedulingMode, Task},
2742
solana_unified_scheduler_pool::{
28-
DefaultTaskHandler, HandlerContext, PooledScheduler, SchedulerPool, TaskHandler,
43+
DefaultSchedulerPool, DefaultTaskHandler, HandlerContext, PooledScheduler, SchedulerPool,
44+
SupportedSchedulingMode, TaskHandler,
2945
},
3046
std::{
3147
collections::HashMap,
32-
sync::{Arc, Mutex},
48+
sync::{atomic::Ordering, Arc, Mutex},
49+
thread::sleep,
50+
time::Duration,
3351
},
3452
};
3553

@@ -185,3 +203,106 @@ fn test_scheduler_waited_by_drop_bank_service() {
185203
// the scheduler used by the pruned_bank have been returned now.
186204
assert_eq!(pool_raw.pooled_scheduler_count(), 1);
187205
}
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+
}

unified-scheduler-pool/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ impl TaskHandler for DefaultTaskHandler {
729729
} = handler_context
730730
.transaction_recorder
731731
.record_transactions(bank.slot(), vec![transaction.to_versioned_transaction()]);
732+
trace!("pre_commit_callback: poh: {result:?}");
732733
match result {
733734
Ok(()) => Ok(starting_transaction_index),
734735
Err(_) => Err(TransactionError::CommitCancelled),

0 commit comments

Comments
 (0)