diff --git a/core/benches/banking_stage.rs b/core/benches/banking_stage.rs index e227a8b020e..aa7dc115679 100644 --- a/core/benches/banking_stage.rs +++ b/core/benches/banking_stage.rs @@ -88,7 +88,7 @@ fn bench_consume_buffered(bencher: &mut Bencher) { let tx = test_tx(); let transactions = vec![tx; 4194304]; - let batches = transactions_to_deserialized_packets(&transactions).unwrap(); + let batches = transactions_to_deserialized_packets(&transactions, false).unwrap(); let batches_len = batches.len(); let mut transaction_buffer = UnprocessedTransactionStorage::new_transaction_storage( UnprocessedPacketBatches::from_iter(batches.into_iter(), 2 * batches_len), diff --git a/core/benches/unprocessed_packet_batches.rs b/core/benches/unprocessed_packet_batches.rs index dc07a5b57f1..aa7e031873c 100644 --- a/core/benches/unprocessed_packet_batches.rs +++ b/core/benches/unprocessed_packet_batches.rs @@ -53,7 +53,7 @@ fn insert_packet_batches( (0..batch_count).for_each(|_| { let (packet_batch, packet_indexes) = build_packet_batch(packet_per_batch_count, None); - let deserialized_packets = deserialize_packets(&packet_batch, &packet_indexes); + let deserialized_packets = deserialize_packets(&packet_batch, &packet_indexes, false); unprocessed_packet_batches.insert_batch(deserialized_packets); }); } @@ -129,7 +129,7 @@ fn buffer_iter_desc_and_forward( (0..batch_count).for_each(|_| { let (packet_batch, packet_indexes) = build_packet_batch(packet_per_batch_count, Some(genesis_config.hash())); - let deserialized_packets = deserialize_packets(&packet_batch, &packet_indexes); + let deserialized_packets = deserialize_packets(&packet_batch, &packet_indexes, false); unprocessed_packet_batches.insert_batch(deserialized_packets); }); } diff --git a/core/src/banking_stage.rs b/core/src/banking_stage.rs index e3ff83d66f8..ce70048d666 100644 --- a/core/src/banking_stage.rs +++ b/core/src/banking_stage.rs @@ -390,7 +390,8 @@ impl BankingStage { ), }; - let mut packet_receiver = PacketReceiver::new(id, packet_receiver); + let mut packet_receiver = + PacketReceiver::new(id, packet_receiver, bank_forks.clone()); let poh_recorder = poh_recorder.clone(); let committer = Committer::new( diff --git a/core/src/banking_stage/consumer.rs b/core/src/banking_stage/consumer.rs index d4d8051b832..46fc530c4ad 100644 --- a/core/src/banking_stage/consumer.rs +++ b/core/src/banking_stage/consumer.rs @@ -1713,8 +1713,11 @@ mod tests { let recorder = poh_recorder.read().unwrap().new_recorder(); let num_conflicting_transactions = transactions.len(); let deserialized_packets = - unprocessed_packet_batches::transactions_to_deserialized_packets(&transactions) - .unwrap(); + unprocessed_packet_batches::transactions_to_deserialized_packets( + &transactions, + false, + ) + .unwrap(); assert_eq!(deserialized_packets.len(), num_conflicting_transactions); let mut buffered_packet_batches = UnprocessedTransactionStorage::new_transaction_storage( @@ -1793,8 +1796,11 @@ mod tests { let recorder = poh_recorder.read().unwrap().new_recorder(); let num_conflicting_transactions = transactions.len(); let deserialized_packets = - unprocessed_packet_batches::transactions_to_deserialized_packets(&transactions) - .unwrap(); + unprocessed_packet_batches::transactions_to_deserialized_packets( + &transactions, + false, + ) + .unwrap(); assert_eq!(deserialized_packets.len(), num_conflicting_transactions); let mut buffered_packet_batches = UnprocessedTransactionStorage::new_transaction_storage( @@ -1846,8 +1852,11 @@ mod tests { let recorder = poh_recorder.read().unwrap().new_recorder(); let num_conflicting_transactions = transactions.len(); let deserialized_packets = - unprocessed_packet_batches::transactions_to_deserialized_packets(&transactions) - .unwrap(); + unprocessed_packet_batches::transactions_to_deserialized_packets( + &transactions, + false, + ) + .unwrap(); assert_eq!(deserialized_packets.len(), num_conflicting_transactions); let retryable_packet = deserialized_packets[0].clone(); let mut buffered_packet_batches = diff --git a/core/src/banking_stage/forwarder.rs b/core/src/banking_stage/forwarder.rs index f278ad6a427..e56be768752 100644 --- a/core/src/banking_stage/forwarder.rs +++ b/core/src/banking_stage/forwarder.rs @@ -356,7 +356,7 @@ mod tests { Hash::new_unique(), ); let packet = Packet::from_data(None, tx).unwrap(); - let deserialized_packet = DeserializedPacket::new(packet).unwrap(); + let deserialized_packet = DeserializedPacket::new(packet, false).unwrap(); let test_cases = vec![ ("budget-restricted", DataBudget::restricted(), 0), @@ -425,14 +425,14 @@ mod tests { let transaction = system_transaction::transfer(&keypair, &pubkey, 1, fwd_block_hash); let mut packet = Packet::from_data(None, transaction).unwrap(); packet.meta_mut().flags |= PacketFlags::FORWARDED; - DeserializedPacket::new(packet).unwrap() + DeserializedPacket::new(packet, false).unwrap() }; let normal_block_hash = Hash::new_unique(); let normal_packet = { let transaction = system_transaction::transfer(&keypair, &pubkey, 1, normal_block_hash); let packet = Packet::from_data(None, transaction).unwrap(); - DeserializedPacket::new(packet).unwrap() + DeserializedPacket::new(packet, false).unwrap() }; let mut unprocessed_packet_batches = UnprocessedTransactionStorage::new_transaction_storage( diff --git a/core/src/banking_stage/packet_receiver.rs b/core/src/banking_stage/packet_receiver.rs index b8ab06d190b..18c7941afe6 100644 --- a/core/src/banking_stage/packet_receiver.rs +++ b/core/src/banking_stage/packet_receiver.rs @@ -10,20 +10,30 @@ use { }, crossbeam_channel::RecvTimeoutError, solana_measure::{measure::Measure, measure_us}, + solana_runtime::bank_forks::BankForks, solana_sdk::{saturating_add_assign, timing::timestamp}, - std::{sync::atomic::Ordering, time::Duration}, + std::{ + sync::{atomic::Ordering, Arc, RwLock}, + time::Duration, + }, }; pub struct PacketReceiver { id: u32, packet_deserializer: PacketDeserializer, + bank_forks: Arc>, } impl PacketReceiver { - pub fn new(id: u32, banking_packet_receiver: BankingPacketReceiver) -> Self { + pub fn new( + id: u32, + banking_packet_receiver: BankingPacketReceiver, + bank_forks: Arc>, + ) -> Self { Self { id, packet_deserializer: PacketDeserializer::new(banking_packet_receiver), + bank_forks, } } @@ -37,11 +47,17 @@ impl PacketReceiver { ) -> Result<(), RecvTimeoutError> { let (result, recv_time_us) = measure_us!({ let recv_timeout = Self::get_receive_timeout(unprocessed_transaction_storage); + + // get root bank from bank_forks, use it to get feature_set status + let _root_bank = self.bank_forks.read().unwrap().root_bank(); + let support_round_compute_unit_price = false; // TODO get feature from root_bank + let mut recv_and_buffer_measure = Measure::start("recv_and_buffer"); self.packet_deserializer .receive_packets( recv_timeout, unprocessed_transaction_storage.max_receive_size(), + support_round_compute_unit_price, ) // Consumes results if Ok, otherwise we keep the Err .map(|receive_packet_results| { diff --git a/core/src/forward_packet_batches_by_accounts.rs b/core/src/forward_packet_batches_by_accounts.rs index ef0070c752a..29ca8e94683 100644 --- a/core/src/forward_packet_batches_by_accounts.rs +++ b/core/src/forward_packet_batches_by_accounts.rs @@ -163,7 +163,7 @@ mod tests { let tx_cost = CostModel::calculate_cost(&sanitized_transaction, &FeatureSet::all_enabled()); let cost = tx_cost.sum(); let deserialized_packet = - DeserializedPacket::new(Packet::from_data(None, transaction).unwrap()).unwrap(); + DeserializedPacket::new(Packet::from_data(None, transaction).unwrap(), false).unwrap(); // set limit ratio so each batch can only have one test transaction let limit_ratio: u32 = diff --git a/core/src/immutable_deserialized_packet.rs b/core/src/immutable_deserialized_packet.rs index eca2def5ba3..1c0dcc3b187 100644 --- a/core/src/immutable_deserialized_packet.rs +++ b/core/src/immutable_deserialized_packet.rs @@ -46,7 +46,13 @@ pub struct ImmutableDeserializedPacket { } impl ImmutableDeserializedPacket { - pub fn new(packet: Packet) -> Result { + pub fn new( + packet: Packet, + // current working or root bank's feature gate status for supporting rounding + // compute-unit-price. This parameter can be removed once the feature is fully adapted in + // mainnet-beta. + support_round_compute_unit_price: bool, + ) -> Result { let versioned_transaction: VersionedTransaction = packet.deserialize_slice(..)?; let sanitized_transaction = SanitizedVersionedTransaction::try_from(versioned_transaction)?; let message_bytes = packet_message(&packet)?; @@ -55,7 +61,7 @@ impl ImmutableDeserializedPacket { // drop transaction if prioritization fails. let mut priority_details = sanitized_transaction - .get_transaction_priority_details() + .get_transaction_priority_details(support_round_compute_unit_price) .ok_or(DeserializedPacketError::PrioritizationFailure)?; // set priority to zero for vote transactions @@ -160,7 +166,7 @@ mod tests { Hash::new_unique(), ); let packet = Packet::from_data(None, tx).unwrap(); - let deserialized_packet = ImmutableDeserializedPacket::new(packet); + let deserialized_packet = ImmutableDeserializedPacket::new(packet, false); assert!(matches!(deserialized_packet, Ok(_))); } diff --git a/core/src/latest_unprocessed_votes.rs b/core/src/latest_unprocessed_votes.rs index 3805777a6ac..b759bec7fbc 100644 --- a/core/src/latest_unprocessed_votes.rs +++ b/core/src/latest_unprocessed_votes.rs @@ -33,12 +33,19 @@ pub struct LatestValidatorVotePacket { } impl LatestValidatorVotePacket { - pub fn new(packet: Packet, vote_source: VoteSource) -> Result { + pub fn new( + packet: Packet, + vote_source: VoteSource, + support_round_compute_unit_price: bool, + ) -> Result { if !packet.meta().is_simple_vote_tx() { return Err(DeserializedPacketError::VoteTransactionError); } - let vote = Arc::new(ImmutableDeserializedPacket::new(packet)?); + let vote = Arc::new(ImmutableDeserializedPacket::new( + packet, + support_round_compute_unit_price, + )?); Self::new_from_immutable(vote, vote_source) } @@ -351,7 +358,7 @@ mod tests { .meta_mut() .flags .set(PacketFlags::SIMPLE_VOTE_TX, true); - LatestValidatorVotePacket::new(packet, vote_source).unwrap() + LatestValidatorVotePacket::new(packet, vote_source, false).unwrap() } fn deserialize_packets<'a>( @@ -360,7 +367,8 @@ mod tests { vote_source: VoteSource, ) -> impl Iterator + 'a { packet_indexes.iter().filter_map(move |packet_index| { - LatestValidatorVotePacket::new(packet_batch[*packet_index].clone(), vote_source).ok() + LatestValidatorVotePacket::new(packet_batch[*packet_index].clone(), vote_source, false) + .ok() }) } diff --git a/core/src/packet_deserializer.rs b/core/src/packet_deserializer.rs index 1326db5bcf7..46281f5e8a0 100644 --- a/core/src/packet_deserializer.rs +++ b/core/src/packet_deserializer.rs @@ -40,11 +40,13 @@ impl PacketDeserializer { &self, recv_timeout: Duration, capacity: usize, + support_round_compute_unit_price: bool, ) -> Result { let (packet_count, packet_batches) = self.receive_until(recv_timeout, capacity)?; Ok(Self::deserialize_and_collect_packets( packet_count, &packet_batches, + support_round_compute_unit_price, )) } @@ -53,6 +55,7 @@ impl PacketDeserializer { fn deserialize_and_collect_packets( packet_count: usize, banking_batches: &[BankingPacketBatch], + support_round_compute_unit_price: bool, ) -> ReceivePacketResults { let mut passed_sigverify_count: usize = 0; let mut failed_sigverify_count: usize = 0; @@ -66,8 +69,11 @@ impl PacketDeserializer { passed_sigverify_count += packet_indexes.len(); failed_sigverify_count += packet_batch.len().saturating_sub(packet_indexes.len()); - deserialized_packets - .extend(Self::deserialize_packets(packet_batch, &packet_indexes)); + deserialized_packets.extend(Self::deserialize_packets( + packet_batch, + &packet_indexes, + support_round_compute_unit_price, + )); } if let Some(tracer_packet_stats) = &banking_batch.1 { @@ -136,9 +142,14 @@ impl PacketDeserializer { fn deserialize_packets<'a>( packet_batch: &'a PacketBatch, packet_indexes: &'a [usize], + support_round_compute_unit_price: bool, ) -> impl Iterator + 'a { packet_indexes.iter().filter_map(move |packet_index| { - ImmutableDeserializedPacket::new(packet_batch[*packet_index].clone()).ok() + ImmutableDeserializedPacket::new( + packet_batch[*packet_index].clone(), + support_round_compute_unit_price, + ) + .ok() }) } } @@ -160,7 +171,7 @@ mod tests { #[test] fn test_deserialize_and_collect_packets_empty() { - let results = PacketDeserializer::deserialize_and_collect_packets(0, &[]); + let results = PacketDeserializer::deserialize_and_collect_packets(0, &[], false); assert_eq!(results.deserialized_packets.len(), 0); assert!(results.new_tracer_stats_option.is_none()); assert_eq!(results.passed_sigverify_count, 0); @@ -177,6 +188,7 @@ mod tests { let results = PacketDeserializer::deserialize_and_collect_packets( packet_count, &[BankingPacketBatch::new((packet_batches, None))], + false, ); assert_eq!(results.deserialized_packets.len(), 2); assert!(results.new_tracer_stats_option.is_none()); @@ -195,6 +207,7 @@ mod tests { let results = PacketDeserializer::deserialize_and_collect_packets( packet_count, &[BankingPacketBatch::new((packet_batches, None))], + false, ); assert_eq!(results.deserialized_packets.len(), 1); assert!(results.new_tracer_stats_option.is_none()); diff --git a/core/src/unprocessed_packet_batches.rs b/core/src/unprocessed_packet_batches.rs index 2878e599f4e..4d3e5c34629 100644 --- a/core/src/unprocessed_packet_batches.rs +++ b/core/src/unprocessed_packet_batches.rs @@ -26,8 +26,12 @@ impl DeserializedPacket { } } - pub fn new(packet: Packet) -> Result { - let immutable_section = ImmutableDeserializedPacket::new(packet)?; + pub fn new( + packet: Packet, + support_round_compute_unit_price: bool, + ) -> Result { + let immutable_section = + ImmutableDeserializedPacket::new(packet, support_round_compute_unit_price)?; Ok(Self { immutable_section: Arc::new(immutable_section), @@ -293,20 +297,26 @@ impl UnprocessedPacketBatches { pub fn deserialize_packets<'a>( packet_batch: &'a PacketBatch, packet_indexes: &'a [usize], + support_round_compute_unit_price: bool, ) -> impl Iterator + 'a { packet_indexes.iter().filter_map(move |packet_index| { - DeserializedPacket::new(packet_batch[*packet_index].clone()).ok() + DeserializedPacket::new( + packet_batch[*packet_index].clone(), + support_round_compute_unit_price, + ) + .ok() }) } pub fn transactions_to_deserialized_packets( transactions: &[Transaction], + support_round_compute_unit_price: bool, ) -> Result, DeserializedPacketError> { transactions .iter() .map(|transaction| { let packet = Packet::from_data(None, transaction)?; - DeserializedPacket::new(packet) + DeserializedPacket::new(packet, support_round_compute_unit_price) }) .collect() } @@ -335,7 +345,7 @@ mod tests { Hash::new_unique(), ); let packet = Packet::from_data(None, tx).unwrap(); - DeserializedPacket::new(packet).unwrap() + DeserializedPacket::new(packet, false).unwrap() } fn packet_with_priority_details(priority: u64, compute_unit_limit: u64) -> DeserializedPacket { @@ -348,7 +358,7 @@ mod tests { ], Some(&from_account), )); - DeserializedPacket::new(Packet::from_data(None, tx).unwrap()).unwrap() + DeserializedPacket::new(Packet::from_data(None, tx).unwrap(), false).unwrap() } #[test] @@ -464,7 +474,7 @@ mod tests { packet_vector .into_iter() - .map(|p| DeserializedPacket::new(p).unwrap()) + .map(|p| DeserializedPacket::new(p, false).unwrap()) .collect() } diff --git a/core/src/unprocessed_transaction_storage.rs b/core/src/unprocessed_transaction_storage.rs index cf7f3754fe5..51a61a03dd6 100644 --- a/core/src/unprocessed_transaction_storage.rs +++ b/core/src/unprocessed_transaction_storage.rs @@ -1049,7 +1049,7 @@ mod tests { let mut p = Packet::from_data(None, transaction).unwrap(); p.meta_mut().port = packets_id as u16; p.meta_mut().set_tracer(true); - DeserializedPacket::new(p).unwrap() + DeserializedPacket::new(p, false).unwrap() }) .collect_vec(); @@ -1194,9 +1194,9 @@ mod tests { thread_type, ); transaction_storage.insert_batch(vec![ - ImmutableDeserializedPacket::new(small_transfer.clone())?, - ImmutableDeserializedPacket::new(vote.clone())?, - ImmutableDeserializedPacket::new(big_transfer.clone())?, + ImmutableDeserializedPacket::new(small_transfer.clone(), false)?, + ImmutableDeserializedPacket::new(vote.clone(), false)?, + ImmutableDeserializedPacket::new(big_transfer.clone(), false)?, ]); let deserialized_packets = transaction_storage .iter() @@ -1214,9 +1214,9 @@ mod tests { vote_source, ); transaction_storage.insert_batch(vec![ - ImmutableDeserializedPacket::new(small_transfer.clone())?, - ImmutableDeserializedPacket::new(vote.clone())?, - ImmutableDeserializedPacket::new(big_transfer.clone())?, + ImmutableDeserializedPacket::new(small_transfer.clone(), false)?, + ImmutableDeserializedPacket::new(vote.clone(), false)?, + ImmutableDeserializedPacket::new(big_transfer.clone(), false)?, ]); assert_eq!(1, transaction_storage.len()); } @@ -1253,7 +1253,7 @@ mod tests { let mut p = Packet::from_data(None, transaction).unwrap(); p.meta_mut().port = packets_id as u16; p.meta_mut().set_tracer(true); - DeserializedPacket::new(p).unwrap() + DeserializedPacket::new(p, false).unwrap() }) .collect_vec(); diff --git a/runtime/src/prioritization_fee_cache.rs b/runtime/src/prioritization_fee_cache.rs index 2541d80bf37..8dbd2bc521c 100644 --- a/runtime/src/prioritization_fee_cache.rs +++ b/runtime/src/prioritization_fee_cache.rs @@ -212,7 +212,9 @@ impl PrioritizationFeeCache { continue; } - let priority_details = sanitized_transaction.get_transaction_priority_details(); + let support_round_compute_unit_price = false; // TODO read feature status from `bank` + let priority_details = sanitized_transaction + .get_transaction_priority_details(support_round_compute_unit_price); let account_locks = sanitized_transaction .get_account_locks(bank.get_transaction_account_lock_limit()); diff --git a/runtime/src/transaction_priority_details.rs b/runtime/src/transaction_priority_details.rs index b7f916c9b8f..aff5a884314 100644 --- a/runtime/src/transaction_priority_details.rs +++ b/runtime/src/transaction_priority_details.rs @@ -14,10 +14,14 @@ pub struct TransactionPriorityDetails { } pub trait GetTransactionPriorityDetails { - fn get_transaction_priority_details(&self) -> Option; + fn get_transaction_priority_details( + &self, + support_round_compute_unit_price: bool, + ) -> Option; fn process_compute_budget_instruction<'a>( instructions: impl Iterator, + _support_round_compute_unit_price: bool, // a feature gate status will be used by compute_budget. ) -> Option { let mut compute_budget = ComputeBudget::default(); let prioritization_fee_details = compute_budget @@ -37,14 +41,26 @@ pub trait GetTransactionPriorityDetails { } impl GetTransactionPriorityDetails for SanitizedVersionedTransaction { - fn get_transaction_priority_details(&self) -> Option { - Self::process_compute_budget_instruction(self.get_message().program_instructions_iter()) + fn get_transaction_priority_details( + &self, + support_round_compute_unit_price: bool, + ) -> Option { + Self::process_compute_budget_instruction( + self.get_message().program_instructions_iter(), + support_round_compute_unit_price, + ) } } impl GetTransactionPriorityDetails for SanitizedTransaction { - fn get_transaction_priority_details(&self) -> Option { - Self::process_compute_budget_instruction(self.message().program_instructions_iter()) + fn get_transaction_priority_details( + &self, + support_round_compute_unit_price: bool, + ) -> Option { + Self::process_compute_budget_instruction( + self.message().program_instructions_iter(), + support_round_compute_unit_price, + ) } } @@ -78,7 +94,7 @@ mod tests { let sanitized_versioned_transaction = SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap(); assert_eq!( - sanitized_versioned_transaction.get_transaction_priority_details(), + sanitized_versioned_transaction.get_transaction_priority_details(false), Some(TransactionPriorityDetails { priority: 0, compute_unit_limit: @@ -91,7 +107,7 @@ mod tests { let sanitized_transaction = SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap(); assert_eq!( - sanitized_transaction.get_transaction_priority_details(), + sanitized_transaction.get_transaction_priority_details(false), Some(TransactionPriorityDetails { priority: 0, compute_unit_limit: @@ -118,7 +134,7 @@ mod tests { let sanitized_versioned_transaction = SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap(); assert_eq!( - sanitized_versioned_transaction.get_transaction_priority_details(), + sanitized_versioned_transaction.get_transaction_priority_details(false), Some(TransactionPriorityDetails { priority: 0, compute_unit_limit: requested_cu as u64, @@ -129,7 +145,7 @@ mod tests { let sanitized_transaction = SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap(); assert_eq!( - sanitized_transaction.get_transaction_priority_details(), + sanitized_transaction.get_transaction_priority_details(false), Some(TransactionPriorityDetails { priority: 0, compute_unit_limit: requested_cu as u64, @@ -154,7 +170,7 @@ mod tests { let sanitized_versioned_transaction = SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap(); assert_eq!( - sanitized_versioned_transaction.get_transaction_priority_details(), + sanitized_versioned_transaction.get_transaction_priority_details(false), Some(TransactionPriorityDetails { priority: requested_price, compute_unit_limit: @@ -167,7 +183,7 @@ mod tests { let sanitized_transaction = SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap(); assert_eq!( - sanitized_transaction.get_transaction_priority_details(), + sanitized_transaction.get_transaction_priority_details(false), Some(TransactionPriorityDetails { priority: requested_price, compute_unit_limit: