diff --git a/bloom/Cargo.toml b/bloom/Cargo.toml index 250450e6976..bafa976eb2f 100644 --- a/bloom/Cargo.toml +++ b/bloom/Cargo.toml @@ -7,7 +7,7 @@ authors = { workspace = true } repository = { workspace = true } homepage = { workspace = true } license = { workspace = true } -edition = { workspace = true } +edition = "2024" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bloom/benches/bloom.rs b/bloom/benches/bloom.rs index afd6ac896b0..dd3ccc1e147 100644 --- a/bloom/benches/bloom.rs +++ b/bloom/benches/bloom.rs @@ -1,7 +1,7 @@ #![allow(clippy::arithmetic_side_effects)] use { - bencher::{benchmark_group, benchmark_main, Bencher}, + bencher::{Bencher, benchmark_group, benchmark_main}, bv::BitVec, fnv::FnvHasher, rand::Rng, diff --git a/core/Cargo.toml b/core/Cargo.toml index 282f37af168..6d0d5ce3af0 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -7,7 +7,7 @@ description = { workspace = true } repository = { workspace = true } homepage = { workspace = true } license = { workspace = true } -edition = { workspace = true } +edition = "2024" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/core/benches/banking_stage.rs b/core/benches/banking_stage.rs index 34677a458cd..b1df9894a99 100644 --- a/core/benches/banking_stage.rs +++ b/core/benches/banking_stage.rs @@ -16,24 +16,24 @@ use { extern crate test; use { - crossbeam_channel::{unbounded, Receiver}, + crossbeam_channel::{Receiver, unbounded}, log::*, - rand::{rng, Rng}, + rand::{Rng, rng}, rayon::prelude::*, solana_core::{banking_stage::BankingStage, banking_trace::BankingTracer}, - solana_entry::entry::{next_hash, Entry}, + solana_entry::entry::{Entry, next_hash}, solana_genesis_config::GenesisConfig, solana_hash::Hash, solana_keypair::Keypair, solana_ledger::{ blockstore::Blockstore, blockstore_processor::process_entries_for_tests, - genesis_utils::{create_genesis_config, GenesisConfigInfo}, + genesis_utils::{GenesisConfigInfo, create_genesis_config}, get_tmp_ledger_path_auto_delete, }, solana_message::Message, solana_perf::packet::to_packet_batches, - solana_poh::poh_recorder::{create_test_recorder, WorkingBankEntry}, + solana_poh::poh_recorder::{WorkingBankEntry, create_test_recorder}, solana_pubkey as pubkey, solana_runtime::{bank::Bank, bank_forks::BankForks}, solana_signature::Signature, @@ -41,10 +41,10 @@ use { solana_system_interface::instruction as system_instruction, solana_system_transaction as system_transaction, solana_time_utils::timestamp, - solana_transaction::{versioned::VersionedTransaction, Transaction}, + solana_transaction::{Transaction, versioned::VersionedTransaction}, std::{ iter::repeat_with, - sync::{atomic::Ordering, Arc}, + sync::{Arc, atomic::Ordering}, time::{Duration, Instant}, }, test::Bencher, diff --git a/core/benches/banking_trace.rs b/core/benches/banking_trace.rs index 0f532590ab8..f69082a360a 100644 --- a/core/benches/banking_trace.rs +++ b/core/benches/banking_trace.rs @@ -5,15 +5,16 @@ extern crate test; use { agave_banking_stage_ingress_types::BankingPacketBatch, solana_core::banking_trace::{ + BANKING_TRACE_DIR_DEFAULT_BYTE_LIMIT, BankingTracer, Channels, TraceError, + TracerThreadResult, for_test::{ drop_and_clean_temp_dir_unless_suppressed, sample_packet_batch, terminate_tracer, }, - receiving_loop_with_minimized_sender_overhead, BankingTracer, Channels, TraceError, - TracerThreadResult, BANKING_TRACE_DIR_DEFAULT_BYTE_LIMIT, + receiving_loop_with_minimized_sender_overhead, }, std::{ path::PathBuf, - sync::{atomic::AtomicBool, Arc}, + sync::{Arc, atomic::AtomicBool}, thread, }, tempfile::TempDir, diff --git a/core/benches/consensus.rs b/core/benches/consensus.rs index 04c0764aba2..d53d3d5ce93 100644 --- a/core/benches/consensus.rs +++ b/core/benches/consensus.rs @@ -5,7 +5,7 @@ extern crate test; use { solana_core::{ - consensus::{tower_storage::FileTowerStorage, Tower}, + consensus::{Tower, tower_storage::FileTowerStorage}, vote_simulator::VoteSimulator, }, solana_keypair::Keypair, diff --git a/core/benches/receive_and_buffer.rs b/core/benches/receive_and_buffer.rs index c8319bd915f..bce32cab29f 100644 --- a/core/benches/receive_and_buffer.rs +++ b/core/benches/receive_and_buffer.rs @@ -1,7 +1,7 @@ #[path = "receive_and_buffer_utils.rs"] mod utils; use { - criterion::{criterion_group, criterion_main, Criterion, Throughput}, + criterion::{Criterion, Throughput, criterion_group, criterion_main}, solana_core::banking_stage::transaction_scheduler::{ receive_and_buffer::{ReceiveAndBuffer, TransactionViewReceiveAndBuffer}, transaction_state_container::StateContainer, diff --git a/core/benches/receive_and_buffer_utils.rs b/core/benches/receive_and_buffer_utils.rs index d236d5c4248..a8b83517b9d 100644 --- a/core/benches/receive_and_buffer_utils.rs +++ b/core/benches/receive_and_buffer_utils.rs @@ -1,24 +1,24 @@ use { agave_banking_stage_ingress_types::BankingPacketBatch, - crossbeam_channel::{unbounded, Receiver, Sender}, + crossbeam_channel::{Receiver, Sender, unbounded}, rand::prelude::*, solana_account::AccountSharedData, solana_compute_budget_interface::ComputeBudgetInstruction, solana_core::banking_stage::{ + TOTAL_BUFFERED_PACKETS, decision_maker::BufferedPacketsDecision, transaction_scheduler::{ receive_and_buffer::{ReceiveAndBuffer, TransactionViewReceiveAndBuffer}, transaction_state_container::StateContainer, }, - TOTAL_BUFFERED_PACKETS, }, solana_genesis_config::GenesisConfig, solana_hash::Hash, solana_instruction::{AccountMeta, Instruction}, solana_keypair::Keypair, - solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo}, + solana_ledger::genesis_utils::{GenesisConfigInfo, create_genesis_config}, solana_message::{Message, VersionedMessage}, - solana_perf::packet::{to_packet_batches, PacketBatch, NUM_PACKETS}, + solana_perf::packet::{NUM_PACKETS, PacketBatch, to_packet_batches}, solana_pubkey::Pubkey, solana_runtime::{bank::Bank, bank_forks::BankForks}, solana_sdk_ids::system_program, diff --git a/core/benches/scheduler.rs b/core/benches/scheduler.rs index 0ade5a467c2..1dbf4cd0031 100644 --- a/core/benches/scheduler.rs +++ b/core/benches/scheduler.rs @@ -3,8 +3,8 @@ use jemallocator::Jemalloc; #[path = "receive_and_buffer_utils.rs"] mod utils; use { - criterion::{criterion_group, criterion_main, Criterion, Throughput}, - crossbeam_channel::{unbounded, Receiver, Sender}, + criterion::{Criterion, Throughput, criterion_group, criterion_main}, + crossbeam_channel::{Receiver, Sender, unbounded}, solana_core::banking_stage::{ scheduler_messages::{ConsumeWork, FinishedConsumeWork}, transaction_scheduler::{ diff --git a/core/benches/shredder.rs b/core/benches/shredder.rs index b3d61b96a45..8915f2ee49f 100644 --- a/core/benches/shredder.rs +++ b/core/benches/shredder.rs @@ -1,15 +1,15 @@ #![allow(clippy::arithmetic_side_effects)] use { - bencher::{benchmark_group, benchmark_main, Bencher}, + bencher::{Bencher, benchmark_group, benchmark_main}, rand::Rng, - solana_entry::entry::{create_ticks, Entry}, + solana_entry::entry::{Entry, create_ticks}, solana_hash::Hash, solana_keypair::Keypair, solana_ledger::shred::{ - get_data_shred_bytes_per_batch_typical, max_entries_per_n_shred, max_ticks_per_n_shreds, - recover, ProcessShredsStats, ReedSolomonCache, Shred, Shredder, - CODING_SHREDS_PER_FEC_BLOCK, DATA_SHREDS_PER_FEC_BLOCK, + CODING_SHREDS_PER_FEC_BLOCK, DATA_SHREDS_PER_FEC_BLOCK, ProcessShredsStats, + ReedSolomonCache, Shred, Shredder, get_data_shred_bytes_per_batch_typical, + max_entries_per_n_shred, max_ticks_per_n_shreds, recover, }, solana_perf::test_tx, std::hint::black_box, diff --git a/core/benches/sigverify_stage.rs b/core/benches/sigverify_stage.rs index f12edd8c0ad..d64a1c06f82 100644 --- a/core/benches/sigverify_stage.rs +++ b/core/benches/sigverify_stage.rs @@ -3,12 +3,13 @@ extern crate solana_core; use { - bencher::{benchmark_main, Bencher, TDynBenchFn, TestDesc, TestDescAndFn, TestFn}, + bencher::{Bencher, TDynBenchFn, TestDesc, TestDescAndFn, TestFn, benchmark_main}, crossbeam_channel::unbounded, log::*, rand::{ + Rng, distr::{Distribution, Uniform}, - rng, Rng, + rng, }, solana_core::{ banking_trace::BankingTracer, @@ -19,7 +20,7 @@ use { solana_keypair::Keypair, solana_measure::measure::Measure, solana_perf::{ - packet::{to_packet_batches, PacketBatch}, + packet::{PacketBatch, to_packet_batches}, test_tx::test_tx, }, solana_signer::Signer, diff --git a/core/src/banking_simulation.rs b/core/src/banking_simulation.rs index 9df7c1a4743..53aa715c579 100644 --- a/core/src/banking_simulation.rs +++ b/core/src/banking_simulation.rs @@ -2,14 +2,14 @@ use { crate::{ banking_stage::{ + BankingStage, BankingStageHandle, LikeClusterInfo, transaction_scheduler::scheduler_controller::SchedulerConfig, unified_scheduler::ensure_banking_stage_setup, - update_bank_forks_and_poh_recorder_for_new_tpu_bank, BankingStage, BankingStageHandle, - LikeClusterInfo, + update_bank_forks_and_poh_recorder_for_new_tpu_bank, }, banking_trace::{ - BankingTracer, ChannelLabel, Channels, TimedTracedEvent, TracedEvent, TracedSender, - TracerThread, BANKING_TRACE_DIR_DEFAULT_BYTE_LIMIT, BASENAME, + BANKING_TRACE_DIR_DEFAULT_BYTE_LIMIT, BASENAME, BankingTracer, ChannelLabel, Channels, + TimedTracedEvent, TracedEvent, TracedSender, TracerThread, }, validator::BlockProductionMethod, }, @@ -17,10 +17,10 @@ use { agave_votor_messages::migration::MigrationStatus, assert_matches::assert_matches, bincode::deserialize_from, - crossbeam_channel::{bounded, unbounded, Sender}, + crossbeam_channel::{Sender, bounded, unbounded}, itertools::Itertools, log::*, - solana_clock::{Slot, DEFAULT_MS_PER_SLOT, HOLD_TRANSACTIONS_SLOT_OFFSET}, + solana_clock::{DEFAULT_MS_PER_SLOT, HOLD_TRANSACTIONS_SLOT_OFFSET, Slot}, solana_genesis_config::GenesisConfig, solana_gossip::{cluster_info::ClusterInfo, contact_info::ContactInfoQuery, node::Node}, solana_keypair::Keypair, @@ -29,13 +29,13 @@ use { leader_schedule_cache::LeaderScheduleCache, }, solana_net_utils::{ - sockets::{bind_in_range_with_config, SocketConfiguration}, SocketAddrSpace, + sockets::{SocketConfiguration, bind_in_range_with_config}, }, solana_poh::{ poh_controller::PohController, - poh_recorder::{PohRecorder, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS}, - poh_service::{PohService, DEFAULT_HASHES_PER_BATCH, DEFAULT_PINNED_CPU_CORE}, + poh_recorder::{GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS, PohRecorder}, + poh_service::{DEFAULT_HASHES_PER_BATCH, DEFAULT_PINNED_CPU_CORE, PohService}, record_channels::record_channels, transaction_recorder::TransactionRecorder, }, @@ -57,10 +57,10 @@ use { net::{IpAddr, Ipv4Addr}, path::PathBuf, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, JoinHandle}, + thread::{self, JoinHandle, sleep}, time::{Duration, Instant, SystemTime}, }, thiserror::Error, @@ -296,26 +296,26 @@ impl SimulatorLoopLogger { fn log_jitter(&self, bank: &Bank) { let old_slot = bank.slot(); - if let Some(event_time) = self.freeze_time_by_slot.get(&old_slot) { - if log_enabled!(log::Level::Info) { - let current_simulation_time = SystemTime::now(); - let elapsed_simulation_time = current_simulation_time - .duration_since(self.base_simulation_time) - .unwrap(); - let elapsed_event_time = event_time.duration_since(self.base_event_time).unwrap(); - info!( - "jitter(parent_slot: {}): {}{:?} (sim: {:?} event: {:?})", - old_slot, - if elapsed_simulation_time > elapsed_event_time { - "+" - } else { - "-" - }, - elapsed_simulation_time.abs_diff(elapsed_event_time), - elapsed_simulation_time, - elapsed_event_time, - ); - } + if let Some(event_time) = self.freeze_time_by_slot.get(&old_slot) + && log_enabled!(log::Level::Info) + { + let current_simulation_time = SystemTime::now(); + let elapsed_simulation_time = current_simulation_time + .duration_since(self.base_simulation_time) + .unwrap(); + let elapsed_event_time = event_time.duration_since(self.base_event_time).unwrap(); + info!( + "jitter(parent_slot: {}): {}{:?} (sim: {:?} event: {:?})", + old_slot, + if elapsed_simulation_time > elapsed_event_time { + "+" + } else { + "-" + }, + elapsed_simulation_time.abs_diff(elapsed_event_time), + elapsed_simulation_time, + elapsed_event_time, + ); } } diff --git a/core/src/banking_stage.rs b/core/src/banking_stage.rs index 0caa0b34c57..4998334dba6 100644 --- a/core/src/banking_stage.rs +++ b/core/src/banking_stage.rs @@ -15,7 +15,7 @@ use { transaction_scheduler::{ prio_graph_scheduler::PrioGraphScheduler, scheduler_controller::{ - SchedulerConfig, SchedulerController, DEFAULT_SCHEDULER_PACING_FILL_TIME_MILLIS, + DEFAULT_SCHEDULER_PACING_FILL_TIME_MILLIS, SchedulerConfig, SchedulerController, }, scheduler_error::SchedulerError, }, @@ -23,8 +23,8 @@ use { validator::BlockProductionMethod, }, agave_banking_stage_ingress_types::BankingPacketReceiver, - crossbeam_channel::{unbounded, Receiver, Sender}, - futures::{stream::FuturesUnordered, StreamExt}, + crossbeam_channel::{Receiver, Sender, unbounded}, + futures::{StreamExt, stream::FuturesUnordered}, histogram::Histogram, solana_gossip::{cluster_info::ClusterInfo, contact_info::ContactInfoQuery}, solana_ledger::blockstore_processor::TransactionStatusSender, @@ -44,8 +44,8 @@ use { num::{NonZeroU64, NonZeroUsize, Saturating}, ops::Deref, sync::{ - atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}, Arc, RwLock, + atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}, }, thread::{self, Builder, JoinHandle}, time::Duration, @@ -933,13 +933,13 @@ mod tests { solana_ledger::{ blockstore::Blockstore, genesis_utils::{ - create_genesis_config, create_genesis_config_with_leader, GenesisConfigInfo, + GenesisConfigInfo, create_genesis_config, create_genesis_config_with_leader, }, get_tmp_ledger_path_auto_delete, }, solana_perf::packet::to_packet_batches, solana_poh::{ - poh_recorder::{create_test_recorder, PohRecorderError}, + poh_recorder::{PohRecorderError, create_test_recorder}, record_channels::record_channels, transaction_recorder::RecordTransactionsSummary, }, @@ -949,7 +949,7 @@ mod tests { solana_runtime_transaction::runtime_transaction::RuntimeTransaction, solana_signer::Signer, solana_system_transaction as system_transaction, - solana_transaction::{sanitized::SanitizedTransaction, Transaction}, + solana_transaction::{Transaction, sanitized::SanitizedTransaction}, solana_vote::vote_transaction::new_tower_sync_transaction, solana_vote_program::vote_state::TowerSync, std::{sync::atomic::Ordering, thread::sleep, time::Instant}, @@ -1089,9 +1089,11 @@ mod tests { .collect(); trace!("done"); assert_eq!(entries.len(), genesis_config.ticks_per_slot as usize); - assert!(entries - .verify(&start_hash, &entry::thread_pool_for_tests()) - .status()); + assert!( + entries + .verify(&start_hash, &entry::thread_pool_for_tests()) + .status() + ); assert_eq!(entries[entries.len() - 1].hash, bank.last_blockhash()); } @@ -1209,9 +1211,11 @@ mod tests { .map(|(_bank, (entry, _tick_height))| entry), ); - assert!(entries - .verify(&blockhash, &entry::thread_pool_for_tests()) - .status()); + assert!( + entries + .verify(&blockhash, &entry::thread_pool_for_tests()) + .status() + ); for entry in entries { bank.process_entry_transactions(entry.transactions) .iter() diff --git a/core/src/banking_stage/consume_worker.rs b/core/src/banking_stage/consume_worker.rs index a1a53dfe9b7..fcafcbccc99 100644 --- a/core/src/banking_stage/consume_worker.rs +++ b/core/src/banking_stage/consume_worker.rs @@ -12,8 +12,8 @@ use { solana_time_utils::AtomicInterval, std::{ sync::{ - atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}, Arc, + atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}, }, time::{Duration, Instant}, }, @@ -94,7 +94,7 @@ impl ConsumeWorker { sleep_duration = backoff(idle_duration, &sleep_duration); } Err(TryRecvError::Disconnected) => { - return Err(ConsumeWorkerError::Recv(TryRecvError::Disconnected)) + return Err(ConsumeWorkerError::Recv(TryRecvError::Disconnected)); } } } @@ -181,18 +181,18 @@ pub(crate) mod external { committer::CommitTransactionDetails, scheduler_messages::MaxAge, transaction_scheduler::receive_and_buffer::{ - translate_to_runtime_view, PacketHandlingError, + PacketHandlingError, translate_to_runtime_view, }, }, agave_scheduler_bindings::{ + MAX_TRANSACTIONS_PER_MESSAGE, PackToWorkerMessage, SharablePubkeys, + TransactionResponseRegion, WorkerToPackMessage, pack_message_flags::{self, check_flags, execution_flags}, processed_codes, worker_message_types::{ - fee_payer_balance_flags, not_included_reasons, parsing_and_sanitization_flags, - resolve_flags, status_check_flags, CheckResponse, ExecutionResponse, + CheckResponse, ExecutionResponse, fee_payer_balance_flags, not_included_reasons, + parsing_and_sanitization_flags, resolve_flags, status_check_flags, }, - PackToWorkerMessage, SharablePubkeys, TransactionResponseRegion, WorkerToPackMessage, - MAX_TRANSACTIONS_PER_MESSAGE, }, agave_scheduling_utils::{ error::transaction_error_to_not_included_reason, @@ -204,7 +204,7 @@ pub(crate) mod external { transaction_data::TransactionData, transaction_view::SanitizedTransactionView, }, solana_account::ReadableAccount, - solana_clock::{Slot, MAX_PROCESSING_AGE}, + solana_clock::{MAX_PROCESSING_AGE, Slot}, solana_cost_model::cost_model::CostModel, solana_message::v0::LoadedAddresses, solana_pubkey::Pubkey, @@ -2128,16 +2128,16 @@ mod tests { tests::{create_slow_genesis_config, sanitize_transactions}, }, crossbeam_channel::unbounded, - solana_clock::{Slot, MAX_PROCESSING_AGE}, + solana_clock::{MAX_PROCESSING_AGE, Slot}, solana_genesis_config::GenesisConfig, solana_keypair::Keypair, solana_ledger::genesis_utils::GenesisConfigInfo, solana_message::{ - v0::{self, LoadedAddresses}, AddressLookupTableAccount, SimpleAddressLoader, VersionedMessage, + v0::{self, LoadedAddresses}, }, solana_poh::{ - record_channels::{record_channels, RecordReceiver}, + record_channels::{RecordReceiver, record_channels}, transaction_recorder::TransactionRecorder, }, solana_pubkey::Pubkey, @@ -2156,7 +2156,7 @@ mod tests { solana_transaction_error::TransactionError, std::{ collections::HashSet, - sync::{atomic::AtomicBool, RwLock}, + sync::{RwLock, atomic::AtomicBool}, }, test_case::test_case, }; diff --git a/core/src/banking_stage/consumer.rs b/core/src/banking_stage/consumer.rs index 4e1132bd38a..a6e2a6b0889 100644 --- a/core/src/banking_stage/consumer.rs +++ b/core/src/banking_stage/consumer.rs @@ -329,8 +329,8 @@ impl Consumer { }) .collect(); - let (load_and_execute_transactions_output, load_execute_us) = measure_us!(bank - .load_and_execute_transactions( + let (load_and_execute_transactions_output, load_execute_us) = + measure_us!(bank.load_and_execute_transactions( batch, MAX_PROCESSING_AGE, &mut execute_and_commit_timings.execute_timings, @@ -381,8 +381,8 @@ impl Consumer { attempted_processing_count: processing_results.len() as u64, }; - let (processed_transactions, processing_results_to_transactions_us) = - measure_us!(processing_results + let (processed_transactions, processing_results_to_transactions_us) = measure_us!( + processing_results .iter() .zip(batch.sanitized_transactions()) .filter_map(|(processing_result, tx)| { @@ -392,14 +392,16 @@ impl Consumer { None } }) - .collect_vec()); + .collect_vec() + ); let (freeze_lock, freeze_lock_us) = measure_us!(bank.freeze_lock()); execute_and_commit_timings.freeze_lock_us = freeze_lock_us; - let (record_transactions_summary, record_us) = measure_us!(self - .transaction_recorder - .record_transactions(bank.bank_id(), processed_transactions)); + let (record_transactions_summary, record_us) = measure_us!( + self.transaction_recorder + .record_transactions(bank.bank_id(), processed_transactions) + ); execute_and_commit_timings.record_us = record_us; let RecordTransactionsSummary { @@ -538,7 +540,7 @@ mod tests { crate::banking_stage::tests::{create_slow_genesis_config, sanitize_transactions}, agave_reserved_account_keys::ReservedAccountKeys, crossbeam_channel::unbounded, - solana_account::{state_traits::StateMut, AccountSharedData}, + solana_account::{AccountSharedData, state_traits::StateMut}, solana_address_lookup_table_interface::{ self as address_lookup_table, state::{AddressLookupTable, LookupTableMeta}, @@ -551,17 +553,17 @@ mod tests { solana_ledger::{ blockstore_processor::{TransactionStatusMessage, TransactionStatusSender}, genesis_utils::{ - bootstrap_validator_stake_lamports, create_genesis_config_with_leader, - GenesisConfigInfo, + GenesisConfigInfo, bootstrap_validator_stake_lamports, + create_genesis_config_with_leader, }, }, solana_message::{ - v0::{self, MessageAddressTableLookup}, MessageHeader, VersionedMessage, + v0::{self, MessageAddressTableLookup}, }, solana_nonce::{self as nonce, state::DurableNonce}, solana_nonce_account::verify_nonce_account, - solana_poh::record_channels::{record_channels, RecordReceiver}, + solana_poh::record_channels::{RecordReceiver, record_channels}, solana_pubkey::Pubkey, solana_runtime::bank_forks::BankForks, solana_runtime_transaction::runtime_transaction::RuntimeTransaction, @@ -569,7 +571,7 @@ mod tests { solana_system_interface::program as system_program, solana_system_transaction as system_transaction, solana_transaction::{ - sanitized::MessageHash, versioned::VersionedTransaction, Transaction, + Transaction, sanitized::MessageHash, versioned::VersionedTransaction, }, std::{ borrow::Cow, @@ -1283,9 +1285,11 @@ mod tests { } = process_transactions_summary; // Transaction is successfully processed, but not committed due to poh recording error. - assert!(execute_and_commit_transactions_output - .commit_transactions_result - .is_err()); + assert!( + execute_and_commit_transactions_output + .commit_transactions_result + .is_err() + ); assert_eq!( execute_and_commit_transactions_output .transaction_counts diff --git a/core/src/banking_stage/decision_maker.rs b/core/src/banking_stage/decision_maker.rs index 276edfbcaef..9103298327c 100644 --- a/core/src/banking_stage/decision_maker.rs +++ b/core/src/banking_stage/decision_maker.rs @@ -7,8 +7,8 @@ use { solana_runtime::bank::Bank, solana_unified_scheduler_pool::{BankingStageMonitor, BankingStageStatus}, std::sync::{ - atomic::{AtomicBool, Ordering::Relaxed}, Arc, + atomic::{AtomicBool, Ordering::Relaxed}, }, }; diff --git a/core/src/banking_stage/progress_tracker.rs b/core/src/banking_stage/progress_tracker.rs index adc1141e805..090fb0ce747 100644 --- a/core/src/banking_stage/progress_tracker.rs +++ b/core/src/banking_stage/progress_tracker.rs @@ -9,8 +9,8 @@ use { solana_poh::poh_recorder::SharedLeaderState, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, thread::JoinHandle, }, diff --git a/core/src/banking_stage/qos_service.rs b/core/src/banking_stage/qos_service.rs index b0a83b4c239..af1439fc1bc 100644 --- a/core/src/banking_stage/qos_service.rs +++ b/core/src/banking_stage/qos_service.rs @@ -5,8 +5,8 @@ use { super::{ - committer::CommitTransactionDetails, BatchedTransactionCostDetails, - BatchedTransactionDetails, BatchedTransactionErrorDetails, + BatchedTransactionCostDetails, BatchedTransactionDetails, BatchedTransactionErrorDetails, + committer::CommitTransactionDetails, }, agave_feature_set::FeatureSet, solana_clock::Slot, @@ -595,7 +595,7 @@ mod tests { solana_cost_model::transaction_cost::{UsageCostDetails, WritableKeysTransaction}, solana_hash::Hash, solana_keypair::Keypair, - solana_runtime::genesis_utils::{create_genesis_config, GenesisConfigInfo}, + solana_runtime::genesis_utils::{GenesisConfigInfo, create_genesis_config}, solana_runtime_transaction::runtime_transaction::RuntimeTransaction, solana_signer::Signer, solana_system_transaction as system_transaction, diff --git a/core/src/banking_stage/read_write_account_set.rs b/core/src/banking_stage/read_write_account_set.rs index 0adef25cc93..f554ec5aee1 100644 --- a/core/src/banking_stage/read_write_account_set.rs +++ b/core/src/banking_stage/read_write_account_set.rs @@ -89,8 +89,8 @@ mod tests { solana_keypair::Keypair, solana_ledger::genesis_utils::GenesisConfigInfo, solana_message::{ - v0::{self, MessageAddressTableLookup}, MessageHeader, VersionedMessage, + v0::{self, MessageAddressTableLookup}, }, solana_pubkey::Pubkey, solana_runtime::{bank::Bank, bank_forks::BankForks, genesis_utils::create_genesis_config}, diff --git a/core/src/banking_stage/tpu_to_pack.rs b/core/src/banking_stage/tpu_to_pack.rs index 50864cdbf6a..88548b7e3a6 100644 --- a/core/src/banking_stage/tpu_to_pack.rs +++ b/core/src/banking_stage/tpu_to_pack.rs @@ -3,7 +3,7 @@ use { agave_banking_stage_ingress_types::BankingPacketReceiver, - agave_scheduler_bindings::{tpu_message_flags, SharableTransactionRegion, TpuToPackMessage}, + agave_scheduler_bindings::{SharableTransactionRegion, TpuToPackMessage, tpu_message_flags}, agave_scheduling_utils::handshake::server::AgaveTpuToPackSession, rts_alloc::Allocator, solana_packet::PacketFlags, @@ -12,8 +12,8 @@ use { net::IpAddr, ptr::NonNull, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, thread::JoinHandle, time::Duration, diff --git a/core/src/banking_stage/transaction_scheduler/greedy_scheduler.rs b/core/src/banking_stage/transaction_scheduler/greedy_scheduler.rs index af1593f44ab..caa9897d46a 100644 --- a/core/src/banking_stage/transaction_scheduler/greedy_scheduler.rs +++ b/core/src/banking_stage/transaction_scheduler/greedy_scheduler.rs @@ -4,7 +4,7 @@ use { super::{ scheduler::{PreLockFilterAction, Scheduler, SchedulingSummary}, scheduler_common::{ - select_thread, SchedulingCommon, TransactionSchedulingError, TransactionSchedulingInfo, + SchedulingCommon, TransactionSchedulingError, TransactionSchedulingInfo, select_thread, }, scheduler_error::SchedulerError, transaction_priority_id::TransactionPriorityId, @@ -316,7 +316,7 @@ mod test { solana_runtime_transaction::runtime_transaction::RuntimeTransaction, solana_signer::Signer, solana_system_interface::instruction as system_instruction, - solana_transaction::{sanitized::SanitizedTransaction, Transaction}, + solana_transaction::{Transaction, sanitized::SanitizedTransaction}, std::borrow::Borrow, test_case::test_case, }; diff --git a/core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs b/core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs index 510ea2ea962..da779b717b2 100644 --- a/core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs +++ b/core/src/banking_stage/transaction_scheduler/prio_graph_scheduler.rs @@ -445,7 +445,7 @@ mod tests { scheduler_messages::{MaxAge, TransactionId}, transaction_scheduler::transaction_state_container::TransactionStateContainer, }, - crossbeam_channel::{unbounded, Receiver}, + crossbeam_channel::{Receiver, unbounded}, itertools::Itertools, solana_compute_budget_interface::ComputeBudgetInstruction, solana_hash::Hash, @@ -455,7 +455,7 @@ mod tests { solana_runtime_transaction::runtime_transaction::RuntimeTransaction, solana_signer::Signer, solana_system_interface::instruction as system_instruction, - solana_transaction::{sanitized::SanitizedTransaction, Transaction}, + solana_transaction::{Transaction, sanitized::SanitizedTransaction}, std::borrow::Borrow, }; diff --git a/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs b/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs index aa5647be6bd..fa4e2196aef 100644 --- a/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs +++ b/core/src/banking_stage/transaction_scheduler/receive_and_buffer.rs @@ -5,8 +5,8 @@ use { transaction_priority_id::TransactionPriorityId, transaction_state::TransactionState, transaction_state_container::{ - SharedBytes, StateContainer, TransactionViewState, TransactionViewStateContainer, - EXTRA_CAPACITY, + EXTRA_CAPACITY, SharedBytes, StateContainer, TransactionViewState, + TransactionViewStateContainer, }, }, crate::banking_stage::{ @@ -22,7 +22,7 @@ use { crossbeam_channel::{RecvTimeoutError, TryRecvError}, solana_accounts_db::account_locks::validate_account_locks, solana_address_lookup_table_interface::state::estimate_last_valid_slot, - solana_clock::{Epoch, Slot, MAX_PROCESSING_AGE}, + solana_clock::{Epoch, MAX_PROCESSING_AGE, Slot}, solana_cost_model::cost_model::CostModel, solana_fee_structure::FeeBudgetLimits, solana_message::v0::LoadedAddresses, @@ -575,15 +575,15 @@ mod tests { use { super::*, crate::banking_stage::tests::create_slow_genesis_config, - crossbeam_channel::{unbounded, Receiver}, + crossbeam_channel::{Receiver, unbounded}, solana_hash::Hash, solana_keypair::Keypair, solana_ledger::genesis_utils::GenesisConfigInfo, solana_message::{ - v0, AccountMeta, AddressLookupTableAccount, Instruction, VersionedMessage, + AccountMeta, AddressLookupTableAccount, Instruction, VersionedMessage, v0, }, solana_packet::{Meta, PACKET_DATA_SIZE}, - solana_perf::packet::{to_packet_batches, Packet, PacketBatch, RecycledPacketBatch}, + solana_perf::packet::{Packet, PacketBatch, RecycledPacketBatch, to_packet_batches}, solana_pubkey::Pubkey, solana_runtime::bank_forks::BankForks, solana_signer::Signer, diff --git a/core/src/banking_stage/transaction_scheduler/scheduler_common.rs b/core/src/banking_stage/transaction_scheduler/scheduler_common.rs index c9b4d59e62e..aca8a3ae51d 100644 --- a/core/src/banking_stage/transaction_scheduler/scheduler_common.rs +++ b/core/src/banking_stage/transaction_scheduler/scheduler_common.rs @@ -9,7 +9,7 @@ use { ConsumeWork, FinishedConsumeWork, MaxAge, TransactionBatchId, TransactionId, }, agave_scheduling_utils::thread_aware_account_locks::{ - ThreadAwareAccountLocks, ThreadId, ThreadSet, MAX_THREADS, + MAX_THREADS, ThreadAwareAccountLocks, ThreadId, ThreadSet, }, crossbeam_channel::{Receiver, Sender, TryRecvError}, itertools::izip, @@ -240,16 +240,16 @@ impl SchedulingCommon { // Assumption - retryable indexes are in order (sorted by workers). let mut retryable_iter = retryable_indexes.iter().peekable(); for (index, (id, transaction)) in izip!(ids, transactions).enumerate() { - if let Some(&retryable_index) = retryable_iter.peek() { - if retryable_index.index == index { - container.retry_transaction( - id, - transaction, - retryable_index.immediately_retryable, - ); - retryable_iter.next(); - continue; - } + if let Some(&retryable_index) = retryable_iter.peek() + && retryable_index.index == index + { + container.retry_transaction( + id, + transaction, + retryable_index.immediately_retryable, + ); + retryable_iter.next(); + continue; } container.remove_by_id(id); } diff --git a/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs b/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs index 7eb7de23b0e..8f3fbdf2273 100644 --- a/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs +++ b/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs @@ -10,13 +10,13 @@ use { }, crate::{ banking_stage::{ + TOTAL_BUFFERED_PACKETS, consume_worker::ConsumeWorkerMetrics, consumer::Consumer, decision_maker::{BufferedPacketsDecision, DecisionMaker}, transaction_scheduler::{ receive_and_buffer::ReceivingStats, transaction_state_container::StateContainer, }, - TOTAL_BUFFERED_PACKETS, }, validator::SchedulerPacing, }, @@ -28,8 +28,8 @@ use { std::{ num::{NonZeroU64, Saturating}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, time::{Duration, Instant}, }, @@ -151,18 +151,18 @@ where // If pacing_fill_time is greater than the bank's slot time, // adjust the pacing_fill_time to be the slot time, and warn. let fill_time = self.config.scheduler_pacing.fill_time(); - if let Some(pacing_fill_time) = fill_time.as_ref() { - if pacing_fill_time.as_nanos() > b.ns_per_slot { - warn!( - "scheduler pacing config pacing_fill_time {:?} is greater than \ - the bank's slot time {}, setting to slot time", - pacing_fill_time, b.ns_per_slot, - ); - self.config.scheduler_pacing = SchedulerPacing::FillTimeMillis( - NonZeroU64::new(b.ns_per_slot as u64 / 1_000_000) - .unwrap_or(NonZeroU64::new(1).unwrap()), - ); - } + if let Some(pacing_fill_time) = fill_time.as_ref() + && pacing_fill_time.as_nanos() > b.ns_per_slot + { + warn!( + "scheduler pacing config pacing_fill_time {:?} is greater than the \ + bank's slot time {}, setting to slot time", + pacing_fill_time, b.ns_per_slot, + ); + self.config.scheduler_pacing = SchedulerPacing::FillTimeMillis( + NonZeroU64::new(b.ns_per_slot as u64 / 1_000_000) + .unwrap_or(NonZeroU64::new(1).unwrap()), + ); } CostPacer { @@ -211,16 +211,18 @@ where let scheduling_budget = cost_pacer .expect("cost pacer must be set for Consume") .scheduling_budget(now); - let (scheduling_summary, schedule_time_us) = measure_us!(self.scheduler.schedule( - &mut self.container, - scheduling_budget, - bank.feature_set - .is_active(&agave_feature_set::relax_intrabatch_account_locks::ID), - |txs, results| { - Self::pre_graph_filter(txs, results, bank, MAX_PROCESSING_AGE) - }, - |_| PreLockFilterAction::AttemptToSchedule // no pre-lock filter for now - )?); + let (scheduling_summary, schedule_time_us) = measure_us!( + self.scheduler.schedule( + &mut self.container, + scheduling_budget, + bank.feature_set + .is_active(&agave_feature_set::relax_intrabatch_account_locks::ID), + |txs, results| { + Self::pre_graph_filter(txs, results, bank, MAX_PROCESSING_AGE) + }, + |_| PreLockFilterAction::AttemptToSchedule // no pre-lock filter for now + )? + ); self.count_metrics.update(|count_metrics| { count_metrics.num_scheduled += scheduling_summary.num_scheduled; @@ -453,16 +455,16 @@ mod tests { use { super::*, crate::banking_stage::{ + TransactionViewReceiveAndBuffer, consumer::{RetryableIndex, TARGET_NUM_TRANSACTIONS_PER_BATCH}, scheduler_messages::{ConsumeWork, FinishedConsumeWork, TransactionBatchId}, tests::create_slow_genesis_config, transaction_scheduler::prio_graph_scheduler::{ PrioGraphScheduler, PrioGraphSchedulerConfig, }, - TransactionViewReceiveAndBuffer, }, agave_banking_stage_ingress_types::{BankingPacketBatch, BankingPacketReceiver}, - crossbeam_channel::{unbounded, Receiver, Sender}, + crossbeam_channel::{Receiver, Sender, unbounded}, itertools::Itertools, solana_compute_budget_interface::ComputeBudgetInstruction, solana_fee_calculator::FeeRateGovernor, @@ -470,7 +472,7 @@ mod tests { solana_keypair::Keypair, solana_ledger::genesis_utils::GenesisConfigInfo, solana_message::Message, - solana_perf::packet::{to_packet_batches, PacketBatch, NUM_PACKETS}, + solana_perf::packet::{NUM_PACKETS, PacketBatch, to_packet_batches}, solana_poh::poh_recorder::{LeaderState, SharedLeaderState}, solana_pubkey::Pubkey, solana_runtime::bank::Bank, @@ -617,18 +619,20 @@ mod tests { .unwrap_or_default() {} let now = Instant::now(); - assert!(scheduler_controller - .process_transactions( - &decision, - Some(&CostPacer { - block_limit: u64::MAX, - shared_block_cost: SharedBlockCost::new(0), - detection_time: now.checked_sub(Duration::from_millis(400)).unwrap(), - fill_time: Some(Duration::from_millis(300)), - }), - &now - ) - .is_ok()); + assert!( + scheduler_controller + .process_transactions( + &decision, + Some(&CostPacer { + block_limit: u64::MAX, + shared_block_cost: SharedBlockCost::new(0), + detection_time: now.checked_sub(Duration::from_millis(400)).unwrap(), + fill_time: Some(Duration::from_millis(300)), + }), + &now + ) + .is_ok() + ); } #[test] diff --git a/core/src/banking_stage/transaction_scheduler/transaction_state.rs b/core/src/banking_stage/transaction_scheduler/transaction_state.rs index ecf0debf3c7..fc9dd13ab59 100644 --- a/core/src/banking_stage/transaction_scheduler/transaction_state.rs +++ b/core/src/banking_stage/transaction_scheduler/transaction_state.rs @@ -95,7 +95,7 @@ mod tests { solana_runtime_transaction::runtime_transaction::RuntimeTransaction, solana_signer::Signer, solana_system_interface::instruction as system_instruction, - solana_transaction::{sanitized::SanitizedTransaction, Transaction}, + solana_transaction::{Transaction, sanitized::SanitizedTransaction}, }; fn create_transaction_state( diff --git a/core/src/banking_stage/transaction_scheduler/transaction_state_container.rs b/core/src/banking_stage/transaction_scheduler/transaction_state_container.rs index f9c9f58214d..f2fbdfccd04 100644 --- a/core/src/banking_stage/transaction_scheduler/transaction_state_container.rs +++ b/core/src/banking_stage/transaction_scheduler/transaction_state_container.rs @@ -64,7 +64,7 @@ pub(crate) trait StateContainer { /// Get mutable transaction state by id. fn get_mut_transaction_state(&mut self, id: TransactionId) - -> Option<&mut TransactionState>; + -> Option<&mut TransactionState>; /// Get reference to `SanitizedTransactionTTL` by id. /// Panics if the transaction does not exist. @@ -392,8 +392,8 @@ mod tests { solana_signer::Signer, solana_system_interface::instruction as system_instruction, solana_transaction::{ - sanitized::{MessageHash, SanitizedTransaction}, Transaction, + sanitized::{MessageHash, SanitizedTransaction}, }, std::collections::HashSet, }; @@ -463,9 +463,11 @@ mod tests { let non_existing_id = 7; assert!(container.get_mut_transaction_state(existing_id).is_some()); assert!(container.get_mut_transaction_state(existing_id).is_some()); - assert!(container - .get_mut_transaction_state(non_existing_id) - .is_none()); + assert!( + container + .get_mut_transaction_state(non_existing_id) + .is_none() + ); } #[test] diff --git a/core/src/banking_stage/unified_scheduler.rs b/core/src/banking_stage/unified_scheduler.rs index 5f2f360391b..7d09557e1e4 100644 --- a/core/src/banking_stage/unified_scheduler.rs +++ b/core/src/banking_stage/unified_scheduler.rs @@ -38,7 +38,7 @@ use { solana_accounts_db::account_locks::validate_account_locks, solana_address_lookup_table_interface::state::estimate_last_valid_slot, solana_clock::Slot, - solana_message::{v0::LoadedAddresses, SimpleAddressLoader}, + solana_message::{SimpleAddressLoader, v0::LoadedAddresses}, solana_poh::{poh_recorder::PohRecorder, transaction_recorder::TransactionRecorder}, solana_runtime::{bank::Bank, bank_forks::BankForks}, solana_runtime_transaction::{ @@ -49,7 +49,7 @@ use { }, solana_transaction::{ sanitized::{MessageHash, SanitizedTransaction}, - versioned::{sanitized::SanitizedVersionedTransaction, VersionedTransaction}, + versioned::{VersionedTransaction, sanitized::SanitizedVersionedTransaction}, }, solana_transaction_error::AddressLoaderError, solana_unified_scheduler_pool::{BankingStageHelper, DefaultSchedulerPool}, diff --git a/core/src/banking_stage/vote_packet_receiver.rs b/core/src/banking_stage/vote_packet_receiver.rs index bf3f7ee7573..0167b167a75 100644 --- a/core/src/banking_stage/vote_packet_receiver.rs +++ b/core/src/banking_stage/vote_packet_receiver.rs @@ -1,7 +1,7 @@ use { super::{ - latest_validator_vote_packet::VoteSource, leader_slot_metrics::LeaderSlotMetricsTracker, - vote_storage::VoteStorage, BankingStageStats, + BankingStageStats, latest_validator_vote_packet::VoteSource, + leader_slot_metrics::LeaderSlotMetricsTracker, vote_storage::VoteStorage, }, crate::banking_stage::transaction_scheduler::transaction_state_container::SharedBytes, agave_banking_stage_ingress_types::BankingPacketReceiver, @@ -12,7 +12,7 @@ use { solana_measure::{measure::Measure, measure_us}, std::{ num::Saturating, - sync::{atomic::Ordering, Arc}, + sync::{Arc, atomic::Ordering}, time::{Duration, Instant}, }, }; diff --git a/core/src/banking_stage/vote_storage.rs b/core/src/banking_stage/vote_storage.rs index eafa88038dc..58a6fe38f26 100644 --- a/core/src/banking_stage/vote_storage.rs +++ b/core/src/banking_stage/vote_storage.rs @@ -5,7 +5,7 @@ use { agave_transaction_view::transaction_view::SanitizedTransactionView, ahash::HashMap, itertools::Itertools, - rand::{rng, Rng}, + rand::{Rng, rng}, solana_account::from_account, solana_clock::Epoch, solana_pubkey::Pubkey, @@ -435,12 +435,16 @@ pub(crate) mod tests { None, ); - assert!(vote_storage - .update_latest_vote(vote_a, false /* should replenish */) - .is_none()); - assert!(vote_storage - .update_latest_vote(vote_b, false /* should replenish */) - .is_none()); + assert!( + vote_storage + .update_latest_vote(vote_a, false /* should replenish */) + .is_none() + ); + assert!( + vote_storage + .update_latest_vote(vote_b, false /* should replenish */) + .is_none() + ); assert_eq!(2, vote_storage.len()); assert_eq!( diff --git a/core/src/banking_stage/vote_worker.rs b/core/src/banking_stage/vote_worker.rs index b5ad62b7a6b..322ca519097 100644 --- a/core/src/banking_stage/vote_worker.rs +++ b/core/src/banking_stage/vote_worker.rs @@ -1,5 +1,6 @@ use { super::{ + BankingStageStats, SLOT_BOUNDARY_CHECK_PERIOD, consumer::Consumer, decision_maker::{BufferedPacketsDecision, DecisionMaker}, latest_validator_vote_packet::VoteSource, @@ -8,7 +9,6 @@ use { }, vote_packet_receiver::VotePacketReceiver, vote_storage::VoteStorage, - BankingStageStats, SLOT_BOUNDARY_CHECK_PERIOD, }, crate::banking_stage::{ consumer::{ExecuteAndCommitTransactionsOutput, ProcessTransactionBatchOutput}, @@ -38,8 +38,8 @@ use { solana_transaction_error::TransactionError, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, time::Instant, }, @@ -95,8 +95,11 @@ impl VoteWorker { if !self.storage.is_empty() || last_metrics_update.elapsed() >= SLOT_BOUNDARY_CHECK_PERIOD { - let (_, process_buffered_packets_us) = measure_us!(self - .process_buffered_packets(&mut banking_stage_stats, &mut slot_metrics_tracker)); + let (_, process_buffered_packets_us) = + measure_us!(self.process_buffered_packets( + &mut banking_stage_stats, + &mut slot_metrics_tracker + )); slot_metrics_tracker .increment_process_buffered_packets_us(process_buffered_packets_us); last_metrics_update = Instant::now(); @@ -294,8 +297,8 @@ impl VoteWorker { return None; } - let (process_transactions_summary, process_packets_transactions_us) = measure_us!(self - .process_packets_transactions( + let (process_transactions_summary, process_packets_transactions_us) = + measure_us!(self.process_packets_transactions( bank, sanitized_transactions, banking_stage_stats, diff --git a/core/src/banking_trace.rs b/core/src/banking_trace.rs index 3a73123dcbe..220dd739e52 100644 --- a/core/src/banking_trace.rs +++ b/core/src/banking_trace.rs @@ -4,7 +4,7 @@ use { agave_banking_stage_ingress_types::{BankingPacketBatch, BankingPacketReceiver}, bincode::serialize_into, chrono::{DateTime, Local}, - crossbeam_channel::{unbounded, Receiver, SendError, Sender, TryRecvError}, + crossbeam_channel::{Receiver, SendError, Sender, TryRecvError, unbounded}, rolling_file::{RollingCondition, RollingConditionBasic, RollingFileAppender}, serde::{Deserialize, Serialize}, solana_clock::Slot, @@ -14,10 +14,10 @@ use { io::{self, Write}, path::PathBuf, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, JoinHandle}, + thread::{self, JoinHandle, sleep}, time::{Duration, SystemTime}, }, thiserror::Error, @@ -272,12 +272,12 @@ impl BankingTracer { } fn trace_event(&self, on_trace: impl Fn() -> TimedTracedEvent) { - if let Some(ActiveTracer { trace_sender, exit }) = &self.active_tracer { - if !exit.load(Ordering::Relaxed) { - trace_sender - .send(on_trace()) - .expect("active tracer thread unless exited"); - } + if let Some(ActiveTracer { trace_sender, exit }) = &self.active_tracer + && !exit.load(Ordering::Relaxed) + { + trace_sender + .send(on_trace()) + .expect("active tracer thread unless exited"); } } @@ -482,18 +482,18 @@ impl TracedSender { } pub fn send(&self, batch: BankingPacketBatch) -> Result<(), SendError> { - if let Some(ActiveTracer { trace_sender, exit }) = &self.active_tracer { - if !exit.load(Ordering::Relaxed) { - trace_sender - .send(TimedTracedEvent( - SystemTime::now(), - TracedEvent::PacketBatch(self.label, BankingPacketBatch::clone(&batch)), - )) - .map_err(|err| { - error!("unexpected error when tracing a banking event...: {err:?}"); - SendError(BankingPacketBatch::clone(&batch)) - })?; - } + if let Some(ActiveTracer { trace_sender, exit }) = &self.active_tracer + && !exit.load(Ordering::Relaxed) + { + trace_sender + .send(TimedTracedEvent( + SystemTime::now(), + TracedEvent::PacketBatch(self.label, BankingPacketBatch::clone(&batch)), + )) + .map_err(|err| { + error!("unexpected error when tracing a banking event...: {err:?}"); + SendError(BankingPacketBatch::clone(&batch)) + })?; } self.current_sender().send(batch) } diff --git a/core/src/block_creation_loop.rs b/core/src/block_creation_loop.rs index ac3f5638ef8..7406a9d34ad 100644 --- a/core/src/block_creation_loop.rs +++ b/core/src/block_creation_loop.rs @@ -21,7 +21,7 @@ use { }, solana_measure::measure::Measure, solana_poh::{ - poh_recorder::{PohRecorder, PohRecorderError, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS}, + poh_recorder::{GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS, PohRecorder, PohRecorderError}, record_channels::RecordReceiver, }, solana_pubkey::Pubkey, @@ -33,8 +33,8 @@ use { stats::{LoopMetrics, SlotMetrics}, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, Condvar, Mutex, RwLock, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, diff --git a/core/src/cluster_info_vote_listener.rs b/core/src/cluster_info_vote_listener.rs index 98b344a7dda..ebe1a19f803 100644 --- a/core/src/cluster_info_vote_listener.rs +++ b/core/src/cluster_info_vote_listener.rs @@ -8,9 +8,9 @@ use { sigverify, }, agave_banking_stage_ingress_types::BankingPacketBatch, - crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Select, Sender}, + crossbeam_channel::{Receiver, RecvTimeoutError, Select, Sender, unbounded}, log::*, - solana_clock::{Slot, DEFAULT_MS_PER_SLOT}, + solana_clock::{DEFAULT_MS_PER_SLOT, Slot}, solana_gossip::{ cluster_info::{ClusterInfo, GOSSIP_SLEEP_MILLIS}, crds::Cursor, @@ -45,10 +45,10 @@ use { collections::HashMap, iter::repeat, sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, RwLock, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::{Duration, Instant}, }, }; @@ -535,10 +535,10 @@ impl ClusterInfoVoteListener { let _ = gossip_verified_vote_hash_sender.send((*vote_pubkey, slot, hash)); } - if reached_threshold_results[0] { - if let Some(sender) = duplicate_confirmed_slot_sender { - let _ = sender.send(vec![(slot, hash)]); - } + if reached_threshold_results[0] + && let Some(sender) = duplicate_confirmed_slot_sender + { + let _ = sender.send(vec![(slot, hash)]); } if reached_threshold_results[1] { new_optimistic_confirmed_slots.push((slot, hash)); @@ -753,18 +753,18 @@ mod tests { bank::Bank, commitment::BlockCommitmentCache, genesis_utils::{ - self, create_genesis_config, GenesisConfigInfo, ValidatorVoteKeypairs, + self, GenesisConfigInfo, ValidatorVoteKeypairs, create_genesis_config, }, vote_sender_types::ReplayVoteSender, }, solana_signature::Signature, solana_signer::Signer, solana_vote::vote_transaction, - solana_vote_program::vote_state::{TowerSync, Vote, MAX_LOCKOUT_HISTORY}, + solana_vote_program::vote_state::{MAX_LOCKOUT_HISTORY, TowerSync, Vote}, std::{ collections::BTreeSet, iter::repeat_with, - sync::{atomic::AtomicU64, Arc}, + sync::{Arc, atomic::AtomicU64}, }, }; @@ -803,18 +803,22 @@ mod tests { // the ref count, which would prevent cleanup let new_voter_ = new_voter; vote_tracker.insert_vote(bank.slot(), new_voter_); - assert!(vote_tracker - .slot_vote_trackers - .read() - .unwrap() - .contains_key(&bank.slot())); + assert!( + vote_tracker + .slot_vote_trackers + .read() + .unwrap() + .contains_key(&bank.slot()) + ); let bank1 = Bank::new_from_parent(bank.clone(), &Pubkey::default(), bank.slot() + 1); vote_tracker.progress_with_new_root_bank(&bank1); - assert!(!vote_tracker - .slot_vote_trackers - .read() - .unwrap() - .contains_key(&bank.slot())); + assert!( + !vote_tracker + .slot_vote_trackers + .read() + .unwrap() + .contains_key(&bank.slot()) + ); // Check `keys` and `epoch_authorized_voters` are purged when new // root bank moves to the next epoch @@ -1099,11 +1103,13 @@ mod tests { for voting_keypairs in &validator_voting_keypairs { let pubkey = voting_keypairs.vote_keypair.pubkey(); assert!(r_slot_vote_tracker.voted.contains_key(&pubkey)); - assert!(r_slot_vote_tracker - .voted_slot_updates - .as_ref() - .unwrap() - .contains(&Arc::new(pubkey))); + assert!( + r_slot_vote_tracker + .voted_slot_updates + .as_ref() + .unwrap() + .contains(&Arc::new(pubkey)) + ); // Only the last vote in the stack of `gossip_vote` and `replay_vote_slots` // should count towards the `optimistic` vote set, let optimistic_votes_tracker = @@ -1220,11 +1226,13 @@ mod tests { for voting_keypairs in keyset { let pubkey = voting_keypairs.vote_keypair.pubkey(); assert!(r_slot_vote_tracker.voted.contains_key(&pubkey)); - assert!(r_slot_vote_tracker - .voted_slot_updates - .as_ref() - .unwrap() - .contains(&Arc::new(pubkey))); + assert!( + r_slot_vote_tracker + .voted_slot_updates + .as_ref() + .unwrap() + .contains(&Arc::new(pubkey)) + ); // All the votes were single votes, so they should all count towards // the optimistic confirmation vote set let optimistic_votes_tracker = r_slot_vote_tracker diff --git a/core/src/cluster_slots_service.rs b/core/src/cluster_slots_service.rs index 0e1cd15c8bc..502f8f20601 100644 --- a/core/src/cluster_slots_service.rs +++ b/core/src/cluster_slots_service.rs @@ -10,8 +10,8 @@ use { solana_runtime::bank_forks::BankForks, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, diff --git a/core/src/cluster_slots_service/cluster_slots.rs b/core/src/cluster_slots_service/cluster_slots.rs index 0012e4949d0..15b701bc7db 100644 --- a/core/src/cluster_slots_service/cluster_slots.rs +++ b/core/src/cluster_slots_service/cluster_slots.rs @@ -18,8 +18,8 @@ use { hash::RandomState, ops::Range, sync::{ - atomic::{AtomicU64, Ordering}, Arc, Mutex, RwLock, + atomic::{AtomicU64, Ordering}, }, }, }; @@ -502,11 +502,11 @@ impl ClusterSlots { let mut indices = Vec::with_capacity(repair_peers.len()); for (index, peer) in repair_peers.iter().enumerate() { - if let Some(stake) = slot_peers.get_support_by_pubkey(peer.pubkey()) { - if stake > 0 { - weights.push(stake.max(1)); - indices.push(index); - } + if let Some(stake) = slot_peers.get_support_by_pubkey(peer.pubkey()) + && stake > 0 + { + weights.push(stake.max(1)); + indices.push(index); } } (weights, indices) diff --git a/core/src/cluster_slots_service/slot_supporters.rs b/core/src/cluster_slots_service/slot_supporters.rs index d64842a4f4d..76f11fa2c3e 100644 --- a/core/src/cluster_slots_service/slot_supporters.rs +++ b/core/src/cluster_slots_service/slot_supporters.rs @@ -6,8 +6,8 @@ use { hash::RandomState, ptr, sync::{ - atomic::{AtomicU64, Ordering}, Arc, + atomic::{AtomicU64, Ordering}, }, }, }; diff --git a/core/src/commitment_service.rs b/core/src/commitment_service.rs index 38a8aac6cfa..595f49057d7 100644 --- a/core/src/commitment_service.rs +++ b/core/src/commitment_service.rs @@ -1,6 +1,6 @@ use { - crate::consensus::{tower_vote_state::TowerVoteState, Stake}, - crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}, + crate::consensus::{Stake, tower_vote_state::TowerVoteState}, + crossbeam_channel::{Receiver, RecvTimeoutError, Sender, unbounded}, solana_clock::Slot, solana_measure::measure::Measure, solana_metrics::datapoint_info, @@ -14,8 +14,8 @@ use { cmp::max, collections::HashMap, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::Duration, @@ -78,18 +78,20 @@ impl AggregateCommitmentService { Self { t_commitment: Builder::new() .name("solAggCommitSvc".to_string()) - .spawn(move || loop { - if exit.load(Ordering::Relaxed) { - break; - } - - if let Err(RecvTimeoutError::Disconnected) = Self::run( - &receiver, - &block_commitment_cache, - subscriptions.as_deref(), - &exit, - ) { - break; + .spawn(move || { + loop { + if exit.load(Ordering::Relaxed) { + break; + } + + if let Err(RecvTimeoutError::Disconnected) = Self::run( + &receiver, + &block_commitment_cache, + subscriptions.as_deref(), + &exit, + ) { + break; + } } }) .unwrap(), @@ -271,18 +273,18 @@ impl AggregateCommitmentService { mod tests { use { super::*, - solana_account::{state_traits::StateMut, Account, ReadableAccount}, - solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo}, + solana_account::{Account, ReadableAccount, state_traits::StateMut}, + solana_ledger::genesis_utils::{GenesisConfigInfo, create_genesis_config}, solana_pubkey::Pubkey, solana_runtime::{ - genesis_utils::{create_genesis_config_with_vote_accounts, ValidatorVoteKeypairs}, + genesis_utils::{ValidatorVoteKeypairs, create_genesis_config_with_vote_accounts}, stake_utils, }, solana_signer::Signer, solana_vote::vote_transaction, solana_vote_program::vote_state::{ - self, process_slot_vote_unchecked, TowerSync, VoteStateV4, VoteStateVersions, - MAX_LOCKOUT_HISTORY, + self, MAX_LOCKOUT_HISTORY, TowerSync, VoteStateV4, VoteStateVersions, + process_slot_vote_unchecked, }, }; diff --git a/core/src/completed_data_sets_service.rs b/core/src/completed_data_sets_service.rs index 840e46b4c8c..5a2c49cb63a 100644 --- a/core/src/completed_data_sets_service.rs +++ b/core/src/completed_data_sets_service.rs @@ -12,8 +12,8 @@ use { solana_signature::Signature, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::Duration, diff --git a/core/src/consensus.rs b/core/src/consensus.rs index c703e93b4d3..c855fc913bd 100644 --- a/core/src/consensus.rs +++ b/core/src/consensus.rs @@ -14,10 +14,10 @@ use { heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice, latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks, progress_map::{LockoutIntervals, ProgressMap}, - tower1_14_11::Tower1_14_11, - tower1_7_14::Tower1_7_14, tower_storage::{SavedTower, SavedTowerVersions, TowerStorage}, tower_vote_state::TowerVoteState, + tower1_7_14::Tower1_7_14, + tower1_14_11::Tower1_14_11, }, crate::{consensus::progress_map::LockoutInterval, replay_stage::DUPLICATE_THRESHOLD}, chrono::prelude::*, @@ -484,14 +484,14 @@ impl Tower { vote_slots.insert(slot); } - if start_root != vote_state.root_slot { - if let Some(root) = start_root { - // The account's prior root can be older than this fork's root; clamp to - // the same range for the same reason as above. - if root > root_slot { - trace!("ROOT: {root}"); - vote_slots.insert(root); - } + if start_root != vote_state.root_slot + && let Some(root) = start_root + { + // The account's prior root can be older than this fork's root; clamp to + // the same range for the same reason as above. + if root > root_slot { + trace!("ROOT: {root}"); + vote_slots.insert(root); } } if let Some(root) = vote_state.root_slot { @@ -703,15 +703,15 @@ impl Tower { enable_tower_sync_ix: bool, block_id: Hash, ) -> Option { - if let Some(last_voted_slot) = self.vote_state.last_voted_slot() { - if vote_slot <= last_voted_slot { - panic!( - "Error while recording vote {} {} in local tower {:?}", - vote_slot, - vote_hash, - VoteError::VoteTooOld - ); - } + if let Some(last_voted_slot) = self.vote_state.last_voted_slot() + && vote_slot <= last_voted_slot + { + panic!( + "Error while recording vote {} {} in local tower {:?}", + vote_slot, + vote_hash, + VoteError::VoteTooOld + ); } trace!("{} record_vote for {}", self.node_pubkey, vote_slot); @@ -807,10 +807,10 @@ impl Tower { if slot <= last_voted_slot { return false; } - } else if let Some(root) = self.vote_state.root_slot { - if slot <= root { - return false; - } + } else if let Some(root) = self.vote_state.root_slot + && slot <= root + { + return false; } true } @@ -841,15 +841,15 @@ impl Tower { } } - if let Some(root_slot) = vote_state.root_slot { - if slot != root_slot { - // This case should never happen because bank forks purges all - // non-descendants of the root every time root is set - assert!( - ancestors.contains(&root_slot), - "ancestors: {ancestors:?}, slot: {slot} root: {root_slot}" - ); - } + if let Some(root_slot) = vote_state.root_slot + && slot != root_slot + { + // This case should never happen because bank forks purges all + // non-descendants of the root every time root is set + assert!( + ancestors.contains(&root_slot), + "ancestors: {ancestors:?}, slot: {slot} root: {root_slot}" + ); } false @@ -1829,11 +1829,11 @@ pub mod test { solana_slot_history::SlotHistory, solana_vote::vote_account::VoteAccount, solana_vote_program::vote_state::{ - process_slot_vote_unchecked, Vote, VoteStateV4, VoteStateVersions, MAX_LOCKOUT_HISTORY, + MAX_LOCKOUT_HISTORY, Vote, VoteStateV4, VoteStateVersions, process_slot_vote_unchecked, }, std::{ collections::{HashMap, VecDeque}, - fs::{remove_file, OpenOptions}, + fs::{OpenOptions, remove_file}, io::{Read, Seek, SeekFrom, Write}, path::PathBuf, sync::Arc, @@ -1873,22 +1873,26 @@ pub mod test { fn test_to_vote_instruction() { let vote = Vote::default(); let mut decision = SwitchForkDecision::FailedSwitchThreshold(0, 1); - assert!(decision - .to_vote_instruction( - VoteTransaction::from(vote.clone()), - &Pubkey::default(), - &Pubkey::default() - ) - .is_none()); + assert!( + decision + .to_vote_instruction( + VoteTransaction::from(vote.clone()), + &Pubkey::default(), + &Pubkey::default() + ) + .is_none() + ); decision = SwitchForkDecision::FailedSwitchDuplicateRollback(0); - assert!(decision - .to_vote_instruction( - VoteTransaction::from(vote.clone()), - &Pubkey::default(), - &Pubkey::default() - ) - .is_none()); + assert!( + decision + .to_vote_instruction( + VoteTransaction::from(vote.clone()), + &Pubkey::default(), + &Pubkey::default() + ) + .is_none() + ); decision = SwitchForkDecision::SameFork; assert_eq!( @@ -1938,9 +1942,11 @@ pub mod test { // Simulate the votes for vote in votes { - assert!(vote_simulator - .simulate_vote(vote, &node_pubkey, &mut tower,) - .is_empty()); + assert!( + vote_simulator + .simulate_vote(vote, &node_pubkey, &mut tower,) + .is_empty() + ); } for i in 1..5 { @@ -2390,9 +2396,11 @@ pub mod test { vote_simulator.fill_bank_forks(forks, &cluster_votes, true); // Vote on the first minor fork at slot 14, should succeed - assert!(vote_simulator - .simulate_vote(14, &node_pubkey, &mut tower,) - .is_empty()); + assert!( + vote_simulator + .simulate_vote(14, &node_pubkey, &mut tower,) + .is_empty() + ); // The other two validators voted at slots 46, 47, which // will only both show up in slot 48, at which point @@ -2469,9 +2477,11 @@ pub mod test { // Simulate the votes. for vote in &my_votes { // All these votes should be ok - assert!(vote_simulator - .simulate_vote(*vote, &node_pubkey, &mut tower,) - .is_empty()); + assert!( + vote_simulator + .simulate_vote(*vote, &node_pubkey, &mut tower,) + .is_empty() + ); } info!("local tower: {:#?}", tower.vote_state.votes); @@ -2607,9 +2617,11 @@ pub mod test { stakes.insert(i, 1); tower.record_vote(i, Hash::default()); } - assert!(!tower - .check_vote_stake_thresholds(MAX_LOCKOUT_HISTORY as u64 + 1, &stakes, 2) - .is_empty()); + assert!( + !tower + .check_vote_stake_thresholds(MAX_LOCKOUT_HISTORY as u64 + 1, &stakes, 2) + .is_empty() + ); } #[test] @@ -2768,9 +2780,11 @@ pub mod test { for slot in 0..VOTE_THRESHOLD_DEPTH { tower.record_vote(slot as Slot, Hash::default()); } - assert!(tower - .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 4) - .is_empty()); + assert!( + tower + .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 4) + .is_empty() + ); } #[test] @@ -2782,9 +2796,11 @@ pub mod test { for slot in 0..VOTE_THRESHOLD_DEPTH { tower.record_vote(slot as Slot, Hash::default()); } - assert!(!tower - .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 10) - .is_empty()); + assert!( + !tower + .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 10) + .is_empty() + ); } #[test] @@ -2796,9 +2812,11 @@ pub mod test { for slot in 0..VOTE_THRESHOLD_DEPTH { tower.record_vote(slot as Slot, Hash::default()); } - assert!(!tower - .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 10) - .is_empty()); + assert!( + !tower + .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 10) + .is_empty() + ); } #[test] @@ -2892,9 +2910,11 @@ pub mod test { &mut LatestValidatorVotesForFrozenBanks::default(), &mut vote_slots, ); - assert!(tower - .check_vote_stake_thresholds(vote_to_evaluate, &voted_stakes, total_stake) - .is_empty()); + assert!( + tower + .check_vote_stake_thresholds(vote_to_evaluate, &voted_stakes, total_stake) + .is_empty() + ); // CASE 2: Now we want to evaluate a vote for slot VOTE_THRESHOLD_DEPTH + 1. This slot // will expire the vote in one of the vote accounts, so we should have insufficient @@ -2914,9 +2934,11 @@ pub mod test { &mut LatestValidatorVotesForFrozenBanks::default(), &mut vote_slots, ); - assert!(!tower - .check_vote_stake_thresholds(vote_to_evaluate, &voted_stakes, total_stake) - .is_empty()); + assert!( + !tower + .check_vote_stake_thresholds(vote_to_evaluate, &voted_stakes, total_stake) + .is_empty() + ); } fn vote_and_check_recent(num_votes: usize) { diff --git a/core/src/consensus/fork_choice.rs b/core/src/consensus/fork_choice.rs index 5cbf88caa73..0e073bee84a 100644 --- a/core/src/consensus/fork_choice.rs +++ b/core/src/consensus/fork_choice.rs @@ -2,9 +2,9 @@ use { super::heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice, crate::{ consensus::{ + SWITCH_FORK_THRESHOLD, SwitchForkDecision, ThresholdDecision, Tower, latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks, - progress_map::ProgressMap, SwitchForkDecision, ThresholdDecision, Tower, - SWITCH_FORK_THRESHOLD, + progress_map::ProgressMap, }, replay_stage::HeaviestForkFailures, }, diff --git a/core/src/consensus/heaviest_subtree_fork_choice.rs b/core/src/consensus/heaviest_subtree_fork_choice.rs index 3c76e7e94e8..b355e13b766 100644 --- a/core/src/consensus/heaviest_subtree_fork_choice.rs +++ b/core/src/consensus/heaviest_subtree_fork_choice.rs @@ -2,9 +2,9 @@ use trees::{Tree, TreeWalk}; use { crate::consensus::{ - fork_choice::ForkChoice, + Tower, fork_choice::ForkChoice, latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks, - progress_map::ProgressMap, tree_diff::TreeDiff, Tower, + progress_map::ProgressMap, tree_diff::TreeDiff, }, solana_clock::{Epoch, Slot}, solana_epoch_schedule::EpochSchedule, @@ -16,7 +16,7 @@ use { borrow::Borrow, cmp::Ordering, collections::{ - btree_set::Iter, hash_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet, VecDeque, + BTreeMap, BTreeSet, HashMap, HashSet, VecDeque, btree_set::Iter, hash_map::Entry, }, sync::{Arc, RwLock}, time::Instant, @@ -140,15 +140,15 @@ impl ForkInfo { my_key: &SlotHashKey, newly_valid_ancestor: Slot, ) { - if let Some(latest_invalid_ancestor) = self.latest_invalid_ancestor { - if latest_invalid_ancestor <= newly_valid_ancestor { - info!( - "Fork choice for {my_key:?} clearing latest invalid ancestor \ - {latest_invalid_ancestor:?} because {newly_valid_ancestor:?} was duplicate \ - confirmed" - ); - self.latest_invalid_ancestor = None; - } + if let Some(latest_invalid_ancestor) = self.latest_invalid_ancestor + && latest_invalid_ancestor <= newly_valid_ancestor + { + info!( + "Fork choice for {my_key:?} clearing latest invalid ancestor \ + {latest_invalid_ancestor:?} because {newly_valid_ancestor:?} was duplicate \ + confirmed" + ); + self.latest_invalid_ancestor = None; } } @@ -597,12 +597,13 @@ impl HeaviestSubtreeForkChoice { // Insert aggregate operations up to the root self.insert_aggregate_operations(&mut update_operations, *slot_hash_key); // Remove child link so that this slot cannot be chosen as best or deepest - assert!(self - .fork_infos - .get_mut(&parent) - .expect("Parent must exist in fork_infos") - .children - .remove(slot_hash_key)); + assert!( + self.fork_infos + .get_mut(&parent) + .expect("Parent must exist in fork_infos") + .children + .remove(slot_hash_key) + ); // Aggregate self.process_update_operations(update_operations); @@ -1520,9 +1521,11 @@ mod test { 5 ); - assert!(heaviest_subtree_fork_choice - .parent(&(2, Hash::default())) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .parent(&(2, Hash::default())) + .is_none() + ); } #[test] @@ -1558,10 +1561,12 @@ mod test { .map(|s| (s, Hash::default())) .collect::>() ); - assert!(heaviest_subtree_fork_choice - .ancestor_iterator((0, Hash::default())) - .next() - .is_none()); + assert!( + heaviest_subtree_fork_choice + .ancestor_iterator((0, Hash::default())) + .next() + .is_none() + ); // Set a root, everything but slots 2, 4 should be removed heaviest_subtree_fork_choice.set_tree_root((2, Hash::default())); @@ -1608,9 +1613,11 @@ mod test { HeaviestSubtreeForkChoice::new_from_frozen_banks((root, root_hash), &frozen_banks); let bank0_hash = bank_forks.read().unwrap().get(0).unwrap().hash(); - assert!(heaviest_subtree_fork_choice - .parent(&(0, bank0_hash)) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .parent(&(0, bank0_hash)) + .is_none() + ); let bank1_hash = bank_forks.read().unwrap().get(1).unwrap().hash(); assert_eq!( @@ -1648,31 +1655,39 @@ mod test { ); // Check parent and children of invalid hash don't exist let invalid_hash = Hash::new_unique(); - assert!((&heaviest_subtree_fork_choice) - .children(&(2, invalid_hash)) - .is_none()); - assert!(heaviest_subtree_fork_choice - .parent(&(2, invalid_hash)) - .is_none()); + assert!( + (&heaviest_subtree_fork_choice) + .children(&(2, invalid_hash)) + .is_none() + ); + assert!( + heaviest_subtree_fork_choice + .parent(&(2, invalid_hash)) + .is_none() + ); assert_eq!( heaviest_subtree_fork_choice.parent(&(3, bank3_hash)), Some((1, bank1_hash)) ); - assert!((&heaviest_subtree_fork_choice) - .children(&(3, bank3_hash)) - .unwrap() - .collect_vec() - .is_empty()); + assert!( + (&heaviest_subtree_fork_choice) + .children(&(3, bank3_hash)) + .unwrap() + .collect_vec() + .is_empty() + ); assert_eq!( heaviest_subtree_fork_choice.parent(&(4, bank4_hash)), Some((2, bank2_hash)) ); - assert!((&heaviest_subtree_fork_choice) - .children(&(4, bank4_hash)) - .unwrap() - .collect_vec() - .is_empty()); + assert!( + (&heaviest_subtree_fork_choice) + .children(&(4, bank4_hash)) + .unwrap() + .collect_vec() + .is_empty() + ); } #[test] @@ -1888,11 +1903,13 @@ mod test { .iter() .chain(std::iter::once(&duplicate_leaves_descended_from_4[1])) { - assert!((&heaviest_subtree_fork_choice) - .children(duplicate_leaf) - .unwrap() - .collect_vec() - .is_empty(),); + assert!( + (&heaviest_subtree_fork_choice) + .children(duplicate_leaf) + .unwrap() + .collect_vec() + .is_empty(), + ); } // Re-adding same duplicate slot should not overwrite existing one @@ -2244,14 +2261,9 @@ mod test { } }; - let expected_deepest_slot = - |slot, _heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice| -> Slot { - if [2, 4].contains(&slot) { - 4 - } else { - 6 - } - }; + let expected_deepest_slot = |slot, + _heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice| + -> Slot { if [2, 4].contains(&slot) { 4 } else { 6 } }; check_process_update_correctness( &mut heaviest_subtree_fork_choice, @@ -3276,15 +3288,21 @@ mod test { let mut heaviest_subtree_fork_choice = setup_forks(); // Diff of same root is empty, no matter root, intermediate node, or leaf - assert!((&heaviest_subtree_fork_choice) - .subtree_diff((0, Hash::default()), (0, Hash::default())) - .is_empty()); - assert!((&heaviest_subtree_fork_choice) - .subtree_diff((5, Hash::default()), (5, Hash::default())) - .is_empty()); - assert!((&heaviest_subtree_fork_choice) - .subtree_diff((6, Hash::default()), (6, Hash::default())) - .is_empty()); + assert!( + (&heaviest_subtree_fork_choice) + .subtree_diff((0, Hash::default()), (0, Hash::default())) + .is_empty() + ); + assert!( + (&heaviest_subtree_fork_choice) + .subtree_diff((5, Hash::default()), (5, Hash::default())) + .is_empty() + ); + assert!( + (&heaviest_subtree_fork_choice) + .subtree_diff((6, Hash::default()), (6, Hash::default())) + .is_empty() + ); // The set reachable from slot 3, excluding subtree 1, is just everything // in slot 3 since subtree 1 is an ancestor @@ -3323,9 +3341,11 @@ mod test { heaviest_subtree_fork_choice.set_tree_root((1, Hash::default())); // Zero no longer exists, set reachable from 0 is empty - assert!((&heaviest_subtree_fork_choice) - .subtree_diff((0, Hash::default()), (6, Hash::default())) - .is_empty()); + assert!( + (&heaviest_subtree_fork_choice) + .subtree_diff((0, Hash::default()), (6, Hash::default())) + .is_empty() + ); } #[test] @@ -3411,14 +3431,18 @@ mod test { // Mark slot 5 as invalid let invalid_candidate = last_voted_slot_hash; heaviest_subtree_fork_choice.mark_fork_invalid_candidate(&invalid_candidate); - assert!(!heaviest_subtree_fork_choice - .is_candidate(&invalid_candidate) - .unwrap()); + assert!( + !heaviest_subtree_fork_choice + .is_candidate(&invalid_candidate) + .unwrap() + ); // The ancestor 3 is still a candidate - assert!(heaviest_subtree_fork_choice - .is_candidate(&(3, Hash::default())) - .unwrap()); + assert!( + heaviest_subtree_fork_choice + .is_candidate(&(3, Hash::default())) + .unwrap() + ); // The best fork should be its ancestor 3, not the other fork at 4. assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 3); @@ -3477,9 +3501,11 @@ mod test { // should also mark `invalid_candidate` as valid, and the best slot should // be the leaf of the heaviest fork, `new_leaf_slot`. heaviest_subtree_fork_choice.mark_fork_valid_candidate(&invalid_candidate); - assert!(heaviest_subtree_fork_choice - .is_candidate(&invalid_candidate) - .unwrap()); + assert!( + heaviest_subtree_fork_choice + .is_candidate(&invalid_candidate) + .unwrap() + ); assert_eq!( heaviest_subtree_fork_choice.best_overall_slot(), // Should pick the smaller slot of the two new equally weighted leaves @@ -3625,17 +3651,23 @@ mod test { for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() { let slot = slot_hash_key.0; if slot <= duplicate_confirmed_slot { - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); } else { - assert!(!heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); + assert!( + !heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); } - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } // Mark a later descendant invalid @@ -3648,19 +3680,25 @@ mod test { // All ancestors of the duplicate confirmed slot should: // 1) Be duplicate confirmed // 2) Have no invalid ancestors - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } else if slot >= invalid_descendant_slot { // Anything descended from the invalid slot should: // 1) Not be duplicate confirmed // 2) Should have an invalid ancestor == `invalid_descendant_slot` - assert!(!heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); + assert!( + !heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); assert_eq!( heaviest_subtree_fork_choice .latest_invalid_ancestor(slot_hash_key) @@ -3671,12 +3709,16 @@ mod test { // Anything in between the duplicate confirmed slot and the invalid slot should: // 1) Not be duplicate confirmed // 2) Should not have an invalid ancestor - assert!(!heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + !heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } } @@ -3695,19 +3737,25 @@ mod test { // All ancestors of the later_duplicate_confirmed_slot should: // 1) Be duplicate confirmed // 2) Have no invalid ancestors - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } else if slot >= invalid_descendant_slot { // Anything descended from the invalid slot should: // 1) Not be duplicate confirmed // 2) Should have an invalid ancestor == `invalid_descendant_slot` - assert!(!heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); + assert!( + !heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); assert_eq!( heaviest_subtree_fork_choice .latest_invalid_ancestor(slot_hash_key) @@ -3718,12 +3766,16 @@ mod test { // Anything in between the duplicate confirmed slot and the invalid slot should: // 1) Not be duplicate confirmed // 2) Should not have an invalid ancestor - assert!(!heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + !heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } } @@ -3732,12 +3784,16 @@ mod test { let last_duplicate_confirmed_key = last_duplicate_confirmed_slot.slot_hash(); heaviest_subtree_fork_choice.mark_fork_valid_candidate(&last_duplicate_confirmed_key); for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() { - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } } @@ -3773,9 +3829,11 @@ mod test { for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() { let slot = slot_hash_key.0; if slot < smaller_duplicate_slot { - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } else if slot < larger_duplicate_slot { assert_eq!( heaviest_subtree_fork_choice @@ -3813,24 +3871,32 @@ mod test { if slot < larger_duplicate_slot { // Only slots <= smaller_duplicate_slot have been duplicate confirmed if slot <= smaller_duplicate_slot { - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); } else { - assert!(!heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap()); + assert!( + !heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap() + ); } // The unconfirmed duplicate flag has been cleared on the smaller // descendants because their most recent duplicate ancestor has // been confirmed - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } else { - assert!(!heaviest_subtree_fork_choice - .is_duplicate_confirmed(slot_hash_key) - .unwrap(),); + assert!( + !heaviest_subtree_fork_choice + .is_duplicate_confirmed(slot_hash_key) + .unwrap(), + ); // The unconfirmed duplicate flag has not been cleared on the smaller // descendants because their most recent duplicate ancestor, // `larger_duplicate_slot` has not yet been confirmed @@ -3856,9 +3922,11 @@ mod test { .unwrap(), slot <= larger_duplicate_slot ); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } } @@ -3887,9 +3955,11 @@ mod test { .unwrap(), slot <= larger_duplicate_slot ); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(slot_hash_key) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(slot_hash_key) + .is_none() + ); } } @@ -3948,12 +4018,13 @@ mod test { tree.stake_voted_subtree(&(6, Hash::default())).unwrap() ); - assert!(tree - .fork_infos - .get(&tree.tree_root) - .unwrap() - .parent - .is_none()); + assert!( + tree.fork_infos + .get(&tree.tree_root) + .unwrap() + .parent + .is_none() + ); } #[test] diff --git a/core/src/consensus/latest_validator_votes_for_frozen_banks.rs b/core/src/consensus/latest_validator_votes_for_frozen_banks.rs index af48f7018ef..2fbb20a3a47 100644 --- a/core/src/consensus/latest_validator_votes_for_frozen_banks.rs +++ b/core/src/consensus/latest_validator_votes_for_frozen_banks.rs @@ -3,7 +3,7 @@ use { solana_clock::Slot, solana_hash::Hash, solana_pubkey::Pubkey, - std::collections::{hash_map::Entry, HashMap}, + std::collections::{HashMap, hash_map::Entry}, }; #[derive(Default)] @@ -146,15 +146,21 @@ mod tests { // the highest voted frozen slot (false, None) ); - assert!(latest_validator_votes_for_frozen_banks - .max_replay_frozen_votes - .is_empty()); - assert!(latest_validator_votes_for_frozen_banks - .max_gossip_frozen_votes - .is_empty()); - assert!(latest_validator_votes_for_frozen_banks - .fork_choice_dirty_set - .is_empty()); + assert!( + latest_validator_votes_for_frozen_banks + .max_replay_frozen_votes + .is_empty() + ); + assert!( + latest_validator_votes_for_frozen_banks + .max_gossip_frozen_votes + .is_empty() + ); + assert!( + latest_validator_votes_for_frozen_banks + .fork_choice_dirty_set + .is_empty() + ); // Case 2: Frozen vote should be added, but the same vote added again // shouldn't update state @@ -190,9 +196,11 @@ mod tests { (vote_slot, vec![frozen_hash]) ); } else { - assert!(!latest_validator_votes_for_frozen_banks - .fork_choice_dirty_set - .contains_key(&vote_pubkey)); + assert!( + !latest_validator_votes_for_frozen_banks + .fork_choice_dirty_set + .contains_key(&vote_pubkey) + ); } } @@ -223,9 +231,11 @@ mod tests { (vote_slot, all_frozen_hashes.clone()) ); } else { - assert!(!latest_validator_votes_for_frozen_banks - .fork_choice_dirty_set - .contains_key(&vote_pubkey)); + assert!( + !latest_validator_votes_for_frozen_banks + .fork_choice_dirty_set + .contains_key(&vote_pubkey) + ); } // Case 4: Adding duplicate vote that is not frozen should not update the state @@ -254,9 +264,11 @@ mod tests { (vote_slot, all_frozen_hashes.clone()) ); } else { - assert!(!latest_validator_votes_for_frozen_banks - .fork_choice_dirty_set - .contains_key(&vote_pubkey)); + assert!( + !latest_validator_votes_for_frozen_banks + .fork_choice_dirty_set + .contains_key(&vote_pubkey) + ); } // Case 5: Adding a vote for a new higher slot that is not yet frozen @@ -288,9 +300,11 @@ mod tests { (old_vote_slot, all_frozen_hashes) ); } else { - assert!(!latest_validator_votes_for_frozen_banks - .fork_choice_dirty_set - .contains_key(&vote_pubkey)); + assert!( + !latest_validator_votes_for_frozen_banks + .fork_choice_dirty_set + .contains_key(&vote_pubkey) + ); } // Case 6: Adding a vote for a new higher slot that *is* frozen @@ -320,9 +334,11 @@ mod tests { (vote_slot, vec![frozen_hash]) ); } else { - assert!(!latest_validator_votes_for_frozen_banks - .fork_choice_dirty_set - .contains_key(&vote_pubkey)); + assert!( + !latest_validator_votes_for_frozen_banks + .fork_choice_dirty_set + .contains_key(&vote_pubkey) + ); } // Case 7: Adding a vote for a new pubkey should also update the state @@ -353,9 +369,11 @@ mod tests { (vote_slot, vec![frozen_hash]) ); } else { - assert!(!latest_validator_votes_for_frozen_banks - .fork_choice_dirty_set - .contains_key(&vote_pubkey)); + assert!( + !latest_validator_votes_for_frozen_banks + .fork_choice_dirty_set + .contains_key(&vote_pubkey) + ); } } @@ -426,9 +444,11 @@ mod tests { votes_dirty_set_output.sort(); expected_dirty_set.sort(); assert_eq!(votes_dirty_set_output, expected_dirty_set); - assert!(latest_validator_votes_for_frozen_banks - .take_votes_dirty_set(0) - .is_empty()); + assert!( + latest_validator_votes_for_frozen_banks + .take_votes_dirty_set(0) + .is_empty() + ); // Taking all the dirty votes >= num_validators - 1 will only return the last vote let root = num_validators - 1; @@ -441,9 +461,11 @@ mod tests { votes_dirty_set_output.sort(); expected_dirty_set.sort(); assert_eq!(votes_dirty_set_output, expected_dirty_set); - assert!(latest_validator_votes_for_frozen_banks - .take_votes_dirty_set(0) - .is_empty()); + assert!( + latest_validator_votes_for_frozen_banks + .take_votes_dirty_set(0) + .is_empty() + ); } #[test] @@ -484,12 +506,16 @@ mod tests { (vote_slot, vec![frozen_hash]) ); // Shouldn't find the vote in the replayed votes - assert!(latest_validator_votes_for_frozen_banks - .latest_vote(&vote_pubkey, !is_replay_vote) - .is_none()); - assert!(latest_validator_votes_for_frozen_banks - .take_votes_dirty_set(0) - .is_empty()); + assert!( + latest_validator_votes_for_frozen_banks + .latest_vote(&vote_pubkey, !is_replay_vote) + .is_none() + ); + assert!( + latest_validator_votes_for_frozen_banks + .take_votes_dirty_set(0) + .is_empty() + ); // Next simulate vote from replay is_replay_vote = true; diff --git a/core/src/consensus/tower1_14_11.rs b/core/src/consensus/tower1_14_11.rs index 70c0825f6ed..3c943a9ceec 100644 --- a/core/src/consensus/tower1_14_11.rs +++ b/core/src/consensus/tower1_14_11.rs @@ -4,7 +4,7 @@ use { solana_clock::Slot, solana_pubkey::Pubkey, solana_vote::vote_transaction::VoteTransaction, - solana_vote_program::vote_state::{vote_state_1_14_11::VoteState1_14_11, BlockTimestamp}, + solana_vote_program::vote_state::{BlockTimestamp, vote_state_1_14_11::VoteState1_14_11}, }; #[cfg_attr( diff --git a/core/src/consensus/tower1_7_14.rs b/core/src/consensus/tower1_7_14.rs index ac2acf137de..f473730ea9b 100644 --- a/core/src/consensus/tower1_7_14.rs +++ b/core/src/consensus/tower1_7_14.rs @@ -5,7 +5,7 @@ use { solana_pubkey::Pubkey, solana_signature::Signature, solana_signer::Signer, - solana_vote_program::vote_state::{vote_state_1_14_11::VoteState1_14_11, BlockTimestamp, Vote}, + solana_vote_program::vote_state::{BlockTimestamp, Vote, vote_state_1_14_11::VoteState1_14_11}, }; #[cfg_attr( diff --git a/core/src/consensus/tower_storage.rs b/core/src/consensus/tower_storage.rs index 8f32fae6fef..fcb93a987b7 100644 --- a/core/src/consensus/tower_storage.rs +++ b/core/src/consensus/tower_storage.rs @@ -1,7 +1,7 @@ use { crate::consensus::{ - tower1_14_11::Tower1_14_11, tower1_7_14::SavedTower1_7_14, Result, Tower, TowerError, - TowerVersions, + Result, Tower, TowerError, TowerVersions, tower1_7_14::SavedTower1_7_14, + tower1_14_11::Tower1_14_11, }, serde::{Deserialize, Serialize}, solana_pubkey::Pubkey, @@ -225,14 +225,14 @@ pub mod test { use { super::*, crate::consensus::{ - tower1_7_14::{SavedTower1_7_14, Tower1_7_14}, BlockhashStatus, Tower, + tower1_7_14::{SavedTower1_7_14, Tower1_7_14}, }, solana_hash::Hash, solana_keypair::Keypair, solana_vote::vote_transaction::VoteTransaction, solana_vote_program::vote_state::{ - BlockTimestamp, Lockout, Vote, VoteState1_14_11, MAX_LOCKOUT_HISTORY, + BlockTimestamp, Lockout, MAX_LOCKOUT_HISTORY, Vote, VoteState1_14_11, }, tempfile::TempDir, }; diff --git a/core/src/consensus/tower_vote_state.rs b/core/src/consensus/tower_vote_state.rs index ae9482dc748..920a23e8cd9 100644 --- a/core/src/consensus/tower_vote_state.rs +++ b/core/src/consensus/tower_vote_state.rs @@ -2,7 +2,7 @@ use { solana_clock::Slot, solana_vote::vote_state_view::VoteStateView, solana_vote_program::vote_state::{ - Lockout, VoteState1_14_11, VoteStateV3, VoteStateV4, MAX_LOCKOUT_HISTORY, + Lockout, MAX_LOCKOUT_HISTORY, VoteState1_14_11, VoteStateV3, VoteStateV4, }, std::collections::VecDeque, }; diff --git a/core/src/fetch_stage.rs b/core/src/fetch_stage.rs index 9c3d793f1e8..b2656466c31 100644 --- a/core/src/fetch_stage.rs +++ b/core/src/fetch_stage.rs @@ -2,7 +2,7 @@ use { crate::result::{Error, Result}, - crossbeam_channel::{unbounded, RecvTimeoutError}, + crossbeam_channel::{RecvTimeoutError, unbounded}, solana_clock::{DEFAULT_TICKS_PER_SLOT, HOLD_TRANSACTIONS_SLOT_OFFSET}, solana_metrics::{inc_new_counter_debug, inc_new_counter_info}, solana_packet::PacketFlags, @@ -17,10 +17,10 @@ use { std::{ net::UdpSocket, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::Duration, }, }; @@ -153,16 +153,18 @@ impl FetchStage { let fwd_thread_hdl = Builder::new() .name("solFetchStgFwRx".to_string()) - .spawn(move || loop { - if let Err(e) = - Self::handle_forwarded_packets(&forward_receiver, &sender, &poh_recorder) - { - match e { - Error::RecvTimeout(RecvTimeoutError::Disconnected) => break, - Error::RecvTimeout(RecvTimeoutError::Timeout) => (), - Error::Recv(_) => break, - Error::Send => break, - _ => error!("{e:?}"), + .spawn(move || { + loop { + if let Err(e) = + Self::handle_forwarded_packets(&forward_receiver, &sender, &poh_recorder) + { + match e { + Error::RecvTimeout(RecvTimeoutError::Disconnected) => break, + Error::RecvTimeout(RecvTimeoutError::Timeout) => (), + Error::Recv(_) => break, + Error::Send => break, + _ => error!("{e:?}"), + } } } }) @@ -170,13 +172,15 @@ impl FetchStage { let metrics_thread_hdl = Builder::new() .name("solFetchStgMetr".to_string()) - .spawn(move || loop { - sleep(Duration::from_secs(1)); + .spawn(move || { + loop { + sleep(Duration::from_secs(1)); - tpu_vote_stats.report(); + tpu_vote_stats.report(); - if exit.load(Ordering::Relaxed) { - return; + if exit.load(Ordering::Relaxed) { + return; + } } }) .unwrap(); diff --git a/core/src/forwarding_stage.rs b/core/src/forwarding_stage.rs index e3f88ba73e5..86fdca10b0b 100644 --- a/core/src/forwarding_stage.rs +++ b/core/src/forwarding_stage.rs @@ -26,14 +26,14 @@ use { solana_runtime_transaction::{ runtime_transaction::RuntimeTransaction, transaction_meta::StaticMeta, }, - solana_streamer::sendmmsg::{batch_send, SendPktsError}, + solana_streamer::sendmmsg::{SendPktsError, batch_send}, solana_tpu_client_next::{ + ConnectionWorkersScheduler, connection_workers_scheduler::{ BindTarget, ConnectionWorkersSchedulerConfig, Fanout, StakeIdentity, }, leader_updater::LeaderUpdater, transaction_batch::TransactionBatch, - ConnectionWorkersScheduler, }, solana_transaction::sanitized::MessageHash, solana_transaction_error::TransportError, diff --git a/core/src/gen_keys.rs b/core/src/gen_keys.rs index cbe9cd3518a..7e45ee876ce 100644 --- a/core/src/gen_keys.rs +++ b/core/src/gen_keys.rs @@ -4,7 +4,7 @@ use { rand::{Rng, SeedableRng}, rand_chacha::ChaChaRng, rayon::prelude::*, - solana_keypair::{keypair_from_seed, Keypair}, + solana_keypair::{Keypair, keypair_from_seed}, }; pub struct GenKeys { diff --git a/core/src/mock_alpenglow_consensus.rs b/core/src/mock_alpenglow_consensus.rs index 0fa012a1389..c180efffa84 100644 --- a/core/src/mock_alpenglow_consensus.rs +++ b/core/src/mock_alpenglow_consensus.rs @@ -2,13 +2,13 @@ use { crate::consensus::Stake, bytemuck::{Pod, Zeroable}, - crossbeam_channel::{bounded, Receiver, Sender}, - serde::{de::DeserializeOwned, Deserialize, Serialize}, - solana_clock::{Slot, DEFAULT_MS_PER_SLOT}, + crossbeam_channel::{Receiver, Sender, bounded}, + serde::{Deserialize, Serialize, de::DeserializeOwned}, + solana_clock::{DEFAULT_MS_PER_SLOT, Slot}, solana_gossip::{cluster_info::ClusterInfo, epoch_specs::EpochSpecs}, solana_keypair::Keypair, solana_packet::{Meta, Packet}, - solana_pubkey::{Pubkey, PUBKEY_BYTES}, + solana_pubkey::{PUBKEY_BYTES, Pubkey}, solana_runtime::bank::Bank, solana_signature::SIGNATURE_BYTES, solana_signer::Signer, @@ -18,8 +18,8 @@ use { iter::once, net::{SocketAddr, UdpSocket}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, + atomic::{AtomicBool, Ordering}, }, thread::{self, JoinHandle}, time::{Duration, Instant}, @@ -356,8 +356,7 @@ impl MockAlpenglowConsensus { if !state.is_ready_for_slot(vote_pkt.slot_number) { trace!( "Packet does not have matching slot number {} != {}", - vote_pkt.slot_number, - state.current_slot + vote_pkt.slot_number, state.current_slot ); continue; } @@ -378,9 +377,7 @@ impl MockAlpenglowConsensus { } trace!( "RX slot {}: {:?} from {}", - vote_pkt.slot_number, - votor_msg, - pk + vote_pkt.slot_number, votor_msg, pk ); let toa = &mut peer_info.relative_time_of_arrival[votor_msg as u64 as usize]; if toa.is_none() { @@ -397,8 +394,7 @@ impl MockAlpenglowConsensus { state.alpenglow_state.notarize_stake_collected += stake; trace!( "{my_id}:{} of {} Notarize stake collected", - state.alpenglow_state.notarize_stake_collected, - stake_60_percent + state.alpenglow_state.notarize_stake_collected, stake_60_percent ); if !state.alpenglow_state.block_notarized && state.alpenglow_state.notarize_stake_collected >= stake_60_percent @@ -438,8 +434,7 @@ impl MockAlpenglowConsensus { state.alpenglow_state.finalize_stake_collected += stake; trace!( "{my_id}:{} of {} Finalize stake collected", - state.alpenglow_state.finalize_stake_collected, - stake_60_percent + state.alpenglow_state.finalize_stake_collected, stake_60_percent ); if !state.alpenglow_state.block_finalized && state.alpenglow_state.finalize_stake_collected >= stake_60_percent @@ -574,15 +569,15 @@ impl MockAlpenglowConsensus { } } - if let Some(slot_sender) = self.slot_sender.as_ref() { - if slot_sender.try_send(slot).is_err() { - error!("Can not initiate mock voting, worker is busy"); - datapoint_info!( - "mock_alpenglow", - ("runner_stuck", 1, i64), - ("slot", slot, i64) - ); - } + if let Some(slot_sender) = self.slot_sender.as_ref() + && slot_sender.try_send(slot).is_err() + { + error!("Can not initiate mock voting, worker is busy"); + datapoint_info!( + "mock_alpenglow", + ("runner_stuck", 1, i64), + ("slot", slot, i64) + ); } } @@ -773,9 +768,9 @@ fn get_test_config_from_account(bank: &Bank) -> Option { mod tests { use { crate::mock_alpenglow_consensus::{ + MOCK_VOTE_HEADER_SIZE, MOCK_VOTE_PACKET_SIZE, MockAlpenglowConsensus, NUM_VOTOR_TYPES, + PeerData, SendCommand, SharedState, StateArray, TestConfig, VotorMessageType, compute_stake_weighted_means, get_state_for_slot_index, prep_and_sign_packet, - MockAlpenglowConsensus, PeerData, SendCommand, SharedState, StateArray, TestConfig, - VotorMessageType, MOCK_VOTE_HEADER_SIZE, MOCK_VOTE_PACKET_SIZE, NUM_VOTOR_TYPES, }, crossbeam_channel::bounded, solana_clock::Slot, @@ -786,7 +781,7 @@ mod tests { std::{ collections::HashMap, net::UdpSocket, - sync::{atomic::AtomicBool, Arc, Mutex}, + sync::{Arc, Mutex, atomic::AtomicBool}, thread::sleep, time::{Duration, Instant}, }, diff --git a/core/src/optimistic_confirmation_verifier.rs b/core/src/optimistic_confirmation_verifier.rs index ced702e906a..4b1ea3441ef 100644 --- a/core/src/optimistic_confirmation_verifier.rs +++ b/core/src/optimistic_confirmation_verifier.rs @@ -167,9 +167,11 @@ mod test { ); assert_eq!(blockstore.get_latest_optimistic_slots(10).unwrap().len(), 1); assert_eq!(optimistic_confirmation_verifier.unchecked_slots.len(), 1); - assert!(optimistic_confirmation_verifier - .unchecked_slots - .contains(&(snapshot_start_slot + 1, bank_hash))); + assert!( + optimistic_confirmation_verifier + .unchecked_slots + .contains(&(snapshot_start_slot + 1, bank_hash)) + ); } #[test] @@ -192,9 +194,11 @@ mod test { vec![(1, bad_bank_hash)] ); assert_eq!(optimistic_confirmation_verifier.unchecked_slots.len(), 1); - assert!(optimistic_confirmation_verifier - .unchecked_slots - .contains(&(3, Hash::default()))); + assert!( + optimistic_confirmation_verifier + .unchecked_slots + .contains(&(3, Hash::default())) + ); } #[test] @@ -226,9 +230,11 @@ mod test { .add_new_optimistic_confirmed_slots(optimistic_slots.clone(), &blockstore); assert_eq!(blockstore.get_latest_optimistic_slots(10).unwrap().len(), 3); let bank5 = vote_simulator.bank_forks.read().unwrap().get(5).unwrap(); - assert!(optimistic_confirmation_verifier - .verify_for_unrooted_optimistic_slots(&bank5, &blockstore) - .is_empty()); + assert!( + optimistic_confirmation_verifier + .verify_for_unrooted_optimistic_slots(&bank5, &blockstore) + .is_empty() + ); // 5 is >= than all the unchecked slots, so should clear everything assert!(optimistic_confirmation_verifier.unchecked_slots.is_empty()); @@ -236,14 +242,18 @@ mod test { optimistic_confirmation_verifier .add_new_optimistic_confirmed_slots(optimistic_slots.clone(), &blockstore); let bank3 = vote_simulator.bank_forks.read().unwrap().get(3).unwrap(); - assert!(optimistic_confirmation_verifier - .verify_for_unrooted_optimistic_slots(&bank3, &blockstore) - .is_empty()); + assert!( + optimistic_confirmation_verifier + .verify_for_unrooted_optimistic_slots(&bank3, &blockstore) + .is_empty() + ); // 3 is bigger than only slot 1, so slot 5 should be left over assert_eq!(optimistic_confirmation_verifier.unchecked_slots.len(), 1); - assert!(optimistic_confirmation_verifier - .unchecked_slots - .contains(&optimistic_slots[2])); + assert!( + optimistic_confirmation_verifier + .unchecked_slots + .contains(&optimistic_slots[2]) + ); // If root is on different fork, the slots < root on different fork should // be returned @@ -257,9 +267,11 @@ mod test { ); // 4 is bigger than only slots 1 and 3, so slot 5 should be left over assert_eq!(optimistic_confirmation_verifier.unchecked_slots.len(), 1); - assert!(optimistic_confirmation_verifier - .unchecked_slots - .contains(&optimistic_slots[2])); + assert!( + optimistic_confirmation_verifier + .unchecked_slots + .contains(&optimistic_slots[2]) + ); // Now set a root at slot 5, purging BankForks of slots < 5 vote_simulator.set_root(5); @@ -289,9 +301,11 @@ mod test { blockstore.set_roots([1, 3].iter()).unwrap(); optimistic_confirmation_verifier .add_new_optimistic_confirmed_slots(optimistic_slots, &blockstore); - assert!(optimistic_confirmation_verifier - .verify_for_unrooted_optimistic_slots(&bank7, &blockstore) - .is_empty()); + assert!( + optimistic_confirmation_verifier + .verify_for_unrooted_optimistic_slots(&bank7, &blockstore) + .is_empty() + ); assert!(optimistic_confirmation_verifier.unchecked_slots.is_empty()); assert_eq!(blockstore.get_latest_optimistic_slots(10).unwrap().len(), 3); } diff --git a/core/src/repair/ancestor_hashes_service.rs b/core/src/repair/ancestor_hashes_service.rs index 1925e501f48..7f7083a7d51 100644 --- a/core/src/repair/ancestor_hashes_service.rs +++ b/core/src/repair/ancestor_hashes_service.rs @@ -17,15 +17,15 @@ use { shred_fetch_stage::receive_quic_datagrams, }, bytes::Bytes, - crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}, - dashmap::{mapref::entry::Entry::Occupied, DashMap}, - solana_clock::{Slot, DEFAULT_MS_PER_SLOT}, + crossbeam_channel::{Receiver, RecvTimeoutError, Sender, unbounded}, + dashmap::{DashMap, mapref::entry::Entry::Occupied}, + solana_clock::{DEFAULT_MS_PER_SLOT, Slot}, solana_cluster_type::ClusterType, solana_gossip::{cluster_info::ClusterInfo, contact_info::Protocol, ping_pong::Pong}, - solana_keypair::{signable::Signable, Keypair, Signer}, + solana_keypair::{Keypair, Signer, signable::Signable}, solana_ledger::blockstore::Blockstore, solana_perf::{ - packet::{deserialize_from_with_limit, PacketBatch, PacketFlags, PacketRef}, + packet::{PacketBatch, PacketFlags, PacketRef, deserialize_from_with_limit}, recycler::Recycler, }, solana_pubkey::Pubkey, @@ -37,10 +37,10 @@ use { io::{Cursor, Read}, net::{SocketAddr, UdpSocket}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::{Duration, Instant}, }, tokio::sync::mpsc::Sender as AsyncSender, @@ -631,27 +631,29 @@ impl AncestorHashesService { let mut request_throttle = vec![]; Builder::new() .name("solManAncReqs".to_string()) - .spawn(move || loop { - if exit.load(Ordering::Relaxed) { - return; - } - Self::manage_ancestor_requests( - &ancestor_hashes_request_statuses, - &ancestor_hashes_request_socket, - &ancestor_hashes_request_quic_sender, - &repair_info, - &outstanding_requests, - &ancestor_hashes_replay_update_receiver, - &retryable_slots_receiver, - &serve_repair, - &mut repair_stats, - &mut dead_slot_pool, - &mut repairable_dead_slot_pool, - &mut popular_pruned_slot_pool, - &mut request_throttle, - ); + .spawn(move || { + loop { + if exit.load(Ordering::Relaxed) { + return; + } + Self::manage_ancestor_requests( + &ancestor_hashes_request_statuses, + &ancestor_hashes_request_socket, + &ancestor_hashes_request_quic_sender, + &repair_info, + &outstanding_requests, + &ancestor_hashes_replay_update_receiver, + &retryable_slots_receiver, + &serve_repair, + &mut repair_stats, + &mut dead_slot_pool, + &mut repairable_dead_slot_pool, + &mut popular_pruned_slot_pool, + &mut request_throttle, + ); - sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT)); + sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT)); + } }) .unwrap() } @@ -888,9 +890,11 @@ impl AncestorHashesService { duplicate_slot, request_type, ); - assert!(ancestor_hashes_request_statuses - .insert(duplicate_slot, ancestor_request_status) - .is_none()); + assert!( + ancestor_hashes_request_statuses + .insert(duplicate_slot, ancestor_request_status) + .is_none() + ); true } } @@ -908,8 +912,8 @@ mod test { serve_repair_service::adapt_repair_requests_packets, }, replay_stage::{ - tests::{replay_blockstore_components, ReplayBlockstoreComponents}, ReplayStage, + tests::{ReplayBlockstoreComponents, replay_blockstore_components}, }, vote_simulator::VoteSimulator, }, @@ -924,7 +928,7 @@ mod test { blockstore::make_many_slot_entries, get_tmp_ledger_path, get_tmp_ledger_path_auto_delete, shred::Nonce, }, - solana_net_utils::{sockets::bind_to_localhost_unique, SocketAddrSpace}, + solana_net_utils::{SocketAddrSpace, sockets::bind_to_localhost_unique}, solana_perf::packet::Packet, solana_runtime::bank_forks::BankForks, solana_signer::Signer, @@ -1963,16 +1967,18 @@ mod test { let mut packet = Packet::default(); packet.meta_mut().size = 0; - assert!(AncestorHashesService::verify_and_process_ancestor_response( - &packet, - &ancestor_hashes_request_statuses, - &mut AncestorHashesResponsesStats::default(), - &outstanding_requests, - &blockstore, - &repair_info.cluster_info.keypair(), - &ancestor_hashes_request_socket, - ) - .is_none()); + assert!( + AncestorHashesService::verify_and_process_ancestor_response( + &packet, + &ancestor_hashes_request_statuses, + &mut AncestorHashesResponsesStats::default(), + &outstanding_requests, + &blockstore, + &repair_info.cluster_info.keypair(), + &ancestor_hashes_request_socket, + ) + .is_none() + ); } #[test] diff --git a/core/src/repair/cluster_slot_state_verifier.rs b/core/src/repair/cluster_slot_state_verifier.rs index b8542bb4c70..7aab8d5e11c 100644 --- a/core/src/repair/cluster_slot_state_verifier.rs +++ b/core/src/repair/cluster_slot_state_verifier.rs @@ -640,17 +640,14 @@ fn on_epoch_slots_frozen( // // Thus if we have a duplicate confirmation, but `slot` is pruned, we continue // processing it as `epoch_slots_frozen`. - if !is_popular_pruned { - if let Some(duplicate_confirmed_hash) = duplicate_confirmed_hash { - if epoch_slots_frozen_hash != duplicate_confirmed_hash { - warn!( - "EpochSlots sample returned slot {slot} with hash {epoch_slots_frozen_hash}, \ - but we already saw duplicate confirmation on hash: \ - {duplicate_confirmed_hash:?}", - ); - } - return vec![]; + if !is_popular_pruned && let Some(duplicate_confirmed_hash) = duplicate_confirmed_hash { + if epoch_slots_frozen_hash != duplicate_confirmed_hash { + warn!( + "EpochSlots sample returned slot {slot} with hash {epoch_slots_frozen_hash}, but \ + we already saw duplicate confirmation on hash: {duplicate_confirmed_hash:?}", + ); } + return vec![]; } match bank_status { @@ -900,10 +897,10 @@ pub(crate) fn check_slot_agrees_with_cluster( // Avoid duplicate work from multiple of the same DuplicateConfirmed signal. This can // happen if we get duplicate confirmed from gossip and from local replay. if let SlotStateUpdate::DuplicateConfirmed(state) = &slot_state_update { - if let Some(bank_hash) = state.bank_status.bank_hash() { - if let Some(true) = fork_choice.is_duplicate_confirmed(&(slot, bank_hash)) { - return; - } + if let Some(bank_hash) = state.bank_status.bank_hash() + && let Some(true) = fork_choice.is_duplicate_confirmed(&(slot, bank_hash)) + { + return; } datapoint_info!( @@ -926,15 +923,13 @@ pub(crate) fn check_slot_agrees_with_cluster( ); } - if let SlotStateUpdate::EpochSlotsFrozen(epoch_slots_frozen_state) = &slot_state_update { - if let Some(old_epoch_slots_frozen_hash) = + if let SlotStateUpdate::EpochSlotsFrozen(epoch_slots_frozen_state) = &slot_state_update + && let Some(old_epoch_slots_frozen_hash) = epoch_slots_frozen_slots.insert(slot, epoch_slots_frozen_state.epoch_slots_frozen_hash) - { - if old_epoch_slots_frozen_hash == epoch_slots_frozen_state.epoch_slots_frozen_hash { - // If EpochSlots has already told us this same hash was frozen, return - return; - } - } + && old_epoch_slots_frozen_hash == epoch_slots_frozen_state.epoch_slots_frozen_hash + { + // If EpochSlots has already told us this same hash was frozen, return + return; } let state_changes = slot_state_update.into_state_changes(slot); @@ -1626,9 +1621,11 @@ mod test { &mut purge_repair_slot_counter, vec![ResultingStateChange::MarkSlotDuplicate(duplicate_slot_hash)], ); - assert!(!heaviest_subtree_fork_choice - .is_candidate(&(duplicate_slot, duplicate_slot_hash)) - .unwrap()); + assert!( + !heaviest_subtree_fork_choice + .is_candidate(&(duplicate_slot, duplicate_slot_hash)) + .unwrap() + ); for child_slot in descendants .get(&duplicate_slot) .unwrap() @@ -1794,16 +1791,20 @@ mod test { .iter() .chain(std::iter::once(&duplicate_slot)) { - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(&( - *child_slot, - bank_forks.read().unwrap().get(*child_slot).unwrap().hash() - )) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(&( + *child_slot, + bank_forks.read().unwrap().get(*child_slot).unwrap().hash() + )) + .is_none() + ); } - assert!(heaviest_subtree_fork_choice - .is_candidate(&(duplicate_slot, our_duplicate_slot_hash)) - .unwrap()); + assert!( + heaviest_subtree_fork_choice + .is_candidate(&(duplicate_slot, our_duplicate_slot_hash)) + .unwrap() + ); assert!(duplicate_slots_to_repair.is_empty()); assert!(purge_repair_slot_counter.is_empty()); assert_eq!( @@ -1875,9 +1876,11 @@ mod test { // Nothing should be applied yet to fork choice, since bank was not yet frozen for slot in 2..=3 { let slot_hash = bank_forks.read().unwrap().get(slot).unwrap().hash(); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(&(slot, slot_hash)) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(&(slot, slot_hash)) + .is_none() + ); } // Now freeze the bank @@ -1910,9 +1913,11 @@ mod test { // Progress map should have the correct updates, fork choice should mark duplicate // as unvotable - assert!(heaviest_subtree_fork_choice - .is_unconfirmed_duplicate(&(duplicate_slot, frozen_duplicate_slot_hash)) - .unwrap()); + assert!( + heaviest_subtree_fork_choice + .is_unconfirmed_duplicate(&(duplicate_slot, frozen_duplicate_slot_hash)) + .unwrap() + ); // The ancestor of the duplicate slot should be the best slot now let (duplicate_ancestor, duplicate_parent_hash) = { @@ -1979,21 +1984,27 @@ mod test { &mut purge_repair_slot_counter, SlotStateUpdate::DuplicateConfirmed(duplicate_confirmed_state), ); - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(2, slot2_hash)) - .unwrap()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(2, slot2_hash)) + .unwrap() + ); assert_eq!( heaviest_subtree_fork_choice.best_overall_slot(), (3, slot3_hash) ); for slot in 0..=2 { let slot_hash = bank_forks.read().unwrap().get(slot).unwrap().hash(); - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(slot, slot_hash)) - .unwrap()); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(&(slot, slot_hash)) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(slot, slot_hash)) + .unwrap() + ); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(&(slot, slot_hash)) + .is_none() + ); } // Mark 3 as duplicate, should not remove the duplicate confirmed slot 2 from @@ -2025,16 +2036,22 @@ mod test { for slot in 0..=3 { let slot_hash = bank_forks.read().unwrap().get(slot).unwrap().hash(); if slot <= 2 { - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(slot, slot_hash)) - .unwrap()); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(&(slot, slot_hash)) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(slot, slot_hash)) + .unwrap() + ); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(&(slot, slot_hash)) + .is_none() + ); } else { - assert!(!heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(slot, slot_hash)) - .unwrap()); + assert!( + !heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(slot, slot_hash)) + .unwrap() + ); assert_eq!( heaviest_subtree_fork_choice .latest_invalid_ancestor(&(slot, slot_hash)) @@ -2127,12 +2144,16 @@ mod test { ); for slot in 0..=3 { let slot_hash = bank_forks.read().unwrap().get(slot).unwrap().hash(); - assert!(heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(slot, slot_hash)) - .unwrap()); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(&(slot, slot_hash)) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(slot, slot_hash)) + .unwrap() + ); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(&(slot, slot_hash)) + .is_none() + ); } assert_eq!( heaviest_subtree_fork_choice.best_overall_slot(), @@ -2157,9 +2178,11 @@ mod test { .unwrap(), expected_is_duplicate_confirmed ); - assert!(heaviest_subtree_fork_choice - .latest_invalid_ancestor(&(slot, slot_hash)) - .is_none()); + assert!( + heaviest_subtree_fork_choice + .latest_invalid_ancestor(&(slot, slot_hash)) + .is_none() + ); } } diff --git a/core/src/repair/duplicate_repair_status.rs b/core/src/repair/duplicate_repair_status.rs index 128ccaf3164..5eff267d4a3 100644 --- a/core/src/repair/duplicate_repair_status.rs +++ b/core/src/repair/duplicate_repair_status.rs @@ -614,9 +614,11 @@ pub mod tests { // Try adding a response from an invalid peer, should not be registered let rand_addr = create_rand_socket_addr(); - assert!(status - .add_response(&rand_addr, vec![(99, Hash::new_unique())], &blockstore) - .is_none()); + assert!( + status + .add_response(&rand_addr, vec![(99, Hash::new_unique())], &blockstore) + .is_none() + ); assert_eq!(status.num_responses, 0); assert!(status.ancestor_request_responses.is_empty()); } @@ -647,9 +649,11 @@ pub mod tests { } else { incorrect_ancestors_response.clone() }; - assert!(status - .add_response(responder_addr, response, &blockstore) - .is_none()); + assert!( + status + .add_response(responder_addr, response, &blockstore) + .is_none() + ); assert_eq!(status.num_responses, 1); assert_eq!(status.ancestor_request_responses.len(), 1); let correct_responses = status diff --git a/core/src/repair/outstanding_requests.rs b/core/src/repair/outstanding_requests.rs index 5cdb134ea53..80a4a76c090 100644 --- a/core/src/repair/outstanding_requests.rs +++ b/core/src/repair/outstanding_requests.rs @@ -1,7 +1,7 @@ use { crate::repair::request_response::RequestResponse, lru::LruCache, - rand::{rng, Rng}, + rand::{Rng, rng}, solana_ledger::shred::Nonce, }; @@ -116,9 +116,11 @@ pub(crate) mod tests { .unwrap() .expire_timestamp; - assert!(outstanding_requests - .register_response(nonce, shred.payload(), expire_timestamp + 1, |_| ()) - .is_none()); + assert!( + outstanding_requests + .register_response(nonce, shred.payload(), expire_timestamp + 1, |_| ()) + .is_none() + ); assert!(outstanding_requests.requests.get(&nonce).is_none()); } @@ -142,9 +144,11 @@ pub(crate) mod tests { assert!(num_expected_responses > 1); // Response that passes all checks should decrease num_expected_responses - assert!(outstanding_requests - .register_response(nonce, shred.payload(), expire_timestamp - 1, |_| ()) - .is_some()); + assert!( + outstanding_requests + .register_response(nonce, shred.payload(), expire_timestamp - 1, |_| ()) + .is_some() + ); num_expected_responses -= 1; assert_eq!( outstanding_requests @@ -156,12 +160,16 @@ pub(crate) mod tests { ); // Response with incorrect nonce is ignored - assert!(outstanding_requests - .register_response(nonce + 1, shred.payload(), expire_timestamp - 1, |_| ()) - .is_none()); - assert!(outstanding_requests - .register_response(nonce + 1, shred.payload(), expire_timestamp, |_| ()) - .is_none()); + assert!( + outstanding_requests + .register_response(nonce + 1, shred.payload(), expire_timestamp - 1, |_| ()) + .is_none() + ); + assert!( + outstanding_requests + .register_response(nonce + 1, shred.payload(), expire_timestamp, |_| ()) + .is_none() + ); assert_eq!( outstanding_requests .requests @@ -173,9 +181,11 @@ pub(crate) mod tests { // Response with timestamp over limit should remove status, preventing late // responses from being accepted - assert!(outstanding_requests - .register_response(nonce, shred.payload(), expire_timestamp, |_| ()) - .is_none()); + assert!( + outstanding_requests + .register_response(nonce, shred.payload(), expire_timestamp, |_| ()) + .is_none() + ); assert!(outstanding_requests.requests.get(&nonce).is_none()); // If number of outstanding requests hits zero, should also remove the entry @@ -193,9 +203,11 @@ pub(crate) mod tests { assert!(num_expected_responses > 1); for _ in 0..num_expected_responses { assert!(outstanding_requests.requests.get(&nonce).is_some()); - assert!(outstanding_requests - .register_response(nonce, shred.payload(), expire_timestamp - 1, |_| ()) - .is_some()); + assert!( + outstanding_requests + .register_response(nonce, shred.payload(), expire_timestamp - 1, |_| ()) + .is_some() + ); } assert!(outstanding_requests.requests.get(&nonce).is_none()); } diff --git a/core/src/repair/quic_endpoint.rs b/core/src/repair/quic_endpoint.rs index ff99f723d70..0f57fec25ee 100644 --- a/core/src/repair/quic_endpoint.rs +++ b/core/src/repair/quic_endpoint.rs @@ -4,14 +4,14 @@ use { futures::future::{TryJoin, TryJoin3}, log::error, quinn::{ - crypto::rustls::{QuicClientConfig, QuicServerConfig}, ClientConfig, ConnectError, Connecting, Connection, ConnectionError, Endpoint, EndpointConfig, IdleTimeout, SendDatagramError, ServerConfig, TokioRuntime, TransportConfig, VarInt, + crypto::rustls::{QuicClientConfig, QuicServerConfig}, }, rustls::{ - pki_types::{CertificateDer, PrivateKeyDer}, CertificateError, KeyLogFile, + pki_types::{CertificateDer, PrivateKeyDer}, }, solana_gossip::contact_info::Protocol, solana_keypair::Keypair, @@ -23,20 +23,20 @@ use { }, std::{ cmp::Reverse, - collections::{hash_map::Entry, HashMap}, + collections::{HashMap, hash_map::Entry}, io::Error as IoError, net::{SocketAddr, UdpSocket}, sync::{ - atomic::{AtomicBool, AtomicU64, Ordering}, Arc, RwLock, + atomic::{AtomicBool, AtomicU64, Ordering}, }, time::Duration, }, thiserror::Error, tokio::{ sync::{ - mpsc::{error::TrySendError, Receiver as AsyncReceiver, Sender as AsyncSender}, Mutex, RwLock as AsyncRwLock, + mpsc::{Receiver as AsyncReceiver, Sender as AsyncSender, error::TrySendError}, }, task::JoinHandle, }, @@ -566,10 +566,10 @@ async fn handle_connection( } } drop_connection(remote_pubkey, &connection, &cache).await; - if let Entry::Occupied(entry) = router.write().await.entry(remote_address) { - if entry.get().is_closed() { - entry.remove(); - } + if let Entry::Occupied(entry) = router.write().await.entry(remote_address) + && entry.get().is_closed() + { + entry.remove(); } } @@ -744,10 +744,10 @@ async fn drop_connection( CONNECTION_CLOSE_ERROR_CODE_DROPPED, CONNECTION_CLOSE_REASON_DROPPED, ); - if let Entry::Occupied(entry) = cache.lock().await.entry(remote_pubkey) { - if entry.get().stable_id() == connection.stable_id() { - entry.remove(); - } + if let Entry::Occupied(entry) = cache.lock().await.entry(remote_pubkey) + && entry.get().stable_id() == connection.stable_id() + { + entry.remove(); } } @@ -1016,7 +1016,7 @@ mod tests { use { super::*, itertools::{izip, multiunzip}, - solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo}, + solana_ledger::genesis_utils::{GenesisConfigInfo, create_genesis_config}, solana_net_utils::sockets::{bind_to, localhost_port_range_for_tests}, solana_runtime::bank::Bank, solana_signer::Signer, diff --git a/core/src/repair/repair_generic_traversal.rs b/core/src/repair/repair_generic_traversal.rs index f6695a81b20..68e3ecd39dd 100644 --- a/core/src/repair/repair_generic_traversal.rs +++ b/core/src/repair/repair_generic_traversal.rs @@ -59,17 +59,17 @@ pub fn get_unknown_last_index( let slot_meta = slot_meta_cache .entry(slot) .or_insert_with(|| blockstore.meta(slot).unwrap()); - if let Some(slot_meta) = slot_meta { - if slot_meta.last_index.is_none() { - let shred_index = blockstore.get_index(slot).unwrap(); - let num_processed_shreds = if let Some(shred_index) = shred_index { - shred_index.data().num_shreds() as u64 - } else { - slot_meta.consumed - }; - unknown_last.push((slot, slot_meta.received, num_processed_shreds)); - processed_slots.insert(slot); - } + if let Some(slot_meta) = slot_meta + && slot_meta.last_index.is_none() + { + let shred_index = blockstore.get_index(slot).unwrap(); + let num_processed_shreds = if let Some(shred_index) = shred_index { + shred_index.data().num_shreds() as u64 + } else { + slot_meta.consumed + }; + unknown_last.push((slot, slot_meta.received, num_processed_shreds)); + processed_slots.insert(slot); } } // prioritize slots with more received shreds @@ -100,12 +100,12 @@ fn get_unrepaired_path( let slot_meta = slot_meta_cache .entry(slot) .or_insert_with(|| blockstore.meta(slot).unwrap()); - if let Some(slot_meta) = slot_meta { - if !slot_meta.is_full() { - path.push(slot); - if let Some(parent_slot) = slot_meta.parent_slot { - slot = parent_slot - } + if let Some(slot_meta) = slot_meta + && !slot_meta.is_full() + { + path.push(slot); + if let Some(parent_slot) = slot_meta.parent_slot { + slot = parent_slot } } } @@ -217,7 +217,7 @@ pub mod test { crate::repair::repair_service::sleep_shred_deferment_period, solana_hash::Hash, solana_ledger::{blockstore::Blockstore, get_tmp_ledger_path}, - trees::{tr, Tree, TreeWalk}, + trees::{Tree, TreeWalk, tr}, }; #[test] diff --git a/core/src/repair/repair_response.rs b/core/src/repair/repair_response.rs index c4be8afaefe..ae53a792f69 100644 --- a/core/src/repair/repair_response.rs +++ b/core/src/repair/repair_response.rs @@ -49,7 +49,7 @@ mod test { solana_keypair::Keypair, solana_ledger::{ shred::Shredder, - sigverify_shreds::{verify_shred_cpu, LruCache, SlotPubkeys}, + sigverify_shreds::{LruCache, SlotPubkeys, verify_shred_cpu}, }, solana_packet::PacketFlags, solana_signer::Signer, diff --git a/core/src/repair/repair_service.rs b/core/src/repair/repair_service.rs index fef6f71dc8e..891da0fe929 100644 --- a/core/src/repair/repair_service.rs +++ b/core/src/repair/repair_service.rs @@ -13,8 +13,8 @@ use { outstanding_requests::OutstandingRequests, repair_weight::RepairWeight, serve_repair::{ - self, RepairPeers, RepairProtocol, RepairRequestHeader, ServeRepair, - ShredRepairType, REPAIR_PEERS_CACHE_CAPACITY, + self, REPAIR_PEERS_CACHE_CAPACITY, RepairPeers, RepairProtocol, + RepairRequestHeader, ServeRepair, ShredRepairType, }, }, }, @@ -23,7 +23,7 @@ use { lru::LruCache, rand::prelude::IndexedRandom as _, solana_client::connection_cache::Protocol, - solana_clock::{Slot, DEFAULT_TICKS_PER_SECOND, MS_PER_TICK}, + solana_clock::{DEFAULT_TICKS_PER_SECOND, MS_PER_TICK, Slot}, solana_epoch_schedule::EpochSchedule, solana_gossip::cluster_info::ClusterInfo, solana_hash::Hash, @@ -38,17 +38,17 @@ use { bank::Bank, bank_forks::{BankForks, SharableBanks}, }, - solana_streamer::sendmmsg::{batch_send, SendPktsError}, + solana_streamer::sendmmsg::{SendPktsError, batch_send}, solana_time_utils::timestamp, std::{ - collections::{hash_map::Entry, HashMap, HashSet}, + collections::{HashMap, HashSet, hash_map::Entry}, iter::Iterator, net::{SocketAddr, UdpSocket}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::{Duration, Instant}, }, tokio::sync::mpsc::Sender as AsyncSender, @@ -1284,13 +1284,13 @@ mod test { solana_keypair::Keypair, solana_ledger::{ blockstore::{ - make_chaining_slot_entries, make_many_slot_entries, make_slot_entries, Blockstore, + Blockstore, make_chaining_slot_entries, make_many_slot_entries, make_slot_entries, }, - genesis_utils::{create_genesis_config, GenesisConfigInfo}, + genesis_utils::{GenesisConfigInfo, create_genesis_config}, get_tmp_ledger_path_auto_delete, shred::max_ticks_per_n_shreds, }, - solana_net_utils::{sockets::bind_to_localhost_unique, SocketAddrSpace}, + solana_net_utils::{SocketAddrSpace, sockets::bind_to_localhost_unique}, solana_runtime::bank::Bank, solana_signer::Signer, solana_time_utils::timestamp, @@ -1694,11 +1694,13 @@ mod test { &RwLock::new(OutstandingRequests::default()), &identity_keypair, ); - assert!(duplicate_slot_repair_statuses - .get(&dead_slot) - .unwrap() - .repair_pubkey_and_addr - .is_none()); + assert!( + duplicate_slot_repair_statuses + .get(&dead_slot) + .unwrap() + .repair_pubkey_and_addr + .is_none() + ); assert!(duplicate_slot_repair_statuses.contains_key(&dead_slot)); // Give the slot a repair address diff --git a/core/src/repair/repair_weight.rs b/core/src/repair/repair_weight.rs index f30f301aa53..78c680eca10 100644 --- a/core/src/repair/repair_weight.rs +++ b/core/src/repair/repair_weight.rs @@ -558,17 +558,16 @@ impl RepairWeight { epoch_stakes, epoch_schedule, ); - if let Some(new_orphan_root) = new_orphan_root { - if new_orphan_root != self.root { - if let Some(repair_request) = RepairService::request_repair_if_needed( - outstanding_repairs, - ShredRepairType::Orphan(new_orphan_root), - ) { - repairs.push(repair_request); - processed_slots.insert(new_orphan_root); - new_best_orphan_requests += 1; - } - } + if let Some(new_orphan_root) = new_orphan_root + && new_orphan_root != self.root + && let Some(repair_request) = RepairService::request_repair_if_needed( + outstanding_repairs, + ShredRepairType::Orphan(new_orphan_root), + ) + { + repairs.push(repair_request); + processed_slots.insert(new_orphan_root); + new_best_orphan_requests += 1; } } } @@ -728,10 +727,11 @@ impl RepairWeight { &orphan_tree, TreeRoot::PrunedRoot(*next_earliest_ancestor), ); - assert!(self - .pruned_trees - .insert(*next_earliest_ancestor, orphan_tree) - .is_none()); + assert!( + self.pruned_trees + .insert(*next_earliest_ancestor, orphan_tree) + .is_none() + ); return None; } } @@ -989,7 +989,7 @@ mod test { solana_accounts_db::contains::Contains, solana_hash::Hash, solana_ledger::{ - blockstore::{make_chaining_slot_entries, Blockstore}, + blockstore::{Blockstore, make_chaining_slot_entries}, get_tmp_ledger_path, }, solana_runtime::{bank::Bank, bank_utils}, @@ -1012,11 +1012,13 @@ mod test { // Try to add a vote for slot < root and a slot that is unrooted for old_slot in &[2, 4] { if *old_slot > root { - assert!(repair_weight - .slot_to_tree - .get(old_slot) - .unwrap() - .is_pruned()); + assert!( + repair_weight + .slot_to_tree + .get(old_slot) + .unwrap() + .is_pruned() + ); } else { assert!(!repair_weight.slot_to_tree.contains(old_slot)); } @@ -1029,11 +1031,13 @@ mod test { ); if *old_slot > root { assert!(repair_weight.pruned_trees.contains_key(old_slot)); - assert!(repair_weight - .slot_to_tree - .get(old_slot) - .unwrap() - .is_pruned()); + assert!( + repair_weight + .slot_to_tree + .get(old_slot) + .unwrap() + .is_pruned() + ); } else { assert!(!repair_weight.trees.contains_key(old_slot)); assert!(!repair_weight.slot_to_tree.contains_key(old_slot)); @@ -1170,12 +1174,14 @@ mod test { .ancestors((1, Hash::default())), vec![(0, Hash::default())] ); - assert!(repair_weight - .trees - .get(&8) - .unwrap() - .ancestors((8, Hash::default())) - .is_empty()); + assert!( + repair_weight + .trees + .get(&8) + .unwrap() + .ancestors((8, Hash::default())) + .is_empty() + ); let votes = vec![(1, vote_pubkeys.clone()), (10, vote_pubkeys.clone())]; let mut repair_weight = RepairWeight::new(0); @@ -1801,11 +1807,13 @@ mod test { assert!(!repair_weight.trees.contains_key(&purged_slot)); } for pruned_slot in &[4, 8, 10] { - assert!(repair_weight - .slot_to_tree - .get(pruned_slot) - .unwrap() - .is_pruned()); + assert!( + repair_weight + .slot_to_tree + .get(pruned_slot) + .unwrap() + .is_pruned() + ); } assert_eq!( repair_weight.pruned_trees.keys().copied().collect_vec(), @@ -2050,11 +2058,13 @@ mod test { // Check assert_eq!(repair_weight.pruned_trees.len(), 1); if *old_parent > root { - assert!(repair_weight - .slot_to_tree - .get(old_parent) - .unwrap() - .is_pruned()); + assert!( + repair_weight + .slot_to_tree + .get(old_parent) + .unwrap() + .is_pruned() + ); assert_eq!( repair_weight .pruned_trees @@ -2171,11 +2181,13 @@ mod test { bank.epoch_schedule(), ); - assert!(repair_weight - .slot_to_tree - .get(&new_vote_slot) - .unwrap() - .is_pruned()); + assert!( + repair_weight + .slot_to_tree + .get(&new_vote_slot) + .unwrap() + .is_pruned() + ); if *old_parent > root { // Adds to new tree assert_eq!(repair_weight.pruned_trees.len(), 1); @@ -2478,18 +2490,21 @@ mod test { repair_weight.set_root(4); assert_eq!(repair_weight.trees.len(), 1); assert_eq!(repair_weight.pruned_trees.len(), 3); - assert!(repair_weight - .pruned_trees - .iter() - .all( - |(root, pruned_tree)| pruned_tree.stake_voted_subtree(&(*root, Hash::default())) - == Some(stake) - )); + assert!( + repair_weight + .pruned_trees + .iter() + .all(|(root, pruned_tree)| pruned_tree + .stake_voted_subtree(&(*root, Hash::default())) + == Some(stake)) + ); // No fork has DUPLICATE_THRESHOLD, should not be any popular forks - assert!(repair_weight - .get_popular_pruned_forks(epoch_stakes, epoch_schedule) - .is_empty()); + assert!( + repair_weight + .get_popular_pruned_forks(epoch_stakes, epoch_schedule) + .is_empty() + ); // 500 stake, still less than DUPLICATE_THRESHOLD, should not be any popular forks let five_votes = vote_pubkeys.iter().copied().take(5).collect_vec(); @@ -2500,9 +2515,11 @@ mod test { bank.epoch_stakes_map(), bank.epoch_schedule(), ); - assert!(repair_weight - .get_popular_pruned_forks(epoch_stakes, epoch_schedule) - .is_empty()); + assert!( + repair_weight + .get_popular_pruned_forks(epoch_stakes, epoch_schedule) + .is_empty() + ); // 600 stake, since we voted for leaf, leaf should be returned let votes = vec![(11, vec![vote_pubkeys[5]]), (6, vec![vote_pubkeys[6]])]; @@ -2655,18 +2672,21 @@ mod test { repair_weight.set_root(4); assert_eq!(repair_weight.trees.len(), 1); assert_eq!(repair_weight.pruned_trees.len(), 3); - assert!(repair_weight - .pruned_trees - .iter() - .all( - |(root, pruned_tree)| pruned_tree.stake_voted_subtree(&(*root, Hash::default())) - == Some(stake) - )); + assert!( + repair_weight + .pruned_trees + .iter() + .all(|(root, pruned_tree)| pruned_tree + .stake_voted_subtree(&(*root, Hash::default())) + == Some(stake)) + ); // No fork hash `DUPLICATE_THRESHOLD`, should not be any popular forks - assert!(repair_weight - .get_popular_pruned_forks(&epoch_stakes, &epoch_schedule) - .is_empty()); + assert!( + repair_weight + .get_popular_pruned_forks(&epoch_stakes, &epoch_schedule) + .is_empty() + ); // 400 stake, For the 6 tree it will be less than `DUPLICATE_THRESHOLD`, however 11 // has epoch modifications where at some point 400 stake is enough. For 22, although it diff --git a/core/src/repair/serve_repair.rs b/core/src/repair/serve_repair.rs index 59b380bb58d..57f2f897e64 100644 --- a/core/src/repair/serve_repair.rs +++ b/core/src/repair/serve_repair.rs @@ -11,21 +11,21 @@ use { duplicate_repair_status::get_ancestor_hash_repair_sample_size, quic_endpoint::RemoteRequest, repair_handler::RepairHandler, - repair_service::{OutstandingShredRepairs, RepairStats, REPAIR_MS}, + repair_service::{OutstandingShredRepairs, REPAIR_MS, RepairStats}, request_response::RequestResponse, result::{Error, RepairVerifyError, Result}, }, }, - bincode::{serialize, Options}, + bincode::{Options, serialize}, bytes::Bytes, crossbeam_channel::{Receiver, RecvTimeoutError}, lru::LruCache, rand::{ + Rng, distr::{ - weighted::{Error as WeightedError, WeightedIndex}, Distribution, + weighted::{Error as WeightedError, WeightedIndex}, }, - Rng, }, serde::{Deserialize, Serialize}, solana_clock::Slot, @@ -36,21 +36,21 @@ use { ping_pong::{self, Pong}, weighted_shuffle::WeightedShuffle, }, - solana_hash::{Hash, HASH_BYTES}, - solana_keypair::{signable::Signable, Keypair}, - solana_ledger::shred::{self, Nonce, ShredFetchStats, SIZE_OF_NONCE}, + solana_hash::{HASH_BYTES, Hash}, + solana_keypair::{Keypair, signable::Signable}, + solana_ledger::shred::{self, Nonce, SIZE_OF_NONCE, ShredFetchStats}, solana_net_utils::SocketAddrSpace, solana_packet::PACKET_DATA_SIZE, solana_perf::{ data_budget::DataBudget, packet::{Packet, PacketBatch, PacketBatchRecycler, RecycledPacketBatch}, }, - solana_pubkey::{Pubkey, PUBKEY_BYTES}, + solana_pubkey::{PUBKEY_BYTES, Pubkey}, solana_runtime::bank_forks::SharableBanks, - solana_signature::{Signature, SIGNATURE_BYTES}, + solana_signature::{SIGNATURE_BYTES, Signature}, solana_signer::Signer, solana_streamer::{ - sendmmsg::{batch_send, SendPktsError}, + sendmmsg::{SendPktsError, batch_send}, streamer::PacketBatchSender, }, solana_time_utils::timestamp, @@ -59,8 +59,8 @@ use { collections::{HashMap, HashSet}, net::{SocketAddr, UdpSocket}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, thread::{Builder, JoinHandle}, time::{Duration, Instant}, @@ -560,13 +560,13 @@ impl ServeRepair { return Err(Error::from(RepairVerifyError::Malformed)); } Self::verify_signed_packet(my_id, &remote_request.bytes, &request)?; - if let Some(remote_pubkey) = remote_request.remote_pubkey { - if Some(&remote_pubkey) != request.sender() { - error!( - "remote pubkey {remote_pubkey} != request sender {:?}", - request.sender() - ); - } + if let Some(remote_pubkey) = remote_request.remote_pubkey + && Some(&remote_pubkey) != request.sender() + { + error!( + "remote pubkey {remote_pubkey} != request sender {:?}", + request.sender() + ); } if request.sender() == Some(my_id) { error!("self repair: from_addr={from_addr} my_id={my_id} request={request:?}"); @@ -1355,16 +1355,16 @@ mod tests { solana_hash::Hash, solana_keypair::Keypair, solana_ledger::{ - blockstore::{make_many_slot_entries, Blockstore}, + blockstore::{Blockstore, make_many_slot_entries}, blockstore_processor::fill_blockstore_slot_with_ticks, - genesis_utils::{create_genesis_config, GenesisConfigInfo}, + genesis_utils::{GenesisConfigInfo, create_genesis_config}, get_tmp_ledger_path_auto_delete, shred::{ - max_ticks_per_n_shreds, ProcessShredsStats, ReedSolomonCache, Shred, Shredder, + ProcessShredsStats, ReedSolomonCache, Shred, Shredder, max_ticks_per_n_shreds, }, }, solana_net_utils::SocketAddrSpace, - solana_perf::packet::{deserialize_from_with_limit, Packet, PacketFlags, PacketRef}, + solana_perf::packet::{Packet, PacketFlags, PacketRef, deserialize_from_with_limit}, solana_pubkey::Pubkey, solana_runtime::bank::Bank, solana_time_utils::timestamp, @@ -1518,9 +1518,11 @@ mod tests { assert_eq!(&header.sender, &serve_repair.my_id()); assert_eq!(&header.recipient, &repair_peer_id); let signed_data = [&rsp[..4], &rsp[4 + SIGNATURE_BYTES..]].concat(); - assert!(header - .signature - .verify(keypair.pubkey().as_ref(), &signed_data)); + assert!( + header + .signature + .verify(keypair.pubkey().as_ref(), &signed_data) + ); } else { panic!("unexpected request type {:?}", &deserialized_request); } @@ -1561,9 +1563,11 @@ mod tests { assert_eq!(&header.sender, &serve_repair.my_id()); assert_eq!(&header.recipient, &repair_peer_id); let signed_data = [&request_bytes[..4], &request_bytes[4 + SIGNATURE_BYTES..]].concat(); - assert!(header - .signature - .verify(keypair.pubkey().as_ref(), &signed_data)); + assert!( + header + .signature + .verify(keypair.pubkey().as_ref(), &signed_data) + ); } else { panic!("unexpected request type {:?}", &deserialized_request); } @@ -1614,9 +1618,11 @@ mod tests { assert_eq!(&header.sender, &serve_repair.my_id()); assert_eq!(&header.recipient, &repair_peer_id); let signed_data = [&request_bytes[..4], &request_bytes[4 + SIGNATURE_BYTES..]].concat(); - assert!(header - .signature - .verify(keypair.pubkey().as_ref(), &signed_data)); + assert!( + header + .signature + .verify(keypair.pubkey().as_ref(), &signed_data) + ); } else { panic!("unexpected request type {:?}", &deserialized_request); } @@ -1648,9 +1654,11 @@ mod tests { assert_eq!(&header.sender, &serve_repair.my_id()); assert_eq!(&header.recipient, &repair_peer_id); let signed_data = [&request_bytes[..4], &request_bytes[4 + SIGNATURE_BYTES..]].concat(); - assert!(header - .signature - .verify(keypair.pubkey().as_ref(), &signed_data)); + assert!( + header + .signature + .verify(keypair.pubkey().as_ref(), &signed_data) + ); } else { panic!("unexpected request type {:?}", &deserialized_request); } @@ -2063,14 +2071,10 @@ mod tests { .expect("Expect successful ledger write"); let nonce = 42; // Make sure repair response is corrupted - assert!(repair_response::repair_response_packet( - &blockstore, - 1, - 0, - &socketaddr_any!(), - nonce, - ) - .is_none()); + assert!( + repair_response::repair_response_packet(&blockstore, 1, 0, &socketaddr_any!(), nonce,) + .is_none() + ); // Orphan request for slot 2 should only return slot 1 since // calling `repair_response_packet` on slot 1's shred will @@ -2081,14 +2085,16 @@ mod tests { .expect("run_orphan packets"); // Verify responses - let expected = RecycledPacketBatch::new(vec![repair_response::repair_response_packet( - &blockstore, - 2, - 31, // shred_index - &socketaddr_any!(), - nonce, - ) - .unwrap()]) + let expected = RecycledPacketBatch::new(vec![ + repair_response::repair_response_packet( + &blockstore, + 2, + 31, // shred_index + &socketaddr_any!(), + nonce, + ) + .unwrap(), + ]) .into(); assert_eq!(rv, expected); } @@ -2204,9 +2210,11 @@ mod tests { // then no repairs should be generated for pubkey in &[solana_pubkey::new_rand(), *me.pubkey()] { let known_validators = Some(vec![*pubkey].into_iter().collect()); - assert!(serve_repair - .repair_peers(&known_validators, 1, &identity_keypair.pubkey()) - .is_empty()); + assert!( + serve_repair + .repair_peers(&known_validators, 1, &identity_keypair.pubkey()) + .is_empty() + ); assert_matches!( serve_repair.repair_request( &cluster_slots, diff --git a/core/src/repair/serve_repair_service.rs b/core/src/repair/serve_repair_service.rs index c62fe688653..b4609a4f963 100644 --- a/core/src/repair/serve_repair_service.rs +++ b/core/src/repair/serve_repair_service.rs @@ -1,13 +1,13 @@ use { crate::repair::{quic_endpoint::RemoteRequest, serve_repair::ServeRepair}, bytes::Bytes, - crossbeam_channel::{unbounded, Receiver, Sender}, + crossbeam_channel::{Receiver, Sender, unbounded}, solana_net_utils::SocketAddrSpace, solana_perf::{packet::PacketBatch, recycler::Recycler}, solana_streamer::streamer::{self, StreamerReceiveStats}, std::{ net::{SocketAddr, UdpSocket}, - sync::{atomic::AtomicBool, Arc}, + sync::{Arc, atomic::AtomicBool}, thread::{self, Builder, JoinHandle}, time::Duration, }, diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs index 51980b6dcf2..58ec5657ec8 100644 --- a/core/src/replay_stage.rs +++ b/core/src/replay_stage.rs @@ -7,17 +7,17 @@ use { cluster_info_vote_listener::{ DuplicateConfirmedSlotsReceiver, GossipVerifiedVoteHashReceiver, VoteTracker, }, - cluster_slots_service::{cluster_slots::ClusterSlots, ClusterSlotsUpdateSender}, + cluster_slots_service::{ClusterSlotsUpdateSender, cluster_slots::ClusterSlots}, commitment_service::{AggregateCommitmentService, CommitmentAggregationData}, consensus::{ - fork_choice::{select_vote_and_reset_forks, ForkChoice, SelectVoteAndResetForkResult}, + BlockhashStatus, ComputedBankState, SWITCH_FORK_THRESHOLD, Stake, SwitchForkDecision, + Tower, TowerError, VotedStakes, + fork_choice::{ForkChoice, SelectVoteAndResetForkResult, select_vote_and_reset_forks}, heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice, latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks, progress_map::{ForkProgress, ProgressMap, PropagatedStats}, tower_storage::{SavedTower, SavedTowerVersions, TowerStorage}, tower_vote_state::TowerVoteState, - BlockhashStatus, ComputedBankState, Stake, SwitchForkDecision, Tower, TowerError, - VotedStakes, SWITCH_FORK_THRESHOLD, }, cost_update_service::CostUpdate, repair::{ @@ -34,9 +34,9 @@ use { }, agave_votor::root_utils, crossbeam_channel::{Receiver, RecvTimeoutError, Sender}, - rayon::{prelude::*, ThreadPool}, + rayon::{ThreadPool, prelude::*}, solana_accounts_db::contains::Contains, - solana_clock::{BankId, Slot, NUM_CONSECUTIVE_LEADER_SLOTS}, + solana_clock::{BankId, NUM_CONSECUTIVE_LEADER_SLOTS, Slot}, solana_geyser_plugin_manager::block_metadata_notifier_interface::BlockMetadataNotifierArc, solana_gossip::cluster_info::ClusterInfo, solana_hash::Hash, @@ -55,7 +55,7 @@ use { solana_measure::measure::Measure, solana_poh::{ poh_controller::PohController, - poh_recorder::{PohLeaderStatus, PohRecorder, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS}, + poh_recorder::{GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS, PohLeaderStatus, PohRecorder}, }, solana_pubkey::Pubkey, solana_rpc::{ @@ -65,7 +65,7 @@ use { }, solana_rpc_client_api::response::SlotUpdate, solana_runtime::{ - bank::{bank_hash_details, Bank, NewBankOptions}, + bank::{Bank, NewBankOptions, bank_hash_details}, bank_forks::{BankForks, MAX_ROOT_DISTANCE_FOR_VOTE_ONLY}, commitment::BlockCommitmentCache, installed_scheduler_pool::BankWithScheduler, @@ -84,8 +84,8 @@ use { num::{NonZeroUsize, Saturating}, result, sync::{ - atomic::{AtomicBool, AtomicU64, Ordering}, Arc, RwLock, + atomic::{AtomicBool, AtomicU64, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, @@ -1205,8 +1205,9 @@ impl ReplayStage { // may add a bank that will not included in either of these maps. drop(ancestors); drop(descendants); - if !tpu_has_bank && !poh_controller.has_pending_message() { - if let Some(poh_slot) = Self::maybe_start_leader( + if !tpu_has_bank + && !poh_controller.has_pending_message() + && let Some(poh_slot) = Self::maybe_start_leader( &my_pubkey, &bank_forks, &poh_recorder, @@ -1221,14 +1222,14 @@ impl ReplayStage { has_new_vote_been_rooted, &first_alpenglow_slot, &mut is_alpenglow_migration_complete, - ) { - Self::log_leader_change( - &my_pubkey, - poh_slot, - &mut current_leader, - &my_pubkey, - ); - } + ) + { + Self::log_leader_change( + &my_pubkey, + poh_slot, + &mut current_leader, + &my_pubkey, + ); } start_leader_time.stop(); @@ -1372,30 +1373,29 @@ impl ReplayStage { for slot in first_leader_group_slot..=latest_leader_slot { let is_propagated = progress.is_propagated(slot); - if let Some(retransmit_info) = progress.get_retransmit_info_mut(slot) { - if !is_propagated.expect( + if let Some(retransmit_info) = progress.get_retransmit_info_mut(slot) + && !is_propagated.expect( "presence of retransmit_info ensures that propagation status is present", - ) { - if retransmit_info.reached_retransmit_threshold() { - info!( - "Retrying retransmit: latest_leader_slot={} slot={} \ - retransmit_info={:?}", - latest_leader_slot, slot, &retransmit_info, - ); - datapoint_info!( - metric_name, - ("latest_leader_slot", latest_leader_slot, i64), - ("slot", slot, i64), - ("retry_iteration", retransmit_info.retry_iteration, i64), - ); - let _ = retransmit_slots_sender.send(slot); - retransmit_info.increment_retry_iteration(); - } else { - debug!( - "Bypass retransmit of slot={} retransmit_info={:?}", - slot, &retransmit_info - ); - } + ) + { + if retransmit_info.reached_retransmit_threshold() { + info!( + "Retrying retransmit: latest_leader_slot={} slot={} retransmit_info={:?}", + latest_leader_slot, slot, &retransmit_info, + ); + datapoint_info!( + metric_name, + ("latest_leader_slot", latest_leader_slot, i64), + ("slot", slot, i64), + ("retry_iteration", retransmit_info.retry_iteration, i64), + ); + let _ = retransmit_slots_sender.send(slot); + retransmit_info.increment_retry_iteration(); + } else { + debug!( + "Bypass retransmit of slot={} retransmit_info={:?}", + slot, &retransmit_info + ); } } } @@ -2050,17 +2050,17 @@ impl ReplayStage { current_leader: &mut Option, new_leader: &Pubkey, ) { - if let Some(current_leader) = current_leader.as_ref() { - if current_leader != new_leader { - let msg = if current_leader == my_pubkey { - ". I am no longer the leader" - } else if new_leader == my_pubkey { - ". I am now the leader" - } else { - "" - }; - info!("LEADER CHANGE at slot: {bank_slot} leader: {new_leader}{msg}"); - } + if let Some(current_leader) = current_leader.as_ref() + && current_leader != new_leader + { + let msg = if current_leader == my_pubkey { + ". I am no longer the leader" + } else if new_leader == my_pubkey { + ". I am now the leader" + } else { + "" + }; + info!("LEADER CHANGE at slot: {bank_slot} leader: {new_leader}{msg}"); } current_leader.replace(new_leader.to_owned()); } @@ -2165,21 +2165,17 @@ impl ReplayStage { }; // Check if migration is necessary - if let Some(first_alpenglow_slot) = first_alpenglow_slot { - if !(*is_alpenglow_migration_complete) && poh_slot >= *first_alpenglow_slot { - // Initiate migration - // TODO: need to keep the ticks around for parent slots in previous epoch - // because reset below will delete those ticks - info!( - "initiating alpenglow migration from maybe_start_leader() for slot {poh_slot}", - ); - Self::maybe_initiate_alpenglow_migration( - poh_recorder, - is_alpenglow_migration_complete, - ); - // Votor will handle leader blocks from now on - return None; - } + if let Some(first_alpenglow_slot) = first_alpenglow_slot + && !(*is_alpenglow_migration_complete) + && poh_slot >= *first_alpenglow_slot + { + // Initiate migration + // TODO: need to keep the ticks around for parent slots in previous epoch + // because reset below will delete those ticks + info!("initiating alpenglow migration from maybe_start_leader() for slot {poh_slot}",); + Self::maybe_initiate_alpenglow_migration(poh_recorder, is_alpenglow_migration_complete); + // Votor will handle leader blocks from now on + return None; } trace!("{my_pubkey} reached_leader_slot"); @@ -2477,19 +2473,18 @@ impl ReplayStage { let new_root = tower.record_bank_vote(bank); if let Some(new_root) = new_root { - if first_alpenglow_slot.is_none() { - if let Some(activation_slot) = bank_forks + if first_alpenglow_slot.is_none() + && let Some(activation_slot) = bank_forks .read() .unwrap() .root_bank() .compute_pending_activation_slot(&agave_feature_set::alpenglow::id()) - { - *first_alpenglow_slot = Some(activation_slot); - info!( - "alpenglow feature detected in root bank {new_root}, to be enabled on \ - slot {activation_slot}", - ); - } + { + *first_alpenglow_slot = Some(activation_slot); + info!( + "alpenglow feature detected in root bank {new_root}, to be enabled on slot \ + {activation_slot}", + ); } let highest_super_majority_root = Some( block_commitment_cache @@ -2573,10 +2568,10 @@ impl ReplayStage { if authorized_voter_keypairs.is_empty() { return GenerateVoteTxResult::NonVoting; } - if let Some(slot) = wait_to_vote_slot { - if bank.slot() < slot { - return GenerateVoteTxResult::Failed; - } + if let Some(slot) = wait_to_vote_slot + && bank.slot() < slot + { + return GenerateVoteTxResult::Failed; } let Some(vote_account) = bank.get_vote_account(vote_account_pubkey) else { warn!("Vote account {vote_account_pubkey} does not exist. Unable to vote",); @@ -3206,17 +3201,18 @@ impl ReplayStage { assert_eq!(bank_slot, bank.slot()); if bank.is_complete() { - if let Some(first_alpenglow_slot) = first_alpenglow_slot { - if !*is_alpenglow_migration_complete && bank.slot() >= first_alpenglow_slot { - info!( - "initiating alpenglow migration from replaying bank {}", - bank.slot() - ); - Self::maybe_initiate_alpenglow_migration( - poh_recorder, - is_alpenglow_migration_complete, - ); - } + if let Some(first_alpenglow_slot) = first_alpenglow_slot + && !*is_alpenglow_migration_complete + && bank.slot() >= first_alpenglow_slot + { + info!( + "initiating alpenglow migration from replaying bank {}", + bank.slot() + ); + Self::maybe_initiate_alpenglow_migration( + poh_recorder, + is_alpenglow_migration_complete, + ); } let mut bank_complete_time = Measure::start("bank_complete_time"); let bank_progress = progress @@ -3702,34 +3698,35 @@ impl ReplayStage { tower.vote_state.root_slot ); - if let Some(local_root) = tower.vote_state.root_slot { - if bank_vote_state + if let Some(local_root) = tower.vote_state.root_slot + && bank_vote_state .root_slot .map(|bank_root| local_root > bank_root) .unwrap_or(true) - { - // If the local root is larger than this on chain vote state - // root (possible due to supermajority roots being set on - // startup), then we need to adjust the tower - bank_vote_state.root_slot = Some(local_root); - bank_vote_state - .votes - .retain(|lockout| lockout.slot() > local_root); - info!( - "Local root is larger than on chain root, overwrote bank root {:?} and \ - updated votes {:?}", - bank_vote_state.root_slot, bank_vote_state.votes - ); + { + // If the local root is larger than this on chain vote state + // root (possible due to supermajority roots being set on + // startup), then we need to adjust the tower + bank_vote_state.root_slot = Some(local_root); + bank_vote_state + .votes + .retain(|lockout| lockout.slot() > local_root); + info!( + "Local root is larger than on chain root, overwrote bank root {:?} and updated \ + votes {:?}", + bank_vote_state.root_slot, bank_vote_state.votes + ); - if let Some(first_vote) = bank_vote_state.votes.front() { - assert!(ancestors + if let Some(first_vote) = bank_vote_state.votes.front() { + assert!( + ancestors .get(&first_vote.slot()) .expect( "Ancestors map must contain an entry for all slots on this fork \ greater than `local_root` and less than `bank_slot`" ) - .contains(&local_root)); - } + .contains(&local_root) + ); } } @@ -4422,20 +4419,20 @@ pub(crate) mod tests { super::*, crate::{ consensus::{ - progress_map::{ValidatorStakeInfo, RETRANSMIT_BASE_DELAY_MS}, + ThresholdDecision, Tower, VOTE_THRESHOLD_DEPTH, + progress_map::{RETRANSMIT_BASE_DELAY_MS, ValidatorStakeInfo}, tower_storage::{FileTowerStorage, NullTowerStorage}, tree_diff::TreeDiff, - ThresholdDecision, Tower, VOTE_THRESHOLD_DEPTH, }, replay_stage::ReplayStage, vote_simulator::{self, VoteSimulator}, }, blockstore_processor::{ - confirm_full_slot, fill_blockstore_slot_with_ticks, process_bank_0, ProcessOptions, + ProcessOptions, confirm_full_slot, fill_blockstore_slot_with_ticks, process_bank_0, }, crossbeam_channel::unbounded, itertools::Itertools, - solana_account::{state_traits::StateMut, ReadableAccount}, + solana_account::{ReadableAccount, state_traits::StateMut}, solana_client::connection_cache::ConnectionCache, solana_clock::NUM_CONSECUTIVE_LEADER_SLOTS, solana_entry::entry::{self, Entry}, @@ -4445,7 +4442,7 @@ pub(crate) mod tests { solana_instruction::error::InstructionError, solana_keypair::Keypair, solana_ledger::{ - blockstore::{entries_to_test_shreds, make_slot_entries, BlockstoreError}, + blockstore::{BlockstoreError, entries_to_test_shreds, make_slot_entries}, create_new_tmp_ledger, genesis_utils::{create_genesis_config, create_genesis_config_with_leader}, get_tmp_ledger_path, get_tmp_ledger_path_auto_delete, @@ -4473,11 +4470,11 @@ pub(crate) mod tests { std::{ fs::remove_dir_all, iter, - sync::{atomic::AtomicU64, Arc, Mutex, RwLock}, + sync::{Arc, Mutex, RwLock, atomic::AtomicU64}, }, tempfile::tempdir, test_case::test_case, - trees::{tr, Tree}, + trees::{Tree, tr}, }; #[test] @@ -4645,11 +4642,13 @@ pub(crate) mod tests { 8, // num_entries ); blockstore.insert_shreds(shreds, None, false).unwrap(); - assert!(bank_forks - .read() - .unwrap() - .get(NUM_CONSECUTIVE_LEADER_SLOTS) - .is_none()); + assert!( + bank_forks + .read() + .unwrap() + .get(NUM_CONSECUTIVE_LEADER_SLOTS) + .is_none() + ); let mut replay_timing = ReplayLoopTiming::default(); ReplayStage::generate_new_bank_forks( &blockstore, @@ -4660,21 +4659,25 @@ pub(crate) mod tests { &mut progress, &mut replay_timing, ); - assert!(bank_forks - .read() - .unwrap() - .get(NUM_CONSECUTIVE_LEADER_SLOTS) - .is_some()); + assert!( + bank_forks + .read() + .unwrap() + .get(NUM_CONSECUTIVE_LEADER_SLOTS) + .is_some() + ); // Insert shreds for slot 2 * NUM_CONSECUTIVE_LEADER_SLOTS, // chaining to slot 1 let (shreds, _) = make_slot_entries(2 * NUM_CONSECUTIVE_LEADER_SLOTS, 1, 8); blockstore.insert_shreds(shreds, None, false).unwrap(); - assert!(bank_forks - .read() - .unwrap() - .get(2 * NUM_CONSECUTIVE_LEADER_SLOTS) - .is_none()); + assert!( + bank_forks + .read() + .unwrap() + .get(2 * NUM_CONSECUTIVE_LEADER_SLOTS) + .is_none() + ); ReplayStage::generate_new_bank_forks( &blockstore, &bank_forks, @@ -4684,16 +4687,20 @@ pub(crate) mod tests { &mut progress, &mut replay_timing, ); - assert!(bank_forks - .read() - .unwrap() - .get(NUM_CONSECUTIVE_LEADER_SLOTS) - .is_some()); - assert!(bank_forks - .read() - .unwrap() - .get(2 * NUM_CONSECUTIVE_LEADER_SLOTS) - .is_some()); + assert!( + bank_forks + .read() + .unwrap() + .get(NUM_CONSECUTIVE_LEADER_SLOTS) + .is_some() + ); + assert!( + bank_forks + .read() + .unwrap() + .get(2 * NUM_CONSECUTIVE_LEADER_SLOTS) + .is_some() + ); // // There are 20 equally staked accounts, of which 3 have built // banks above or at bank 1. Because 3/20 < SUPERMINORITY_THRESHOLD, @@ -4706,11 +4713,13 @@ pub(crate) mod tests { for slot in expected_leader_slots { let leader = leader_schedule_cache.slot_leader_at(slot, None).unwrap(); let vote_key = validator_node_to_vote_keys.get(&leader).unwrap(); - assert!(progress - .get_propagated_stats(1) - .unwrap() - .propagated_validators - .contains(vote_key)); + assert!( + progress + .get_propagated_stats(1) + .unwrap() + .propagated_validators + .contains(vote_key) + ); } } @@ -5217,10 +5226,12 @@ pub(crate) mod tests { } assert!(dead_slots.lock().unwrap().contains(&bank1.slot())); // Check that the erroring bank was marked as dead in the progress map - assert!(progress - .get(&bank1.slot()) - .map(|b| b.is_dead) - .unwrap_or(false)); + assert!( + progress + .get(&bank1.slot()) + .map(|b| b.is_dead) + .unwrap_or(false) + ); // Check that the erroring bank was marked as dead in blockstore assert!(blockstore.is_dead(bank1.slot())); @@ -5274,16 +5285,20 @@ pub(crate) mod tests { rpc_subscriptions, ); - assert!(block_commitment_cache - .read() - .unwrap() - .get_block_commitment(0) - .is_none()); - assert!(block_commitment_cache - .read() - .unwrap() - .get_block_commitment(1) - .is_none()); + assert!( + block_commitment_cache + .read() + .unwrap() + .get_block_commitment(0) + .is_none() + ); + assert!( + block_commitment_cache + .read() + .unwrap() + .get_block_commitment(1) + .is_none() + ); for i in 1..=3 { let prev_bank = bank_forks.read().unwrap().get(i - 1).unwrap(); @@ -5650,9 +5665,11 @@ pub(crate) mod tests { // Fill banks with votes for vote in votes { - assert!(vote_simulator - .simulate_vote(vote, &my_node_pubkey, &mut tower,) - .is_empty()); + assert!( + vote_simulator + .simulate_vote(vote, &my_node_pubkey, &mut tower,) + .is_empty() + ); } let mut frozen_banks: Vec<_> = vote_simulator @@ -5973,19 +5990,23 @@ pub(crate) mod tests { assert!(propagated_stats.slot_vote_tracker.is_some()); // Updates should have been consumed - assert!(propagated_stats - .slot_vote_tracker - .as_ref() - .unwrap() - .write() - .unwrap() - .get_voted_slot_updates() - .is_none()); + assert!( + propagated_stats + .slot_vote_tracker + .as_ref() + .unwrap() + .write() + .unwrap() + .get_voted_slot_updates() + .is_none() + ); // The voter should be recorded - assert!(propagated_stats - .propagated_validators - .contains(&vote_pubkey)); + assert!( + propagated_stats + .propagated_validators + .contains(&vote_pubkey) + ); assert_eq!(propagated_stats.propagated_validators_stake, stake); } @@ -8743,23 +8764,25 @@ pub(crate) mod tests { let rpc_subscriptions = Some(rpc_subscriptions); - assert!(ReplayStage::maybe_start_leader( - my_pubkey, - bank_forks, - &poh_recorder, - &mut poh_controller, - &leader_schedule_cache, - rpc_subscriptions.as_deref(), - &None, - &mut progress, - &retransmit_slots_sender, - &mut SkippedSlotsInfo::default(), - &banking_tracer, - has_new_vote_been_rooted, - &None, - &mut false, - ) - .is_none()); + assert!( + ReplayStage::maybe_start_leader( + my_pubkey, + bank_forks, + &poh_recorder, + &mut poh_controller, + &leader_schedule_cache, + rpc_subscriptions.as_deref(), + &None, + &mut progress, + &retransmit_slots_sender, + &mut SkippedSlotsInfo::default(), + &banking_tracer, + has_new_vote_been_rooted, + &None, + &mut false, + ) + .is_none() + ); } #[test] @@ -9337,14 +9360,18 @@ pub(crate) mod tests { let bank_forks = bank_forks.read().unwrap(); // 4 (the artificial root) is the tree root and no longer duplicate assert_eq!(fork_choice.tree_root().0, 4); - assert!(fork_choice - .is_candidate(&(4, bank_forks.bank_hash(4).unwrap())) - .unwrap()); + assert!( + fork_choice + .is_candidate(&(4, bank_forks.bank_hash(4).unwrap())) + .unwrap() + ); // 5 is still considered duplicate, so it is not a valid fork choice candidate - assert!(!fork_choice - .is_candidate(&(5, bank_forks.bank_hash(5).unwrap())) - .unwrap()); + assert!( + !fork_choice + .is_candidate(&(5, bank_forks.bank_hash(5).unwrap())) + .unwrap() + ); } #[test] @@ -9418,23 +9445,25 @@ pub(crate) mod tests { poh_recorder.read().unwrap().reached_leader_slot(&my_pubkey), PohLeaderStatus::NotReached ); - assert!(ReplayStage::maybe_start_leader( - &my_pubkey, - &bank_forks, - &poh_recorder, - &mut poh_controller, - &leader_schedule_cache, - rpc_subscriptions.as_deref(), - &None, - &mut progress, - &retransmit_slots_sender, - &mut SkippedSlotsInfo::default(), - &banking_tracer, - has_new_vote_been_rooted, - &None, - &mut false, - ) - .is_none()); + assert!( + ReplayStage::maybe_start_leader( + &my_pubkey, + &bank_forks, + &poh_recorder, + &mut poh_controller, + &leader_schedule_cache, + rpc_subscriptions.as_deref(), + &None, + &mut progress, + &retransmit_slots_sender, + &mut SkippedSlotsInfo::default(), + &banking_tracer, + has_new_vote_been_rooted, + &None, + &mut false, + ) + .is_none() + ); // Register another slots worth of ticks with PoH recorder poh_recorder @@ -9448,23 +9477,25 @@ pub(crate) mod tests { // We should now start leader for dummy_slot + 1 let good_slot = dummy_slot + 1; - assert!(ReplayStage::maybe_start_leader( - &my_pubkey, - &bank_forks, - &poh_recorder, - &mut poh_controller, - &leader_schedule_cache, - rpc_subscriptions.as_deref(), - &None, - &mut progress, - &retransmit_slots_sender, - &mut SkippedSlotsInfo::default(), - &banking_tracer, - has_new_vote_been_rooted, - &None, - &mut false, - ) - .is_some()); + assert!( + ReplayStage::maybe_start_leader( + &my_pubkey, + &bank_forks, + &poh_recorder, + &mut poh_controller, + &leader_schedule_cache, + rpc_subscriptions.as_deref(), + &None, + &mut progress, + &retransmit_slots_sender, + &mut SkippedSlotsInfo::default(), + &banking_tracer, + has_new_vote_been_rooted, + &None, + &mut false, + ) + .is_some() + ); wait_for_poh_service(&poh_controller); // Get the new working bank, which is also the new leader bank/slot @@ -9538,10 +9569,12 @@ pub(crate) mod tests { ); assert_eq!(*duplicate_confirmed_slots.get(&5).unwrap(), bank_hash_5); - assert!(tbft_structs - .heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(5, bank_hash_5)) - .unwrap_or(false)); + assert!( + tbft_structs + .heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(5, bank_hash_5)) + .unwrap_or(false) + ); // Mark 5 and 6 as duplicate confirmed, should succeed let bank_hash_6 = bank_forks.read().unwrap().bank_hash(6).unwrap(); @@ -9562,15 +9595,19 @@ pub(crate) mod tests { ); assert_eq!(*duplicate_confirmed_slots.get(&5).unwrap(), bank_hash_5); - assert!(tbft_structs - .heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(5, bank_hash_5)) - .unwrap_or(false)); + assert!( + tbft_structs + .heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(5, bank_hash_5)) + .unwrap_or(false) + ); assert_eq!(*duplicate_confirmed_slots.get(&6).unwrap(), bank_hash_6); - assert!(tbft_structs - .heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(6, bank_hash_6)) - .unwrap_or(false)); + assert!( + tbft_structs + .heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(6, bank_hash_6)) + .unwrap_or(false) + ); // Mark 6 as duplicate confirmed again with a different hash, should panic let confirmed_slots = [(6, Hash::new_unique())]; @@ -9653,10 +9690,12 @@ pub(crate) mod tests { ); assert_eq!(*duplicate_confirmed_slots.get(&5).unwrap(), bank_hash_5); - assert!(tbft_structs - .heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(5, bank_hash_5)) - .unwrap_or(false)); + assert!( + tbft_structs + .heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(5, bank_hash_5)) + .unwrap_or(false) + ); // Mark 5 and 6 as duplicate confirmed, should succeed let bank_hash_6 = bank_forks.read().unwrap().bank_hash(6).unwrap(); @@ -9684,15 +9723,19 @@ pub(crate) mod tests { ); assert_eq!(*duplicate_confirmed_slots.get(&5).unwrap(), bank_hash_5); - assert!(tbft_structs - .heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(5, bank_hash_5)) - .unwrap_or(false)); + assert!( + tbft_structs + .heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(5, bank_hash_5)) + .unwrap_or(false) + ); assert_eq!(*duplicate_confirmed_slots.get(&6).unwrap(), bank_hash_6); - assert!(tbft_structs - .heaviest_subtree_fork_choice - .is_duplicate_confirmed(&(6, bank_hash_6)) - .unwrap_or(false)); + assert!( + tbft_structs + .heaviest_subtree_fork_choice + .is_duplicate_confirmed(&(6, bank_hash_6)) + .unwrap_or(false) + ); // Mark 6 as duplicate confirmed again with a different hash, should panic sender.send(vec![(6, Hash::new_unique())]).unwrap(); diff --git a/core/src/result.rs b/core/src/result.rs index 80295230672..65a5959ff46 100644 --- a/core/src/result.rs +++ b/core/src/result.rs @@ -44,7 +44,7 @@ impl std::convert::From> for Error { mod tests { use { crate::result::{Error, Result}, - crossbeam_channel::{unbounded, RecvError, RecvTimeoutError}, + crossbeam_channel::{RecvError, RecvTimeoutError, unbounded}, std::{io, io::Write, panic}, }; diff --git a/core/src/sample_performance_service.rs b/core/src/sample_performance_service.rs index 5653182aae1..c61e7ddb6e5 100644 --- a/core/src/sample_performance_service.rs +++ b/core/src/sample_performance_service.rs @@ -3,10 +3,10 @@ use { solana_runtime::bank_forks::BankForks, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::{Duration, Instant}, }, }; diff --git a/core/src/scheduler_bindings_server.rs b/core/src/scheduler_bindings_server.rs index d0553d43fc4..4eb5860da83 100644 --- a/core/src/scheduler_bindings_server.rs +++ b/core/src/scheduler_bindings_server.rs @@ -10,20 +10,22 @@ pub(crate) fn spawn(path: &Path, session_sender: mpsc::Sender std::thread::Builder::new() .name("solBindingSrv".to_string()) - .spawn(move || loop { - match listener.accept() { - Ok(session) => { - if session_sender - .blocking_send(BankingControlMsg::External { session }) - .is_err() - { - break; + .spawn(move || { + loop { + match listener.accept() { + Ok(session) => { + if session_sender + .blocking_send(BankingControlMsg::External { session }) + .is_err() + { + break; + } } - } - Err(err) => { - error!("External scheduler handshake failed; err={err}") - } - }; + Err(err) => { + error!("External scheduler handshake failed; err={err}") + } + }; + } }) .unwrap(); } diff --git a/core/src/shred_fetch_stage.rs b/core/src/shred_fetch_stage.rs index 9739d82c391..d8da3492eab 100644 --- a/core/src/shred_fetch_stage.rs +++ b/core/src/shred_fetch_stage.rs @@ -4,13 +4,13 @@ use { crate::repair::{repair_service::OutstandingShredRepairs, serve_repair::ServeRepair}, agave_feature_set::FeatureSet, bytes::Bytes, - crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}, + crossbeam_channel::{Receiver, RecvTimeoutError, Sender, unbounded}, itertools::Itertools, - solana_clock::{Slot, DEFAULT_MS_PER_SLOT}, + solana_clock::{DEFAULT_MS_PER_SLOT, Slot}, solana_epoch_schedule::EpochSchedule, solana_gossip::cluster_info::ClusterInfo, solana_keypair::Keypair, - solana_ledger::shred::{self, should_discard_shred, ShredFetchStats}, + solana_ledger::shred::{self, ShredFetchStats, should_discard_shred}, solana_packet::{Meta, PACKET_DATA_SIZE}, solana_perf::packet::{ BytesPacket, BytesPacketBatch, PacketBatch, PacketBatchRecycler, PacketFlags, PacketRef, @@ -24,8 +24,8 @@ use { std::{ net::{SocketAddr, UdpSocket}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, @@ -179,10 +179,10 @@ impl ShredFetchStage { packet.meta_mut().flags.insert(flags); } } - if stats.maybe_submit(name, STATS_SUBMIT_CADENCE) { - if let Some(stats) = recvr_stats.as_ref() { - stats.report(); - } + if stats.maybe_submit(name, STATS_SUBMIT_CADENCE) + && let Some(stats) = recvr_stats.as_ref() + { + stats.report(); } if let Err(send_err) = sendr.try_send(packet_batch) { match send_err { diff --git a/core/src/sigverify.rs b/core/src/sigverify.rs index bbb18e00e60..dbe0707cbc9 100644 --- a/core/src/sigverify.rs +++ b/core/src/sigverify.rs @@ -3,7 +3,7 @@ //! cores. pub use solana_perf::sigverify::{ - count_packets_in_batches, ed25519_verify, ed25519_verify_disabled, TxOffset, + TxOffset, count_packets_in_batches, ed25519_verify, ed25519_verify_disabled, }; use { crate::{ diff --git a/core/src/sigverify_stage.rs b/core/src/sigverify_stage.rs index 18fcd932911..1f145a53191 100644 --- a/core/src/sigverify_stage.rs +++ b/core/src/sigverify_stage.rs @@ -439,7 +439,7 @@ mod tests { crate::{banking_trace::BankingTracer, sigverify::TransactionSigVerifier}, crossbeam_channel::unbounded, solana_perf::{ - packet::{to_packet_batches, Packet, RecycledPacketBatch}, + packet::{Packet, RecycledPacketBatch, to_packet_batches}, test_tx::test_tx, }, }; diff --git a/core/src/snapshot_packager_service.rs b/core/src/snapshot_packager_service.rs index 9d3ab06d3a8..52068367052 100644 --- a/core/src/snapshot_packager_service.rs +++ b/core/src/snapshot_packager_service.rs @@ -1,8 +1,8 @@ mod snapshot_gossip_manager; use { agave_snapshots::{ - paths as snapshot_paths, snapshot_config::SnapshotConfig, - snapshot_hash::StartingSnapshotHashes, SnapshotKind, + SnapshotKind, paths as snapshot_paths, snapshot_config::SnapshotConfig, + snapshot_hash::StartingSnapshotHashes, }, snapshot_gossip_manager::SnapshotGossipManager, solana_accounts_db::account_storage_entry::AccountStorageEntry, @@ -18,8 +18,8 @@ use { }, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, diff --git a/core/src/snapshot_packager_service/snapshot_gossip_manager.rs b/core/src/snapshot_packager_service/snapshot_gossip_manager.rs index 2c532f33c92..a2af31d690b 100644 --- a/core/src/snapshot_packager_service/snapshot_gossip_manager.rs +++ b/core/src/snapshot_packager_service/snapshot_gossip_manager.rs @@ -1,9 +1,9 @@ use { agave_snapshots::{ + SnapshotArchiveKind, SnapshotKind, snapshot_hash::{ FullSnapshotHash, IncrementalSnapshotHash, SnapshotHash, StartingSnapshotHashes, }, - SnapshotArchiveKind, SnapshotKind, }, solana_clock::Slot, solana_gossip::cluster_info::ClusterInfo, @@ -41,7 +41,7 @@ impl SnapshotGossipManager { if let Some(starting_incremental_snapshot_hash) = starting_snapshot_hashes.incremental { self.update_latest_incremental_snapshot_hash( starting_incremental_snapshot_hash, - starting_snapshot_hashes.full.0 .0, + starting_snapshot_hashes.full.0.0, ); } self.push_latest_snapshot_hashes_to_cluster(); @@ -106,10 +106,10 @@ impl SnapshotGossipManager { .as_mut() .expect("there must already be a full snapshot hash"); assert_eq!( - base_slot, latest_snapshot_hashes.full.0 .0, + base_slot, latest_snapshot_hashes.full.0.0, "the incremental snapshot's base slot ({}) must match the latest full snapshot's slot \ ({})", - base_slot, latest_snapshot_hashes.full.0 .0, + base_slot, latest_snapshot_hashes.full.0.0, ); latest_snapshot_hashes.incremental = Some(incremental_snapshot_hash); } diff --git a/core/src/staked_nodes_updater_service.rs b/core/src/staked_nodes_updater_service.rs index be2e153af58..471c07b8d7b 100644 --- a/core/src/staked_nodes_updater_service.rs +++ b/core/src/staked_nodes_updater_service.rs @@ -5,8 +5,8 @@ use { std::{ collections::HashMap, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::Duration, diff --git a/core/src/stats_reporter_service.rs b/core/src/stats_reporter_service.rs index b192db1495d..8d5fb220f20 100644 --- a/core/src/stats_reporter_service.rs +++ b/core/src/stats_reporter_service.rs @@ -3,8 +3,8 @@ use { std::{ result::Result, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::Duration, @@ -22,14 +22,16 @@ impl StatsReporterService { ) -> Self { let thread_hdl = Builder::new() .name("solStatsReport".to_owned()) - .spawn(move || loop { - if exit.load(Ordering::Relaxed) { - return; - } - if let Err(e) = Self::receive_reporting_func(&reporting_receiver) { - match e { - RecvTimeoutError::Disconnected => break, - RecvTimeoutError::Timeout => (), + .spawn(move || { + loop { + if exit.load(Ordering::Relaxed) { + return; + } + if let Err(e) = Self::receive_reporting_func(&reporting_receiver) { + match e { + RecvTimeoutError::Disconnected => break, + RecvTimeoutError::Timeout => (), + } } } }) diff --git a/core/src/system_monitor_service.rs b/core/src/system_monitor_service.rs index 55fc4802303..5538f62bf7b 100644 --- a/core/src/system_monitor_service.rs +++ b/core/src/system_monitor_service.rs @@ -1,7 +1,7 @@ #[cfg(target_arch = "x86")] -use core::arch::x86::{CpuidResult, __cpuid, __cpuid_count, __get_cpuid_max}; +use core::arch::x86::{__cpuid, __cpuid_count, __get_cpuid_max, CpuidResult}; #[cfg(target_arch = "x86_64")] -use core::arch::x86_64::{CpuidResult, __cpuid, __cpuid_count, __get_cpuid_max}; +use core::arch::x86_64::{__cpuid, __cpuid_count, __get_cpuid_max, CpuidResult}; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use num_enum::{IntoPrimitive, TryFromPrimitive}; #[cfg(target_os = "linux")] @@ -12,10 +12,10 @@ use { collections::HashMap, io::BufRead, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::Duration, }, sys_info::{Error, LoadAvg}, diff --git a/core/src/tpu.rs b/core/src/tpu.rs index 35e1db997ec..123d8fb9ead 100644 --- a/core/src/tpu.rs +++ b/core/src/tpu.rs @@ -6,8 +6,8 @@ use { crate::{ admin_rpc_post_init::{KeyUpdaterType, KeyUpdaters}, banking_stage::{ - transaction_scheduler::scheduler_controller::SchedulerConfig, BankingControlMsg, - BankingStage, BankingStageHandle, + BankingControlMsg, BankingStage, BankingStageHandle, + transaction_scheduler::scheduler_controller::SchedulerConfig, }, banking_trace::{Channels, TracerThread}, cluster_info_vote_listener::{ @@ -16,7 +16,7 @@ use { }, fetch_stage::FetchStage, forwarding_stage::{ - spawn_forwarding_stage, ForwardAddressGetter, SpawnForwardingStageResult, + ForwardAddressGetter, SpawnForwardingStageResult, spawn_forwarding_stage, }, sigverify::TransactionSigVerifier, sigverify_stage::SigVerifyStage, @@ -25,7 +25,7 @@ use { validator::{BlockProductionMethod, GeneratorConfig}, vortexor_receiver_adapter::VortexorReceiverAdapter, }, - crossbeam_channel::{bounded, unbounded, Receiver}, + crossbeam_channel::{Receiver, bounded, unbounded}, solana_clock::Slot, solana_gossip::cluster_info::ClusterInfo, solana_keypair::Keypair, @@ -50,8 +50,8 @@ use { }, solana_streamer::{ quic::{ - spawn_simple_qos_server, spawn_stake_wighted_qos_server, SimpleQosQuicStreamerConfig, - SpawnServerResult, SwQosQuicStreamerConfig, + SimpleQosQuicStreamerConfig, SpawnServerResult, SwQosQuicStreamerConfig, + spawn_simple_qos_server, spawn_stake_wighted_qos_server, }, streamer::StakedNodes, }, @@ -64,7 +64,7 @@ use { net::UdpSocket, num::NonZeroUsize, path::PathBuf, - sync::{atomic::AtomicBool, Arc, RwLock}, + sync::{Arc, RwLock, atomic::AtomicBool}, thread::{self, JoinHandle}, time::Duration, }, @@ -431,13 +431,13 @@ impl Tpu { tpu_entry_notifier.join()?; } let _ = broadcast_result?; - if let Some(tracer_thread_hdl) = self.tracer_thread_hdl { - if let Err(tracer_result) = tracer_thread_hdl.join()? { - error!( - "banking tracer thread returned error after successful thread join: \ - {tracer_result:?}" - ); - } + if let Some(tracer_thread_hdl) = self.tracer_thread_hdl + && let Err(tracer_result) = tracer_thread_hdl.join()? + { + error!( + "banking tracer thread returned error after successful thread join: \ + {tracer_result:?}" + ); } Ok(()) } diff --git a/core/src/tpu_entry_notifier.rs b/core/src/tpu_entry_notifier.rs index 583ef343510..d4d46f6f2e2 100644 --- a/core/src/tpu_entry_notifier.rs +++ b/core/src/tpu_entry_notifier.rs @@ -5,8 +5,8 @@ use { solana_poh::poh_recorder::WorkingBankEntry, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::Duration, diff --git a/core/src/tvu.rs b/core/src/tvu.rs index e7985fe0d97..74499f93ae7 100644 --- a/core/src/tvu.rs +++ b/core/src/tvu.rs @@ -8,20 +8,20 @@ use { DuplicateConfirmedSlotsReceiver, GossipVerifiedVoteHashReceiver, VerifiedVoterSlotsReceiver, VoteTracker, }, - cluster_slots_service::{cluster_slots::ClusterSlots, ClusterSlotsService}, + cluster_slots_service::{ClusterSlotsService, cluster_slots::ClusterSlots}, completed_data_sets_service::CompletedDataSetsSender, - consensus::{tower_storage::TowerStorage, Tower}, + consensus::{Tower, tower_storage::TowerStorage}, cost_update_service::CostUpdateService, drop_bank_service::DropBankService, repair::repair_service::{OutstandingShredRepairs, RepairInfo, RepairServiceChannels}, replay_stage::{ReplayReceivers, ReplaySenders, ReplayStage, ReplayStageConfig}, - shred_fetch_stage::{ShredFetchStage, SHRED_FETCH_CHANNEL_SIZE}, + shred_fetch_stage::{SHRED_FETCH_CHANNEL_SIZE, ShredFetchStage}, voting_service::VotingService, warm_quic_cache_service::WarmQuicCacheService, window_service::{WindowService, WindowServiceChannels}, }, bytes::Bytes, - crossbeam_channel::{unbounded, Receiver, Sender}, + crossbeam_channel::{Receiver, Sender, unbounded}, solana_client::connection_cache::ConnectionCache, solana_clock::Slot, solana_geyser_plugin_manager::block_metadata_notifier_interface::BlockMetadataNotifierArc, @@ -52,7 +52,7 @@ use { collections::HashSet, net::{SocketAddr, UdpSocket}, num::NonZeroUsize, - sync::{atomic::AtomicBool, Arc, RwLock}, + sync::{Arc, RwLock, atomic::AtomicBool}, thread::{self, JoinHandle}, }, tokio::sync::mpsc::Sender as AsyncSender, @@ -468,7 +468,7 @@ pub mod tests { blockstore::BlockstoreSignals, blockstore_options::BlockstoreOptions, create_new_tmp_ledger, - genesis_utils::{create_genesis_config, GenesisConfigInfo}, + genesis_utils::{GenesisConfigInfo, create_genesis_config}, }, solana_net_utils::SocketAddrSpace, solana_poh::poh_recorder::create_test_recorder, diff --git a/core/src/unfrozen_gossip_verified_vote_hashes.rs b/core/src/unfrozen_gossip_verified_vote_hashes.rs index 2006ae95a0b..b49f0559d14 100644 --- a/core/src/unfrozen_gossip_verified_vote_hashes.rs +++ b/core/src/unfrozen_gossip_verified_vote_hashes.rs @@ -92,9 +92,11 @@ mod tests { ); } - assert!(unfrozen_gossip_verified_vote_hashes - .votes_per_slot - .is_empty()); + assert!( + unfrozen_gossip_verified_vote_hashes + .votes_per_slot + .is_empty() + ); } // Case 2: Other >= non-frozen banks should be added in case they're frozen later @@ -125,9 +127,11 @@ mod tests { assert_eq!(*pubkey_votes, validator_keys); } } else { - assert!(unfrozen_gossip_verified_vote_hashes - .votes_per_slot - .is_empty()); + assert!( + unfrozen_gossip_verified_vote_hashes + .votes_per_slot + .is_empty() + ); } } } diff --git a/core/src/validator.rs b/core/src/validator.rs index bfdbf83968b..5b66cfde70a 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -5,17 +5,16 @@ use { crate::{ admin_rpc_post_init::{AdminRpcRequestMetadataPostInit, KeyUpdaterType, KeyUpdaters}, banking_stage::{ - transaction_scheduler::scheduler_controller::SchedulerConfig, - unified_scheduler::ensure_banking_stage_setup, BankingStage, + BankingStage, transaction_scheduler::scheduler_controller::SchedulerConfig, + unified_scheduler::ensure_banking_stage_setup, }, banking_trace::{self, BankingTracer, TraceError}, block_creation_loop::{BlockCreationLoop, BlockCreationLoopConfig, ReplayHighestFrozen}, cluster_info_vote_listener::VoteTracker, completed_data_sets_service::CompletedDataSetsService, consensus::{ - reconcile_blockstore_roots_with_external_source, + ExternalRootSource, Tower, reconcile_blockstore_roots_with_external_source, tower_storage::{NullTowerStorage, TowerStorage}, - ExternalRootSource, Tower, }, repair::{ self, @@ -23,27 +22,27 @@ use { repair_handler::RepairHandlerType, serve_repair_service::ServeRepairService, }, - resource_limits::{adjust_nofile_limit, ResourceLimitError}, + resource_limits::{ResourceLimitError, adjust_nofile_limit}, sample_performance_service::SamplePerformanceService, snapshot_packager_service::SnapshotPackagerService, stats_reporter_service::StatsReporterService, system_monitor_service::{ - verify_net_stats_access, SystemMonitorService, SystemMonitorStatsReportConfig, + SystemMonitorService, SystemMonitorStatsReportConfig, verify_net_stats_access, }, tpu::{ForwardingClientOption, Tpu, TpuSockets}, tvu::{Tvu, TvuConfig, TvuSockets}, }, agave_snapshots::{ - snapshot_archive_info::SnapshotArchiveInfoGetter as _, snapshot_config::SnapshotConfig, - snapshot_hash::StartingSnapshotHashes, SnapshotInterval, + SnapshotInterval, snapshot_archive_info::SnapshotArchiveInfoGetter as _, + snapshot_config::SnapshotConfig, snapshot_hash::StartingSnapshotHashes, }, - anyhow::{anyhow, Context, Result}, - crossbeam_channel::{bounded, unbounded, Receiver}, + anyhow::{Context, Result, anyhow}, + crossbeam_channel::{Receiver, bounded, unbounded}, quinn::Endpoint, serde::{Deserialize, Serialize}, solana_account::ReadableAccount, solana_accounts_db::{ - accounts_db::{AccountsDbConfig, ACCOUNTS_DB_CONFIG_FOR_TESTING}, + accounts_db::{ACCOUNTS_DB_CONFIG_FOR_TESTING, AccountsDbConfig}, accounts_update_notifier_interface::AccountsUpdateNotifier, utils::move_and_async_delete_path_contents, }, @@ -54,10 +53,10 @@ use { solana_epoch_schedule::MAX_LEADER_SCHEDULE_EPOCH_OFFSET, solana_genesis_config::GenesisConfig, solana_genesis_utils::{ - open_genesis_config, OpenGenesisConfigError, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, + MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, OpenGenesisConfigError, open_genesis_config, }, solana_geyser_plugin_manager::{ - geyser_plugin_service::GeyserPluginService, GeyserPluginManagerRequest, + GeyserPluginManagerRequest, geyser_plugin_service::GeyserPluginService, }, solana_gossip::{ cluster_info::{ @@ -75,11 +74,11 @@ use { solana_ledger::{ bank_forks_utils, blockstore::{ - Blockstore, BlockstoreError, PurgeType, MAX_COMPLETED_SLOTS_IN_CHANNEL, - MAX_REPLAY_WAKE_UP_SIGNALS, + Blockstore, BlockstoreError, MAX_COMPLETED_SLOTS_IN_CHANNEL, + MAX_REPLAY_WAKE_UP_SIGNALS, PurgeType, }, blockstore_metric_report_service::BlockstoreMetricReportService, - blockstore_options::{BlockstoreOptions, BLOCKSTORE_DIRECTORY_ROCKS_LEVEL}, + blockstore_options::{BLOCKSTORE_DIRECTORY_ROCKS_LEVEL, BlockstoreOptions}, blockstore_processor::{self, TransactionStatusSender}, entry_notifier_interface::EntryNotifierArc, entry_notifier_service::{EntryNotifierSender, EntryNotifierService}, @@ -141,13 +140,13 @@ use { solana_turbine::{ self, broadcast_stage::BroadcastStageType, - xdp::{master_ip_if_bonded, XdpConfig, XdpRetransmitter}, + xdp::{XdpConfig, XdpRetransmitter, master_ip_if_bonded}, }, solana_unified_scheduler_logic::SchedulingMode, solana_unified_scheduler_pool::{DefaultSchedulerPool, SupportedSchedulingMode}, solana_validator_exit::Exit, solana_vote_program::vote_state::VoteStateV4, - solana_wen_restart::wen_restart::{wait_for_wen_restart, WenRestartConfig}, + solana_wen_restart::wen_restart::{WenRestartConfig, wait_for_wen_restart}, std::{ borrow::Cow, collections::{HashMap, HashSet}, @@ -156,8 +155,8 @@ use { path::{Path, PathBuf}, str::FromStr, sync::{ - atomic::{AtomicBool, AtomicU64, Ordering}, Arc, Mutex, RwLock, + atomic::{AtomicBool, AtomicU64, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, @@ -572,10 +571,10 @@ impl BlockstoreRootScan { } fn join(self) { - if let Some(blockstore_root_scan) = self.thread { - if let Err(err) = blockstore_root_scan.join() { - warn!("blockstore_root_scan failed to join {err:?}"); - } + if let Some(blockstore_root_scan) = self.thread + && let Err(err) = blockstore_root_scan.join() + { + warn!("blockstore_root_scan failed to join {err:?}"); } } } @@ -921,14 +920,14 @@ impl Validator { let shred_version = compute_shred_version(&genesis_config.hash(), Some(&hard_forks)); info!("shred version: {shred_version}, hard forks: {hard_forks:?}"); - if let Some(expected_shred_version) = config.expected_shred_version { - if expected_shred_version != shred_version { - return Err(ValidatorError::ShredVersionMismatch { - actual: shred_version, - expected: expected_shred_version, - } - .into()); + if let Some(expected_shred_version) = config.expected_shred_version + && expected_shred_version != shred_version + { + return Err(ValidatorError::ShredVersionMismatch { + actual: shred_version, + expected: expected_shred_version, } + .into()); } if let Some(start_slot) = should_cleanup_blockstore_incorrect_shred_versions( @@ -1988,10 +1987,10 @@ impl Validator { } fn active_vote_account_exists_in_bank(bank: &Bank, vote_account: &Pubkey) -> bool { - if let Some(account) = &bank.get_account(vote_account) { - if let Ok(vote_state) = VoteStateV4::deserialize(account.data(), vote_account) { - return !vote_state.votes.is_empty(); - } + if let Some(account) = &bank.get_account(vote_account) + && let Ok(vote_state) = VoteStateV4::deserialize(account.data(), vote_account) + { + return !vote_state.votes.is_empty(); } false } @@ -2029,10 +2028,10 @@ fn check_poh_speed(bank: &Bank, maybe_hash_samples: Option) -> Result<(), V fn maybe_cluster_restart_with_hard_fork(config: &ValidatorConfig, root_slot: Slot) -> Option { // detect cluster restart (hard fork) indirectly via wait_for_supermajority... - if let Some(wait_slot_for_supermajority) = config.wait_for_supermajority { - if wait_slot_for_supermajority == root_slot { - return Some(wait_slot_for_supermajority); - } + if let Some(wait_slot_for_supermajority) = config.wait_for_supermajority + && wait_slot_for_supermajority == root_slot + { + return Some(wait_slot_for_supermajority); } None @@ -2137,13 +2136,13 @@ fn load_genesis( let genesis_hash = genesis_config.hash(); info!("genesis hash: {genesis_hash}"); - if let Some(expected_genesis_hash) = config.expected_genesis_hash { - if genesis_hash != expected_genesis_hash { - return Err(ValidatorError::GenesisHashMismatch( - genesis_hash, - expected_genesis_hash, - )); - } + if let Some(expected_genesis_hash) = config.expected_genesis_hash + && genesis_hash != expected_genesis_hash + { + return Err(ValidatorError::GenesisHashMismatch( + genesis_hash, + expected_genesis_hash, + )); } Ok(genesis_config) @@ -2737,13 +2736,13 @@ fn wait_for_supermajority( _ => {} } - if let Some(expected_bank_hash) = config.expected_bank_hash { - if bank.hash() != expected_bank_hash { - return Err(ValidatorError::BankHashMismatch( - bank.hash(), - expected_bank_hash, - )); - } + if let Some(expected_bank_hash) = config.expected_bank_hash + && bank.hash() != expected_bank_hash + { + return Err(ValidatorError::BankHashMismatch( + bank.hash(), + expected_bank_hash, + )); } for i in 1.. { @@ -2912,7 +2911,7 @@ pub fn is_snapshot_config_valid(snapshot_config: &SnapshotConfig) -> bool { mod tests { use { super::*, - crossbeam_channel::{bounded, RecvTimeoutError}, + crossbeam_channel::{RecvTimeoutError, bounded}, solana_entry::entry, solana_genesis_config::create_genesis_config, solana_gossip::contact_info::ContactInfo, @@ -3131,10 +3130,12 @@ mod tests { // assert that slots less than 5 aren't affected assert!(blockstore.meta(4).unwrap().unwrap().next_slots.is_empty()); for i in 5..10 { - assert!(blockstore - .get_data_shreds_for_slot(i, 0) - .unwrap() - .is_empty()); + assert!( + blockstore + .get_data_shreds_for_slot(i, 0) + .unwrap() + .is_empty() + ); } } @@ -3218,15 +3219,17 @@ mod tests { let rpc_override_health_check = Arc::new(AtomicBool::new(false)); let start_progress = Arc::new(RwLock::new(ValidatorStartProgress::default())); - assert!(!wait_for_supermajority( - &config, - None, - &bank_forks, - &cluster_info, - rpc_override_health_check.clone(), - &start_progress, - ) - .unwrap()); + assert!( + !wait_for_supermajority( + &config, + None, + &bank_forks, + &cluster_info, + rpc_override_health_check.clone(), + &start_progress, + ) + .unwrap() + ); // bank=0, wait=1, should fail config.wait_for_supermajority = Some(1); @@ -3249,15 +3252,17 @@ mod tests { 1, )); config.wait_for_supermajority = Some(0); - assert!(!wait_for_supermajority( - &config, - None, - &bank_forks, - &cluster_info, - rpc_override_health_check.clone(), - &start_progress, - ) - .unwrap()); + assert!( + !wait_for_supermajority( + &config, + None, + &bank_forks, + &cluster_info, + rpc_override_health_check.clone(), + &start_progress, + ) + .unwrap() + ); // bank=1, wait=1, equal, but bad hash provided config.wait_for_supermajority = Some(1); diff --git a/core/src/vortexor_receiver_adapter.rs b/core/src/vortexor_receiver_adapter.rs index b105d8d56f8..2716ef2c3d8 100644 --- a/core/src/vortexor_receiver_adapter.rs +++ b/core/src/vortexor_receiver_adapter.rs @@ -6,11 +6,11 @@ use { crate::banking_trace::TracedSender, agave_banking_stage_ingress_types::BankingPacketBatch, agave_verified_packet_receiver::receiver::VerifiedPacketReceiver, - crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}, + crossbeam_channel::{Receiver, RecvTimeoutError, Sender, unbounded}, solana_perf::packet::PacketBatch, std::{ net::UdpSocket, - sync::{atomic::AtomicBool, Arc}, + sync::{Arc, atomic::AtomicBool}, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, }, diff --git a/core/src/vote_simulator.rs b/core/src/vote_simulator.rs index 95a4259d606..cda986d8035 100644 --- a/core/src/vote_simulator.rs +++ b/core/src/vote_simulator.rs @@ -4,12 +4,12 @@ use { cluster_info_vote_listener::VoteTracker, cluster_slots_service::cluster_slots::ClusterSlots, consensus::{ - fork_choice::{select_vote_and_reset_forks, SelectVoteAndResetForkResult}, + Tower, + fork_choice::{SelectVoteAndResetForkResult, select_vote_and_reset_forks}, heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice, latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks, progress_map::{ForkProgress, LockoutInterval, ProgressMap}, tower_vote_state::TowerVoteState, - Tower, }, repair::cluster_slot_state_verifier::{ DuplicateConfirmedSlots, DuplicateSlotsTracker, EpochSlotsFrozenSlots, @@ -26,7 +26,7 @@ use { bank::Bank, bank_forks::BankForks, genesis_utils::{ - create_genesis_config_with_vote_accounts, GenesisConfigInfo, ValidatorVoteKeypairs, + GenesisConfigInfo, ValidatorVoteKeypairs, create_genesis_config_with_vote_accounts, }, }, solana_signer::Signer, @@ -36,7 +36,7 @@ use { collections::{HashMap, HashSet, VecDeque}, sync::{Arc, RwLock}, }, - trees::{tr, Tree, TreeWalk}, + trees::{Tree, TreeWalk, tr}, }; pub struct VoteSimulator { @@ -144,9 +144,11 @@ impl VoteSimulator { .get_vote_account(&keypairs.vote_keypair.pubkey()) .unwrap(); let vote_state_view = vote_account.vote_state_view(); - assert!(vote_state_view - .votes_iter() - .any(|lockout| lockout.slot() == parent)); + assert!( + vote_state_view + .votes_iter() + .any(|lockout| lockout.slot() == parent) + ); } } diff --git a/core/src/voting_service.rs b/core/src/voting_service.rs index 60a94f36225..ac8352bbde3 100644 --- a/core/src/voting_service.rs +++ b/core/src/voting_service.rs @@ -7,7 +7,7 @@ use { bincode::serialize, crossbeam_channel::Receiver, solana_client::connection_cache::ConnectionCache, - solana_clock::{Slot, FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET}, + solana_clock::{FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, Slot}, solana_connection_cache::client_connection::ClientConnection, solana_gossip::{cluster_info::ClusterInfo, epoch_specs::EpochSpecs}, solana_measure::measure::Measure, @@ -120,11 +120,11 @@ impl VotingService { connection_cache.clone(), ); // trigger mock alpenglow vote if we have just cast an actual vote - if let Some(slot) = vote_slot { - if let Some(ag) = mock_alpenglow.as_mut() { - let root_bank = { bank_forks.read().unwrap().root_bank() }; - ag.signal_new_slot(slot, &root_bank); - } + if let Some(slot) = vote_slot + && let Some(ag) = mock_alpenglow.as_mut() + { + let root_bank = { bank_forks.read().unwrap().root_bank() }; + ag.signal_new_slot(slot, &root_bank); } } if let Some(ag) = mock_alpenglow { diff --git a/core/src/warm_quic_cache_service.rs b/core/src/warm_quic_cache_service.rs index 4e961b0fc4e..88e96fb4a81 100644 --- a/core/src/warm_quic_cache_service.rs +++ b/core/src/warm_quic_cache_service.rs @@ -2,7 +2,7 @@ // by the time we need it. use { - rand::{rng, Rng}, + rand::{Rng, rng}, solana_client::connection_cache::{ConnectionCache, Protocol}, solana_connection_cache::client_connection::ClientConnection as TpuConnection, solana_gossip::{cluster_info::ClusterInfo, contact_info::ContactInfoQuery}, @@ -11,10 +11,10 @@ use { std::{ net::SocketAddr, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::Duration, }, }; @@ -35,17 +35,16 @@ impl WarmQuicCacheService { contact_info_selector: impl ContactInfoQuery>, log_context: &str, ) { - if let Some(connection_cache) = cache { - if let Some(Some(addr)) = + if let Some(connection_cache) = cache + && let Some(Some(addr)) = cluster_info.lookup_contact_info(leader_pubkey, contact_info_selector) - { - let conn = connection_cache.get_connection(&addr); - if let Err(err) = conn.send_data(&[]) { - warn!( - "Failed to warmup QUIC connection to the leader {leader_pubkey:?} at \ - {addr:?}, Context: {log_context}, Error: {err:?}" - ); - } + { + let conn = connection_cache.get_connection(&addr); + if let Err(err) = conn.send_data(&[]) { + warn!( + "Failed to warmup QUIC connection to the leader {leader_pubkey:?} at \ + {addr:?}, Context: {log_context}, Error: {err:?}" + ); } } } @@ -75,26 +74,26 @@ impl WarmQuicCacheService { .read() .unwrap() .leader_after_n_slots((CACHE_OFFSET_SLOT + slot_jitter) as u64); - if let Some(leader_pubkey) = leader_pubkey { - if maybe_last_leader != Some(leader_pubkey) { - maybe_last_leader = Some(leader_pubkey); - // Warm cache for regular transactions - Self::warmup_connection( - tpu_connection_cache.as_deref(), - &cluster_info, - &leader_pubkey, - |node| node.tpu(Protocol::QUIC), - "tpu", - ); - // Warm cache for vote - Self::warmup_connection( - vote_connection_cache.as_deref(), - &cluster_info, - &leader_pubkey, - |node| node.tpu_vote(Protocol::QUIC), - "vote", - ); - } + if let Some(leader_pubkey) = leader_pubkey + && maybe_last_leader != Some(leader_pubkey) + { + maybe_last_leader = Some(leader_pubkey); + // Warm cache for regular transactions + Self::warmup_connection( + tpu_connection_cache.as_deref(), + &cluster_info, + &leader_pubkey, + |node| node.tpu(Protocol::QUIC), + "tpu", + ); + // Warm cache for vote + Self::warmup_connection( + vote_connection_cache.as_deref(), + &cluster_info, + &leader_pubkey, + |node| node.tpu_vote(Protocol::QUIC), + "vote", + ); } sleep(Duration::from_millis(200)); } diff --git a/core/src/window_service.rs b/core/src/window_service.rs index 40e75a40ab8..feed24b9d35 100644 --- a/core/src/window_service.rs +++ b/core/src/window_service.rs @@ -11,9 +11,9 @@ use { result::{Error, Result}, }, agave_feature_set as feature_set, - crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}, - rayon::{prelude::*, ThreadPool}, - solana_clock::{Slot, DEFAULT_MS_PER_SLOT}, + crossbeam_channel::{Receiver, RecvTimeoutError, Sender, unbounded}, + rayon::{ThreadPool, prelude::*}, + solana_clock::{DEFAULT_MS_PER_SLOT, Slot}, solana_gossip::cluster_info::ClusterInfo, solana_ledger::{ blockstore::{Blockstore, BlockstoreInsertionMetrics, PossibleDuplicateShred}, @@ -30,8 +30,8 @@ use { borrow::Cow, net::UdpSocket, sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, RwLock, + atomic::{AtomicBool, AtomicUsize, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, @@ -356,10 +356,9 @@ impl WindowService { &duplicate_receiver, &duplicate_slots_sender, &bank_forks, - ) { - if Self::should_exit_on_error(e, &handle_error) { - break; - } + ) && Self::should_exit_on_error(e, &handle_error) + { + break; } } }) @@ -458,12 +457,12 @@ mod test { use { super::*, rand::Rng, - solana_entry::entry::{create_ticks, Entry}, + solana_entry::entry::{Entry, create_ticks}, solana_gossip::contact_info::ContactInfo, solana_hash::Hash, solana_keypair::Keypair, solana_ledger::{ - blockstore::{make_many_slot_entries, Blockstore}, + blockstore::{Blockstore, make_many_slot_entries}, genesis_utils::create_genesis_config, get_tmp_ledger_path_auto_delete, shred::{ProcessShredsStats, Shredder}, diff --git a/core/tests/fork-selection.rs b/core/tests/fork-selection.rs index 4e69383e178..cb616d3b28c 100644 --- a/core/tests/fork-selection.rs +++ b/core/tests/fork-selection.rs @@ -75,7 +75,7 @@ extern crate rand; use { - rand::{rng, Rng}, + rand::{Rng, rng}, std::collections::{HashMap, VecDeque}, }; diff --git a/core/tests/scheduler_cost_adjustment.rs b/core/tests/scheduler_cost_adjustment.rs index ab293cff698..20424a33674 100644 --- a/core/tests/scheduler_cost_adjustment.rs +++ b/core/tests/scheduler_cost_adjustment.rs @@ -5,8 +5,8 @@ use { solana_compute_budget::compute_budget_limits::MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT, solana_compute_budget_interface::ComputeBudgetInstruction, solana_cost_model::cost_model::CostModel, - solana_genesis_config::{create_genesis_config, GenesisConfig}, - solana_instruction::{error::InstructionError, AccountMeta, Instruction}, + solana_genesis_config::{GenesisConfig, create_genesis_config}, + solana_instruction::{AccountMeta, Instruction, error::InstructionError}, solana_keypair::Keypair, solana_loader_v3_interface::state::UpgradeableLoaderState, solana_message::Message, diff --git a/core/tests/snapshots.rs b/core/tests/snapshots.rs index 7f27e274a80..73442d70160 100644 --- a/core/tests/snapshots.rs +++ b/core/tests/snapshots.rs @@ -3,8 +3,8 @@ use { crate::snapshot_utils::create_tmp_accounts_dir_for_tests, agave_snapshots::{ - paths as snapshot_paths, snapshot_archive_info::FullSnapshotArchiveInfo, - snapshot_config::SnapshotConfig, SnapshotInterval, SnapshotKind, + SnapshotInterval, SnapshotKind, paths as snapshot_paths, + snapshot_archive_info::FullSnapshotArchiveInfo, snapshot_config::SnapshotConfig, }, crossbeam_channel::unbounded, itertools::Itertools, @@ -24,7 +24,7 @@ use { }, bank::{Bank, BankTestConfig}, bank_forks::BankForks, - genesis_utils::{create_genesis_config_with_leader, GenesisConfigInfo}, + genesis_utils::{GenesisConfigInfo, create_genesis_config_with_leader}, runtime_config::RuntimeConfig, snapshot_bank_utils, snapshot_controller::SnapshotController, @@ -40,8 +40,8 @@ use { num::NonZeroU64, path::PathBuf, sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, RwLock, + atomic::{AtomicBool, Ordering}, }, time::{Duration, Instant}, }, diff --git a/core/tests/unified_scheduler.rs b/core/tests/unified_scheduler.rs index c479475afb5..74f4138c85f 100644 --- a/core/tests/unified_scheduler.rs +++ b/core/tests/unified_scheduler.rs @@ -5,7 +5,7 @@ use { itertools::Itertools, log::*, solana_core::{ - banking_stage::{unified_scheduler::ensure_banking_stage_setup, BankingStage}, + banking_stage::{BankingStage, unified_scheduler::ensure_banking_stage_setup}, banking_trace::BankingTracer, consensus::{ heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice, @@ -42,7 +42,7 @@ use { }, std::{ collections::HashMap, - sync::{atomic::Ordering, Arc, Mutex}, + sync::{Arc, Mutex, atomic::Ordering}, thread::sleep, time::Duration, }, diff --git a/gossip/Cargo.toml b/gossip/Cargo.toml index 97a5a64749a..f07aed3ecc6 100644 --- a/gossip/Cargo.toml +++ b/gossip/Cargo.toml @@ -7,7 +7,7 @@ description = { workspace = true } repository = { workspace = true } homepage = { workspace = true } license = { workspace = true } -edition = { workspace = true } +edition = "2024" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/gossip/benches/crds.rs b/gossip/benches/crds.rs index e1f29edbc88..afbdc73ffc3 100644 --- a/gossip/benches/crds.rs +++ b/gossip/benches/crds.rs @@ -1,10 +1,10 @@ use { - criterion::{criterion_group, criterion_main, Criterion}, - rand::{rng, Rng}, + criterion::{Criterion, criterion_group, criterion_main}, + rand::{Rng, rng}, rayon::ThreadPoolBuilder, solana_gossip::{ crds::{Crds, GossipRoute}, - crds_gossip_pull::{CrdsTimeouts, CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS}, + crds_gossip_pull::{CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS, CrdsTimeouts}, crds_value::CrdsValue, }, solana_pubkey::Pubkey, diff --git a/gossip/benches/crds_gossip_pull.rs b/gossip/benches/crds_gossip_pull.rs index b8c4e82c80f..d3b8e8670fc 100644 --- a/gossip/benches/crds_gossip_pull.rs +++ b/gossip/benches/crds_gossip_pull.rs @@ -1,6 +1,6 @@ use { - criterion::{criterion_group, criterion_main, Criterion}, - rand::{rng, Rng}, + criterion::{Criterion, criterion_group, criterion_main}, + rand::{Rng, rng}, rayon::ThreadPoolBuilder, solana_gossip::{ crds::{Crds, GossipRoute}, diff --git a/gossip/benches/crds_shards.rs b/gossip/benches/crds_shards.rs index 10fb19cccc3..e7ee10cb0aa 100644 --- a/gossip/benches/crds_shards.rs +++ b/gossip/benches/crds_shards.rs @@ -1,6 +1,6 @@ use { - criterion::{criterion_group, criterion_main, Criterion}, - rand::{rng, Rng}, + criterion::{Criterion, criterion_group, criterion_main}, + rand::{Rng, rng}, solana_gossip::{ crds::{Crds, GossipRoute, VersionedCrdsValue}, crds_shards::CrdsShards, diff --git a/gossip/benches/weighted_shuffle.rs b/gossip/benches/weighted_shuffle.rs index e3c28721162..80e328ded89 100644 --- a/gossip/benches/weighted_shuffle.rs +++ b/gossip/benches/weighted_shuffle.rs @@ -1,5 +1,5 @@ use { - criterion::{criterion_group, criterion_main, Criterion}, + criterion::{Criterion, criterion_group, criterion_main}, rand::{Rng, SeedableRng}, rand_chacha::ChaChaRng, solana_gossip::weighted_shuffle::WeightedShuffle, diff --git a/gossip/src/cluster_info.rs b/gossip/src/cluster_info.rs index 1f690994634..bcc8d81b496 100644 --- a/gossip/src/cluster_info.rs +++ b/gossip/src/cluster_info.rs @@ -18,13 +18,13 @@ use { cluster_info_metrics::{Counter, GossipStats, ScopedTimer, TimedGuard}, contact_info::{self, ContactInfo, ContactInfoQuery, Error as ContactInfoError}, crds::{Crds, Cursor, GossipRoute}, - crds_data::{self, CrdsData, EpochSlotsIndex, LowestSlot, SnapshotHashes, Vote, MAX_VOTES}, - crds_filter::{should_retain_crds_value, GossipFilterDirection}, + crds_data::{self, CrdsData, EpochSlotsIndex, LowestSlot, MAX_VOTES, SnapshotHashes, Vote}, + crds_filter::{GossipFilterDirection, should_retain_crds_value}, crds_gossip::CrdsGossip, crds_gossip_error::CrdsGossipError, crds_gossip_pull::{ - get_max_bloom_filter_bytes, CrdsFilter, CrdsTimeouts, ProcessPullStats, PullRequest, - CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS, + CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS, CrdsFilter, CrdsTimeouts, ProcessPullStats, + PullRequest, get_max_bloom_filter_bytes, }, crds_value::{CrdsValue, CrdsValueLabel}, duplicate_shred::DuplicateShred, @@ -33,10 +33,10 @@ use { gossip_error::GossipError, ping_pong::Pong, protocol::{ - split_gossip_messages, Ping, PingCache, Protocol, PruneData, DUPLICATE_SHRED_MAX_PAYLOAD_SIZE, MAX_INCREMENTAL_SNAPSHOT_HASHES, MAX_PRUNE_DATA_NODES, PULL_RESPONSE_MAX_PAYLOAD_SIZE, - PULL_RESPONSE_MIN_SERIALIZED_SIZE, PUSH_MESSAGE_MAX_PAYLOAD_SIZE, + PULL_RESPONSE_MIN_SERIALIZED_SIZE, PUSH_MESSAGE_MAX_PAYLOAD_SIZE, Ping, PingCache, + Protocol, PruneData, split_gossip_messages, }, restart_crds_values::{ RestartHeaviestFork, RestartLastVotedForkSlots, RestartLastVotedForkSlotsError, @@ -46,17 +46,16 @@ use { arc_swap::ArcSwap, crossbeam_channel::{Receiver, TrySendError}, itertools::{Either, Itertools}, - rand::{prelude::IndexedMutRandom, CryptoRng, Rng}, - rayon::{prelude::*, ThreadPool, ThreadPoolBuilder}, - solana_clock::{Slot, DEFAULT_MS_PER_SLOT, DEFAULT_SLOTS_PER_EPOCH}, + rand::{CryptoRng, Rng, prelude::IndexedMutRandom}, + rayon::{ThreadPool, ThreadPoolBuilder, prelude::*}, + solana_clock::{DEFAULT_MS_PER_SLOT, DEFAULT_SLOTS_PER_EPOCH, Slot}, solana_hash::Hash, - solana_keypair::{signable::Signable, Keypair}, + solana_keypair::{Keypair, signable::Signable}, solana_ledger::shred::Shred, solana_net_utils::{ - bind_in_range, + PortRange, SocketAddrSpace, VALIDATOR_PORT_RANGE, bind_in_range, multihomed_sockets::BindIpAddrs, sockets::{bind_gossip_port_in_range, bind_to_localhost_unique}, - PortRange, SocketAddrSpace, VALIDATOR_PORT_RANGE, }, solana_perf::{ data_budget::DataBudget, @@ -89,10 +88,10 @@ use { rc::Rc, result::Result, sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, RwLock, RwLockReadGuard, + atomic::{AtomicBool, Ordering}, }, - thread::{sleep, Builder, JoinHandle}, + thread::{Builder, JoinHandle, sleep}, time::{Duration, Instant}, }, thiserror::Error, @@ -1205,15 +1204,14 @@ impl ClusterInfo { return Either::Left(pulls); } entrypoint.set_wallclock(now); - if let Some(entrypoint_gossip) = entrypoint.gossip() { - if self + if let Some(entrypoint_gossip) = entrypoint.gossip() + && self .time_gossip_read_lock("entrypoint", &self.stats.entrypoint) .get_nodes_contact_info() .any(|node| node.gossip() == Some(entrypoint_gossip)) - { - // Found the entrypoint, no need to pull from it. - return Either::Left(pulls); - } + { + // Found the entrypoint, no need to pull from it. + return Either::Left(pulls); } } let Some(entrypoint) = entrypoint.gossip() else { @@ -1378,12 +1376,12 @@ impl ClusterInfo { ) .filter_map(|(addr, data)| make_gossip_packet(addr, &data, &self.stats)) .for_each(|pkt| packet_batch.push(pkt)); - if !packet_batch.is_empty() { - if let Err(TrySendError::Full(packet_batch)) = sender.try_send(packet_batch.into()) { - self.stats - .gossip_transmit_packets_dropped_count - .add_relaxed(packet_batch.len() as u64); - } + if !packet_batch.is_empty() + && let Err(TrySendError::Full(packet_batch)) = sender.try_send(packet_batch.into()) + { + self.stats + .gossip_transmit_packets_dropped_count + .add_relaxed(packet_batch.len() as u64); } self.stats .gossip_transmit_loop_iterations_since_last_report @@ -1610,13 +1608,12 @@ impl ClusterInfo { let _st = ScopedTimer::from(&self.stats.handle_batch_pull_requests_time); if !requests.is_empty() { let response = self.handle_pull_requests(thread_pool, recycler, requests, stakes); - if !response.is_empty() { - if let Err(TrySendError::Full(response)) = response_sender.try_send(response.into()) - { - self.stats - .gossip_packets_dropped_count - .add_relaxed(response.len() as u64); - } + if !response.is_empty() + && let Err(TrySendError::Full(response)) = response_sender.try_send(response.into()) + { + self.stats + .gossip_packets_dropped_count + .add_relaxed(response.len() as u64); } } } @@ -1892,14 +1889,13 @@ impl ClusterInfo { self.new_push_requests(stakes) .filter_map(|(addr, data)| make_gossip_packet(addr, &data, &self.stats)) .for_each(|pkt| packet_batch.push(pkt)); - if !packet_batch.is_empty() { - if let Err(TrySendError::Full(packet_batch)) = + if !packet_batch.is_empty() + && let Err(TrySendError::Full(packet_batch)) = response_sender.try_send(packet_batch.into()) - { - self.stats - .gossip_packets_dropped_count - .add_relaxed(packet_batch.len() as u64); - } + { + self.stats + .gossip_packets_dropped_count + .add_relaxed(packet_batch.len() as u64); } } @@ -2471,7 +2467,7 @@ fn discard_different_shred_version( Protocol::PullRequest(..) => return, // No CRDS values in Prune, Ping and Pong messages. Protocol::PruneMessage(_, _) | Protocol::PingMessage(_) | Protocol::PongMessage(_) => { - return + return; } }; let num_values = values.len(); @@ -2593,7 +2589,7 @@ mod tests { solana_streamer::quic::DEFAULT_QUIC_ENDPOINTS, solana_vote_program::{ vote_instruction, - vote_state::{Vote, MAX_LOCKOUT_HISTORY}, + vote_state::{MAX_LOCKOUT_HISTORY, Vote}, }, std::{ iter::repeat_with, @@ -3236,12 +3232,14 @@ mod tests { tower.clear(); tower.extend(0..=slot); let vote = new_vote_transaction(vec![slot]); - assert!(panic::catch_unwind(|| cluster_info.push_vote(&tower, vote)) - .err() - .and_then(|a| a - .downcast_ref::() - .map(|s| { s.starts_with("Submitting old vote") })) - .unwrap_or_default()); + assert!( + panic::catch_unwind(|| cluster_info.push_vote(&tower, vote)) + .err() + .and_then(|a| a + .downcast_ref::() + .map(|s| { s.starts_with("Submitting old vote") })) + .unwrap_or_default() + ); } #[test] @@ -3273,9 +3271,11 @@ mod tests { { let mut gossip_crds = cluster_info.gossip.crds.write().unwrap(); for entry in entries { - assert!(gossip_crds - .insert(entry, /*now=*/ 0, GossipRoute::LocalMessage) - .is_ok()); + assert!( + gossip_crds + .insert(entry, /*now=*/ 0, GossipRoute::LocalMessage) + .is_ok() + ); } } // Should exclude other node's epoch-slot because of different @@ -3410,9 +3410,11 @@ mod tests { let (pings, pulls) = cluster_info.old_pull_requests(&thread_pool, None, &stakes); assert!(pings.is_empty()); assert_eq!(pulls.len(), MIN_NUM_BLOOM_FILTERS); - assert!(pulls - .into_iter() - .all(|(addr, _)| addr == other_node.gossip().unwrap())); + assert!( + pulls + .into_iter() + .all(|(addr, _)| addr == other_node.gossip().unwrap()) + ); // Pull request 2: pretend it's been a while since we've pulled from `entrypoint`. There should // now be two pull requests @@ -3434,9 +3436,11 @@ mod tests { let (pings, pulls) = cluster_info.old_pull_requests(&thread_pool, None, &stakes); assert!(pings.is_empty()); assert_eq!(pulls.len(), MIN_NUM_BLOOM_FILTERS); - assert!(pulls - .into_iter() - .all(|(addr, _)| addr == other_node.gossip().unwrap())); + assert!( + pulls + .into_iter() + .all(|(addr, _)| addr == other_node.gossip().unwrap()) + ); } #[test] @@ -3591,9 +3595,11 @@ mod tests { let leader = Arc::new(Keypair::new()); let shred1 = new_rand_shred(&mut rng, next_shred_index, &shredder, &leader); let shred2 = new_rand_shred(&mut rng, next_shred_index, &shredder, &leader); - assert!(cluster_info - .push_duplicate_shred(&shred1, shred2.payload()) - .is_ok()); + assert!( + cluster_info + .push_duplicate_shred(&shred1, shred2.payload()) + .is_ok() + ); cluster_info.flush_push_queue(); let entries = cluster_info.get_duplicate_shreds(&mut cursor); // One duplicate shred proof is split into 3 chunks. @@ -3609,9 +3615,11 @@ mod tests { let next_shred_index = 354; let shred3 = new_rand_shred(&mut rng, next_shred_index, &shredder, &leader); let shred4 = new_rand_shred(&mut rng, next_shred_index, &shredder, &leader); - assert!(cluster_info - .push_duplicate_shred(&shred3, shred4.payload()) - .is_ok()); + assert!( + cluster_info + .push_duplicate_shred(&shred3, shred4.payload()) + .is_ok() + ); cluster_info.flush_push_queue(); let entries1 = cluster_info.get_duplicate_shreds(&mut cursor); // One duplicate shred proof is split into 3 chunks. @@ -3636,9 +3644,11 @@ mod tests { update.push(i * 1050 + j); } } - assert!(cluster_info - .push_restart_last_voted_fork_slots(&update, Hash::default()) - .is_ok()); + assert!( + cluster_info + .push_restart_last_voted_fork_slots(&update, Hash::default()) + .is_ok() + ); cluster_info.flush_push_queue(); let mut cursor = Cursor::default(); @@ -3665,9 +3675,11 @@ mod tests { { let mut gossip_crds = cluster_info.gossip.crds.write().unwrap(); for entry in entries { - assert!(gossip_crds - .insert(entry, /*now=*/ 0, GossipRoute::LocalMessage) - .is_ok()); + assert!( + gossip_crds + .insert(entry, /*now=*/ 0, GossipRoute::LocalMessage) + .is_ok() + ); } } // Should exclude other node's last-voted-fork-slot because of different @@ -3681,9 +3693,11 @@ mod tests { let mut node = cluster_info.my_contact_info.write().unwrap(); node.set_shred_version(42); } - assert!(cluster_info - .push_restart_last_voted_fork_slots(&update, Hash::default()) - .is_ok()); + assert!( + cluster_info + .push_restart_last_voted_fork_slots(&update, Hash::default()) + .is_ok() + ); cluster_info.flush_push_queue(); // Should now include both slots. let slots = cluster_info.get_restart_last_voted_fork_slots(&mut Cursor::default()); @@ -3742,9 +3756,11 @@ mod tests { { let mut gossip_crds = cluster_info.gossip.crds.write().unwrap(); for entry in entries { - assert!(gossip_crds - .insert(entry, /*now=*/ 0, GossipRoute::LocalMessage) - .is_ok()); + assert!( + gossip_crds + .insert(entry, /*now=*/ 0, GossipRoute::LocalMessage) + .is_ok() + ); } } // Should exclude other node's heaviest_fork because of different @@ -3884,9 +3900,10 @@ mod tests { )), &keypair2, ); - assert!(crds - .insert(ci_wrong_pubkey, /*now=*/ 0, GossipRoute::LocalMessage) - .is_ok()); + assert!( + crds.insert(ci_wrong_pubkey, /*now=*/ 0, GossipRoute::LocalMessage) + .is_ok() + ); // Test insert EpochSlot w/ previous ContactInfo w/ matching shred version but different pubkey -> should be rejected let epoch_slots = EpochSlots::new_rand(&mut rng, Some(keypair.pubkey())); @@ -3898,9 +3915,10 @@ mod tests { } // Now insert ContactInfo with same pubkey as EpochSlot - assert!(crds - .insert(ci.clone(), /*now=*/ 0, GossipRoute::LocalMessage) - .is_ok()); + assert!( + crds.insert(ci.clone(), /*now=*/ 0, GossipRoute::LocalMessage) + .is_ok() + ); let mut msg = Protocol::PushMessage(keypair.pubkey(), vec![es]); discard_different_shred_version(&mut msg, self_shred_version, &crds, &stats); diff --git a/gossip/src/contact_info.rs b/gossip/src/contact_info.rs index d5bf67f80a7..9b5543e034a 100644 --- a/gossip/src/contact_info.rs +++ b/gossip/src/contact_info.rs @@ -681,9 +681,7 @@ macro_rules! socketaddr { ($ip:expr, $port:expr) => { std::net::SocketAddr::from((std::net::Ipv4Addr::from($ip), $port)) }; - ($str:expr) => {{ - $str.parse::().unwrap() - }}; + ($str:expr) => {{ $str.parse::().unwrap() }}; } #[macro_export] @@ -698,8 +696,8 @@ mod tests { use { super::*, rand::{ - prelude::{IndexedRandom as _, SliceRandom as _}, Rng, + prelude::{IndexedRandom as _, SliceRandom as _}, }, solana_keypair::Keypair, solana_signer::Signer, @@ -959,19 +957,22 @@ mod tests { sockets.values().map(SocketAddr::ip).collect::>(), ); // Assert that all sockets reference a valid IP address. - assert!(node - .sockets - .iter() - .map(|entry| node.addrs.get(usize::from(entry.index))) - .all(|addr| addr.is_some())); - // Assert that port offsets don't overflow. - assert!(u16::try_from( + assert!( node.sockets .iter() - .map(|entry| u64::from(entry.offset)) - .sum::() - ) - .is_ok()); + .map(|entry| node.addrs.get(usize::from(entry.index))) + .all(|addr| addr.is_some()) + ); + // Assert that port offsets don't overflow. + assert!( + u16::try_from( + node.sockets + .iter() + .map(|entry| u64::from(entry.offset)) + .sum::() + ) + .is_ok() + ); // Assert that serde round trips. let bytes = bincode::serialize(&node).unwrap(); let other: ContactInfo = bincode::deserialize(&bytes).unwrap(); diff --git a/gossip/src/crds.rs b/gossip/src/crds.rs index abe180b75eb..2d2d75f2401 100644 --- a/gossip/src/crds.rs +++ b/gossip/src/crds.rs @@ -37,17 +37,17 @@ use { }, assert_matches::debug_assert_matches, indexmap::{ - map::{rayon::ParValues, Entry, IndexMap}, + map::{Entry, IndexMap, rayon::ParValues}, set::IndexSet, }, lru::LruCache, - rayon::{prelude::*, ThreadPool}, + rayon::{ThreadPool, prelude::*}, solana_clock::Slot, solana_hash::Hash, solana_pubkey::Pubkey, std::{ cmp::Ordering, - collections::{hash_map, BTreeMap, HashMap, VecDeque}, + collections::{BTreeMap, HashMap, VecDeque, hash_map}, ops::{Bound, Index, IndexMut}, sync::Mutex, }, @@ -192,12 +192,11 @@ fn overrides(value: &CrdsValue, other: &VersionedCrdsValue) -> bool { // Contact-infos are special cased so that if there are // two running instances of the same node, the more recent start is // propagated through gossip regardless of wallclocks. - if let CrdsData::ContactInfo(value) = value.data() { - if let CrdsData::ContactInfo(other) = other.value.data() { - if let Some(out) = value.overrides(other) { - return out; - } - } + if let CrdsData::ContactInfo(value) = value.data() + && let CrdsData::ContactInfo(other) = other.value.data() + && let Some(out) = value.overrides(other) + { + return out; } match value.wallclock().cmp(&other.value.wallclock()) { Ordering::Less => false, @@ -518,16 +517,15 @@ impl Crds { // If the origin's contact-info hasn't expired yet then preserve // all associated values. let origin = CrdsValueLabel::ContactInfo(*pubkey); - if let Some(origin) = self.table.get(&origin) { - if origin + if let Some(origin) = self.table.get(&origin) + && origin .value .wallclock() .min(origin.local_timestamp) .saturating_add(timeout) > now - { - return vec![]; - } + { + return vec![]; } // Otherwise check each value's timestamp individually. index @@ -698,11 +696,11 @@ impl Default for CrdsDataStats { impl CrdsDataStats { fn record_insert(&mut self, entry: &VersionedCrdsValue, route: GossipRoute) { self.counts[Self::ordinal(entry)] += 1; - if let CrdsData::Vote(_, vote) = entry.value.data() { - if let Some(slot) = vote.slot() { - let num_nodes = self.votes.get(&slot).copied().unwrap_or_default(); - self.votes.put(slot, num_nodes + 1); - } + if let CrdsData::Vote(_, vote) = entry.value.data() + && let Some(slot) = vote.slot() + { + let num_nodes = self.votes.get(&slot).copied().unwrap_or_default(); + self.votes.put(slot, num_nodes + 1); } let GossipRoute::PushMessage(from) = route else { @@ -781,8 +779,8 @@ impl CrdsStats { mod tests { use { super::*, - crate::crds_data::{new_rand_timestamp, AccountsHashes}, - rand::{rng, Rng}, + crate::crds_data::{AccountsHashes, new_rand_timestamp}, + rand::{Rng, rng}, rayon::ThreadPoolBuilder, solana_keypair::Keypair, solana_signer::Signer, diff --git a/gossip/src/crds_data.rs b/gossip/src/crds_data.rs index 216c78b75ed..7de2ee7f55c 100644 --- a/gossip/src/crds_data.rs +++ b/gossip/src/crds_data.rs @@ -8,7 +8,7 @@ use { restart_crds_values::{RestartHeaviestFork, RestartLastVotedForkSlots}, }, rand::Rng, - serde::{de::Deserializer, Deserialize, Serialize}, + serde::{Deserialize, Serialize, de::Deserializer}, solana_clock::Slot, solana_hash::Hash, solana_pubkey::{self, Pubkey}, diff --git a/gossip/src/crds_gossip_pull.rs b/gossip/src/crds_gossip_pull.rs index 6a0421334b5..aafa28aca1b 100644 --- a/gossip/src/crds_gossip_pull.rs +++ b/gossip/src/crds_gossip_pull.rs @@ -23,10 +23,10 @@ use { }, itertools::Itertools, rand::{ - distr::{weighted::WeightedIndex, Distribution}, Rng, + distr::{Distribution, weighted::WeightedIndex}, }, - rayon::{prelude::*, ThreadPool}, + rayon::{ThreadPool, prelude::*}, serde::{Deserialize, Serialize}, solana_bloom::bloom::{Bloom, ConcurrentBloom}, solana_hash::Hash, @@ -43,8 +43,8 @@ use { net::SocketAddr, ops::Index, sync::{ - atomic::{AtomicI64, AtomicUsize, Ordering}, LazyLock, Mutex, RwLock, + atomic::{AtomicI64, AtomicUsize, Ordering}, }, time::Duration, }, @@ -680,7 +680,7 @@ pub(crate) mod tests { protocol::Protocol, }, itertools::Itertools, - rand::{prelude::IndexedRandom as _, SeedableRng}, + rand::{SeedableRng, prelude::IndexedRandom as _}, rand_chacha::ChaChaRng, rayon::ThreadPoolBuilder, solana_hash::HASH_BYTES, diff --git a/gossip/src/crds_gossip_push.rs b/gossip/src/crds_gossip_push.rs index 57ad91e1238..c24a586a91e 100644 --- a/gossip/src/crds_gossip_push.rs +++ b/gossip/src/crds_gossip_push.rs @@ -34,8 +34,8 @@ use { net::SocketAddr, ops::{DerefMut, RangeBounds}, sync::{ - atomic::{AtomicUsize, Ordering}, Mutex, RwLock, + atomic::{AtomicUsize, Ordering}, }, }, }; @@ -348,9 +348,10 @@ mod tests { assert_eq!(crds.read().unwrap().get::<&CrdsValue>(&label), Some(&value)); // push it again - assert!(push - .process_push_message(&crds, vec![(Pubkey::default(), vec![value])], 0) - .is_empty()); + assert!( + push.process_push_message(&crds, vec![(Pubkey::default(), vec![value])], 0) + .is_empty() + ); } #[test] fn test_process_push_old_version() { @@ -369,9 +370,10 @@ mod tests { // push an old version ci.set_wallclock(0); let value = CrdsValue::new_unsigned(CrdsData::from(ci)); - assert!(push - .process_push_message(&crds, vec![(Pubkey::default(), vec![value])], 0) - .is_empty()); + assert!( + push.process_push_message(&crds, vec![(Pubkey::default(), vec![value])], 0) + .is_empty() + ); } #[test] fn test_process_push_timeout() { @@ -383,16 +385,18 @@ mod tests { // push a version to far in the future ci.set_wallclock(timeout + 1); let value = CrdsValue::new_unsigned(CrdsData::from(&ci)); - assert!(push - .process_push_message(&crds, vec![(Pubkey::default(), vec![value])], 0) - .is_empty()); + assert!( + push.process_push_message(&crds, vec![(Pubkey::default(), vec![value])], 0) + .is_empty() + ); // push a version to far in the past ci.set_wallclock(0); let value = CrdsValue::new_unsigned(CrdsData::from(ci)); - assert!(push - .process_push_message(&crds, vec![(Pubkey::default(), vec![value])], timeout + 1) - .is_empty()); + assert!( + push.process_push_message(&crds, vec![(Pubkey::default(), vec![value])], timeout + 1) + .is_empty() + ); } #[test] fn test_process_push_update() { @@ -641,13 +645,15 @@ mod tests { ); // push it again - assert!(push - .process_push_message(&crds, vec![(Pubkey::default(), vec![value.clone()])], 0) - .is_empty()); + assert!( + push.process_push_message(&crds, vec![(Pubkey::default(), vec![value.clone()])], 0) + .is_empty() + ); // push it again - assert!(push - .process_push_message(&crds, vec![(Pubkey::default(), vec![value])], 0) - .is_empty()); + assert!( + push.process_push_message(&crds, vec![(Pubkey::default(), vec![value])], 0) + .is_empty() + ); } } diff --git a/gossip/src/crds_shards.rs b/gossip/src/crds_shards.rs index c38ac234bd8..c1faaa92568 100644 --- a/gossip/src/crds_shards.rs +++ b/gossip/src/crds_shards.rs @@ -137,7 +137,7 @@ mod test { crds::{Crds, GossipRoute}, crds_value::CrdsValue, }, - rand::{rng, Rng}, + rand::{Rng, rng}, solana_time_utils::timestamp, std::{collections::HashSet, iter::repeat_with, ops::Index}, }; diff --git a/gossip/src/crds_value.rs b/gossip/src/crds_value.rs index bf5ab282453..c11c7ebac81 100644 --- a/gossip/src/crds_value.rs +++ b/gossip/src/crds_value.rs @@ -8,9 +8,9 @@ use { arrayvec::ArrayVec, bincode::serialize, rand::Rng, - serde::{de::Deserializer, Deserialize, Serialize}, + serde::{Deserialize, Serialize, de::Deserializer}, solana_hash::Hash, - solana_keypair::{signable::Signable, Keypair}, + solana_keypair::{Keypair, signable::Signable}, solana_packet::PACKET_DATA_SIZE, solana_pubkey::Pubkey, solana_sanitize::{Sanitize, SanitizeError}, diff --git a/gossip/src/duplicate_shred.rs b/gossip/src/duplicate_shred.rs index c52e9aed6b9..4f22ee9aadb 100644 --- a/gossip/src/duplicate_shred.rs +++ b/gossip/src/duplicate_shred.rs @@ -11,7 +11,7 @@ use { solana_pubkey::Pubkey, solana_sanitize::{Sanitize, SanitizeError}, std::{ - collections::{hash_map::Entry, HashMap}, + collections::{HashMap, hash_map::Entry}, convert::TryFrom, num::TryFromIntError, }, diff --git a/gossip/src/duplicate_shred_handler.rs b/gossip/src/duplicate_shred_handler.rs index d7d4da27ae4..6c74fb00d2b 100644 --- a/gossip/src/duplicate_shred_handler.rs +++ b/gossip/src/duplicate_shred_handler.rs @@ -238,7 +238,7 @@ mod tests { itertools::Itertools, solana_keypair::Keypair, solana_ledger::{ - genesis_utils::{create_genesis_config_with_leader, GenesisConfigInfo}, + genesis_utils::{GenesisConfigInfo, create_genesis_config_with_leader}, get_tmp_ledger_path_auto_delete, shred::Shredder, }, diff --git a/gossip/src/duplicate_shred_listener.rs b/gossip/src/duplicate_shred_listener.rs index 2c7be1e56e4..3a45e1db2ed 100644 --- a/gossip/src/duplicate_shred_listener.rs +++ b/gossip/src/duplicate_shred_listener.rs @@ -6,10 +6,10 @@ use { }, std::{ sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::Duration, }, }; @@ -77,8 +77,8 @@ mod tests { solana_net_utils::SocketAddrSpace, solana_signer::Signer, std::sync::{ - atomic::{AtomicU32, Ordering}, Arc, + atomic::{AtomicU32, Ordering}, }, }; struct FakeHandler { @@ -118,9 +118,11 @@ mod tests { let leader = Arc::new(Keypair::new()); let shred1 = new_rand_shred(&mut rng, next_shred_index, &shredder, &leader); let shred2 = new_rand_shred(&mut rng, next_shred_index, &shredder, &leader); - assert!(cluster_info - .push_duplicate_shred(&shred1, shred2.payload()) - .is_ok()); + assert!( + cluster_info + .push_duplicate_shred(&shred1, shred2.payload()) + .is_ok() + ); cluster_info.flush_push_queue(); sleep(Duration::from_millis(GOSSIP_SLEEP_MILLIS)); assert_eq!(count.load(Ordering::Relaxed), 3); diff --git a/gossip/src/epoch_specs.rs b/gossip/src/epoch_specs.rs index cd40bf5be67..ac3a62e01c8 100644 --- a/gossip/src/epoch_specs.rs +++ b/gossip/src/epoch_specs.rs @@ -1,5 +1,5 @@ use { - solana_clock::{Epoch, DEFAULT_MS_PER_SLOT}, + solana_clock::{DEFAULT_MS_PER_SLOT, Epoch}, solana_epoch_schedule::EpochSchedule, solana_pubkey::Pubkey, solana_runtime::{ @@ -87,7 +87,7 @@ mod tests { use { super::*, solana_clock::Slot, - solana_runtime::genesis_utils::{create_genesis_config, GenesisConfigInfo}, + solana_runtime::genesis_utils::{GenesisConfigInfo, create_genesis_config}, }; #[test] diff --git a/gossip/src/gossip_service.rs b/gossip/src/gossip_service.rs index 97178aaeb4a..7a5cf126f84 100644 --- a/gossip/src/gossip_service.rs +++ b/gossip/src/gossip_service.rs @@ -8,10 +8,10 @@ use { epoch_specs::EpochSpecs, }, crossbeam_channel::Sender, - rand::{rng, Rng}, + rand::{Rng, rng}, solana_client::{connection_cache::ConnectionCache, tpu_client::TpuClientWrapper}, solana_keypair::Keypair, - solana_net_utils::{SocketAddrSpace, DEFAULT_IP_ECHO_SERVER_THREADS}, + solana_net_utils::{DEFAULT_IP_ECHO_SERVER_THREADS, SocketAddrSpace}, solana_perf::recycler::Recycler, solana_pubkey::Pubkey, solana_rpc_client::rpc_client::RpcClient, @@ -26,10 +26,10 @@ use { collections::HashSet, net::{SocketAddr, TcpListener, UdpSocket}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, - thread::{self, sleep, Builder, JoinHandle}, + thread::{self, Builder, JoinHandle, sleep}, time::{Duration, Instant}, }, }; @@ -385,7 +385,7 @@ mod tests { use { super::*, crate::{cluster_info::ClusterInfo, contact_info::ContactInfo, node::Node}, - std::sync::{atomic::AtomicBool, Arc}, + std::sync::{Arc, atomic::AtomicBool}, }; #[test] diff --git a/gossip/src/node.rs b/gossip/src/node.rs index b5c29eeaa1d..190c96ec433 100644 --- a/gossip/src/node.rs +++ b/gossip/src/node.rs @@ -10,9 +10,9 @@ use { find_available_ports_in_range, multihomed_sockets::BindIpAddrs, sockets::{ - bind_gossip_port_in_range, bind_in_range_with_config, bind_more_with_config, - bind_to_with_config, localhost_port_range_for_tests, multi_bind_in_range_with_config, - SocketConfiguration as SocketConfig, + SocketConfiguration as SocketConfig, bind_gossip_port_in_range, + bind_in_range_with_config, bind_more_with_config, bind_to_with_config, + localhost_port_range_for_tests, multi_bind_in_range_with_config, }, }, solana_pubkey::Pubkey, diff --git a/gossip/src/ping_pong.rs b/gossip/src/ping_pong.rs index b695040b4ed..73945e7fb01 100644 --- a/gossip/src/ping_pong.rs +++ b/gossip/src/ping_pong.rs @@ -6,7 +6,7 @@ use { serde_big_array::BigArray, siphasher::sip::SipHasher24, solana_hash::Hash, - solana_keypair::{signable::Signable, Keypair}, + solana_keypair::{Keypair, signable::Signable}, solana_pubkey::Pubkey, solana_sanitize::{Sanitize, SanitizeError}, solana_signature::Signature, @@ -187,18 +187,18 @@ impl PingCache { return false; }; self.pongs.put(remote_node, now); - if let Some(sent_time) = self.ping_times.pop(&socket.ip()) { - if should_report_message_signature( + if let Some(sent_time) = self.ping_times.pop(&socket.ip()) + && should_report_message_signature( pong.signature(), PONG_SIGNATURE_SAMPLE_LEADING_ZEROS, - ) { - let rtt = now.saturating_duration_since(sent_time); - datapoint_info!( - "ping_rtt", - ("peer_ip", socket.ip().to_string(), String), - ("rtt_us", rtt.as_micros() as i64, i64), - ); - } + ) + { + let rtt = now.saturating_duration_since(sent_time); + datapoint_info!( + "ping_rtt", + ("peer_ip", socket.ip().to_string(), String), + ("rtt_us", rtt.as_micros() as i64, i64), + ); } true } diff --git a/gossip/src/protocol.rs b/gossip/src/protocol.rs index 7a789421f15..b09771e2b0e 100644 --- a/gossip/src/protocol.rs +++ b/gossip/src/protocol.rs @@ -230,25 +230,27 @@ pub(crate) fn split_gossip_messages( let mut data_feed = data_feed.into_iter().fuse(); let mut buffer = vec![]; let mut buffer_size = 0; // Serialized size of buffered values. - std::iter::from_fn(move || loop { - let Some(data) = data_feed.next() else { - return (!buffer.is_empty()).then(|| std::mem::take(&mut buffer)); - }; - let data_size = match bincode::serialized_size(&data) { - Ok(size) => size as usize, - Err(err) => { - error!("serialized_size failed: {err:?}"); - continue; + std::iter::from_fn(move || { + loop { + let Some(data) = data_feed.next() else { + return (!buffer.is_empty()).then(|| std::mem::take(&mut buffer)); + }; + let data_size = match bincode::serialized_size(&data) { + Ok(size) => size as usize, + Err(err) => { + error!("serialized_size failed: {err:?}"); + continue; + } + }; + if buffer_size + data_size <= max_chunk_size { + buffer_size += data_size; + buffer.push(data); + } else if data_size <= max_chunk_size { + buffer_size = data_size; + return Some(std::mem::replace(&mut buffer, vec![data])); + } else { + error!("dropping data larger than the maximum chunk size {data:?}",); } - }; - if buffer_size + data_size <= max_chunk_size { - buffer_size += data_size; - buffer.push(data); - } else if data_size <= max_chunk_size { - buffer_size = data_size; - return Some(std::mem::replace(&mut buffer, vec![data])); - } else { - error!("dropping data larger than the maximum chunk size {data:?}",); } }) } @@ -262,7 +264,7 @@ pub(crate) mod tests { crds_data::{ self, AccountsHashes, CrdsData, LowestSlot, SnapshotHashes, Vote as CrdsVote, }, - duplicate_shred::{self, tests::new_rand_shred, MAX_DUPLICATE_SHREDS}, + duplicate_shred::{self, MAX_DUPLICATE_SHREDS, tests::new_rand_shred}, }, rand::Rng, solana_clock::Slot, diff --git a/gossip/src/push_active_set.rs b/gossip/src/push_active_set.rs index bce579628e5..89692ec22f5 100644 --- a/gossip/src/push_active_set.rs +++ b/gossip/src/push_active_set.rs @@ -226,39 +226,55 @@ mod tests { } let other = &nodes[5]; let origin = &nodes[17]; - assert!(active_set - .get_nodes(&pubkey, origin, &stakes) - .eq([13, 5, 18, 16, 0].into_iter().map(|k| &nodes[k]))); - assert!(active_set - .get_nodes(&pubkey, other, &stakes) - .eq([13, 18, 16, 0].into_iter().map(|k| &nodes[k]))); + assert!( + active_set + .get_nodes(&pubkey, origin, &stakes) + .eq([13, 5, 18, 16, 0].into_iter().map(|k| &nodes[k])) + ); + assert!( + active_set + .get_nodes(&pubkey, other, &stakes) + .eq([13, 18, 16, 0].into_iter().map(|k| &nodes[k])) + ); active_set.prune(&pubkey, &nodes[5], &[*origin], &stakes); active_set.prune(&pubkey, &nodes[3], &[*origin], &stakes); active_set.prune(&pubkey, &nodes[16], &[*origin], &stakes); - assert!(active_set - .get_nodes(&pubkey, origin, &stakes) - .eq([13, 18, 0].into_iter().map(|k| &nodes[k]))); - assert!(active_set - .get_nodes(&pubkey, other, &stakes) - .eq([13, 18, 16, 0].into_iter().map(|k| &nodes[k]))); + assert!( + active_set + .get_nodes(&pubkey, origin, &stakes) + .eq([13, 18, 0].into_iter().map(|k| &nodes[k])) + ); + assert!( + active_set + .get_nodes(&pubkey, other, &stakes) + .eq([13, 18, 16, 0].into_iter().map(|k| &nodes[k])) + ); active_set.rotate(&mut rng, 7, CLUSTER_SIZE, &nodes, &stakes); assert!(active_set.0.iter().all(|entry| entry.0.len() == 7)); - assert!(active_set - .get_nodes(&pubkey, origin, &stakes) - .eq([18, 0, 7, 15, 11].into_iter().map(|k| &nodes[k]))); - assert!(active_set - .get_nodes(&pubkey, other, &stakes) - .eq([18, 16, 0, 7, 15, 11].into_iter().map(|k| &nodes[k]))); + assert!( + active_set + .get_nodes(&pubkey, origin, &stakes) + .eq([18, 0, 7, 15, 11].into_iter().map(|k| &nodes[k])) + ); + assert!( + active_set + .get_nodes(&pubkey, other, &stakes) + .eq([18, 16, 0, 7, 15, 11].into_iter().map(|k| &nodes[k])) + ); let origins = [*origin, *other]; active_set.prune(&pubkey, &nodes[18], &origins, &stakes); active_set.prune(&pubkey, &nodes[0], &origins, &stakes); active_set.prune(&pubkey, &nodes[15], &origins, &stakes); - assert!(active_set - .get_nodes(&pubkey, origin, &stakes) - .eq([7, 11].into_iter().map(|k| &nodes[k]))); - assert!(active_set - .get_nodes(&pubkey, other, &stakes) - .eq([16, 7, 11].into_iter().map(|k| &nodes[k]))); + assert!( + active_set + .get_nodes(&pubkey, origin, &stakes) + .eq([7, 11].into_iter().map(|k| &nodes[k])) + ); + assert!( + active_set + .get_nodes(&pubkey, other, &stakes) + .eq([16, 7, 11].into_iter().map(|k| &nodes[k])) + ); } #[test] @@ -284,9 +300,11 @@ mod tests { if !keys.contains(&origin) { assert!(entry.get_nodes(pubkey, origin).eq(keys)); } else { - assert!(entry - .get_nodes(pubkey, origin) - .eq(keys.into_iter().filter(|&key| key != origin))); + assert!( + entry + .get_nodes(pubkey, origin) + .eq(keys.into_iter().filter(|&key| key != origin)) + ); } } // Assert that each filter already prunes the key. @@ -294,9 +312,11 @@ mod tests { assert!(filter.contains(node)); } for (pubkey, origin) in iproduct!(&nodes, keys) { - assert!(entry - .get_nodes(pubkey, origin) - .eq(keys.into_iter().filter(|&node| node != origin))); + assert!( + entry + .get_nodes(pubkey, origin) + .eq(keys.into_iter().filter(|&node| node != origin)) + ); } // Assert that prune excludes node from get. let origin = &nodes[3]; @@ -304,9 +324,11 @@ mod tests { entry.prune(&nodes[14], origin); entry.prune(&nodes[19], origin); for pubkey in &nodes { - assert!(entry.get_nodes(pubkey, origin).eq(keys - .into_iter() - .filter(|&&node| pubkey == origin || (node != nodes[11] && node != nodes[14])))); + assert!( + entry.get_nodes(pubkey, origin).eq(keys + .into_iter() + .filter(|&&node| pubkey == origin || (node != nodes[11] && node != nodes[14]))) + ); } // Assert that rotate adds new nodes. entry.rotate(&mut rng, 5, NUM_BLOOM_FILTER_ITEMS, &nodes, &weights); diff --git a/gossip/src/weighted_shuffle.rs b/gossip/src/weighted_shuffle.rs index 0ce74648688..ece56349361 100644 --- a/gossip/src/weighted_shuffle.rs +++ b/gossip/src/weighted_shuffle.rs @@ -266,16 +266,20 @@ mod tests { })); assert!(mask.iter().all(|&x| x)); // Assert that the random shuffle is weighted. - assert!(shuffle - .chunks(shuffle.len() / 10) - .map(|chunk| chunk.iter().map(|&i| weights[i]).sum::()) - .tuple_windows() - .all(|(a, b)| a > b)); + assert!( + shuffle + .chunks(shuffle.len() / 10) + .map(|chunk| chunk.iter().map(|&i| weights[i]).sum::()) + .tuple_windows() + .all(|(a, b)| a > b) + ); // Assert that zero weights only appear at the end of the shuffle. - assert!(shuffle - .iter() - .tuple_windows() - .all(|(&i, &j)| weights[i] != 0 || weights[j] == 0)); + assert!( + shuffle + .iter() + .tuple_windows() + .all(|(&i, &j)| weights[i] != 0 || weights[j] == 0) + ); } fn weighted_shuffle_slow(rng: &mut R, mut weights: Vec) -> Vec @@ -445,7 +449,9 @@ mod tests { let mut shuffle = WeightedShuffle::new("", weights); assert_eq!( shuffle.clone().shuffle(&mut rng).collect::>(), - [10, 3, 14, 18, 0, 9, 19, 6, 2, 1, 17, 7, 13, 15, 20, 12, 4, 8, 5, 16, 11] + [ + 10, 3, 14, 18, 0, 9, 19, 6, 2, 1, 17, 7, 13, 15, 20, 12, 4, 8, 5, 16, 11 + ] ); let mut rng = ChaChaRng::from_seed(seed); assert_eq!(shuffle.first(&mut rng), Some(10)); @@ -465,7 +471,9 @@ mod tests { let mut shuffle = WeightedShuffle::new("", weights); assert_eq!( shuffle.clone().shuffle(&mut rng).collect::>(), - [3, 15, 10, 6, 19, 17, 2, 0, 9, 20, 1, 14, 7, 8, 12, 18, 4, 13, 5, 11, 16] + [ + 3, 15, 10, 6, 19, 17, 2, 0, 9, 20, 1, 14, 7, 8, 12, 18, 4, 13, 5, 11, 16 + ] ); let mut rng = ChaChaRng::from_seed(seed); assert_eq!(shuffle.first(&mut rng), Some(3)); diff --git a/gossip/tests/crds_gossip.rs b/gossip/tests/crds_gossip.rs index 570c6768d1d..ff970bf1f52 100644 --- a/gossip/tests/crds_gossip.rs +++ b/gossip/tests/crds_gossip.rs @@ -3,7 +3,7 @@ use { bincode::serialized_size, itertools::Itertools, log::*, - rayon::{prelude::*, ThreadPool, ThreadPoolBuilder}, + rayon::{ThreadPool, ThreadPoolBuilder, prelude::*}, serial_test::serial, solana_gossip::{ cluster_info_metrics::GossipStats, @@ -13,7 +13,7 @@ use { crds_gossip::*, crds_gossip_error::CrdsGossipError, crds_gossip_pull::{ - CrdsTimeouts, ProcessPullStats, PullRequest, CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS, + CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS, CrdsTimeouts, ProcessPullStats, PullRequest, }, crds_gossip_push::CRDS_GOSSIP_PUSH_MSG_TIMEOUT_MS, crds_value::{CrdsValue, CrdsValueLabel}, diff --git a/gossip/tests/gossip.rs b/gossip/tests/gossip.rs index 3522188e824..0d80511fbb8 100644 --- a/gossip/tests/gossip.rs +++ b/gossip/tests/gossip.rs @@ -18,15 +18,15 @@ use { solana_pubkey::Pubkey, solana_runtime::bank_forks::BankForks, solana_signer::Signer, - solana_streamer::sendmmsg::{multi_target_send, SendPktsError}, + solana_streamer::sendmmsg::{SendPktsError, multi_target_send}, solana_time_utils::timestamp, solana_transaction::Transaction, solana_vote_program::{vote_instruction, vote_state::Vote}, std::{ net::UdpSocket, sync::{ - atomic::{AtomicBool, Ordering}, Arc, RwLock, + atomic::{AtomicBool, Ordering}, }, thread::sleep, time::Duration, @@ -290,7 +290,7 @@ pub fn cluster_info_scale() { solana_perf::test_tx::test_tx, solana_runtime::{ bank::Bank, - genesis_utils::{create_genesis_config_with_vote_accounts, ValidatorVoteKeypairs}, + genesis_utils::{ValidatorVoteKeypairs, create_genesis_config_with_vote_accounts}, }, }; agave_logger::setup(); diff --git a/net-utils/Cargo.toml b/net-utils/Cargo.toml index 18159296c96..0fb2e0f273c 100644 --- a/net-utils/Cargo.toml +++ b/net-utils/Cargo.toml @@ -7,7 +7,7 @@ authors = { workspace = true } repository = { workspace = true } homepage = { workspace = true } license = { workspace = true } -edition = { workspace = true } +edition = "2024" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/net-utils/benches/token_bucket.rs b/net-utils/benches/token_bucket.rs index 803a373e6eb..36d47e71258 100644 --- a/net-utils/benches/token_bucket.rs +++ b/net-utils/benches/token_bucket.rs @@ -24,34 +24,38 @@ fn bench_token_bucket() { std::thread::scope(|scope| { for _ in 0..workers { - scope.spawn(|| loop { - if start.elapsed() > run_duration { - break; + scope.spawn(|| { + loop { + if start.elapsed() > run_duration { + break; + } + match tb.consume_tokens(request_size) { + Ok(_) => accepted.fetch_add(1, Ordering::Relaxed), + Err(_) => rejected.fetch_add(1, Ordering::Relaxed), + }; } - match tb.consume_tokens(request_size) { - Ok(_) => accepted.fetch_add(1, Ordering::Relaxed), - Err(_) => rejected.fetch_add(1, Ordering::Relaxed), - }; }); } // periodically check for races - let jh = scope.spawn(|| loop { - std::thread::sleep(Duration::from_millis(100)); - let elapsed = start.elapsed(); - if elapsed > run_duration { - break; + let jh = scope.spawn(|| { + loop { + std::thread::sleep(Duration::from_millis(100)); + let elapsed = start.elapsed(); + if elapsed > run_duration { + break; + } + let acc = accepted.load(Ordering::Relaxed); + let rate = acc as f64 / elapsed.as_secs_f64(); + assert!( + tb.current_tokens() < request_size * 2, + "bucket should have no spare tokens" + ); + assert!( + // allow 1% error + (rate - target_rate).abs() < target_rate / 100.0, + "Accepted rate should be about {target_rate}, actual {rate}" + ); } - let acc = accepted.load(Ordering::Relaxed); - let rate = acc as f64 / elapsed.as_secs_f64(); - assert!( - tb.current_tokens() < request_size * 2, - "bucket should have no spare tokens" - ); - assert!( - // allow 1% error - (rate - target_rate).abs() < target_rate / 100.0, - "Accepted rate should be about {target_rate}, actual {rate}" - ); }); jh.join().expect("Rate checks should pass"); }); diff --git a/net-utils/src/ip_echo_client.rs b/net-utils/src/ip_echo_client.rs index c1ed42ebc5e..7045720a50c 100644 --- a/net-utils/src/ip_echo_client.rs +++ b/net-utils/src/ip_echo_client.rs @@ -1,7 +1,7 @@ use { crate::{ - ip_echo_server::{IpEchoServerMessage, IpEchoServerResponse}, HEADER_LENGTH, IP_ECHO_SERVER_RESPONSE_LENGTH, MAX_PORT_COUNT_PER_MESSAGE, + ip_echo_server::{IpEchoServerMessage, IpEchoServerResponse}, }, anyhow::bail, bytes::{BufMut, BytesMut}, diff --git a/net-utils/src/ip_echo_server.rs b/net-utils/src/ip_echo_server.rs index 0a32d2b8d21..77f427985a8 100644 --- a/net-utils/src/ip_echo_server.rs +++ b/net-utils/src/ip_echo_server.rs @@ -1,5 +1,5 @@ use { - crate::{bind_to_unspecified, HEADER_LENGTH, IP_ECHO_SERVER_RESPONSE_LENGTH}, + crate::{HEADER_LENGTH, IP_ECHO_SERVER_RESPONSE_LENGTH, bind_to_unspecified}, log::*, serde::{Deserialize, Serialize}, solana_serde::default_on_eof, diff --git a/net-utils/src/lib.rs b/net-utils/src/lib.rs index 4c0ebf5bb24..466e46944b7 100644 --- a/net-utils/src/lib.rs +++ b/net-utils/src/lib.rs @@ -30,7 +30,7 @@ pub mod tooling_for_tests; use { ip_echo_client::{ip_echo_server_request, ip_echo_server_request_with_binding}, ip_echo_server::IpEchoServerMessage, - rand::{rng, Rng}, + rand::{Rng, rng}, std::{ io::{self}, net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, ToSocketAddrs, UdpSocket}, @@ -39,8 +39,8 @@ use { }; pub use { ip_echo_server::{ - ip_echo_server, IpEchoServer, DEFAULT_IP_ECHO_SERVER_THREADS, MAX_PORT_COUNT_PER_MESSAGE, - MINIMUM_IP_ECHO_SERVER_THREADS, + DEFAULT_IP_ECHO_SERVER_THREADS, IpEchoServer, MAX_PORT_COUNT_PER_MESSAGE, + MINIMUM_IP_ECHO_SERVER_THREADS, ip_echo_server, }, socket_addr_space::SocketAddrSpace, }; diff --git a/net-utils/src/multihomed_sockets.rs b/net-utils/src/multihomed_sockets.rs index 3162e65685d..8299b58c992 100644 --- a/net-utils/src/multihomed_sockets.rs +++ b/net-utils/src/multihomed_sockets.rs @@ -3,8 +3,8 @@ use std::{ net::{IpAddr, Ipv4Addr, UdpSocket}, ops::Deref, sync::{ - atomic::{AtomicUsize, Ordering}, Arc, + atomic::{AtomicUsize, Ordering}, }, }; diff --git a/net-utils/src/sockets.rs b/net-utils/src/sockets.rs index 7c538e87b48..bdf662b292a 100644 --- a/net-utils/src/sockets.rs +++ b/net-utils/src/sockets.rs @@ -340,11 +340,11 @@ mod tests { use { super::*, crate::{ - bind_in_range, get_cluster_shred_version, get_public_ip_addr_with_binding, - ip_echo_client, ip_echo_server, parse_host, + DEFAULT_IP_ECHO_SERVER_THREADS, MAX_PORT_VERIFY_THREADS, bind_in_range, + get_cluster_shred_version, get_public_ip_addr_with_binding, ip_echo_client, + ip_echo_server, parse_host, sockets::{localhost_port_range_for_tests, unique_port_range_for_tests}, - verify_all_reachable_tcp, verify_all_reachable_udp, DEFAULT_IP_ECHO_SERVER_THREADS, - MAX_PORT_VERIFY_THREADS, + verify_all_reachable_tcp, verify_all_reachable_udp, }, itertools::Itertools, std::{net::Ipv4Addr, time::Duration}, @@ -448,14 +448,16 @@ mod tests { ) { assert!(port2 == port1 + offset); } - assert!(bind_two_in_range_with_offset_and_config( - ip_addr, - (port_range.start, port_range.start + 5), - offset, - config, - config - ) - .is_err()); + assert!( + bind_two_in_range_with_offset_and_config( + ip_addr, + (port_range.start, port_range.start + 5), + offset, + config, + config + ) + .is_err() + ); } #[test] diff --git a/net-utils/src/token_bucket.rs b/net-utils/src/token_bucket.rs index a5c3f8ccc4b..04dcf8e3c66 100644 --- a/net-utils/src/token_bucket.rs +++ b/net-utils/src/token_bucket.rs @@ -4,7 +4,7 @@ //! as connections. use { cfg_if::cfg_if, - dashmap::{mapref::entry::Entry, DashMap}, + dashmap::{DashMap, mapref::entry::Entry}, solana_svm_type_overrides::sync::atomic::{AtomicU64, AtomicUsize, Ordering}, std::{borrow::Borrow, cmp::Reverse, hash::Hash, time::Instant}, }; diff --git a/tls-utils/Cargo.toml b/tls-utils/Cargo.toml index 6afd2b351f3..559c5f9295c 100644 --- a/tls-utils/Cargo.toml +++ b/tls-utils/Cargo.toml @@ -7,7 +7,7 @@ authors = { workspace = true } repository = { workspace = true } homepage = { workspace = true } license = { workspace = true } -edition = { workspace = true } +edition = "2024" [features] agave-unstable-api = [] diff --git a/tls-utils/src/config.rs b/tls-utils/src/config.rs index c0f03882154..2cc9d29eef3 100644 --- a/tls-utils/src/config.rs +++ b/tls-utils/src/config.rs @@ -1,6 +1,6 @@ use { rustls::{ - client::WantsClientCert, server::WantsServerCert, ClientConfig, ConfigBuilder, ServerConfig, + ClientConfig, ConfigBuilder, ServerConfig, client::WantsClientCert, server::WantsServerCert, }, std::sync::Arc, }; diff --git a/tls-utils/src/crypto_provider.rs b/tls-utils/src/crypto_provider.rs index 1e1d754fda4..32dbd57b628 100644 --- a/tls-utils/src/crypto_provider.rs +++ b/tls-utils/src/crypto_provider.rs @@ -1,4 +1,4 @@ -use rustls::{crypto::CryptoProvider, NamedGroup}; +use rustls::{NamedGroup, crypto::CryptoProvider}; pub fn crypto_provider() -> CryptoProvider { let mut provider = rustls::crypto::ring::default_provider(); diff --git a/tls-utils/src/skip_client_verification.rs b/tls-utils/src/skip_client_verification.rs index 5ecc9bb866c..b7f8a1b53fd 100644 --- a/tls-utils/src/skip_client_verification.rs +++ b/tls-utils/src/skip_client_verification.rs @@ -1,11 +1,11 @@ use { crate::crypto_provider, rustls::{ + DigitallySignedStruct, DistinguishedName, Error, SignatureScheme, client::danger::HandshakeSignatureValid, crypto::CryptoProvider, pki_types::{CertificateDer, UnixTime}, server::danger::{ClientCertVerified, ClientCertVerifier}, - DigitallySignedStruct, DistinguishedName, Error, SignatureScheme, }, std::{fmt::Debug, sync::Arc}, }; diff --git a/tls-utils/src/skip_server_verification.rs b/tls-utils/src/skip_server_verification.rs index 4fdef2c3896..5e1dab5b5c2 100644 --- a/tls-utils/src/skip_server_verification.rs +++ b/tls-utils/src/skip_server_verification.rs @@ -1,10 +1,10 @@ use { crate::crypto_provider, rustls::{ + DigitallySignedStruct, Error, SignatureScheme, client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}, - crypto::{verify_tls12_signature, verify_tls13_signature, CryptoProvider}, + crypto::{CryptoProvider, verify_tls12_signature, verify_tls13_signature}, pki_types::{CertificateDer, ServerName, UnixTime}, - DigitallySignedStruct, Error, SignatureScheme, }, std::{ fmt::{self, Debug, Formatter}, diff --git a/turbine/Cargo.toml b/turbine/Cargo.toml index 5b9c8ee87c4..2a84d45c477 100644 --- a/turbine/Cargo.toml +++ b/turbine/Cargo.toml @@ -7,7 +7,7 @@ description = { workspace = true } repository = { workspace = true } homepage = { workspace = true } license = { workspace = true } -edition = { workspace = true } +edition = "2024" [features] agave-unstable-api = [] diff --git a/turbine/benches/cluster_info.rs b/turbine/benches/cluster_info.rs index ed12982bbba..b6714dd5810 100644 --- a/turbine/benches/cluster_info.rs +++ b/turbine/benches/cluster_info.rs @@ -1,23 +1,23 @@ use { - bencher::{benchmark_group, benchmark_main, Bencher}, - rand::{rng, Rng}, + bencher::{Bencher, benchmark_group, benchmark_main}, + rand::{Rng, rng}, solana_entry::entry::Entry, solana_gossip::{cluster_info::ClusterInfo, contact_info::ContactInfo, node::Node}, solana_hash::Hash, solana_keypair::Keypair, solana_ledger::{ - genesis_utils::{create_genesis_config, GenesisConfigInfo}, + genesis_utils::{GenesisConfigInfo, create_genesis_config}, shred::{ProcessShredsStats, ReedSolomonCache, Shredder}, }, - solana_net_utils::{sockets::bind_to_localhost_unique, SocketAddrSpace}, + solana_net_utils::{SocketAddrSpace, sockets::bind_to_localhost_unique}, solana_pubkey as pubkey, solana_runtime::{bank::Bank, bank_forks::BankForks}, solana_signer::Signer, - solana_time_utils::{timestamp, AtomicInterval}, + solana_time_utils::{AtomicInterval, timestamp}, solana_turbine::{ broadcast_stage::{ - broadcast_metrics::TransmitShredsStats, broadcast_shreds, BroadcastSocket, - BroadcastStage, + BroadcastSocket, BroadcastStage, broadcast_metrics::TransmitShredsStats, + broadcast_shreds, }, cluster_nodes::ClusterNodesCache, }, diff --git a/turbine/benches/cluster_nodes.rs b/turbine/benches/cluster_nodes.rs index 9ed4afe582e..00b6c09cd79 100644 --- a/turbine/benches/cluster_nodes.rs +++ b/turbine/benches/cluster_nodes.rs @@ -1,6 +1,6 @@ use { - bencher::{benchmark_group, benchmark_main, Bencher}, - rand::{prelude::IndexedRandom as _, Rng}, + bencher::{Bencher, benchmark_group, benchmark_main}, + rand::{Rng, prelude::IndexedRandom as _}, solana_clock::Slot, solana_cluster_type::ClusterType, solana_gossip::contact_info::ContactInfo, @@ -10,7 +10,7 @@ use { solana_net_utils::SocketAddrSpace, solana_pubkey::Pubkey, solana_turbine::{ - cluster_nodes::{make_test_cluster, new_cluster_nodes, ClusterNodes}, + cluster_nodes::{ClusterNodes, make_test_cluster, new_cluster_nodes}, retransmit_stage::RetransmitStage, }, }; diff --git a/turbine/src/addr_cache.rs b/turbine/src/addr_cache.rs index b1033f5aae3..52ffdf92d94 100644 --- a/turbine/src/addr_cache.rs +++ b/turbine/src/addr_cache.rs @@ -3,11 +3,11 @@ use { itertools::Itertools, solana_clock::Slot, solana_ledger::shred::{ - ShredId, ShredType, MAX_CODE_SHREDS_PER_SLOT, MAX_DATA_SHREDS_PER_SLOT, + MAX_CODE_SHREDS_PER_SLOT, MAX_DATA_SHREDS_PER_SLOT, ShredId, ShredType, }, std::{ cmp::Reverse, - collections::{hash_map::Entry, HashMap, VecDeque}, + collections::{HashMap, VecDeque, hash_map::Entry}, net::SocketAddr, }, }; @@ -397,9 +397,11 @@ mod tests { assert_eq!(entry.index_data, 2); entry.last_shred_in_slot = true; - assert!(entry - .get_shreds(7) - .eq([(ShredType::Code, 3), (ShredType::Data, 2)])); + assert!( + entry + .get_shreds(7) + .eq([(ShredType::Code, 3), (ShredType::Data, 2)]) + ); assert_eq!(entry.index_code, 3); assert_eq!(entry.index_data, 2); diff --git a/turbine/src/broadcast_stage.rs b/turbine/src/broadcast_stage.rs index ca72ccd0412..4c7f1b91361 100644 --- a/turbine/src/broadcast_stage.rs +++ b/turbine/src/broadcast_stage.rs @@ -12,7 +12,7 @@ use { cluster_nodes::{ClusterNodes, ClusterNodesCache}, xdp::XdpSender, }, - crossbeam_channel::{unbounded, Receiver, RecvError, RecvTimeoutError, Sender}, + crossbeam_channel::{Receiver, RecvError, RecvTimeoutError, Sender, unbounded}, itertools::Itertools, solana_clock::Slot, solana_gossip::{ @@ -27,14 +27,14 @@ use { solana_poh::poh_recorder::WorkingBankEntry, solana_pubkey::Pubkey, solana_runtime::{bank::MAX_LEADER_SCHEDULE_STAKES, bank_forks::BankForks}, - solana_streamer::sendmmsg::{batch_send, SendPktsError}, - solana_time_utils::{timestamp, AtomicInterval}, + solana_streamer::sendmmsg::{SendPktsError, batch_send}, + solana_time_utils::{AtomicInterval, timestamp}, std::{ collections::{HashMap, HashSet}, net::UdpSocket, sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, RwLock, + atomic::{AtomicBool, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, @@ -389,16 +389,18 @@ impl BroadcastStage { let retransmit_thread = Builder::new() .name("solBroadcastRtx".to_string()) - .spawn(move || loop { - if let Some(res) = Self::handle_error( - Self::check_retransmit_signals( - &blockstore, - &retransmit_slots_receiver, - &socket_sender, - ), - "solana-broadcaster-retransmit-check_retransmit_signals", - ) { - return res; + .spawn(move || { + loop { + if let Some(res) = Self::handle_error( + Self::check_retransmit_signals( + &blockstore, + &retransmit_slots_receiver, + &socket_sender, + ), + "solana-broadcaster-retransmit-check_retransmit_signals", + ) { + return res; + } } }) .unwrap(); @@ -424,9 +426,11 @@ impl BroadcastStage { .get_data_shreds_for_slot(new_retransmit_slot, 0) .expect("My own shreds must be reconstructable"), ); - debug_assert!(data_shreds - .iter() - .all(|shred| shred.slot() == new_retransmit_slot)); + debug_assert!( + data_shreds + .iter() + .all(|shred| shred.slot() == new_retransmit_slot) + ); if !data_shreds.is_empty() { socket_sender.send((data_shreds, None))?; } @@ -437,9 +441,11 @@ impl BroadcastStage { .expect("My own shreds must be reconstructable"), ); - debug_assert!(coding_shreds - .iter() - .all(|shred| shred.slot() == new_retransmit_slot)); + debug_assert!( + coding_shreds + .iter() + .all(|shred| shred.slot() == new_retransmit_slot) + ); if !coding_shreds.is_empty() { socket_sender.send((coding_shreds, None))?; } @@ -563,15 +569,15 @@ pub mod test { solana_keypair::Keypair, solana_ledger::{ blockstore::Blockstore, - genesis_utils::{create_genesis_config, GenesisConfigInfo}, + genesis_utils::{GenesisConfigInfo, create_genesis_config}, get_tmp_ledger_path_auto_delete, - shred::{max_ticks_per_n_shreds, ProcessShredsStats, ReedSolomonCache, Shredder}, + shred::{ProcessShredsStats, ReedSolomonCache, Shredder, max_ticks_per_n_shreds}, }, solana_runtime::bank::Bank, solana_signer::Signer, std::{ path::Path, - sync::{atomic::AtomicBool, Arc}, + sync::{Arc, atomic::AtomicBool}, thread::sleep, }, }; diff --git a/turbine/src/broadcast_stage/broadcast_duplicates_run.rs b/turbine/src/broadcast_stage/broadcast_duplicates_run.rs index 140d959b218..d5ded506263 100644 --- a/turbine/src/broadcast_stage/broadcast_duplicates_run.rs +++ b/turbine/src/broadcast_stage/broadcast_duplicates_run.rs @@ -275,12 +275,16 @@ impl BroadcastRun for BroadcastDuplicatesRun { // Store the original shreds that this node replayed blockstore_sender.send((original_last_data_shred.clone(), None))?; - assert!(original_last_data_shred - .iter() - .all(|shred| shred.slot() == bank.slot())); - assert!(partition_last_data_shred - .iter() - .all(|shred| shred.slot() == bank.slot())); + assert!( + original_last_data_shred + .iter() + .all(|shred| shred.slot() == bank.slot()) + ); + assert!( + partition_last_data_shred + .iter() + .all(|shred| shred.slot() == bank.slot()) + ); if let Some(duplicate_slot_sender) = &self.config.duplicate_slot_sender { let _ = duplicate_slot_sender.send(bank.slot()); diff --git a/turbine/src/broadcast_stage/broadcast_metrics.rs b/turbine/src/broadcast_stage/broadcast_metrics.rs index 85513f0053f..57926b400e8 100644 --- a/turbine/src/broadcast_stage/broadcast_metrics.rs +++ b/turbine/src/broadcast_stage/broadcast_metrics.rs @@ -166,15 +166,15 @@ impl SlotBroadcastStats { if let Some(num_expected_batches) = batch_info.num_expected_batches { slot_batch_counter.num_expected_batches = Some(num_expected_batches); } - if let Some(num_expected_batches) = slot_batch_counter.num_expected_batches { - if slot_batch_counter.num_batches == num_expected_batches { - slot_batch_counter.broadcast_shred_stats.report_stats( - batch_info.slot, - batch_info.slot_start_ts, - batch_info.was_interrupted, - ); - should_delete = true; - } + if let Some(num_expected_batches) = slot_batch_counter.num_expected_batches + && slot_batch_counter.num_batches == num_expected_batches + { + slot_batch_counter.broadcast_shred_stats.report_stats( + batch_info.slot, + batch_info.slot_start_ts, + batch_info.was_interrupted, + ); + should_delete = true; } } if should_delete { diff --git a/turbine/src/broadcast_stage/broadcast_utils.rs b/turbine/src/broadcast_stage/broadcast_utils.rs index 2b556f372c4..fe242f96ef8 100644 --- a/turbine/src/broadcast_stage/broadcast_utils.rs +++ b/turbine/src/broadcast_stage/broadcast_utils.rs @@ -6,7 +6,7 @@ use { solana_hash::Hash, solana_ledger::{ blockstore::Blockstore, - shred::{self, get_data_shred_bytes_per_batch_typical, ProcessShredsStats}, + shred::{self, ProcessShredsStats, get_data_shred_bytes_per_batch_typical}, }, solana_poh::poh_recorder::WorkingBankEntry, solana_runtime::bank::Bank, @@ -198,7 +198,7 @@ mod tests { super::*, crossbeam_channel::unbounded, solana_genesis_config::GenesisConfig, - solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo}, + solana_ledger::genesis_utils::{GenesisConfigInfo, create_genesis_config}, solana_pubkey::Pubkey, solana_system_transaction as system_transaction, solana_transaction::Transaction, diff --git a/turbine/src/broadcast_stage/standard_broadcast_run.rs b/turbine/src/broadcast_stage/standard_broadcast_run.rs index b8d953db962..4f14a61379d 100644 --- a/turbine/src/broadcast_stage/standard_broadcast_run.rs +++ b/turbine/src/broadcast_stage/standard_broadcast_run.rs @@ -10,8 +10,8 @@ use { solana_hash::Hash, solana_keypair::Keypair, solana_ledger::shred::{ - ProcessShredsStats, ReedSolomonCache, Shred, ShredType, Shredder, MAX_CODE_SHREDS_PER_SLOT, - MAX_DATA_SHREDS_PER_SLOT, + MAX_CODE_SHREDS_PER_SLOT, MAX_DATA_SHREDS_PER_SLOT, ProcessShredsStats, ReedSolomonCache, + Shred, ShredType, Shredder, }, solana_time_utils::AtomicInterval, std::{borrow::Cow, sync::RwLock}, @@ -278,16 +278,16 @@ impl StandardBroadcastRun { // https://github.com/solana-labs/solana/blob/92a0b310c/turbine/src/broadcast_stage/standard_broadcast_run.rs#L132-L142 // By contrast Self::insert skips the 1st data shred with index zero: // https://github.com/solana-labs/solana/blob/92a0b310c/turbine/src/broadcast_stage/standard_broadcast_run.rs#L367-L373 - if let Some(shred) = shreds.iter().find(|shred| shred.is_data()) { - if shred.index() == 0 { - blockstore - .insert_cow_shreds( - [Cow::Borrowed(shred)], - None, // leader_schedule - true, // is_trusted - ) - .expect("Failed to insert shreds in blockstore"); - } + if let Some(shred) = shreds.iter().find(|shred| shred.is_data()) + && shred.index() == 0 + { + blockstore + .insert_cow_shreds( + [Cow::Borrowed(shred)], + None, // leader_schedule + true, // is_trusted + ) + .expect("Failed to insert shreds in blockstore"); } to_shreds_time.stop(); @@ -483,9 +483,9 @@ mod test { blockstore::Blockstore, genesis_utils::create_genesis_config, get_tmp_ledger_path, - shred::{max_ticks_per_n_shreds, DATA_SHREDS_PER_FEC_BLOCK}, + shred::{DATA_SHREDS_PER_FEC_BLOCK, max_ticks_per_n_shreds}, }, - solana_net_utils::{sockets::bind_to_localhost_unique, SocketAddrSpace}, + solana_net_utils::{SocketAddrSpace, sockets::bind_to_localhost_unique}, solana_runtime::bank::Bank, solana_signer::Signer, std::{ops::Deref, sync::Arc, time::Duration}, @@ -678,18 +678,22 @@ mod test { ); // Broadcast stats for interrupted slot should be cleared - assert!(standard_broadcast_run - .transmit_shreds_stats - .lock() - .unwrap() - .get(interrupted_slot) - .is_none()); - assert!(standard_broadcast_run - .insert_shreds_stats - .lock() - .unwrap() - .get(interrupted_slot) - .is_none()); + assert!( + standard_broadcast_run + .transmit_shreds_stats + .lock() + .unwrap() + .get(interrupted_slot) + .is_none() + ); + assert!( + standard_broadcast_run + .insert_shreds_stats + .lock() + .unwrap() + .get(interrupted_slot) + .is_none() + ); // Try to fetch the incomplete ticks from blockstore, should succeed assert_eq!(blockstore.get_slot_entries(0, 0).unwrap(), ticks0); diff --git a/turbine/src/cluster_nodes.rs b/turbine/src/cluster_nodes.rs index daffefd1d28..b34895eb076 100644 --- a/turbine/src/cluster_nodes.rs +++ b/turbine/src/cluster_nodes.rs @@ -3,7 +3,7 @@ use { agave_feature_set::{self as feature_set}, itertools::Either, lazy_lru::LruCache, - rand::{seq::SliceRandom, Rng, RngCore, SeedableRng}, + rand::{Rng, RngCore, SeedableRng, seq::SliceRandom}, rand_chacha::{ChaCha8Rng, ChaChaRng}, solana_clock::{Epoch, Slot}, solana_cluster_type::ClusterType, diff --git a/turbine/src/retransmit_stage.rs b/turbine/src/retransmit_stage.rs index a49877b0f46..a9b2d0f64f6 100644 --- a/turbine/src/retransmit_stage.rs +++ b/turbine/src/retransmit_stage.rs @@ -4,7 +4,7 @@ use { crate::{ addr_cache::AddrCache, cluster_nodes::{ - ClusterNodes, ClusterNodesCache, Error, DATA_PLANE_FANOUT, MAX_NUM_TURBINE_HOPS, + ClusterNodes, ClusterNodesCache, DATA_PLANE_FANOUT, Error, MAX_NUM_TURBINE_HOPS, }, xdp::XdpSender, }, @@ -12,7 +12,7 @@ use { crossbeam_channel::{Receiver, RecvError, Sender, TryRecvError}, lru::LruCache, rand::Rng, - rayon::{prelude::*, ThreadPool, ThreadPoolBuilder}, + rayon::{ThreadPool, ThreadPoolBuilder, prelude::*}, solana_clock::Slot, solana_gossip::cluster_info::ClusterInfo, solana_ledger::{ @@ -32,7 +32,7 @@ use { bank::{Bank, MAX_LEADER_SCHEDULE_STAKES}, bank_forks::BankForks, }, - solana_streamer::sendmmsg::{multi_target_send, SendPktsError}, + solana_streamer::sendmmsg::{SendPktsError, multi_target_send}, solana_time_utils::timestamp, std::{ borrow::Cow, @@ -40,8 +40,8 @@ use { net::{SocketAddr, UdpSocket}, ops::AddAssign, sync::{ - atomic::{AtomicU64, AtomicUsize, Ordering}, Arc, RwLock, + atomic::{AtomicU64, AtomicUsize, Ordering}, }, thread::{self, Builder, JoinHandle}, time::{Duration, Instant}, @@ -481,14 +481,14 @@ fn retransmit_shred( let num_nodes = match socket { RetransmitSocket::Xdp(sender) => { let mut sent = num_addrs; - if num_addrs > 0 { - if let Err(e) = sender.try_send(key.index() as usize, addrs.to_vec(), shred) { - log::warn!("xdp channel full: {e:?}"); - stats - .num_shreds_dropped_xdp_full - .fetch_add(num_addrs, Ordering::Relaxed); - sent = 0; - } + if num_addrs > 0 + && let Err(e) = sender.try_send(key.index() as usize, addrs.to_vec(), shred) + { + log::warn!("xdp channel full: {e:?}"); + stats + .num_shreds_dropped_xdp_full + .fetch_add(num_addrs, Ordering::Relaxed); + sent = 0; } sent } @@ -883,13 +883,13 @@ fn notify_subscribers( .unwrap() .notify_first_shred_received(slot); } - if let Some(votor_event_sender) = votor_event_sender { - if let Err(err) = votor_event_sender.send(VotorEvent::FirstShred(slot)) { - warn!( - "Sending {:?} failed as channel became disconnected. Ignoring.", - err.into_inner() - ); - } + if let Some(votor_event_sender) = votor_event_sender + && let Err(err) = votor_event_sender.send(VotorEvent::FirstShred(slot)) + { + warn!( + "Sending {:?} failed as channel became disconnected. Ignoring.", + err.into_inner() + ); } } diff --git a/turbine/src/sigverify_shreds.rs b/turbine/src/sigverify_shreds.rs index 2e731a361e8..f6186f04ac0 100644 --- a/turbine/src/sigverify_shreds.rs +++ b/turbine/src/sigverify_shreds.rs @@ -1,12 +1,12 @@ use { crate::{ - cluster_nodes::{check_feature_activation, ClusterNodesCache, DATA_PLANE_FANOUT}, + cluster_nodes::{ClusterNodesCache, DATA_PLANE_FANOUT, check_feature_activation}, retransmit_stage::RetransmitStage, }, agave_feature_set as feature_set, crossbeam_channel::{Receiver, RecvTimeoutError, SendError, Sender}, itertools::{Either, Itertools}, - rayon::{prelude::*, ThreadPool, ThreadPoolBuilder}, + rayon::{ThreadPool, ThreadPoolBuilder, prelude::*}, solana_clock::Slot, solana_gossip::cluster_info::ClusterInfo, solana_keypair::Keypair, @@ -17,7 +17,7 @@ use { layout::{get_shred, resign_packet}, wire::is_retransmitter_signed_variant, }, - sigverify_shreds::{verify_shreds, LruCache, SlotPubkeys}, + sigverify_shreds::{LruCache, SlotPubkeys, verify_shreds}, }, solana_perf::{ self, @@ -31,8 +31,8 @@ use { std::{ num::NonZeroUsize, sync::{ - atomic::{AtomicUsize, Ordering}, Arc, RwLock, + atomic::{AtomicUsize, Ordering}, }, thread::{Builder, JoinHandle}, time::{Duration, Instant}, @@ -555,7 +555,7 @@ mod tests { use { super::*, rand::Rng, - solana_entry::entry::{create_ticks, Entry}, + solana_entry::entry::{Entry, create_ticks}, solana_gossip::contact_info::ContactInfo, solana_hash::Hash, solana_keypair::Keypair, diff --git a/turbine/src/xdp.rs b/turbine/src/xdp.rs index a5468d899e0..9e715829f7d 100644 --- a/turbine/src/xdp.rs +++ b/turbine/src/xdp.rs @@ -19,7 +19,7 @@ use { std::{ error::Error, net::{Ipv4Addr, SocketAddr}, - sync::{atomic::AtomicBool, Arc}, + sync::{Arc, atomic::AtomicBool}, thread, }, }; diff --git a/xdp/Cargo.toml b/xdp/Cargo.toml index f7ab4b3589e..6319531c81d 100644 --- a/xdp/Cargo.toml +++ b/xdp/Cargo.toml @@ -5,7 +5,7 @@ version = { workspace = true } repository = { workspace = true } homepage = { workspace = true } license = { workspace = true } -edition = { workspace = true } +edition = "2024" publish = true [features] diff --git a/xdp/src/device.rs b/xdp/src/device.rs index 7e38368394e..3a44978fd65 100644 --- a/xdp/src/device.rs +++ b/xdp/src/device.rs @@ -5,11 +5,11 @@ use { umem::{Frame, FrameOffset}, }, libc::{ - ifreq, mmap, munmap, socket, syscall, xdp_ring_offset, SYS_ioctl, AF_INET, IF_NAMESIZE, - SIOCETHTOOL, SIOCGIFADDR, SIOCGIFHWADDR, SOCK_DGRAM, + AF_INET, IF_NAMESIZE, SIOCETHTOOL, SIOCGIFADDR, SIOCGIFHWADDR, SOCK_DGRAM, SYS_ioctl, + ifreq, mmap, munmap, socket, syscall, xdp_ring_offset, }, std::{ - ffi::{c_char, CStr, CString}, + ffi::{CStr, CString, c_char}, fs, io::{self, ErrorKind}, marker::PhantomData, diff --git a/xdp/src/netlink.rs b/xdp/src/netlink.rs index b3ce4cea4be..efa401b11da 100644 --- a/xdp/src/netlink.rs +++ b/xdp/src/netlink.rs @@ -2,12 +2,12 @@ use { libc::{ - nlattr, nlmsgerr, nlmsghdr, recv, send, setsockopt, sockaddr_nl, socket, AF_INET, AF_INET6, - AF_NETLINK, NDA_DST, NDA_LLADDR, NETLINK_EXT_ACK, NETLINK_ROUTE, NLA_ALIGNTO, - NLA_TYPE_MASK, NLMSG_DONE, NLMSG_ERROR, NLM_F_DUMP, NLM_F_MULTI, NLM_F_REQUEST, RTA_DST, - RTA_GATEWAY, RTA_IIF, RTA_OIF, RTA_PREFSRC, RTA_PRIORITY, RTA_TABLE, RTM_GETNEIGH, - RTM_GETROUTE, RTM_NEWNEIGH, RTM_NEWROUTE, RT_TABLE_MAIN, SOCK_RAW, SOL_NETLINK, SOL_SOCKET, - SO_RCVBUF, + AF_INET, AF_INET6, AF_NETLINK, NDA_DST, NDA_LLADDR, NETLINK_EXT_ACK, NETLINK_ROUTE, + NLA_ALIGNTO, NLA_TYPE_MASK, NLM_F_DUMP, NLM_F_MULTI, NLM_F_REQUEST, NLMSG_DONE, + NLMSG_ERROR, RT_TABLE_MAIN, RTA_DST, RTA_GATEWAY, RTA_IIF, RTA_OIF, RTA_PREFSRC, + RTA_PRIORITY, RTA_TABLE, RTM_GETNEIGH, RTM_GETROUTE, RTM_NEWNEIGH, RTM_NEWROUTE, SO_RCVBUF, + SOCK_RAW, SOL_NETLINK, SOL_SOCKET, nlattr, nlmsgerr, nlmsghdr, recv, send, setsockopt, + sockaddr_nl, socket, }, std::{ collections::HashMap, @@ -412,10 +412,10 @@ pub fn parse_rtm_newneigh(msg: &NetlinkMessage, if_index: Option) -> Option return None; } let nd_msg = unsafe { ptr::read_unaligned(msg.data.as_ptr() as *const ndmsg) }; - if let Some(idx) = if_index { - if nd_msg.ndm_ifindex != idx as i32 { - return None; - } + if let Some(idx) = if_index + && nd_msg.ndm_ifindex != idx as i32 + { + return None; } let Ok(attrs) = parse_attrs(&msg.data[mem::size_of::()..]) else { return None; @@ -429,12 +429,12 @@ pub fn parse_rtm_newneigh(msg: &NetlinkMessage, if_index: Option) -> Option if let Some(dst_attr) = attrs.get(&NDA_DST) { neighbor.destination = parse_ip_address(dst_attr.data, nd_msg.ndm_family); } - if let Some(lladdr_attr) = attrs.get(&NDA_LLADDR) { - if lladdr_attr.data.len() >= 6 { - let mut mac = [0u8; 6]; - mac.copy_from_slice(&lladdr_attr.data[0..6]); - neighbor.lladdr = Some(MacAddress(mac)); - } + if let Some(lladdr_attr) = attrs.get(&NDA_LLADDR) + && lladdr_attr.data.len() >= 6 + { + let mut mac = [0u8; 6]; + mac.copy_from_slice(&lladdr_attr.data[0..6]); + neighbor.lladdr = Some(MacAddress(mac)); } Some(neighbor) } diff --git a/xdp/src/program.rs b/xdp/src/program.rs index f9a74258837..57d1c3d3b0f 100644 --- a/xdp/src/program.rs +++ b/xdp/src/program.rs @@ -2,7 +2,7 @@ use { crate::device::NetworkDevice, - aya::{programs::Xdp, Ebpf, EbpfLoader}, + aya::{Ebpf, EbpfLoader, programs::Xdp}, std::io::{Cursor, Write}, }; @@ -163,7 +163,9 @@ fn write_section_header( addralign: u64, entsize: u64, ) -> std::io::Result<()> { - write_fields!(w, name, type_, flags, addr, offset, size, link, info, addralign, entsize); + write_fields!( + w, name, type_, flags, addr, offset, size, link, info, addralign, entsize + ); Ok(()) } diff --git a/xdp/src/route.rs b/xdp/src/route.rs index e30f822bea7..e3215171149 100644 --- a/xdp/src/route.rs +++ b/xdp/src/route.rs @@ -1,6 +1,6 @@ use { crate::netlink::{ - netlink_get_neighbors, netlink_get_routes, MacAddress, NeighborEntry, RouteEntry, + MacAddress, NeighborEntry, RouteEntry, netlink_get_neighbors, netlink_get_routes, }, libc::{AF_INET, AF_INET6}, std::{ @@ -313,13 +313,17 @@ mod tests { #[test] fn test_ipv6_match() { assert!(is_ipv6_match( - Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, 0xabcd, 0xef01, 0x2345, 0x6789), + Ipv6Addr::new( + 0x2001, 0xdb8, 0x1234, 0x5678, 0xabcd, 0xef01, 0x2345, 0x6789 + ), Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, 0, 0, 0, 0), 64 )); assert!(!is_ipv6_match( - Ipv6Addr::new(0x2001, 0xdb8, 0x1235, 0x5678, 0xabcd, 0xef01, 0x2345, 0x6789), + Ipv6Addr::new( + 0x2001, 0xdb8, 0x1235, 0x5678, 0xabcd, 0xef01, 0x2345, 0x6789 + ), Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, 0, 0, 0, 0), 64 )); diff --git a/xdp/src/route_monitor.rs b/xdp/src/route_monitor.rs index 49626ff65d0..69e97387a16 100644 --- a/xdp/src/route_monitor.rs +++ b/xdp/src/route_monitor.rs @@ -1,20 +1,20 @@ use { crate::{ - netlink::{parse_rtm_newneigh, parse_rtm_newroute, NetlinkMessage, NetlinkSocket}, + netlink::{NetlinkMessage, NetlinkSocket, parse_rtm_newneigh, parse_rtm_newroute}, route::Router, }, arc_swap::ArcSwap, libc::{ - self, pollfd, POLLERR, POLLHUP, POLLIN, POLLNVAL, RTMGRP_IPV4_ROUTE, RTMGRP_NEIGH, - RTM_DELNEIGH, RTM_DELROUTE, RTM_NEWNEIGH, RTM_NEWROUTE, + self, POLLERR, POLLHUP, POLLIN, POLLNVAL, RTM_DELNEIGH, RTM_DELROUTE, RTM_NEWNEIGH, + RTM_NEWROUTE, RTMGRP_IPV4_ROUTE, RTMGRP_NEIGH, pollfd, }, log::*, std::{ io::{Error, ErrorKind}, net::IpAddr, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, thread, time::{Duration, Instant}, @@ -104,17 +104,17 @@ impl RouteMonitor { } } RTM_NEWNEIGH => { - if let Some(n) = parse_rtm_newneigh(m, None) { - if let Some(IpAddr::V4(_)) = n.destination { - dirty |= router.upsert_neighbor(n); - } + if let Some(n) = parse_rtm_newneigh(m, None) + && let Some(IpAddr::V4(_)) = n.destination + { + dirty |= router.upsert_neighbor(n); } } RTM_DELNEIGH => { - if let Some(n) = parse_rtm_newneigh(m, None) { - if let Some(IpAddr::V4(ip)) = n.destination { - dirty |= router.remove_neighbor(ip, n.ifindex as u32); - } + if let Some(n) = parse_rtm_newneigh(m, None) + && let Some(IpAddr::V4(ip)) = n.destination + { + dirty |= router.remove_neighbor(ip, n.ifindex as u32); } } _ => {} diff --git a/xdp/src/socket.rs b/xdp/src/socket.rs index 4bf6542ddf8..e5f99ad3038 100644 --- a/xdp/src/socket.rs +++ b/xdp/src/socket.rs @@ -1,17 +1,18 @@ use { crate::{ device::{ - mmap_ring, DeviceQueue, RingConsumer, RingMmap, RingProducer, RxFillRing, - TxCompletionRing, XdpDesc, + DeviceQueue, RingConsumer, RingMmap, RingProducer, RxFillRing, TxCompletionRing, + XdpDesc, mmap_ring, }, umem::{Frame, Umem}, }, libc::{ - bind, getsockopt, sa_family_t, sendto, setsockopt, sockaddr, sockaddr_xdp, socket, - socklen_t, xdp_mmap_offsets, xdp_umem_reg, AF_XDP, SOCK_RAW, SOL_XDP, XDP_COPY, - XDP_MMAP_OFFSETS, XDP_PGOFF_RX_RING, XDP_PGOFF_TX_RING, XDP_RING_NEED_WAKEUP, XDP_RX_RING, - XDP_TX_RING, XDP_UMEM_COMPLETION_RING, XDP_UMEM_FILL_RING, XDP_UMEM_PGOFF_COMPLETION_RING, - XDP_UMEM_PGOFF_FILL_RING, XDP_USE_NEED_WAKEUP, XDP_ZEROCOPY, + AF_XDP, SOCK_RAW, SOL_XDP, XDP_COPY, XDP_MMAP_OFFSETS, XDP_PGOFF_RX_RING, + XDP_PGOFF_TX_RING, XDP_RING_NEED_WAKEUP, XDP_RX_RING, XDP_TX_RING, + XDP_UMEM_COMPLETION_RING, XDP_UMEM_FILL_RING, XDP_UMEM_PGOFF_COMPLETION_RING, + XDP_UMEM_PGOFF_FILL_RING, XDP_USE_NEED_WAKEUP, XDP_ZEROCOPY, bind, getsockopt, sa_family_t, + sendto, setsockopt, sockaddr, sockaddr_xdp, socket, socklen_t, xdp_mmap_offsets, + xdp_umem_reg, }, std::{ io, diff --git a/xdp/src/tx_loop.rs b/xdp/src/tx_loop.rs index 941f55a0750..8d30dc91618 100644 --- a/xdp/src/tx_loop.rs +++ b/xdp/src/tx_loop.rs @@ -5,8 +5,8 @@ use { device::{NetworkDevice, QueueId, RingSizes}, netlink::MacAddress, packet::{ - write_eth_header, write_ip_header, write_udp_header, ETH_HEADER_SIZE, IP_HEADER_SIZE, - UDP_HEADER_SIZE, + ETH_HEADER_SIZE, IP_HEADER_SIZE, UDP_HEADER_SIZE, write_eth_header, write_ip_header, + write_udp_header, }, route::NextHop, set_cpu_affinity, @@ -18,7 +18,7 @@ use { Capability::{CAP_NET_ADMIN, CAP_NET_RAW}, }, crossbeam_channel::{Receiver, Sender, TryRecvError}, - libc::{sysconf, _SC_PAGESIZE}, + libc::{_SC_PAGESIZE, sysconf}, std::{ net::{IpAddr, Ipv4Addr, SocketAddr}, thread, diff --git a/xdp/src/umem.rs b/xdp/src/umem.rs index 248f3a7904e..3185457839d 100644 --- a/xdp/src/umem.rs +++ b/xdp/src/umem.rs @@ -1,7 +1,7 @@ #![allow(clippy::arithmetic_side_effects)] use { - libc::{munmap, sysconf, _SC_PAGESIZE}, + libc::{_SC_PAGESIZE, munmap, sysconf}, std::{ ffi::c_void, io,