Refactor pass feature status to deserialized packet via packet meta (#31549)
Add a flag to packet, set its value by packet_deserializer when received by banking_stage with working_bank
This commit is contained in:
parent
4d4dddcaea
commit
49f44f5ded
|
@ -399,7 +399,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 poh_recorder = poh_recorder.clone();
|
||||||
|
|
||||||
let committer = Committer::new(
|
let committer = Committer::new(
|
||||||
|
|
|
@ -10,8 +10,12 @@ use {
|
||||||
},
|
},
|
||||||
crossbeam_channel::RecvTimeoutError,
|
crossbeam_channel::RecvTimeoutError,
|
||||||
solana_measure::{measure::Measure, measure_us},
|
solana_measure::{measure::Measure, measure_us},
|
||||||
|
solana_runtime::bank_forks::BankForks,
|
||||||
solana_sdk::{saturating_add_assign, timing::timestamp},
|
solana_sdk::{saturating_add_assign, timing::timestamp},
|
||||||
std::{sync::atomic::Ordering, time::Duration},
|
std::{
|
||||||
|
sync::{atomic::Ordering, Arc, RwLock},
|
||||||
|
time::Duration,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct PacketReceiver {
|
pub struct PacketReceiver {
|
||||||
|
@ -20,10 +24,14 @@ pub struct PacketReceiver {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PacketReceiver {
|
impl PacketReceiver {
|
||||||
pub fn new(id: u32, banking_packet_receiver: BankingPacketReceiver) -> Self {
|
pub fn new(
|
||||||
|
id: u32,
|
||||||
|
banking_packet_receiver: BankingPacketReceiver,
|
||||||
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
packet_deserializer: PacketDeserializer::new(banking_packet_receiver),
|
packet_deserializer: PacketDeserializer::new(banking_packet_receiver, bank_forks),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl ImmutableDeserializedPacket {
|
||||||
|
|
||||||
// drop transaction if prioritization fails.
|
// drop transaction if prioritization fails.
|
||||||
let mut priority_details = sanitized_transaction
|
let mut priority_details = sanitized_transaction
|
||||||
.get_transaction_priority_details()
|
.get_transaction_priority_details(packet.meta().round_compute_unit_price())
|
||||||
.ok_or(DeserializedPacketError::PrioritizationFailure)?;
|
.ok_or(DeserializedPacketError::PrioritizationFailure)?;
|
||||||
|
|
||||||
// set priority to zero for vote transactions
|
// set priority to zero for vote transactions
|
||||||
|
|
|
@ -8,7 +8,11 @@ use {
|
||||||
},
|
},
|
||||||
crossbeam_channel::RecvTimeoutError,
|
crossbeam_channel::RecvTimeoutError,
|
||||||
solana_perf::packet::PacketBatch,
|
solana_perf::packet::PacketBatch,
|
||||||
std::time::{Duration, Instant},
|
solana_runtime::bank_forks::BankForks,
|
||||||
|
std::{
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
time::{Duration, Instant},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Results from deserializing packet batches.
|
/// Results from deserializing packet batches.
|
||||||
|
@ -26,12 +30,18 @@ pub struct ReceivePacketResults {
|
||||||
pub struct PacketDeserializer {
|
pub struct PacketDeserializer {
|
||||||
/// Receiver for packet batches from sigverify stage
|
/// Receiver for packet batches from sigverify stage
|
||||||
packet_batch_receiver: BankingPacketReceiver,
|
packet_batch_receiver: BankingPacketReceiver,
|
||||||
|
/// Provides root bank for deserializer to check feature activation
|
||||||
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PacketDeserializer {
|
impl PacketDeserializer {
|
||||||
pub fn new(packet_batch_receiver: BankingPacketReceiver) -> Self {
|
pub fn new(
|
||||||
|
packet_batch_receiver: BankingPacketReceiver,
|
||||||
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
packet_batch_receiver,
|
packet_batch_receiver,
|
||||||
|
bank_forks,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,9 +52,16 @@ impl PacketDeserializer {
|
||||||
capacity: usize,
|
capacity: usize,
|
||||||
) -> Result<ReceivePacketResults, RecvTimeoutError> {
|
) -> Result<ReceivePacketResults, RecvTimeoutError> {
|
||||||
let (packet_count, packet_batches) = self.receive_until(recv_timeout, capacity)?;
|
let (packet_count, packet_batches) = self.receive_until(recv_timeout, capacity)?;
|
||||||
|
|
||||||
|
// Note: this can be removed after feature `round_compute_unit_price` is activated in
|
||||||
|
// mainnet-beta
|
||||||
|
let _working_bank = self.bank_forks.read().unwrap().working_bank();
|
||||||
|
let round_compute_unit_price_enabled = false; // TODO get from working_bank.feature_set
|
||||||
|
|
||||||
Ok(Self::deserialize_and_collect_packets(
|
Ok(Self::deserialize_and_collect_packets(
|
||||||
packet_count,
|
packet_count,
|
||||||
&packet_batches,
|
&packet_batches,
|
||||||
|
round_compute_unit_price_enabled,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +70,7 @@ impl PacketDeserializer {
|
||||||
fn deserialize_and_collect_packets(
|
fn deserialize_and_collect_packets(
|
||||||
packet_count: usize,
|
packet_count: usize,
|
||||||
banking_batches: &[BankingPacketBatch],
|
banking_batches: &[BankingPacketBatch],
|
||||||
|
round_compute_unit_price_enabled: bool,
|
||||||
) -> ReceivePacketResults {
|
) -> ReceivePacketResults {
|
||||||
let mut passed_sigverify_count: usize = 0;
|
let mut passed_sigverify_count: usize = 0;
|
||||||
let mut failed_sigverify_count: usize = 0;
|
let mut failed_sigverify_count: usize = 0;
|
||||||
|
@ -66,8 +84,11 @@ impl PacketDeserializer {
|
||||||
passed_sigverify_count += packet_indexes.len();
|
passed_sigverify_count += packet_indexes.len();
|
||||||
failed_sigverify_count += packet_batch.len().saturating_sub(packet_indexes.len());
|
failed_sigverify_count += packet_batch.len().saturating_sub(packet_indexes.len());
|
||||||
|
|
||||||
deserialized_packets
|
deserialized_packets.extend(Self::deserialize_packets(
|
||||||
.extend(Self::deserialize_packets(packet_batch, &packet_indexes));
|
packet_batch,
|
||||||
|
&packet_indexes,
|
||||||
|
round_compute_unit_price_enabled,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tracer_packet_stats) = &banking_batch.1 {
|
if let Some(tracer_packet_stats) = &banking_batch.1 {
|
||||||
|
@ -136,9 +157,14 @@ impl PacketDeserializer {
|
||||||
fn deserialize_packets<'a>(
|
fn deserialize_packets<'a>(
|
||||||
packet_batch: &'a PacketBatch,
|
packet_batch: &'a PacketBatch,
|
||||||
packet_indexes: &'a [usize],
|
packet_indexes: &'a [usize],
|
||||||
|
round_compute_unit_price_enabled: bool,
|
||||||
) -> impl Iterator<Item = ImmutableDeserializedPacket> + 'a {
|
) -> impl Iterator<Item = ImmutableDeserializedPacket> + 'a {
|
||||||
packet_indexes.iter().filter_map(move |packet_index| {
|
packet_indexes.iter().filter_map(move |packet_index| {
|
||||||
ImmutableDeserializedPacket::new(packet_batch[*packet_index].clone()).ok()
|
let mut packet_clone = packet_batch[*packet_index].clone();
|
||||||
|
packet_clone
|
||||||
|
.meta_mut()
|
||||||
|
.set_round_compute_unit_price(round_compute_unit_price_enabled);
|
||||||
|
ImmutableDeserializedPacket::new(packet_clone).ok()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +186,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize_and_collect_packets_empty() {
|
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_eq!(results.deserialized_packets.len(), 0);
|
||||||
assert!(results.new_tracer_stats_option.is_none());
|
assert!(results.new_tracer_stats_option.is_none());
|
||||||
assert_eq!(results.passed_sigverify_count, 0);
|
assert_eq!(results.passed_sigverify_count, 0);
|
||||||
|
@ -177,6 +203,7 @@ mod tests {
|
||||||
let results = PacketDeserializer::deserialize_and_collect_packets(
|
let results = PacketDeserializer::deserialize_and_collect_packets(
|
||||||
packet_count,
|
packet_count,
|
||||||
&[BankingPacketBatch::new((packet_batches, None))],
|
&[BankingPacketBatch::new((packet_batches, None))],
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
assert_eq!(results.deserialized_packets.len(), 2);
|
assert_eq!(results.deserialized_packets.len(), 2);
|
||||||
assert!(results.new_tracer_stats_option.is_none());
|
assert!(results.new_tracer_stats_option.is_none());
|
||||||
|
@ -195,6 +222,7 @@ mod tests {
|
||||||
let results = PacketDeserializer::deserialize_and_collect_packets(
|
let results = PacketDeserializer::deserialize_and_collect_packets(
|
||||||
packet_count,
|
packet_count,
|
||||||
&[BankingPacketBatch::new((packet_batches, None))],
|
&[BankingPacketBatch::new((packet_batches, None))],
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
assert_eq!(results.deserialized_packets.len(), 1);
|
assert_eq!(results.deserialized_packets.len(), 1);
|
||||||
assert!(results.new_tracer_stats_option.is_none());
|
assert!(results.new_tracer_stats_option.is_none());
|
||||||
|
|
|
@ -212,7 +212,9 @@ impl PrioritizationFeeCache {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let priority_details = sanitized_transaction.get_transaction_priority_details();
|
let round_compute_unit_price_enabled = false; // TODO: bank.feture_set.is_active(round_compute_unit_price)
|
||||||
|
let priority_details = sanitized_transaction
|
||||||
|
.get_transaction_priority_details(round_compute_unit_price_enabled);
|
||||||
let account_locks = sanitized_transaction
|
let account_locks = sanitized_transaction
|
||||||
.get_account_locks(bank.get_transaction_account_lock_limit());
|
.get_account_locks(bank.get_transaction_account_lock_limit());
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,14 @@ pub struct TransactionPriorityDetails {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GetTransactionPriorityDetails {
|
pub trait GetTransactionPriorityDetails {
|
||||||
fn get_transaction_priority_details(&self) -> Option<TransactionPriorityDetails>;
|
fn get_transaction_priority_details(
|
||||||
|
&self,
|
||||||
|
round_compute_unit_price_enabled: bool,
|
||||||
|
) -> Option<TransactionPriorityDetails>;
|
||||||
|
|
||||||
fn process_compute_budget_instruction<'a>(
|
fn process_compute_budget_instruction<'a>(
|
||||||
instructions: impl Iterator<Item = (&'a Pubkey, &'a CompiledInstruction)>,
|
instructions: impl Iterator<Item = (&'a Pubkey, &'a CompiledInstruction)>,
|
||||||
|
_round_compute_unit_price_enabled: bool,
|
||||||
) -> Option<TransactionPriorityDetails> {
|
) -> Option<TransactionPriorityDetails> {
|
||||||
let mut compute_budget = ComputeBudget::default();
|
let mut compute_budget = ComputeBudget::default();
|
||||||
let prioritization_fee_details = compute_budget
|
let prioritization_fee_details = compute_budget
|
||||||
|
@ -27,6 +31,7 @@ pub trait GetTransactionPriorityDetails {
|
||||||
false, // stop supporting prioritization by request_units_deprecated instruction
|
false, // stop supporting prioritization by request_units_deprecated instruction
|
||||||
true, // enable request heap frame instruction
|
true, // enable request heap frame instruction
|
||||||
true, // enable support set accounts data size instruction
|
true, // enable support set accounts data size instruction
|
||||||
|
// TODO: round_compute_unit_price_enabled: bool
|
||||||
)
|
)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
Some(TransactionPriorityDetails {
|
Some(TransactionPriorityDetails {
|
||||||
|
@ -37,14 +42,26 @@ pub trait GetTransactionPriorityDetails {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetTransactionPriorityDetails for SanitizedVersionedTransaction {
|
impl GetTransactionPriorityDetails for SanitizedVersionedTransaction {
|
||||||
fn get_transaction_priority_details(&self) -> Option<TransactionPriorityDetails> {
|
fn get_transaction_priority_details(
|
||||||
Self::process_compute_budget_instruction(self.get_message().program_instructions_iter())
|
&self,
|
||||||
|
round_compute_unit_price_enabled: bool,
|
||||||
|
) -> Option<TransactionPriorityDetails> {
|
||||||
|
Self::process_compute_budget_instruction(
|
||||||
|
self.get_message().program_instructions_iter(),
|
||||||
|
round_compute_unit_price_enabled,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetTransactionPriorityDetails for SanitizedTransaction {
|
impl GetTransactionPriorityDetails for SanitizedTransaction {
|
||||||
fn get_transaction_priority_details(&self) -> Option<TransactionPriorityDetails> {
|
fn get_transaction_priority_details(
|
||||||
Self::process_compute_budget_instruction(self.message().program_instructions_iter())
|
&self,
|
||||||
|
round_compute_unit_price_enabled: bool,
|
||||||
|
) -> Option<TransactionPriorityDetails> {
|
||||||
|
Self::process_compute_budget_instruction(
|
||||||
|
self.message().program_instructions_iter(),
|
||||||
|
round_compute_unit_price_enabled,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +95,7 @@ mod tests {
|
||||||
let sanitized_versioned_transaction =
|
let sanitized_versioned_transaction =
|
||||||
SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap();
|
SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
sanitized_versioned_transaction.get_transaction_priority_details(),
|
sanitized_versioned_transaction.get_transaction_priority_details(false),
|
||||||
Some(TransactionPriorityDetails {
|
Some(TransactionPriorityDetails {
|
||||||
priority: 0,
|
priority: 0,
|
||||||
compute_unit_limit:
|
compute_unit_limit:
|
||||||
|
@ -91,7 +108,7 @@ mod tests {
|
||||||
let sanitized_transaction =
|
let sanitized_transaction =
|
||||||
SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap();
|
SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
sanitized_transaction.get_transaction_priority_details(),
|
sanitized_transaction.get_transaction_priority_details(false),
|
||||||
Some(TransactionPriorityDetails {
|
Some(TransactionPriorityDetails {
|
||||||
priority: 0,
|
priority: 0,
|
||||||
compute_unit_limit:
|
compute_unit_limit:
|
||||||
|
@ -118,7 +135,7 @@ mod tests {
|
||||||
let sanitized_versioned_transaction =
|
let sanitized_versioned_transaction =
|
||||||
SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap();
|
SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
sanitized_versioned_transaction.get_transaction_priority_details(),
|
sanitized_versioned_transaction.get_transaction_priority_details(false),
|
||||||
Some(TransactionPriorityDetails {
|
Some(TransactionPriorityDetails {
|
||||||
priority: 0,
|
priority: 0,
|
||||||
compute_unit_limit: requested_cu as u64,
|
compute_unit_limit: requested_cu as u64,
|
||||||
|
@ -129,7 +146,7 @@ mod tests {
|
||||||
let sanitized_transaction =
|
let sanitized_transaction =
|
||||||
SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap();
|
SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
sanitized_transaction.get_transaction_priority_details(),
|
sanitized_transaction.get_transaction_priority_details(false),
|
||||||
Some(TransactionPriorityDetails {
|
Some(TransactionPriorityDetails {
|
||||||
priority: 0,
|
priority: 0,
|
||||||
compute_unit_limit: requested_cu as u64,
|
compute_unit_limit: requested_cu as u64,
|
||||||
|
@ -154,7 +171,7 @@ mod tests {
|
||||||
let sanitized_versioned_transaction =
|
let sanitized_versioned_transaction =
|
||||||
SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap();
|
SanitizedVersionedTransaction::try_new(versioned_transaction).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
sanitized_versioned_transaction.get_transaction_priority_details(),
|
sanitized_versioned_transaction.get_transaction_priority_details(false),
|
||||||
Some(TransactionPriorityDetails {
|
Some(TransactionPriorityDetails {
|
||||||
priority: requested_price,
|
priority: requested_price,
|
||||||
compute_unit_limit:
|
compute_unit_limit:
|
||||||
|
@ -167,7 +184,7 @@ mod tests {
|
||||||
let sanitized_transaction =
|
let sanitized_transaction =
|
||||||
SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap();
|
SanitizedTransaction::try_from_legacy_transaction(transaction).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
sanitized_transaction.get_transaction_priority_details(),
|
sanitized_transaction.get_transaction_priority_details(false),
|
||||||
Some(TransactionPriorityDetails {
|
Some(TransactionPriorityDetails {
|
||||||
priority: requested_price,
|
priority: requested_price,
|
||||||
compute_unit_limit:
|
compute_unit_limit:
|
||||||
|
|
|
@ -29,6 +29,10 @@ bitflags! {
|
||||||
const REPAIR = 0b0000_0100;
|
const REPAIR = 0b0000_0100;
|
||||||
const SIMPLE_VOTE_TX = 0b0000_1000;
|
const SIMPLE_VOTE_TX = 0b0000_1000;
|
||||||
const TRACER_PACKET = 0b0001_0000;
|
const TRACER_PACKET = 0b0001_0000;
|
||||||
|
/// to be set by bank.feature_set.is_active(round_compute_unit_price::id()) at the moment
|
||||||
|
/// the packet is built.
|
||||||
|
/// This field can be removed when the above feature gate is adopted by mainnet-beta.
|
||||||
|
const ROUND_COMPUTE_UNIT_PRICE = 0b0010_0000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +218,14 @@ impl Meta {
|
||||||
self.flags.set(PacketFlags::SIMPLE_VOTE_TX, is_simple_vote);
|
self.flags.set(PacketFlags::SIMPLE_VOTE_TX, is_simple_vote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_round_compute_unit_price(&mut self, round_compute_unit_price: bool) {
|
||||||
|
self.flags.set(
|
||||||
|
PacketFlags::ROUND_COMPUTE_UNIT_PRICE,
|
||||||
|
round_compute_unit_price,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn forwarded(&self) -> bool {
|
pub fn forwarded(&self) -> bool {
|
||||||
self.flags.contains(PacketFlags::FORWARDED)
|
self.flags.contains(PacketFlags::FORWARDED)
|
||||||
|
@ -233,6 +245,11 @@ impl Meta {
|
||||||
pub fn is_tracer_packet(&self) -> bool {
|
pub fn is_tracer_packet(&self) -> bool {
|
||||||
self.flags.contains(PacketFlags::TRACER_PACKET)
|
self.flags.contains(PacketFlags::TRACER_PACKET)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn round_compute_unit_price(&self) -> bool {
|
||||||
|
self.flags.contains(PacketFlags::ROUND_COMPUTE_UNIT_PRICE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Meta {
|
impl Default for Meta {
|
||||||
|
|
Loading…
Reference in New Issue