From 9d42cd7efe869223040f68c0a9b2bdfa99f1018a Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Mon, 23 Oct 2023 09:32:41 -0700 Subject: [PATCH] Initialize fork graph in program cache during bank_forks creation (#33810) * Initialize fork graph in program cache during bank_forks creation * rename BankForks::new to BankForks::new_rw_arc * fix compilation * no need to set fork_graph on insert() * fix partition tests --- banking-bench/src/main.rs | 2 +- banks-client/src/lib.rs | 4 +- client-test/tests/client.rs | 12 +- core/benches/banking_stage.rs | 4 +- core/benches/consensus.rs | 10 +- core/src/banking_stage.rs | 10 +- core/src/banking_stage/consume_worker.rs | 2 +- core/src/banking_stage/forward_worker.rs | 2 +- core/src/banking_stage/forwarder.rs | 2 +- core/src/cluster_info_vote_listener.rs | 10 +- core/src/commitment_service.rs | 3 +- .../consensus/heaviest_subtree_fork_choice.rs | 3 +- core/src/repair/ancestor_hashes_service.rs | 2 +- core/src/repair/quic_endpoint.rs | 2 +- core/src/repair/repair_service.rs | 4 +- core/src/repair/serve_repair.rs | 10 +- core/src/replay_stage.rs | 38 ++++--- core/src/tvu.rs | 5 +- core/src/validator.rs | 6 +- core/src/vote_simulator.rs | 16 ++- core/tests/epoch_accounts_hash.rs | 27 +++-- core/tests/snapshots.rs | 82 +++++++++----- gossip/src/duplicate_shred_handler.rs | 18 ++- gossip/tests/gossip.rs | 2 +- ledger/src/bank_forks_utils.rs | 14 +-- ledger/src/blockstore_processor.rs | 11 +- program-runtime/src/loaded_programs.rs | 2 +- program-test/src/lib.rs | 2 +- .../optimistically_confirmed_bank_tracker.rs | 2 +- rpc/src/rpc.rs | 9 +- rpc/src/rpc_health.rs | 2 +- rpc/src/rpc_pubsub.rs | 26 ++--- rpc/src/rpc_pubsub_service.rs | 2 +- rpc/src/rpc_service.rs | 4 +- rpc/src/rpc_subscription_tracker.rs | 4 +- rpc/src/rpc_subscriptions.rs | 38 ++++--- runtime/benches/prioritization_fee_cache.rs | 4 +- runtime/src/bank/tests.rs | 17 ++- runtime/src/bank_forks.rs | 106 +++++++++++------- runtime/src/prioritization_fee_cache.rs | 8 +- runtime/src/root_bank_cache.rs | 2 +- .../src/send_transaction_service.rs | 8 +- turbine/benches/cluster_info.rs | 9 +- turbine/benches/retransmit_stage.rs | 7 +- turbine/src/broadcast_stage.rs | 2 +- .../broadcast_stage/standard_broadcast_run.rs | 2 +- turbine/src/quic_endpoint.rs | 2 +- turbine/src/sigverify_shreds.rs | 2 +- validator/src/admin_rpc_service.rs | 5 +- 49 files changed, 310 insertions(+), 256 deletions(-) diff --git a/banking-bench/src/main.rs b/banking-bench/src/main.rs index c96ab074a6..041df5354f 100644 --- a/banking-bench/src/main.rs +++ b/banking-bench/src/main.rs @@ -334,7 +334,7 @@ fn main() { let (replay_vote_sender, _replay_vote_receiver) = unbounded(); let bank0 = Bank::new_for_benches(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank0))); + let bank_forks = BankForks::new_rw_arc(bank0); let mut bank = bank_forks.read().unwrap().working_bank(); // set cost tracker limits to MAX so it will not filter out TXs diff --git a/banks-client/src/lib.rs b/banks-client/src/lib.rs index f0c2f17d8c..61105575e2 100644 --- a/banks-client/src/lib.rs +++ b/banks-client/src/lib.rs @@ -587,7 +587,7 @@ mod tests { let block_commitment_cache = Arc::new(RwLock::new( BlockCommitmentCache::new_for_tests_with_slots(slot, slot), )); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bob_pubkey = solana_sdk::pubkey::new_rand(); let mint_pubkey = genesis.mint_keypair.pubkey(); @@ -626,7 +626,7 @@ mod tests { let block_commitment_cache = Arc::new(RwLock::new( BlockCommitmentCache::new_for_tests_with_slots(slot, slot), )); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let mint_pubkey = &genesis.mint_keypair.pubkey(); let bob_pubkey = solana_sdk::pubkey::new_rand(); diff --git a/client-test/tests/client.rs b/client-test/tests/client.rs index 01ecc263f6..b68e23753c 100644 --- a/client-test/tests/client.rs +++ b/client-test/tests/client.rs @@ -132,7 +132,7 @@ fn test_account_subscription() { } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); @@ -230,7 +230,7 @@ fn test_block_subscription() { } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); let rent_exempt_amount = bank.get_minimum_balance_for_rent_exemption(0); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); // setup Blockstore let ledger_path = get_tmp_ledger_path_auto_delete!(); @@ -338,7 +338,7 @@ fn test_program_subscription() { } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); @@ -425,7 +425,7 @@ fn test_root_subscription() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); @@ -477,7 +477,7 @@ fn test_slot_subscription() { let exit = Arc::new(AtomicBool::new(false)); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); @@ -553,7 +553,7 @@ async fn test_slot_subscription_async() { let exit = Arc::new(AtomicBool::new(false)); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); diff --git a/core/benches/banking_stage.rs b/core/benches/banking_stage.rs index 2a3d9c297c..bc22ae4774 100644 --- a/core/benches/banking_stage.rs +++ b/core/benches/banking_stage.rs @@ -56,7 +56,7 @@ use { }, std::{ iter::repeat_with, - sync::{atomic::Ordering, Arc, RwLock}, + sync::{atomic::Ordering, Arc}, time::{Duration, Instant}, }, test::Bencher, @@ -217,7 +217,7 @@ fn bench_banking(bencher: &mut Bencher, tx_type: TransactionType) { let mut bank = Bank::new_for_benches(&genesis_config); // Allow arbitrary transaction processing time for the purposes of this bench bank.ns_per_slot = u128::MAX; - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().get(0).unwrap(); // set cost tracker limits to MAX so it will not filter out TXs diff --git a/core/benches/consensus.rs b/core/benches/consensus.rs index a3dd97755e..cff71502df 100644 --- a/core/benches/consensus.rs +++ b/core/benches/consensus.rs @@ -28,7 +28,10 @@ fn bench_save_tower(bench: &mut Bencher) { let vote_account_pubkey = &Pubkey::default(); let node_keypair = Arc::new(Keypair::new()); - let heaviest_bank = BankForks::new(Bank::default_for_tests()).working_bank(); + let heaviest_bank = BankForks::new_rw_arc(Bank::default_for_tests()) + .read() + .unwrap() + .working_bank(); let tower_storage = FileTowerStorage::new(dir.path().to_path_buf()); let tower = Tower::new( &node_keypair.pubkey(), @@ -47,7 +50,10 @@ fn bench_save_tower(bench: &mut Bencher) { fn bench_generate_ancestors_descendants(bench: &mut Bencher) { let vote_account_pubkey = &Pubkey::default(); let node_keypair = Arc::new(Keypair::new()); - let heaviest_bank = BankForks::new(Bank::default_for_tests()).working_bank(); + let heaviest_bank = BankForks::new_rw_arc(Bank::default_for_tests()) + .read() + .unwrap() + .working_bank(); let mut tower = Tower::new( &node_keypair.pubkey(), vote_account_pubkey, diff --git a/core/src/banking_stage.rs b/core/src/banking_stage.rs index a1758616d1..19c3eb55eb 100644 --- a/core/src/banking_stage.rs +++ b/core/src/banking_stage.rs @@ -670,7 +670,7 @@ mod tests { fn test_banking_stage_shutdown1() { let genesis_config = create_genesis_config(2).genesis_config; let bank = Bank::new_no_wallclock_throttle_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().get(0).unwrap(); let banking_tracer = BankingTracer::new_disabled(); let (non_vote_sender, non_vote_receiver) = banking_tracer.create_channel_non_vote(); @@ -722,7 +722,7 @@ mod tests { genesis_config.ticks_per_slot = 4; let num_extra_ticks = 2; let bank = Bank::new_no_wallclock_throttle_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().get(0).unwrap(); let start_hash = bank.last_blockhash(); let banking_tracer = BankingTracer::new_disabled(); @@ -802,7 +802,7 @@ mod tests { .. } = create_slow_genesis_config(10); let bank = Bank::new_no_wallclock_throttle_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().get(0).unwrap(); let start_hash = bank.last_blockhash(); let banking_tracer = BankingTracer::new_disabled(); @@ -974,7 +974,7 @@ mod tests { let entry_receiver = { // start a banking_stage to eat verified receiver let bank = Bank::new_no_wallclock_throttle_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().get(0).unwrap(); let blockstore = Arc::new( Blockstore::open(ledger_path.path()) @@ -1158,7 +1158,7 @@ mod tests { .. } = create_slow_genesis_config(10000); let bank = Bank::new_no_wallclock_throttle_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().get(0).unwrap(); let start_hash = bank.last_blockhash(); let banking_tracer = BankingTracer::new_disabled(); diff --git a/core/src/banking_stage/consume_worker.rs b/core/src/banking_stage/consume_worker.rs index eb58d45c8e..f18f3da5d1 100644 --- a/core/src/banking_stage/consume_worker.rs +++ b/core/src/banking_stage/consume_worker.rs @@ -174,7 +174,7 @@ mod tests { .. } = create_slow_genesis_config(10_000); let bank = Bank::new_no_wallclock_throttle_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().working_bank(); let ledger_path = get_tmp_ledger_path_auto_delete!(); diff --git a/core/src/banking_stage/forward_worker.rs b/core/src/banking_stage/forward_worker.rs index cabd891e76..c13b8c4263 100644 --- a/core/src/banking_stage/forward_worker.rs +++ b/core/src/banking_stage/forward_worker.rs @@ -129,7 +129,7 @@ mod tests { .. } = create_slow_genesis_config(10_000); let bank = Bank::new_no_wallclock_throttle_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().working_bank(); let ledger_path = get_tmp_ledger_path_auto_delete!(); diff --git a/core/src/banking_stage/forwarder.rs b/core/src/banking_stage/forwarder.rs index 777ea12d95..1cb656f0dd 100644 --- a/core/src/banking_stage/forwarder.rs +++ b/core/src/banking_stage/forwarder.rs @@ -307,7 +307,7 @@ mod tests { let GenesisConfigInfo { genesis_config, .. } = &genesis_config_info; let bank: Bank = Bank::new_no_wallclock_throttle_for_tests(genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().working_bank(); let ledger_path = TempDir::new().unwrap(); diff --git a/core/src/cluster_info_vote_listener.rs b/core/src/cluster_info_vote_listener.rs index 183cabcf04..782f10d976 100644 --- a/core/src/cluster_info_vote_listener.rs +++ b/core/src/cluster_info_vote_listener.rs @@ -1439,7 +1439,7 @@ mod tests { ); let bank = Bank::new_for_tests(&genesis_config); let exit = Arc::new(AtomicBool::new(false)); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().get(0).unwrap(); let vote_tracker = VoteTracker::default(); let optimistically_confirmed_bank = @@ -1556,7 +1556,7 @@ mod tests { let bank = Bank::new_for_tests(&genesis_config); let vote_tracker = VoteTracker::default(); let exit = Arc::new(AtomicBool::new(false)); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().get(0).unwrap(); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); @@ -1584,7 +1584,7 @@ mod tests { solana_logger::setup(); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = RwLock::new(BankForks::new(bank)); + let bank_forks = BankForks::new_rw_arc(bank); let votes = vec![]; let (vote_txs, packets) = ClusterInfoVoteListener::verify_votes(votes, &bank_forks); assert!(vote_txs.is_empty()); @@ -1629,7 +1629,7 @@ mod tests { vec![100; voting_keypairs.len()], // stakes ); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = RwLock::new(BankForks::new(bank)); + let bank_forks = BankForks::new_rw_arc(bank); let vote_tx = test_vote_tx(voting_keypairs.first(), hash); let votes = vec![vote_tx]; let (vote_txs, packets) = ClusterInfoVoteListener::verify_votes(votes, &bank_forks); @@ -1654,7 +1654,7 @@ mod tests { vec![100; voting_keypairs.len()], // stakes ); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = RwLock::new(BankForks::new(bank)); + let bank_forks = BankForks::new_rw_arc(bank); let vote_tx = test_vote_tx(voting_keypairs.first(), hash); let mut bad_vote = vote_tx.clone(); bad_vote.signatures[0] = Signature::default(); diff --git a/core/src/commitment_service.rs b/core/src/commitment_service.rs index bdadb1ff72..b15c6d2fec 100644 --- a/core/src/commitment_service.rs +++ b/core/src/commitment_service.rs @@ -509,7 +509,8 @@ mod tests { ); let bank0 = Bank::new_for_tests(&genesis_config); - let mut bank_forks = BankForks::new(bank0); + let bank_forks = BankForks::new_rw_arc(bank0); + let mut bank_forks = bank_forks.write().unwrap(); // Fill bank_forks with banks with votes landing in the next slot // Create enough banks such that vote account will root slots 0 and 1 diff --git a/core/src/consensus/heaviest_subtree_fork_choice.rs b/core/src/consensus/heaviest_subtree_fork_choice.rs index 639272e104..4b58ee78b9 100644 --- a/core/src/consensus/heaviest_subtree_fork_choice.rs +++ b/core/src/consensus/heaviest_subtree_fork_choice.rs @@ -244,7 +244,8 @@ impl HeaviestSubtreeForkChoice { heaviest_subtree_fork_choice } - pub fn new_from_bank_forks(bank_forks: &BankForks) -> Self { + pub fn new_from_bank_forks(bank_forks: Arc>) -> Self { + let bank_forks = bank_forks.read().unwrap(); let mut frozen_banks: Vec<_> = bank_forks.frozen_banks().values().cloned().collect(); frozen_banks.sort_by_key(|bank| bank.slot()); diff --git a/core/src/repair/ancestor_hashes_service.rs b/core/src/repair/ancestor_hashes_service.rs index f6be342939..978d0c074c 100644 --- a/core/src/repair/ancestor_hashes_service.rs +++ b/core/src/repair/ancestor_hashes_service.rs @@ -1931,7 +1931,7 @@ mod test { #[test] fn test_verify_and_process_ancestor_responses_invalid_packet() { let bank0 = Bank::default_for_tests(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank0))); + let bank_forks = BankForks::new_rw_arc(bank0); let ManageAncestorHashesState { ancestor_hashes_request_statuses, diff --git a/core/src/repair/quic_endpoint.rs b/core/src/repair/quic_endpoint.rs index 7d1cd29a32..031de37f94 100644 --- a/core/src/repair/quic_endpoint.rs +++ b/core/src/repair/quic_endpoint.rs @@ -736,7 +736,7 @@ mod tests { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(/*mint_lamports:*/ 100_000); let bank = Bank::new_for_tests(&genesis_config); - Arc::new(RwLock::new(BankForks::new(bank))) + BankForks::new_rw_arc(bank) }; let (endpoints, senders, tasks): (Vec<_>, Vec<_>, Vec<_>) = multiunzip( keypairs diff --git a/core/src/repair/repair_service.rs b/core/src/repair/repair_service.rs index 7f18ced291..20d6a01084 100644 --- a/core/src/repair/repair_service.rs +++ b/core/src/repair/repair_service.rs @@ -1183,7 +1183,7 @@ mod test { pub fn test_generate_and_send_duplicate_repairs() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let ledger_path = get_tmp_ledger_path_auto_delete!(); let blockstore = Blockstore::open(ledger_path.path()).unwrap(); let cluster_slots = ClusterSlots::default(); @@ -1282,7 +1282,7 @@ mod test { pub fn test_update_duplicate_slot_repair_addr() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let dummy_addr = Some(( Pubkey::default(), UdpSocket::bind("0.0.0.0:0").unwrap().local_addr().unwrap(), diff --git a/core/src/repair/serve_repair.rs b/core/src/repair/serve_repair.rs index 27fb63323d..ebb2d21865 100644 --- a/core/src/repair/serve_repair.rs +++ b/core/src/repair/serve_repair.rs @@ -1561,7 +1561,7 @@ mod tests { fn test_serialize_deserialize_signed_request() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let cluster_info = Arc::new(new_test_cluster_info()); let serve_repair = ServeRepair::new( cluster_info.clone(), @@ -1611,7 +1611,7 @@ mod tests { let mut bank = Bank::new_for_tests(&genesis_config); bank.feature_set = Arc::new(FeatureSet::all_enabled()); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let serve_repair = ServeRepair::new( cluster_info, bank_forks, @@ -1647,7 +1647,7 @@ mod tests { fn test_map_requests_signed() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let cluster_info = Arc::new(new_test_cluster_info()); let serve_repair = ServeRepair::new( cluster_info.clone(), @@ -1968,7 +1968,7 @@ mod tests { fn window_index_request() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let cluster_slots = ClusterSlots::default(); let cluster_info = Arc::new(new_test_cluster_info()); let serve_repair = ServeRepair::new( @@ -2299,7 +2299,7 @@ mod tests { fn test_repair_with_repair_validators() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let cluster_slots = ClusterSlots::default(); let cluster_info = Arc::new(new_test_cluster_info()); let me = cluster_info.my_contact_info(); diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs index 1e083e930b..2c5c0ff9f5 100644 --- a/core/src/replay_stage.rs +++ b/core/src/replay_stage.rs @@ -4365,7 +4365,7 @@ pub(crate) mod tests { fn test_handle_new_root() { let genesis_config = create_genesis_config(10_000).genesis_config; let bank0 = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank0))); + let bank_forks = BankForks::new_rw_arc(bank0); let root = 3; let root_bank = Bank::new_from_parent( @@ -4451,7 +4451,7 @@ pub(crate) mod tests { fn test_handle_new_root_ahead_of_highest_super_majority_root() { let genesis_config = create_genesis_config(10_000).genesis_config; let bank0 = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank0))); + let bank_forks = BankForks::new_rw_arc(bank0); let confirmed_root = 1; let fork = 2; let bank1 = Bank::new_from_parent( @@ -4854,7 +4854,7 @@ pub(crate) mod tests { } bank0.freeze(); let arc_bank0 = Arc::new(bank0); - let bank_forks = Arc::new(RwLock::new(BankForks::new_from_banks(&[arc_bank0], 0))); + let bank_forks = BankForks::new_from_banks(&[arc_bank0], 0); let exit = Arc::new(AtomicBool::new(false)); let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default())); @@ -5033,7 +5033,7 @@ pub(crate) mod tests { vote_simulator::initialize_state(&keypairs, 10_000); let mut latest_validator_votes_for_frozen_banks = LatestValidatorVotesForFrozenBanks::default(); - let bank0 = bank_forks.get(0).unwrap(); + let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let my_keypairs = keypairs.get(&my_node_pubkey).unwrap(); let vote_tx = vote_transaction::new_vote_transaction( vec![0], @@ -5045,7 +5045,6 @@ pub(crate) mod tests { None, ); - let bank_forks = RwLock::new(bank_forks); let bank1 = Bank::new_from_parent(bank0.clone(), &my_node_pubkey, 1); bank1.process_transaction(&vote_tx).unwrap(); bank1.freeze(); @@ -5378,7 +5377,7 @@ pub(crate) mod tests { ) { let stake = 10_000; let (bank_forks, _, _) = vote_simulator::initialize_state(all_keypairs, stake); - let root_bank = bank_forks.root_bank(); + let root_bank = bank_forks.read().unwrap().root_bank(); let mut propagated_stats = PropagatedStats { total_epoch_stake: stake * all_keypairs.len() as u64, ..PropagatedStats::default() @@ -5492,8 +5491,9 @@ pub(crate) mod tests { let vote_pubkey = vote_keypairs.vote_keypair.pubkey(); let keypairs: HashMap<_, _> = vec![(node_pubkey, vote_keypairs)].into_iter().collect(); let stake = 10_000; - let (mut bank_forks, mut progress_map, _) = + let (bank_forks_arc, mut progress_map, _) = vote_simulator::initialize_state(&keypairs, stake); + let mut bank_forks = bank_forks_arc.write().unwrap(); let bank0 = bank_forks.get(0).unwrap(); bank_forks.insert(Bank::new_from_parent(bank0.clone(), &Pubkey::default(), 9)); @@ -5535,12 +5535,14 @@ pub(crate) mod tests { // runs in `update_propagation_status` assert!(!progress_map.get_leader_propagation_slot_must_exist(10).0); + drop(bank_forks); + let vote_tracker = VoteTracker::default(); vote_tracker.insert_vote(10, vote_pubkey); ReplayStage::update_propagation_status( &mut progress_map, 10, - &RwLock::new(bank_forks), + &bank_forks_arc, &vote_tracker, &ClusterSlots::default(), ); @@ -5584,8 +5586,9 @@ pub(crate) mod tests { .collect(); let stake_per_validator = 10_000; - let (mut bank_forks, mut progress_map, _) = + let (bank_forks_arc, mut progress_map, _) = vote_simulator::initialize_state(&keypairs, stake_per_validator); + let mut bank_forks = bank_forks_arc.write().unwrap(); progress_map .get_propagated_stats_mut(0) .unwrap() @@ -5626,12 +5629,14 @@ pub(crate) mod tests { vote_tracker.insert_vote(10, *vote_pubkey); } + drop(bank_forks); + // The last bank should reach propagation threshold, and propagate it all // the way back through earlier leader banks ReplayStage::update_propagation_status( &mut progress_map, 10, - &RwLock::new(bank_forks), + &bank_forks_arc, &vote_tracker, &ClusterSlots::default(), ); @@ -5664,8 +5669,9 @@ pub(crate) mod tests { .collect(); let stake_per_validator = 10_000; - let (mut bank_forks, mut progress_map, _) = + let (bank_forks_arc, mut progress_map, _) = vote_simulator::initialize_state(&keypairs, stake_per_validator); + let mut bank_forks = bank_forks_arc.write().unwrap(); progress_map .get_propagated_stats_mut(0) .unwrap() @@ -5711,12 +5717,13 @@ pub(crate) mod tests { // Insert a new vote vote_tracker.insert_vote(10, vote_pubkeys[2]); + drop(bank_forks); // The last bank should reach propagation threshold, and propagate it all // the way back through earlier leader banks ReplayStage::update_propagation_status( &mut progress_map, 10, - &RwLock::new(bank_forks), + &bank_forks_arc, &vote_tracker, &ClusterSlots::default(), ); @@ -5822,7 +5829,8 @@ pub(crate) mod tests { let bank0 = Bank::new_for_tests(&genesis_config::create_genesis_config(10000).0); let parent_slot_bank = Bank::new_from_parent(Arc::new(bank0), &Pubkey::default(), parent_slot); - let mut bank_forks = BankForks::new(parent_slot_bank); + let bank_forks = BankForks::new_rw_arc(parent_slot_bank); + let mut bank_forks = bank_forks.write().unwrap(); let bank5 = Bank::new_from_parent(bank_forks.get(parent_slot).unwrap(), &Pubkey::default(), 5); bank_forks.insert(bank5); @@ -6372,7 +6380,7 @@ pub(crate) mod tests { &vote_tracker, &ClusterSlots::default(), &bank_forks, - &mut HeaviestSubtreeForkChoice::new_from_bank_forks(&bank_forks.read().unwrap()), + &mut HeaviestSubtreeForkChoice::new_from_bank_forks(bank_forks.clone()), &mut LatestValidatorVotesForFrozenBanks::default(), ); @@ -8140,7 +8148,7 @@ pub(crate) mod tests { let in_vote_only_mode = AtomicBool::new(false); let genesis_config = create_genesis_config(10_000).genesis_config; let bank0 = Bank::new_for_tests(&genesis_config); - let bank_forks = RwLock::new(BankForks::new(bank0)); + let bank_forks = BankForks::new_rw_arc(bank0); ReplayStage::check_for_vote_only_mode(1000, 0, &in_vote_only_mode, &bank_forks); assert!(in_vote_only_mode.load(Ordering::Relaxed)); ReplayStage::check_for_vote_only_mode(10, 0, &in_vote_only_mode, &bank_forks); diff --git a/core/src/tvu.rs b/core/src/tvu.rs index ec444ae440..639670479f 100644 --- a/core/src/tvu.rs +++ b/core/src/tvu.rs @@ -400,7 +400,7 @@ pub mod tests { let starting_balance = 10_000; let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(starting_balance); - let bank_forks = BankForks::new(Bank::new_for_tests(&genesis_config)); + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); let keypair = Arc::new(Keypair::new()); let (turbine_quic_endpoint_sender, _turbine_quic_endpoint_receiver) = @@ -422,7 +422,7 @@ pub mod tests { } = Blockstore::open_with_signal(&blockstore_path, BlockstoreOptions::default()) .expect("Expected to successfully open ledger"); let blockstore = Arc::new(blockstore); - let bank = bank_forks.working_bank(); + let bank = bank_forks.read().unwrap().working_bank(); let (exit, poh_recorder, poh_service, _entry_receiver) = create_test_recorder(bank.clone(), blockstore.clone(), None, None); let vote_keypair = Keypair::new(); @@ -434,7 +434,6 @@ pub mod tests { let (replay_vote_sender, _replay_vote_receiver) = unbounded(); let (completed_data_sets_sender, _completed_data_sets_receiver) = unbounded(); let (_, gossip_confirmed_slots_receiver) = unbounded(); - let bank_forks = Arc::new(RwLock::new(bank_forks)); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); let max_complete_rewards_slot = Arc::new(AtomicU64::default()); let ignored_prioritization_fee_cache = Arc::new(PrioritizationFeeCache::new(0u64)); diff --git a/core/src/validator.rs b/core/src/validator.rs index 41d7cf8c94..b67c2f0146 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -2619,7 +2619,7 @@ mod tests { ); let (genesis_config, _mint_keypair) = create_genesis_config(1); - let bank_forks = RwLock::new(BankForks::new(Bank::new_for_tests(&genesis_config))); + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); let mut config = ValidatorConfig::default_for_test(); let rpc_override_health_check = Arc::new(AtomicBool::new(false)); let start_progress = Arc::new(RwLock::new(ValidatorStartProgress::default())); @@ -2649,11 +2649,11 @@ mod tests { ); // bank=1, wait=0, should pass, bank is past the wait slot - let bank_forks = RwLock::new(BankForks::new(Bank::new_from_parent( + let bank_forks = BankForks::new_rw_arc(Bank::new_from_parent( bank_forks.read().unwrap().root_bank(), &Pubkey::default(), 1, - ))); + )); config.wait_for_supermajority = Some(0); assert!(!wait_for_supermajority( &config, diff --git a/core/src/vote_simulator.rs b/core/src/vote_simulator.rs index 50d76bf4ca..3948feab56 100644 --- a/core/src/vote_simulator.rs +++ b/core/src/vote_simulator.rs @@ -58,7 +58,7 @@ impl VoteSimulator { validator_keypairs, node_pubkeys, vote_pubkeys, - bank_forks: Arc::new(RwLock::new(bank_forks)), + bank_forks, progress, heaviest_subtree_fork_choice, latest_validator_votes_for_frozen_banks: LatestValidatorVotesForFrozenBanks::default(), @@ -297,13 +297,14 @@ impl VoteSimulator { false } + #[allow(clippy::type_complexity)] fn init_state( num_keypairs: usize, ) -> ( HashMap, Vec, Vec, - BankForks, + Arc>, ProgressMap, HeaviestSubtreeForkChoice, ) { @@ -339,7 +340,11 @@ impl VoteSimulator { pub fn initialize_state( validator_keypairs_map: &HashMap, stake: u64, -) -> (BankForks, ProgressMap, HeaviestSubtreeForkChoice) { +) -> ( + Arc>, + ProgressMap, + HeaviestSubtreeForkChoice, +) { let validator_keypairs: Vec<_> = validator_keypairs_map.values().collect(); let GenesisConfigInfo { mut genesis_config, @@ -367,7 +372,8 @@ pub fn initialize_state( 0, ForkProgress::new_from_bank(&bank0, bank0.collector_id(), &Pubkey::default(), None, 0, 0), ); - let bank_forks = BankForks::new(bank0); - let heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_bank_forks(&bank_forks); + let bank_forks = BankForks::new_rw_arc(bank0); + let heaviest_subtree_fork_choice = + HeaviestSubtreeForkChoice::new_from_bank_forks(bank_forks.clone()); (bank_forks, progress, heaviest_subtree_fork_choice) } diff --git a/core/tests/epoch_accounts_hash.rs b/core/tests/epoch_accounts_hash.rs index 3b759a0642..2595361573 100755 --- a/core/tests/epoch_accounts_hash.rs +++ b/core/tests/epoch_accounts_hash.rs @@ -116,13 +116,18 @@ impl TestEnvironment { ..snapshot_config }; - let mut bank_forks = BankForks::new(Bank::new_for_tests_with_config( + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests_with_config( &genesis_config_info.genesis_config, BankTestConfig::default(), )); - bank_forks.set_snapshot_config(Some(snapshot_config.clone())); - bank_forks.set_accounts_hash_interval_slots(Self::ACCOUNTS_HASH_INTERVAL); - let bank_forks = Arc::new(RwLock::new(bank_forks)); + bank_forks + .write() + .unwrap() + .set_snapshot_config(Some(snapshot_config.clone())); + bank_forks + .write() + .unwrap() + .set_accounts_hash_interval_slots(Self::ACCOUNTS_HASH_INTERVAL); let exit = Arc::new(AtomicBool::new(false)); let node_id = Arc::new(Keypair::new()); @@ -264,7 +269,7 @@ fn test_epoch_accounts_hash_basic(test_environment: TestEnvironment) { const NUM_EPOCHS_TO_TEST: u64 = 2; const SET_ROOT_INTERVAL: Slot = 3; - let bank_forks = &test_environment.bank_forks; + let bank_forks = test_environment.bank_forks.clone(); let mut expected_epoch_accounts_hash = None; @@ -299,6 +304,7 @@ fn test_epoch_accounts_hash_basic(test_environment: TestEnvironment) { // Set roots so that ABS requests are sent (this is what requests EAH calculations) if bank.slot().checked_rem(SET_ROOT_INTERVAL).unwrap() == 0 { trace!("rooting bank {}", bank.slot()); + bank_forks.read().unwrap().prune_program_cache(bank.slot()); bank_forks.write().unwrap().set_root( bank.slot(), &test_environment @@ -379,7 +385,7 @@ fn test_snapshots_have_expected_epoch_accounts_hash() { let test_environment = TestEnvironment::new_with_snapshots(FULL_SNAPSHOT_INTERVAL, FULL_SNAPSHOT_INTERVAL); - let bank_forks = &test_environment.bank_forks; + let bank_forks = test_environment.bank_forks.clone(); let slots_per_epoch = test_environment .genesis_config_info @@ -411,6 +417,7 @@ fn test_snapshots_have_expected_epoch_accounts_hash() { // Root every bank. This is what a normal validator does as well. // `set_root()` is also what requests snapshots and EAH calculations. + bank_forks.read().unwrap().prune_program_cache(bank.slot()); bank_forks.write().unwrap().set_root( bank.slot(), &test_environment @@ -496,7 +503,7 @@ fn test_background_services_request_handling_for_epoch_accounts_hash() { let test_environment = TestEnvironment::new_with_snapshots(FULL_SNAPSHOT_INTERVAL, FULL_SNAPSHOT_INTERVAL); - let bank_forks = &test_environment.bank_forks; + let bank_forks = test_environment.bank_forks.clone(); let snapshot_config = &test_environment.snapshot_config; let slots_per_epoch = test_environment @@ -534,6 +541,7 @@ fn test_background_services_request_handling_for_epoch_accounts_hash() { if bank.block_height() == set_root_slot { info!("Calling set_root() on bank {}...", bank.slot()); + bank_forks.read().unwrap().prune_program_cache(bank.slot()); bank_forks.write().unwrap().set_root( bank.slot(), &test_environment @@ -577,7 +585,7 @@ fn test_epoch_accounts_hash_and_warping() { solana_logger::setup(); let test_environment = TestEnvironment::new(); - let bank_forks = &test_environment.bank_forks; + let bank_forks = test_environment.bank_forks.clone(); let bank = bank_forks.read().unwrap().working_bank(); let epoch_schedule = test_environment .genesis_config_info @@ -590,6 +598,7 @@ fn test_epoch_accounts_hash_and_warping() { let eah_stop_slot_in_next_epoch = epoch_schedule.get_first_slot_in_epoch(bank.epoch() + 1) + eah_stop_offset; // have to set root here so that we can flush the write cache + bank_forks.read().unwrap().prune_program_cache(bank.slot()); bank_forks.write().unwrap().set_root( bank.slot(), &test_environment @@ -615,6 +624,7 @@ fn test_epoch_accounts_hash_and_warping() { .unwrap() .insert(Bank::new_from_parent(bank, &Pubkey::default(), slot)) .clone_without_scheduler(); + bank_forks.read().unwrap().prune_program_cache(bank.slot()); bank_forks.write().unwrap().set_root( bank.slot(), &test_environment @@ -654,6 +664,7 @@ fn test_epoch_accounts_hash_and_warping() { .unwrap() .insert(Bank::new_from_parent(bank, &Pubkey::default(), slot)) .clone_without_scheduler(); + bank_forks.read().unwrap().prune_program_cache(bank.slot()); bank_forks.write().unwrap().set_root( bank.slot(), &test_environment diff --git a/core/tests/snapshots.rs b/core/tests/snapshots.rs index 1520a410c0..a0c1aa9021 100644 --- a/core/tests/snapshots.rs +++ b/core/tests/snapshots.rs @@ -66,7 +66,7 @@ use { }; struct SnapshotTestConfig { - bank_forks: BankForks, + bank_forks: Arc>, genesis_config_info: GenesisConfigInfo, snapshot_config: SnapshotConfig, incremental_snapshot_archives_dir: TempDir, @@ -109,7 +109,8 @@ impl SnapshotTestConfig { ); bank0.freeze(); bank0.set_startup_verification_complete(); - let mut bank_forks = BankForks::new(bank0); + let bank_forks_arc = BankForks::new_rw_arc(bank0); + let mut bank_forks = bank_forks_arc.write().unwrap(); bank_forks.accounts_hash_interval_slots = accounts_hash_interval_slots; let snapshot_config = SnapshotConfig { @@ -125,7 +126,7 @@ impl SnapshotTestConfig { }; bank_forks.set_snapshot_config(Some(snapshot_config.clone())); SnapshotTestConfig { - bank_forks, + bank_forks: bank_forks_arc.clone(), genesis_config_info, snapshot_config, incremental_snapshot_archives_dir, @@ -138,11 +139,12 @@ impl SnapshotTestConfig { } fn restore_from_snapshot( - old_bank_forks: &BankForks, + old_bank_forks: Arc>, old_last_slot: Slot, old_genesis_config: &GenesisConfig, account_paths: &[PathBuf], ) { + let old_bank_forks = old_bank_forks.read().unwrap(); let snapshot_config = old_bank_forks.snapshot_config.as_ref().unwrap(); let old_last_bank = old_bank_forks.get(old_last_slot).unwrap(); @@ -198,7 +200,7 @@ fn run_bank_forks_snapshot_n( { solana_logger::setup(); // Set up snapshotting config - let mut snapshot_test_config = SnapshotTestConfig::new( + let snapshot_test_config = SnapshotTestConfig::new( snapshot_version, cluster_type, set_root_interval, @@ -206,7 +208,7 @@ fn run_bank_forks_snapshot_n( DISABLED_SNAPSHOT_ARCHIVE_INTERVAL, ); - let bank_forks = &mut snapshot_test_config.bank_forks; + let bank_forks = snapshot_test_config.bank_forks.clone(); let mint_keypair = &snapshot_test_config.genesis_config_info.mint_keypair; let (accounts_package_sender, _accounts_package_receiver) = crossbeam_channel::unbounded(); @@ -219,16 +221,22 @@ fn run_bank_forks_snapshot_n( accounts_package_sender, }; for slot in 1..=last_slot { + let mut bank_forks_w = bank_forks.write().unwrap(); let mut bank = - Bank::new_from_parent(bank_forks[slot - 1].clone(), &Pubkey::default(), slot); + Bank::new_from_parent(bank_forks_w[slot - 1].clone(), &Pubkey::default(), slot); f(&mut bank, mint_keypair); - let bank = bank_forks.insert(bank); + let bank = bank_forks_w.insert(bank); + drop(bank_forks_w); // Set root to make sure we don't end up with too many account storage entries // and to allow snapshotting of bank and the purging logic on status_cache to // kick in if slot % set_root_interval == 0 || slot == last_slot { // set_root should send a snapshot request - bank_forks.set_root(bank.slot(), &request_sender, None); + bank_forks.read().unwrap().prune_program_cache(bank.slot()); + bank_forks + .write() + .unwrap() + .set_root(bank.slot(), &request_sender, None); snapshot_request_handler.handle_snapshot_requests( false, 0, @@ -239,7 +247,7 @@ fn run_bank_forks_snapshot_n( } // Generate a snapshot package for last bank - let last_bank = bank_forks.get(last_slot).unwrap(); + let last_bank = bank_forks.read().unwrap().get(last_slot).unwrap(); let snapshot_config = &snapshot_test_config.snapshot_config; let bank_snapshots_dir = &snapshot_config.bank_snapshots_dir; let last_bank_snapshot_info = snapshot_utils::get_highest_bank_snapshot_pre(bank_snapshots_dir) @@ -278,7 +286,12 @@ fn run_bank_forks_snapshot_n( let (_tmp_dir, temporary_accounts_dir) = create_tmp_accounts_dir_for_tests(); let account_paths = &[temporary_accounts_dir]; let genesis_config = &snapshot_test_config.genesis_config_info.genesis_config; - restore_from_snapshot(bank_forks, last_slot, genesis_config, account_paths); + restore_from_snapshot( + snapshot_test_config.bank_forks.clone(), + last_slot, + genesis_config, + account_paths, + ); } #[test_case(V1_2_0, Development)] @@ -331,7 +344,7 @@ fn test_concurrent_snapshot_packaging( const MAX_BANK_SNAPSHOTS_TO_RETAIN: usize = 8; // Set up snapshotting config - let mut snapshot_test_config = SnapshotTestConfig::new( + let snapshot_test_config = SnapshotTestConfig::new( snapshot_version, cluster_type, 1, @@ -339,7 +352,7 @@ fn test_concurrent_snapshot_packaging( DISABLED_SNAPSHOT_ARCHIVE_INTERVAL, ); - let bank_forks = &mut snapshot_test_config.bank_forks; + let mut bank_forks = snapshot_test_config.bank_forks.write().unwrap(); let snapshot_config = &snapshot_test_config.snapshot_config; let bank_snapshots_dir = &snapshot_config.bank_snapshots_dir; let full_snapshot_archives_dir = &snapshot_config.full_snapshot_archives_dir; @@ -586,24 +599,31 @@ fn test_slots_to_snapshot(snapshot_version: SnapshotVersion, cluster_type: Clust for add_root_interval in &[1, 3, 9] { let (snapshot_sender, _snapshot_receiver) = unbounded(); // Make sure this test never clears bank.slots_since_snapshot - let mut snapshot_test_config = SnapshotTestConfig::new( + let snapshot_test_config = SnapshotTestConfig::new( snapshot_version, cluster_type, (*add_root_interval * num_set_roots * 2) as Slot, (*add_root_interval * num_set_roots * 2) as Slot, DISABLED_SNAPSHOT_ARCHIVE_INTERVAL, ); - let mut current_bank = snapshot_test_config.bank_forks[0].clone(); + let bank_forks = snapshot_test_config.bank_forks.clone(); + let bank_forks_r = bank_forks.read().unwrap(); + let mut current_bank = bank_forks_r[0].clone(); + drop(bank_forks_r); let request_sender = AbsRequestSender::new(snapshot_sender); for _ in 0..num_set_roots { for _ in 0..*add_root_interval { let new_slot = current_bank.slot() + 1; let new_bank = Bank::new_from_parent(current_bank, &Pubkey::default(), new_slot); - snapshot_test_config.bank_forks.insert(new_bank); - current_bank = snapshot_test_config.bank_forks[new_slot].clone(); + current_bank = bank_forks.write().unwrap().insert(new_bank).clone(); } - snapshot_test_config - .bank_forks + bank_forks + .read() + .unwrap() + .prune_program_cache(current_bank.slot()); + bank_forks + .write() + .unwrap() .set_root(current_bank.slot(), &request_sender, None); // Since the accounts background services are not runnning, EpochAccountsHash @@ -629,10 +649,10 @@ fn test_slots_to_snapshot(snapshot_version: SnapshotVersion, cluster_type: Clust let expected_slots_to_snapshot = num_old_slots as u64..=num_set_roots as u64 * *add_root_interval as u64; - let slots_to_snapshot = snapshot_test_config - .bank_forks - .get(snapshot_test_config.bank_forks.root()) + let slots_to_snapshot = bank_forks + .read() .unwrap() + .root_bank() .status_cache .read() .unwrap() @@ -704,7 +724,7 @@ fn test_bank_forks_incremental_snapshot( info!("Running bank forks incremental snapshot test, full snapshot interval: {} slots, incremental snapshot interval: {} slots, last slot: {}, set root interval: {} slots", FULL_SNAPSHOT_ARCHIVE_INTERVAL_SLOTS, INCREMENTAL_SNAPSHOT_ARCHIVE_INTERVAL_SLOTS, LAST_SLOT, SET_ROOT_INTERVAL); - let mut snapshot_test_config = SnapshotTestConfig::new( + let snapshot_test_config = SnapshotTestConfig::new( snapshot_version, cluster_type, SET_ROOT_INTERVAL, @@ -714,7 +734,7 @@ fn test_bank_forks_incremental_snapshot( trace!("SnapshotTestConfig:\naccounts_dir: {}\nbank_snapshots_dir: {}\nfull_snapshot_archives_dir: {}\nincremental_snapshot_archives_dir: {}", snapshot_test_config.accounts_dir.display(), snapshot_test_config.bank_snapshots_dir.path().display(), snapshot_test_config.full_snapshot_archives_dir.path().display(), snapshot_test_config.incremental_snapshot_archives_dir.path().display()); - let bank_forks = &mut snapshot_test_config.bank_forks; + let bank_forks = snapshot_test_config.bank_forks.clone(); let mint_keypair = &snapshot_test_config.genesis_config_info.mint_keypair; let (accounts_package_sender, _accounts_package_receiver) = crossbeam_channel::unbounded(); @@ -731,8 +751,8 @@ fn test_bank_forks_incremental_snapshot( for slot in 1..=LAST_SLOT { // Make a new bank and perform some transactions let bank = { - let bank = - Bank::new_from_parent(bank_forks[slot - 1].clone(), &Pubkey::default(), slot); + let parent = bank_forks.read().unwrap().get(slot - 1).unwrap(); + let bank = Bank::new_from_parent(parent, &Pubkey::default(), slot); let key = solana_sdk::pubkey::new_rand(); let tx = system_transaction::transfer(mint_keypair, &key, 1, bank.last_blockhash()); @@ -746,7 +766,7 @@ fn test_bank_forks_incremental_snapshot( bank.register_unique_tick(); } - bank_forks.insert(bank) + bank_forks.write().unwrap().insert(bank) }; // Set root to make sure we don't end up with too many account storage entries @@ -754,7 +774,11 @@ fn test_bank_forks_incremental_snapshot( // kick in if slot % SET_ROOT_INTERVAL == 0 { // set_root sends a snapshot request - bank_forks.set_root(bank.slot(), &request_sender, None); + bank_forks.read().unwrap().prune_program_cache(bank.slot()); + bank_forks + .write() + .unwrap() + .set_root(bank.slot(), &request_sender, None); snapshot_request_handler.handle_snapshot_requests( false, 0, @@ -964,7 +988,7 @@ fn test_snapshots_with_background_services( let (accounts_package_sender, accounts_package_receiver) = unbounded(); let (snapshot_package_sender, snapshot_package_receiver) = unbounded(); - let bank_forks = Arc::new(RwLock::new(snapshot_test_config.bank_forks)); + let bank_forks = snapshot_test_config.bank_forks.clone(); bank_forks .read() .unwrap() diff --git a/gossip/src/duplicate_shred_handler.rs b/gossip/src/duplicate_shred_handler.rs index 366eef0913..ba95178bc8 100644 --- a/gossip/src/duplicate_shred_handler.rs +++ b/gossip/src/duplicate_shred_handler.rs @@ -271,15 +271,12 @@ mod tests { let my_pubkey = my_keypair.pubkey(); let genesis_config_info = create_genesis_config_with_leader(10_000, &my_pubkey, 10_000); let GenesisConfigInfo { genesis_config, .. } = genesis_config_info; - let bank_forks = BankForks::new(Bank::new_for_tests(&genesis_config)); + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); let leader_schedule_cache = Arc::new(LeaderScheduleCache::new_from_bank( - &bank_forks.working_bank(), + &bank_forks.read().unwrap().working_bank(), )); - let mut duplicate_shred_handler = DuplicateShredHandler::new( - blockstore.clone(), - leader_schedule_cache, - Arc::new(RwLock::new(bank_forks)), - ); + let mut duplicate_shred_handler = + DuplicateShredHandler::new(blockstore.clone(), leader_schedule_cache, bank_forks); let chunks = create_duplicate_proof( my_keypair.clone(), None, @@ -340,13 +337,12 @@ mod tests { let my_pubkey = my_keypair.pubkey(); let genesis_config_info = create_genesis_config_with_leader(10_000, &my_pubkey, 10_000); let GenesisConfigInfo { genesis_config, .. } = genesis_config_info; - let bank_forks = BankForks::new(Bank::new_for_tests(&genesis_config)); + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); let leader_schedule_cache = Arc::new(LeaderScheduleCache::new_from_bank( - &bank_forks.working_bank(), + &bank_forks.read().unwrap().working_bank(), )); - let bank_forks_ptr = Arc::new(RwLock::new(bank_forks)); let mut duplicate_shred_handler = - DuplicateShredHandler::new(blockstore.clone(), leader_schedule_cache, bank_forks_ptr); + DuplicateShredHandler::new(blockstore.clone(), leader_schedule_cache, bank_forks); let start_slot: Slot = 1; // This proof will not be accepted because num_chunks is too large. diff --git a/gossip/tests/gossip.rs b/gossip/tests/gossip.rs index d9abeec31b..569f7c480d 100644 --- a/gossip/tests/gossip.rs +++ b/gossip/tests/gossip.rs @@ -309,7 +309,7 @@ pub fn cluster_info_scale() { vec![100; vote_keypairs.len()], ); let bank0 = Bank::new_for_tests(&genesis_config_info.genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank0))); + let bank_forks = BankForks::new_rw_arc(bank0); let nodes: Vec<_> = vote_keypairs .into_iter() diff --git a/ledger/src/bank_forks_utils.rs b/ledger/src/bank_forks_utils.rs index 8552a59033..c75380581f 100644 --- a/ledger/src/bank_forks_utils.rs +++ b/ledger/src/bank_forks_utils.rs @@ -189,15 +189,6 @@ pub fn load_bank_forks( (bank_forks, None) }; - bank_forks - .read() - .expect("Failed to read lock the bank forks") - .root_bank() - .loaded_programs_cache - .write() - .expect("Failed to write lock the program cache") - .set_fork_graph(bank_forks.clone()); - let mut leader_schedule_cache = LeaderScheduleCache::new_from_bank(&bank_forks.read().unwrap().root_bank()); if process_options.full_leader_cache { @@ -367,8 +358,5 @@ fn bank_forks_from_snapshot( incremental: incremental_snapshot_hash, }; - ( - Arc::new(RwLock::new(BankForks::new(bank))), - starting_snapshot_hashes, - ) + (BankForks::new_rw_arc(bank), starting_snapshot_hashes) } diff --git a/ledger/src/blockstore_processor.rs b/ledger/src/blockstore_processor.rs index d89ee2758f..bf8fa02249 100644 --- a/ledger/src/blockstore_processor.rs +++ b/ledger/src/blockstore_processor.rs @@ -717,7 +717,7 @@ pub(crate) fn process_blockstore_for_bank_0( exit, ); let bank0_slot = bank0.slot(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank0))); + let bank_forks = BankForks::new_rw_arc(bank0); info!("Processing ledger for slot 0..."); process_bank_0( @@ -3574,8 +3574,8 @@ pub mod tests { blockstore.set_roots([3, 5].iter()).unwrap(); // Set up bank1 - let mut bank_forks = BankForks::new(Bank::new_for_tests(&genesis_config)); - let bank0 = bank_forks.get_with_scheduler(0).unwrap(); + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); + let bank0 = bank_forks.read().unwrap().get_with_scheduler(0).unwrap(); let opts = ProcessOptions { run_verification: true, accounts_db_test_hash_calculation: true, @@ -3584,7 +3584,7 @@ pub mod tests { let recyclers = VerifyRecyclers::default(); process_bank_0(&bank0, &blockstore, &opts, &recyclers, None, None); let bank0_last_blockhash = bank0.last_blockhash(); - let bank1 = bank_forks.insert(Bank::new_from_parent( + let bank1 = bank_forks.write().unwrap().insert(Bank::new_from_parent( bank0.clone_without_scheduler(), &Pubkey::default(), 1, @@ -3601,7 +3601,7 @@ pub mod tests { &mut ExecuteTimings::default(), ) .unwrap(); - bank_forks.set_root( + bank_forks.write().unwrap().set_root( 1, &solana_runtime::accounts_background_service::AbsRequestSender::default(), None, @@ -3610,7 +3610,6 @@ pub mod tests { let leader_schedule_cache = LeaderScheduleCache::new_from_bank(&bank1); // Test process_blockstore_from_root() from slot 1 onwards - let bank_forks = RwLock::new(bank_forks); process_blockstore_from_root( &blockstore, &bank_forks, diff --git a/program-runtime/src/loaded_programs.rs b/program-runtime/src/loaded_programs.rs index eb4abd1821..678b2a3e18 100644 --- a/program-runtime/src/loaded_programs.rs +++ b/program-runtime/src/loaded_programs.rs @@ -455,7 +455,7 @@ pub struct LoadedPrograms { /// Environments of the current epoch pub environments: ProgramRuntimeEnvironments, pub stats: Stats, - fork_graph: Option>>, + pub fork_graph: Option>>, } impl Debug for LoadedPrograms { diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index 5da0534860..5192319aec 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -846,7 +846,7 @@ impl ProgramTest { }; let slot = bank.slot(); let last_blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let block_commitment_cache = Arc::new(RwLock::new( BlockCommitmentCache::new_for_tests_with_slots(slot, slot), )); diff --git a/rpc/src/optimistically_confirmed_bank_tracker.rs b/rpc/src/optimistically_confirmed_bank_tracker.rs index 0cd37fb8a3..6a9e0e2a8a 100644 --- a/rpc/src/optimistically_confirmed_bank_tracker.rs +++ b/rpc/src/optimistically_confirmed_bank_tracker.rs @@ -424,7 +424,7 @@ mod tests { let exit = Arc::new(AtomicBool::new(false)); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(100); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index 1a8cc045fa..a36ec712eb 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -347,10 +347,7 @@ impl JsonRpcRequestProcessor { connection_cache: Arc, ) -> Self { let genesis_hash = bank.hash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new_from_banks( - &[bank.clone()], - bank.slot(), - ))); + let bank_forks = BankForks::new_from_banks(&[bank.clone()], bank.slot()); let blockstore = Arc::new(Blockstore::open(&get_tmp_ledger_path!()).unwrap()); let exit = Arc::new(AtomicBool::new(false)); let cluster_info = Arc::new({ @@ -6634,7 +6631,7 @@ pub mod tests { let bank = Bank::new_for_tests_with_config(&genesis_config, config); ( - Arc::new(RwLock::new(BankForks::new(bank))), + BankForks::new_rw_arc(bank), mint_keypair, Arc::new(voting_keypair), ) @@ -8317,7 +8314,7 @@ pub mod tests { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(100); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); diff --git a/rpc/src/rpc_health.rs b/rpc/src/rpc_health.rs index 8a6347cc7a..aff4fa48f0 100644 --- a/rpc/src/rpc_health.rs +++ b/rpc/src/rpc_health.rs @@ -150,7 +150,7 @@ pub mod tests { let blockstore = Arc::new(Blockstore::open(ledger_path.path()).unwrap()); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(100); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let bank0 = bank_forks.read().unwrap().root_bank(); diff --git a/rpc/src/rpc_pubsub.rs b/rpc/src/rpc_pubsub.rs index e45a5f8af6..6bb6fd7854 100644 --- a/rpc/src/rpc_pubsub.rs +++ b/rpc/src/rpc_pubsub.rs @@ -684,7 +684,7 @@ mod tests { let bob_pubkey = bob.pubkey(); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); let max_complete_rewards_slot = Arc::new(AtomicU64::default()); let rpc_subscriptions = Arc::new(RpcSubscriptions::new_for_tests( @@ -813,7 +813,7 @@ mod tests { let bob_pubkey = solana_sdk::pubkey::new_rand(); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let mut io = IoHandler::<()>::default(); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); @@ -871,7 +871,7 @@ mod tests { let stake_program_id = stake::program::id(); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); @@ -999,7 +999,7 @@ mod tests { let nonce_account = Keypair::new(); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); @@ -1088,9 +1088,7 @@ mod tests { let bob_pubkey = solana_sdk::pubkey::new_rand(); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); - let bank_forks = Arc::new(RwLock::new(BankForks::new(Bank::new_for_tests( - &genesis_config, - )))); + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); let mut io = IoHandler::<()>::default(); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); @@ -1138,7 +1136,7 @@ mod tests { } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bob = Keypair::new(); let exit = Arc::new(AtomicBool::new(false)); @@ -1190,7 +1188,7 @@ mod tests { } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); @@ -1272,7 +1270,7 @@ mod tests { fn test_slot_subscribe() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); let max_complete_rewards_slot = Arc::new(AtomicU64::default()); let rpc_subscriptions = Arc::new(RpcSubscriptions::default_with_bank_forks( @@ -1305,7 +1303,7 @@ mod tests { fn test_slot_unsubscribe() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); let max_complete_rewards_slot = Arc::new(AtomicU64::default()); let rpc_subscriptions = Arc::new(RpcSubscriptions::default_with_bank_forks( @@ -1348,7 +1346,7 @@ mod tests { ); let exit = Arc::new(AtomicBool::new(false)); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); // Setup Subscriptions let optimistically_confirmed_bank = @@ -1390,7 +1388,7 @@ mod tests { fn test_vote_unsubscribe() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); let max_complete_rewards_slot = Arc::new(AtomicU64::default()); let rpc_subscriptions = Arc::new(RpcSubscriptions::default_with_bank_forks( @@ -1409,7 +1407,7 @@ mod tests { fn test_get_version() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); let max_complete_rewards_slot = Arc::new(AtomicU64::default()); let rpc_subscriptions = Arc::new(RpcSubscriptions::default_with_bank_forks( diff --git a/rpc/src/rpc_pubsub_service.rs b/rpc/src/rpc_pubsub_service.rs index 7d12feac72..76227b9708 100644 --- a/rpc/src/rpc_pubsub_service.rs +++ b/rpc/src/rpc_pubsub_service.rs @@ -491,7 +491,7 @@ mod tests { let max_complete_rewards_slot = Arc::new(AtomicU64::default()); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let subscriptions = Arc::new(RpcSubscriptions::new_for_tests( diff --git a/rpc/src/rpc_service.rs b/rpc/src/rpc_service.rs index 9c8616b874..2703a5f0af 100644 --- a/rpc/src/rpc_service.rs +++ b/rpc/src/rpc_service.rs @@ -617,7 +617,7 @@ mod tests { ip_addr, solana_net_utils::find_available_port_in_range(ip_addr, (10000, 65535)).unwrap(), ); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let ledger_path = get_tmp_ledger_path_auto_delete!(); let blockstore = Arc::new(Blockstore::open(ledger_path.path()).unwrap()); let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default())); @@ -674,7 +674,7 @@ mod tests { } = create_genesis_config(10_000); genesis_config.cluster_type = ClusterType::MainnetBeta; let bank = Bank::new_for_tests(&genesis_config); - Arc::new(RwLock::new(BankForks::new(bank))) + BankForks::new_rw_arc(bank) } #[test] diff --git a/rpc/src/rpc_subscription_tracker.rs b/rpc/src/rpc_subscription_tracker.rs index 41a2f3506c..97ceb57663 100644 --- a/rpc/src/rpc_subscription_tracker.rs +++ b/rpc/src/rpc_subscription_tracker.rs @@ -700,7 +700,7 @@ mod tests { fn subscription_info() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let mut tracker = SubscriptionsTracker::new(bank_forks); tracker.subscribe(SubscriptionParams::Slot, 0.into(), || 0); @@ -746,7 +746,7 @@ mod tests { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let mut tracker = SubscriptionsTracker::new(bank_forks); tracker.subscribe(SubscriptionParams::Slot, 0.into(), || 0); diff --git a/rpc/src/rpc_subscriptions.rs b/rpc/src/rpc_subscriptions.rs index 4a6ef24171..7a5a5628d1 100644 --- a/rpc/src/rpc_subscriptions.rs +++ b/rpc/src/rpc_subscriptions.rs @@ -1325,7 +1325,7 @@ pub(crate) mod tests { } = create_genesis_config(100); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); @@ -1471,7 +1471,7 @@ pub(crate) mod tests { } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); let rent_exempt_amount = bank.get_minimum_balance_for_rent_exemption(0); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let ledger_path = get_tmp_ledger_path_auto_delete!(); @@ -1591,7 +1591,7 @@ pub(crate) mod tests { } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); let rent_exempt_amount = bank.get_minimum_balance_for_rent_exemption(0); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let ledger_path = get_tmp_ledger_path_auto_delete!(); @@ -1709,7 +1709,7 @@ pub(crate) mod tests { } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); let rent_exempt_amount = bank.get_minimum_balance_for_rent_exemption(0); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let ledger_path = get_tmp_ledger_path_auto_delete!(); @@ -1827,7 +1827,7 @@ pub(crate) mod tests { } = create_genesis_config(100); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let alice = Keypair::new(); let tx = system_transaction::create_account( &mint_keypair, @@ -1939,7 +1939,7 @@ pub(crate) mod tests { bank.lazy_rent_collection.store(true, Relaxed); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); @@ -2134,7 +2134,7 @@ pub(crate) mod tests { bank.lazy_rent_collection.store(true, Relaxed); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); @@ -2250,7 +2250,7 @@ pub(crate) mod tests { bank.lazy_rent_collection.store(true, Relaxed); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0, &Pubkey::default(), 1); @@ -2436,7 +2436,8 @@ pub(crate) mod tests { } = create_genesis_config(100); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let mut bank_forks = BankForks::new(bank); + let bank_forks_arc = BankForks::new_rw_arc(bank); + let mut bank_forks = bank_forks_arc.write().unwrap(); let alice = Keypair::new(); let past_bank_tx = @@ -2466,8 +2467,6 @@ pub(crate) mod tests { .unwrap(); let bank1 = bank_forks[1].clone(); - let bank_forks = Arc::new(RwLock::new(bank_forks)); - let mut cache0 = BlockCommitment::default(); cache0.increase_confirmation_stake(1, 10); let cache1 = BlockCommitment::default(); @@ -2484,16 +2483,19 @@ pub(crate) mod tests { }, ); + // Drop the write locked bank_forks + drop(bank_forks); + let exit = Arc::new(AtomicBool::new(false)); let optimistically_confirmed_bank = - OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); + OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks_arc); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); let max_complete_rewards_slot = Arc::new(AtomicU64::default()); let subscriptions = Arc::new(RpcSubscriptions::new_for_tests( exit, max_complete_transaction_status_slot, max_complete_rewards_slot, - bank_forks, + bank_forks_arc, Arc::new(RwLock::new(block_commitment_cache)), optimistically_confirmed_bank, )); @@ -2660,7 +2662,7 @@ pub(crate) mod tests { let exit = Arc::new(AtomicBool::new(false)); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); @@ -2707,7 +2709,7 @@ pub(crate) mod tests { let exit = Arc::new(AtomicBool::new(false)); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let optimistically_confirmed_bank = OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); @@ -2756,7 +2758,7 @@ pub(crate) mod tests { } = create_genesis_config(100); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().get(0).unwrap(); let bank1 = Bank::new_from_parent(bank0.clone(), &Pubkey::default(), 1); bank_forks.write().unwrap().insert(bank1); @@ -2970,7 +2972,7 @@ pub(crate) mod tests { } = create_genesis_config(100); let bank = Bank::new_for_tests(&genesis_config); let blockhash = bank.last_blockhash(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let alice = Keypair::new(); @@ -3054,7 +3056,7 @@ pub(crate) mod tests { let bank = Bank::new_for_tests(&genesis_config); let max_complete_transaction_status_slot = Arc::new(AtomicU64::default()); let max_complete_rewards_slot = Arc::new(AtomicU64::default()); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let subscriptions = Arc::new(RpcSubscriptions::default_with_bank_forks( max_complete_transaction_status_slot, max_complete_rewards_slot, diff --git a/runtime/benches/prioritization_fee_cache.rs b/runtime/benches/prioritization_fee_cache.rs index 95efc8cefd..506aac4fb7 100644 --- a/runtime/benches/prioritization_fee_cache.rs +++ b/runtime/benches/prioritization_fee_cache.rs @@ -100,8 +100,8 @@ fn bench_process_transactions_multiple_slots(bencher: &mut Bencher) { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank0 = Bank::new_for_benches(&genesis_config); - let bank_forks = BankForks::new(bank0); - let bank = bank_forks.working_bank(); + let bank_forks = BankForks::new_rw_arc(bank0); + let bank = bank_forks.read().unwrap().working_bank(); let collector = solana_sdk::pubkey::new_rand(); let banks = (1..=NUM_SLOTS) .map(|n| Arc::new(Bank::new_from_parent(bank.clone(), &collector, n as u64))) diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index a20c6e3740..773a971371 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -12504,8 +12504,8 @@ fn test_runtime_feature_enable_with_program_cache() { genesis_config .accounts .remove(&feature_set::reject_callx_r10::id()); - let mut bank_forks = BankForks::new(Bank::new_for_tests(&genesis_config)); - let root_bank = bank_forks.root_bank(); + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); + let root_bank = bank_forks.read().unwrap().root_bank(); // Test a basic transfer let amount = genesis_config.rent.minimum_balance(0); @@ -12564,9 +12564,16 @@ fn test_runtime_feature_enable_with_program_cache() { // Reroot to call LoadedPrograms::prune() and end the current recompilation phase goto_end_of_slot(bank.clone()); - bank_forks.insert(Arc::into_inner(bank).unwrap()); - let bank = bank_forks.working_bank(); - bank_forks.set_root(bank.slot, &AbsRequestSender::default(), None); + bank_forks + .write() + .unwrap() + .insert(Arc::into_inner(bank).unwrap()); + let bank = bank_forks.read().unwrap().working_bank(); + bank_forks.read().unwrap().prune_program_cache(bank.slot); + bank_forks + .write() + .unwrap() + .set_root(bank.slot, &AbsRequestSender::default(), None); // Advance to next epoch, which starts the next recompilation phase let bank = new_from_parent_next_epoch(bank, 1); diff --git a/runtime/src/bank_forks.rs b/runtime/src/bank_forks.rs index 528c9d6aee..b24f3ed3e8 100644 --- a/runtime/src/bank_forks.rs +++ b/runtime/src/bank_forks.rs @@ -16,7 +16,7 @@ use { ops::Index, sync::{ atomic::{AtomicBool, AtomicU64, Ordering}, - Arc, + Arc, RwLock, }, time::Instant, }, @@ -77,7 +77,7 @@ impl Index for BankForks { } impl BankForks { - pub fn new(bank: Bank) -> Self { + pub fn new_rw_arc(bank: Bank) -> Arc> { let root = bank.slot(); Self::new_from_banks(&[Arc::new(bank)], root) } @@ -159,7 +159,7 @@ impl BankForks { self[self.root()].clone() } - pub fn new_from_banks(initial_forks: &[Arc], root: Slot) -> Self { + pub fn new_from_banks(initial_forks: &[Arc], root: Slot) -> Arc> { let mut banks = HashMap::new(); // Iterate through the heads of all the different forks @@ -189,7 +189,7 @@ impl BankForks { descendants.entry(parent).or_default().insert(*slot); } } - Self { + let bank_forks = Arc::new(RwLock::new(Self { root: Arc::new(AtomicSlot::new(root)), banks, descendants, @@ -198,7 +198,16 @@ impl BankForks { last_accounts_hash_slot: root, in_vote_only_mode: Arc::new(AtomicBool::new(false)), highest_slot_at_startup: 0, + })); + + for bank in bank_forks.read().unwrap().banks.values() { + bank.loaded_programs_cache + .write() + .unwrap() + .set_fork_graph(bank_forks.clone()); } + + bank_forks } pub fn insert(&mut self, mut bank: Bank) -> BankWithScheduler { @@ -713,7 +722,8 @@ mod tests { fn test_bank_forks_new() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let mut bank_forks = BankForks::new(bank); + let bank_forks = BankForks::new_rw_arc(bank); + let mut bank_forks = bank_forks.write().unwrap(); let child_bank = Bank::new_from_parent(bank_forks[0].clone(), &Pubkey::default(), 1); child_bank.register_default_tick_for_test(); bank_forks.insert(child_bank); @@ -728,19 +738,20 @@ mod tests { let child_bank = Arc::new(Bank::new_from_parent(bank.clone(), &Pubkey::default(), 1)); let bank_forks = BankForks::new_from_banks(&[bank.clone(), child_bank.clone()], 0); - assert_eq!(bank_forks.root(), 0); - assert_eq!(bank_forks.working_bank().slot(), 1); + assert_eq!(bank_forks.read().unwrap().root(), 0); + assert_eq!(bank_forks.read().unwrap().working_bank().slot(), 1); let bank_forks = BankForks::new_from_banks(&[child_bank, bank], 0); - assert_eq!(bank_forks.root(), 0); - assert_eq!(bank_forks.working_bank().slot(), 1); + assert_eq!(bank_forks.read().unwrap().root(), 0); + assert_eq!(bank_forks.read().unwrap().working_bank().slot(), 1); } #[test] fn test_bank_forks_descendants() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let mut bank_forks = BankForks::new(bank); + let bank_forks = BankForks::new_rw_arc(bank); + let mut bank_forks = bank_forks.write().unwrap(); let bank0 = bank_forks[0].clone(); let bank = Bank::new_from_parent(bank0.clone(), &Pubkey::default(), 1); bank_forks.insert(bank); @@ -757,7 +768,8 @@ mod tests { fn test_bank_forks_ancestors() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let mut bank_forks = BankForks::new(bank); + let bank_forks = BankForks::new_rw_arc(bank); + let mut bank_forks = bank_forks.write().unwrap(); let bank0 = bank_forks[0].clone(); let bank = Bank::new_from_parent(bank0.clone(), &Pubkey::default(), 1); bank_forks.insert(bank); @@ -775,7 +787,8 @@ mod tests { fn test_bank_forks_frozen_banks() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let mut bank_forks = BankForks::new(bank); + let bank_forks = BankForks::new_rw_arc(bank); + let mut bank_forks = bank_forks.write().unwrap(); let bank0 = bank_forks[0].clone(); let child_bank = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.insert(child_bank); @@ -787,7 +800,8 @@ mod tests { fn test_bank_forks_active_banks() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let mut bank_forks = BankForks::new(bank); + let bank_forks = BankForks::new_rw_arc(bank); + let mut bank_forks = bank_forks.write().unwrap(); let bank0 = bank_forks[0].clone(); let child_bank = Bank::new_from_parent(bank0, &Pubkey::default(), 1); bank_forks.insert(child_bank); @@ -839,11 +853,13 @@ mod tests { }; let bank0 = Bank::new_for_tests(&genesis_config); - let mut bank_forks0 = BankForks::new(bank0); + let bank_forks0 = BankForks::new_rw_arc(bank0); + let mut bank_forks0 = bank_forks0.write().unwrap(); bank_forks0.set_root(0, &abs_request_sender, None); let bank1 = Bank::new_for_tests(&genesis_config); - let mut bank_forks1 = BankForks::new(bank1); + let bank_forks1 = BankForks::new_rw_arc(bank1); + let mut bank_forks1 = bank_forks1.write().unwrap(); let additional_timestamp_secs = 2; @@ -899,10 +915,11 @@ mod tests { .collect() } - fn extend_bank_forks(bank_forks: &mut BankForks, parent_child_pairs: &[(Slot, Slot)]) { + fn extend_bank_forks(bank_forks: Arc>, parent_child_pairs: &[(Slot, Slot)]) { for (parent, child) in parent_child_pairs.iter() { - bank_forks.insert(Bank::new_from_parent( - bank_forks[*parent].clone(), + let parent: Arc = bank_forks.read().unwrap().banks[parent].clone(); + bank_forks.write().unwrap().insert(Bank::new_from_parent( + parent, &Pubkey::default(), *child, )); @@ -913,13 +930,13 @@ mod tests { fn test_bank_forks_with_set_root() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let mut bank_forks = BankForks::new(bank); + let bank_forks = BankForks::new_rw_arc(bank); let parent_child_pairs = vec![(0, 1), (1, 2), (0, 3), (3, 4)]; - extend_bank_forks(&mut bank_forks, &parent_child_pairs); + extend_bank_forks(bank_forks.clone(), &parent_child_pairs); assert_eq!( - bank_forks.ancestors(), + bank_forks.read().unwrap().ancestors(), make_hash_map(vec![ (0, vec![]), (1, vec![0]), @@ -929,7 +946,7 @@ mod tests { ]) ); assert_eq!( - bank_forks.descendants(), + bank_forks.read().unwrap().descendants(), make_hash_map(vec![ (0, vec![1, 2, 3, 4]), (1, vec![2]), @@ -938,26 +955,29 @@ mod tests { (4, vec![]), ]) ); - bank_forks.set_root( + bank_forks.write().unwrap().set_root( 2, &AbsRequestSender::default(), None, // highest confirmed root ); - bank_forks[2].squash(); - assert_eq!(bank_forks.ancestors(), make_hash_map(vec![(2, vec![]),])); + bank_forks.read().unwrap().get(2).unwrap().squash(); assert_eq!( - bank_forks.descendants(), + bank_forks.read().unwrap().ancestors(), + make_hash_map(vec![(2, vec![]),]) + ); + assert_eq!( + bank_forks.read().unwrap().descendants(), make_hash_map(vec![(0, vec![2]), (1, vec![2]), (2, vec![]),]) ); let parent_child_pairs = vec![(2, 5), (5, 6)]; - extend_bank_forks(&mut bank_forks, &parent_child_pairs); + extend_bank_forks(bank_forks.clone(), &parent_child_pairs); assert_eq!( - bank_forks.ancestors(), + bank_forks.read().unwrap().ancestors(), make_hash_map(vec![(2, vec![]), (5, vec![2]), (6, vec![2, 5])]) ); assert_eq!( - bank_forks.descendants(), + bank_forks.read().unwrap().descendants(), make_hash_map(vec![ (0, vec![2]), (1, vec![2]), @@ -973,13 +993,13 @@ mod tests { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); assert_eq!(bank.slot(), 0); - let mut bank_forks = BankForks::new(bank); + let bank_forks = BankForks::new_rw_arc(bank); let parent_child_pairs = vec![(0, 1), (1, 2), (0, 3), (3, 4)]; - extend_bank_forks(&mut bank_forks, &parent_child_pairs); + extend_bank_forks(bank_forks.clone(), &parent_child_pairs); assert_eq!( - bank_forks.ancestors(), + bank_forks.read().unwrap().ancestors(), make_hash_map(vec![ (0, vec![]), (1, vec![0]), @@ -989,7 +1009,7 @@ mod tests { ]) ); assert_eq!( - bank_forks.descendants(), + bank_forks.read().unwrap().descendants(), make_hash_map(vec![ (0, vec![1, 2, 3, 4]), (1, vec![2]), @@ -998,25 +1018,25 @@ mod tests { (4, vec![]), ]) ); - bank_forks.set_root( + bank_forks.write().unwrap().set_root( 2, &AbsRequestSender::default(), Some(1), // highest confirmed root ); - bank_forks[2].squash(); + bank_forks.read().unwrap().get(2).unwrap().squash(); assert_eq!( - bank_forks.ancestors(), + bank_forks.read().unwrap().ancestors(), make_hash_map(vec![(1, vec![]), (2, vec![]),]) ); assert_eq!( - bank_forks.descendants(), + bank_forks.read().unwrap().descendants(), make_hash_map(vec![(0, vec![1, 2]), (1, vec![2]), (2, vec![]),]) ); let parent_child_pairs = vec![(2, 5), (5, 6)]; - extend_bank_forks(&mut bank_forks, &parent_child_pairs); + extend_bank_forks(bank_forks.clone(), &parent_child_pairs); assert_eq!( - bank_forks.ancestors(), + bank_forks.read().unwrap().ancestors(), make_hash_map(vec![ (1, vec![]), (2, vec![]), @@ -1025,7 +1045,7 @@ mod tests { ]) ); assert_eq!( - bank_forks.descendants(), + bank_forks.read().unwrap().descendants(), make_hash_map(vec![ (0, vec![1, 2]), (1, vec![2]), @@ -1040,7 +1060,7 @@ mod tests { fn test_fork_graph() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let mut bank_forks = BankForks::new(bank); + let bank_forks = BankForks::new_rw_arc(bank); let parent_child_pairs = vec![ (0, 1), @@ -1053,7 +1073,7 @@ mod tests { (4, 6), (6, 12), ]; - extend_bank_forks(&mut bank_forks, &parent_child_pairs); + extend_bank_forks(bank_forks.clone(), &parent_child_pairs); // Fork graph created for the test // 0 @@ -1065,7 +1085,7 @@ mod tests { // 8 5 6 // | | // 10 12 - + let mut bank_forks = bank_forks.write().unwrap(); assert_matches!(bank_forks.relationship(0, 3), BlockRelation::Ancestor); assert_matches!(bank_forks.relationship(0, 10), BlockRelation::Ancestor); assert_matches!(bank_forks.relationship(0, 12), BlockRelation::Ancestor); diff --git a/runtime/src/prioritization_fee_cache.rs b/runtime/src/prioritization_fee_cache.rs index 5f8e3d9220..c41d5a72bd 100644 --- a/runtime/src/prioritization_fee_cache.rs +++ b/runtime/src/prioritization_fee_cache.rs @@ -612,8 +612,8 @@ mod tests { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank0 = Bank::new_for_benches(&genesis_config); - let bank_forks = BankForks::new(bank0); - let bank = bank_forks.working_bank(); + let bank_forks = BankForks::new_rw_arc(bank0); + let bank = bank_forks.read().unwrap().working_bank(); let collector = solana_sdk::pubkey::new_rand(); let bank1 = Arc::new(Bank::new_from_parent(bank.clone(), &collector, 1)); let bank2 = Arc::new(Bank::new_from_parent(bank.clone(), &collector, 2)); @@ -864,8 +864,8 @@ mod tests { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank0 = Bank::new_for_benches(&genesis_config); - let bank_forks = BankForks::new(bank0); - let bank = bank_forks.working_bank(); + let bank_forks = BankForks::new_rw_arc(bank0); + let bank = bank_forks.read().unwrap().working_bank(); let collector = solana_sdk::pubkey::new_rand(); let slot: Slot = 999; let bank1 = Arc::new(Bank::new_from_parent(bank.clone(), &collector, slot)); diff --git a/runtime/src/root_bank_cache.rs b/runtime/src/root_bank_cache.rs index 8a9ff1b8b5..09a8f2690c 100644 --- a/runtime/src/root_bank_cache.rs +++ b/runtime/src/root_bank_cache.rs @@ -60,7 +60,7 @@ mod tests { fn test_root_bank_cache() { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let mut root_bank_cache = RootBankCache::new(bank_forks.clone()); diff --git a/send-transaction-service/src/send_transaction_service.rs b/send-transaction-service/src/send_transaction_service.rs index 137160844d..27aa1bea40 100644 --- a/send-transaction-service/src/send_transaction_service.rs +++ b/send-transaction-service/src/send_transaction_service.rs @@ -826,7 +826,7 @@ mod test { fn service_exit() { let tpu_address = "127.0.0.1:0".parse().unwrap(); let bank = Bank::default_for_tests(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let (sender, receiver) = unbounded(); let connection_cache = Arc::new(ConnectionCache::new("connection_cache_test")); @@ -849,7 +849,7 @@ mod test { fn validator_exit() { let tpu_address = "127.0.0.1:0".parse().unwrap(); let bank = Bank::default_for_tests(); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let (sender, receiver) = bounded(0); let dummy_tx_info = || TransactionInfo { @@ -893,7 +893,7 @@ mod test { let (genesis_config, mint_keypair) = create_genesis_config(4); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let tpu_address = "127.0.0.1:0".parse().unwrap(); let config = Config { leader_forward_count: 1, @@ -1159,7 +1159,7 @@ mod test { let (genesis_config, mint_keypair) = create_genesis_config(4); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let tpu_address = "127.0.0.1:0".parse().unwrap(); let config = Config { leader_forward_count: 1, diff --git a/turbine/benches/cluster_info.rs b/turbine/benches/cluster_info.rs index 954e32903c..1f15137175 100644 --- a/turbine/benches/cluster_info.rs +++ b/turbine/benches/cluster_info.rs @@ -25,12 +25,7 @@ use { }, cluster_nodes::ClusterNodesCache, }, - std::{ - collections::HashMap, - net::UdpSocket, - sync::{Arc, RwLock}, - time::Duration, - }, + std::{collections::HashMap, net::UdpSocket, sync::Arc, time::Duration}, test::Bencher, }; @@ -49,7 +44,7 @@ fn broadcast_shreds_bench(bencher: &mut Bencher) { let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_benches(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); const NUM_SHREDS: usize = 32; let shred = Shred::new_from_data(0, 0, 0, &[], ShredFlags::empty(), 0, 0, 0); diff --git a/turbine/benches/retransmit_stage.rs b/turbine/benches/retransmit_stage.rs index b0dd67db82..bfd68239fe 100644 --- a/turbine/benches/retransmit_stage.rs +++ b/turbine/benches/retransmit_stage.rs @@ -32,7 +32,7 @@ use { net::{Ipv4Addr, UdpSocket}, sync::{ atomic::{AtomicUsize, Ordering}, - Arc, RwLock, + Arc, }, thread::{sleep, Builder}, time::Duration, @@ -74,9 +74,8 @@ fn bench_retransmitter(bencher: &mut Bencher) { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(100_000); let bank0 = Bank::new_for_benches(&genesis_config); - let bank_forks = BankForks::new(bank0); - let bank = bank_forks.working_bank(); - let bank_forks = Arc::new(RwLock::new(bank_forks)); + let bank_forks = BankForks::new_rw_arc(bank0); + let bank = bank_forks.read().unwrap().working_bank(); let (shreds_sender, shreds_receiver) = unbounded(); const NUM_THREADS: usize = 2; let sockets = (0..NUM_THREADS) diff --git a/turbine/src/broadcast_stage.rs b/turbine/src/broadcast_stage.rs index e9568da69e..f866747ad8 100644 --- a/turbine/src/broadcast_stage.rs +++ b/turbine/src/broadcast_stage.rs @@ -668,7 +668,7 @@ pub mod test { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank = bank_forks.read().unwrap().root_bank(); // Start up the broadcast stage diff --git a/turbine/src/broadcast_stage/standard_broadcast_run.rs b/turbine/src/broadcast_stage/standard_broadcast_run.rs index 6dcaccd9f2..f574dca0d4 100644 --- a/turbine/src/broadcast_stage/standard_broadcast_run.rs +++ b/turbine/src/broadcast_stage/standard_broadcast_run.rs @@ -544,7 +544,7 @@ mod test { genesis_config.ticks_per_slot = max_ticks_per_n_shreds(num_shreds_per_slot, None) + 1; let bank = Bank::new_for_tests(&genesis_config); - let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); + let bank_forks = BankForks::new_rw_arc(bank); let bank0 = bank_forks.read().unwrap().root_bank(); ( blockstore, diff --git a/turbine/src/quic_endpoint.rs b/turbine/src/quic_endpoint.rs index 0f362fd1a3..e9789357c0 100644 --- a/turbine/src/quic_endpoint.rs +++ b/turbine/src/quic_endpoint.rs @@ -598,7 +598,7 @@ mod tests { let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(/*mint_lamports:*/ 100_000); let bank = Bank::new_for_tests(&genesis_config); - Arc::new(RwLock::new(BankForks::new(bank))) + BankForks::new_rw_arc(bank) }; let (endpoints, senders, tasks): (Vec<_>, Vec<_>, Vec<_>) = multiunzip(keypairs.iter().zip(sockets).zip(senders).map( diff --git a/turbine/src/sigverify_shreds.rs b/turbine/src/sigverify_shreds.rs index 35e4977de8..76088a8115 100644 --- a/turbine/src/sigverify_shreds.rs +++ b/turbine/src/sigverify_shreds.rs @@ -284,7 +284,7 @@ mod tests { &create_genesis_config_with_leader(100, &leader_pubkey, 10).genesis_config, ); let leader_schedule_cache = LeaderScheduleCache::new_from_bank(&bank); - let bank_forks = RwLock::new(BankForks::new(bank)); + let bank_forks = BankForks::new_rw_arc(bank); let batch_size = 2; let mut batch = PacketBatch::with_capacity(batch_size); batch.resize(batch_size, Packet::default()); diff --git a/validator/src/admin_rpc_service.rs b/validator/src/admin_rpc_service.rs index e10ab05ea0..6958482209 100644 --- a/validator/src/admin_rpc_service.rs +++ b/validator/src/admin_rpc_service.rs @@ -917,10 +917,7 @@ mod tests { } = create_genesis_config(1_000_000_000); let bank = Bank::new_for_tests_with_config(&genesis_config, config); - ( - Arc::new(RwLock::new(BankForks::new(bank))), - Arc::new(voting_keypair), - ) + (BankForks::new_rw_arc(bank), Arc::new(voting_keypair)) } #[test]