adds bitflags to Packet.Meta
Instead of a separate bool type for each flag, all the flags can be encoded in a type-safe bitflags encoded in a single u8: https://github.com/solana-labs/solana/blob/d6ec103be/sdk/src/packet.rs#L19-L31
This commit is contained in:
parent
73a7741c49
commit
01a096adc8
|
@ -5641,6 +5641,7 @@ dependencies = [
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"base64 0.13.0",
|
"base64 0.13.0",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
"bitflags",
|
||||||
"borsh",
|
"borsh",
|
||||||
"bs58 0.4.0",
|
"bs58 0.4.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
|
@ -54,7 +54,7 @@ fn bench_packet_discard(bencher: &mut Bencher) {
|
||||||
SigVerifyStage::discard_excess_packets(&mut batches, 10_000);
|
SigVerifyStage::discard_excess_packets(&mut batches, 10_000);
|
||||||
for batch in batches.iter_mut() {
|
for batch in batches.iter_mut() {
|
||||||
for p in batch.packets.iter_mut() {
|
for p in batch.packets.iter_mut() {
|
||||||
p.meta.discard = false;
|
p.meta.set_discard(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -406,7 +406,7 @@ impl BankingStage {
|
||||||
let packet_vec: Vec<_> = packets
|
let packet_vec: Vec<_> = packets
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
if !p.meta.forwarded && data_budget.take(p.meta.size) {
|
if !p.meta.forwarded() && data_budget.take(p.meta.size) {
|
||||||
Some((&p.data[..p.meta.size], tpu_forwards))
|
Some((&p.data[..p.meta.size], tpu_forwards))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1125,7 +1125,7 @@ impl BankingStage {
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|tx_index| {
|
.filter_map(|tx_index| {
|
||||||
let p = &packet_batch.packets[*tx_index];
|
let p = &packet_batch.packets[*tx_index];
|
||||||
if votes_only && !p.meta.is_simple_vote_tx {
|
if votes_only && !p.meta.is_simple_vote_tx() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1135,7 +1135,7 @@ impl BankingStage {
|
||||||
let tx = SanitizedTransaction::try_create(
|
let tx = SanitizedTransaction::try_create(
|
||||||
tx,
|
tx,
|
||||||
message_hash,
|
message_hash,
|
||||||
Some(p.meta.is_simple_vote_tx),
|
Some(p.meta.is_simple_vote_tx()),
|
||||||
|_| Err(TransactionError::UnsupportedVersion),
|
|_| Err(TransactionError::UnsupportedVersion),
|
||||||
)
|
)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
@ -1306,15 +1306,8 @@ impl BankingStage {
|
||||||
fn generate_packet_indexes(vers: &PinnedVec<Packet>) -> Vec<usize> {
|
fn generate_packet_indexes(vers: &PinnedVec<Packet>) -> Vec<usize> {
|
||||||
vers.iter()
|
vers.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(
|
.filter(|(_, pkt)| !pkt.meta.discard())
|
||||||
|(index, ver)| {
|
.map(|(index, _)| index)
|
||||||
if !ver.meta.discard {
|
|
||||||
Some(index)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1492,7 +1485,7 @@ mod tests {
|
||||||
get_tmp_ledger_path,
|
get_tmp_ledger_path,
|
||||||
leader_schedule_cache::LeaderScheduleCache,
|
leader_schedule_cache::LeaderScheduleCache,
|
||||||
},
|
},
|
||||||
solana_perf::packet::to_packet_batches,
|
solana_perf::packet::{to_packet_batches, PacketFlags},
|
||||||
solana_poh::{
|
solana_poh::{
|
||||||
poh_recorder::{create_test_recorder, Record, WorkingBankEntry},
|
poh_recorder::{create_test_recorder, Record, WorkingBankEntry},
|
||||||
poh_service::PohService,
|
poh_service::PohService,
|
||||||
|
@ -1638,7 +1631,7 @@ mod tests {
|
||||||
b.packets
|
b.packets
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(v)
|
.zip(v)
|
||||||
.for_each(|(p, f)| p.meta.discard = *f == 0)
|
.for_each(|(p, f)| p.meta.set_discard(*f == 0))
|
||||||
});
|
});
|
||||||
with_vers.into_iter().map(|(b, _)| b).collect()
|
with_vers.into_iter().map(|(b, _)| b).collect()
|
||||||
}
|
}
|
||||||
|
@ -2843,7 +2836,7 @@ mod tests {
|
||||||
const FWD_PACKET: u8 = 1;
|
const FWD_PACKET: u8 = 1;
|
||||||
let forwarded_packet = {
|
let forwarded_packet = {
|
||||||
let mut packet = Packet::from_data(None, &[FWD_PACKET]).unwrap();
|
let mut packet = Packet::from_data(None, &[FWD_PACKET]).unwrap();
|
||||||
packet.meta.forwarded = true;
|
packet.meta.flags |= PacketFlags::FORWARDED;
|
||||||
packet
|
packet
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3084,7 +3077,7 @@ mod tests {
|
||||||
packet_indexes.push(index);
|
packet_indexes.push(index);
|
||||||
}
|
}
|
||||||
for index in vote_indexes.iter() {
|
for index in vote_indexes.iter() {
|
||||||
packet_batch.packets[*index].meta.is_simple_vote_tx = true;
|
packet_batch.packets[*index].meta.flags |= PacketFlags::SIMPLE_VOTE_TX;
|
||||||
}
|
}
|
||||||
(packet_batch, packet_indexes)
|
(packet_batch, packet_indexes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -308,7 +308,7 @@ impl ClusterInfoVoteListener {
|
||||||
.filter(|(_, packet_batch)| {
|
.filter(|(_, packet_batch)| {
|
||||||
// to_packet_batches() above splits into 1 packet long batches
|
// to_packet_batches() above splits into 1 packet long batches
|
||||||
assert_eq!(packet_batch.packets.len(), 1);
|
assert_eq!(packet_batch.packets.len(), 1);
|
||||||
!packet_batch.packets[0].meta.discard
|
!packet_batch.packets[0].meta.discard()
|
||||||
})
|
})
|
||||||
.filter_map(|(tx, packet_batch)| {
|
.filter_map(|(tx, packet_batch)| {
|
||||||
let (vote_account_key, vote, _) = vote_transaction::parse_vote_transaction(&tx)?;
|
let (vote_account_key, vote, _) = vote_transaction::parse_vote_transaction(&tx)?;
|
||||||
|
|
|
@ -8,7 +8,10 @@ use {
|
||||||
solana_metrics::{inc_new_counter_debug, inc_new_counter_info},
|
solana_metrics::{inc_new_counter_debug, inc_new_counter_info},
|
||||||
solana_perf::{packet::PacketBatchRecycler, recycler::Recycler},
|
solana_perf::{packet::PacketBatchRecycler, recycler::Recycler},
|
||||||
solana_poh::poh_recorder::PohRecorder,
|
solana_poh::poh_recorder::PohRecorder,
|
||||||
solana_sdk::{clock::DEFAULT_TICKS_PER_SLOT, packet::Packet},
|
solana_sdk::{
|
||||||
|
clock::DEFAULT_TICKS_PER_SLOT,
|
||||||
|
packet::{Packet, PacketFlags},
|
||||||
|
},
|
||||||
solana_streamer::streamer::{self, PacketBatchReceiver, PacketBatchSender},
|
solana_streamer::streamer::{self, PacketBatchReceiver, PacketBatchSender},
|
||||||
std::{
|
std::{
|
||||||
net::UdpSocket,
|
net::UdpSocket,
|
||||||
|
@ -84,7 +87,7 @@ impl FetchStage {
|
||||||
poh_recorder: &Arc<Mutex<PohRecorder>>,
|
poh_recorder: &Arc<Mutex<PohRecorder>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mark_forwarded = |packet: &mut Packet| {
|
let mark_forwarded = |packet: &mut Packet| {
|
||||||
packet.meta.forwarded = true;
|
packet.meta.flags |= PacketFlags::FORWARDED;
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut packet_batch = recvr.recv()?;
|
let mut packet_batch = recvr.recv()?;
|
||||||
|
|
|
@ -56,7 +56,10 @@ mod test {
|
||||||
shred::{Shred, Shredder},
|
shred::{Shred, Shredder},
|
||||||
sigverify_shreds::verify_shred_cpu,
|
sigverify_shreds::verify_shred_cpu,
|
||||||
},
|
},
|
||||||
solana_sdk::signature::{Keypair, Signer},
|
solana_sdk::{
|
||||||
|
packet::PacketFlags,
|
||||||
|
signature::{Keypair, Signer},
|
||||||
|
},
|
||||||
std::{
|
std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
net::{IpAddr, Ipv4Addr},
|
net::{IpAddr, Ipv4Addr},
|
||||||
|
@ -87,7 +90,7 @@ mod test {
|
||||||
nonce,
|
nonce,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
packet.meta.repair = true;
|
packet.meta.flags |= PacketFlags::REPAIR;
|
||||||
|
|
||||||
let leader_slots = [(slot, keypair.pubkey().to_bytes())]
|
let leader_slots = [(slot, keypair.pubkey().to_bytes())]
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -615,7 +615,7 @@ mod tests {
|
||||||
let mut packet_batch = PacketBatch::new(vec![]);
|
let mut packet_batch = PacketBatch::new(vec![]);
|
||||||
solana_streamer::packet::recv_from(&mut packet_batch, &me_retransmit, 1).unwrap();
|
solana_streamer::packet::recv_from(&mut packet_batch, &me_retransmit, 1).unwrap();
|
||||||
assert_eq!(packet_batch.packets.len(), 1);
|
assert_eq!(packet_batch.packets.len(), 1);
|
||||||
assert!(!packet_batch.packets[0].meta.repair);
|
assert!(!packet_batch.packets[0].meta.repair());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -6,7 +6,7 @@ use {
|
||||||
solana_ledger::shred::{get_shred_slot_index_type, ShredFetchStats},
|
solana_ledger::shred::{get_shred_slot_index_type, ShredFetchStats},
|
||||||
solana_perf::{
|
solana_perf::{
|
||||||
cuda_runtime::PinnedVec,
|
cuda_runtime::PinnedVec,
|
||||||
packet::{Packet, PacketBatchRecycler},
|
packet::{Packet, PacketBatchRecycler, PacketFlags},
|
||||||
recycler::Recycler,
|
recycler::Recycler,
|
||||||
},
|
},
|
||||||
solana_runtime::bank_forks::BankForks,
|
solana_runtime::bank_forks::BankForks,
|
||||||
|
@ -40,7 +40,7 @@ impl ShredFetchStage {
|
||||||
) where
|
) where
|
||||||
F: Fn(&mut Packet),
|
F: Fn(&mut Packet),
|
||||||
{
|
{
|
||||||
p.meta.discard = true;
|
p.meta.set_discard(true);
|
||||||
if let Some((slot, _index, _shred_type)) = get_shred_slot_index_type(p, stats) {
|
if let Some((slot, _index, _shred_type)) = get_shred_slot_index_type(p, stats) {
|
||||||
// Seems reasonable to limit shreds to 2 epochs away
|
// Seems reasonable to limit shreds to 2 epochs away
|
||||||
if slot > last_root && slot < (last_slot + 2 * slots_per_epoch) {
|
if slot > last_root && slot < (last_slot + 2 * slots_per_epoch) {
|
||||||
|
@ -50,7 +50,7 @@ impl ShredFetchStage {
|
||||||
|
|
||||||
if shreds_received.get(&hash).is_none() {
|
if shreds_received.get(&hash).is_none() {
|
||||||
shreds_received.put(hash, ());
|
shreds_received.put(hash, ());
|
||||||
p.meta.discard = false;
|
p.meta.set_discard(false);
|
||||||
modify(p);
|
modify(p);
|
||||||
} else {
|
} else {
|
||||||
stats.duplicate_shred += 1;
|
stats.duplicate_shred += 1;
|
||||||
|
@ -192,7 +192,7 @@ impl ShredFetchStage {
|
||||||
recycler.clone(),
|
recycler.clone(),
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
"shred_fetch_tvu_forwards",
|
"shred_fetch_tvu_forwards",
|
||||||
|p| p.meta.forwarded = true,
|
|p| p.meta.flags.insert(PacketFlags::FORWARDED),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (repair_receiver, repair_handler) = Self::packet_modifier(
|
let (repair_receiver, repair_handler) = Self::packet_modifier(
|
||||||
|
@ -202,7 +202,7 @@ impl ShredFetchStage {
|
||||||
recycler,
|
recycler,
|
||||||
bank_forks,
|
bank_forks,
|
||||||
"shred_fetch_repair",
|
"shred_fetch_repair",
|
||||||
|p| p.meta.repair = true,
|
|p| p.meta.flags.insert(PacketFlags::REPAIR),
|
||||||
);
|
);
|
||||||
|
|
||||||
tvu_threads.extend(tvu_forwards_threads.into_iter());
|
tvu_threads.extend(tvu_forwards_threads.into_iter());
|
||||||
|
@ -266,7 +266,7 @@ mod tests {
|
||||||
&|_p| {},
|
&|_p| {},
|
||||||
&hasher,
|
&hasher,
|
||||||
);
|
);
|
||||||
assert!(!packet.meta.discard);
|
assert!(!packet.meta.discard());
|
||||||
let coding = solana_ledger::shred::Shredder::generate_coding_shreds(
|
let coding = solana_ledger::shred::Shredder::generate_coding_shreds(
|
||||||
&[shred],
|
&[shred],
|
||||||
false, // is_last_in_slot
|
false, // is_last_in_slot
|
||||||
|
@ -283,7 +283,7 @@ mod tests {
|
||||||
&|_p| {},
|
&|_p| {},
|
||||||
&hasher,
|
&hasher,
|
||||||
);
|
);
|
||||||
assert!(!packet.meta.discard);
|
assert!(!packet.meta.discard());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -310,7 +310,7 @@ mod tests {
|
||||||
&hasher,
|
&hasher,
|
||||||
);
|
);
|
||||||
assert_eq!(stats.index_overrun, 1);
|
assert_eq!(stats.index_overrun, 1);
|
||||||
assert!(packet.meta.discard);
|
assert!(packet.meta.discard());
|
||||||
let shred = Shred::new_from_data(1, 3, 0, None, true, true, 0, 0, 0);
|
let shred = Shred::new_from_data(1, 3, 0, None, true, true, 0, 0, 0);
|
||||||
shred.copy_to_packet(&mut packet);
|
shred.copy_to_packet(&mut packet);
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ mod tests {
|
||||||
&|_p| {},
|
&|_p| {},
|
||||||
&hasher,
|
&hasher,
|
||||||
);
|
);
|
||||||
assert!(packet.meta.discard);
|
assert!(packet.meta.discard());
|
||||||
|
|
||||||
// Accepted for 1,3
|
// Accepted for 1,3
|
||||||
ShredFetchStage::process_packet(
|
ShredFetchStage::process_packet(
|
||||||
|
@ -338,7 +338,7 @@ mod tests {
|
||||||
&|_p| {},
|
&|_p| {},
|
||||||
&hasher,
|
&hasher,
|
||||||
);
|
);
|
||||||
assert!(!packet.meta.discard);
|
assert!(!packet.meta.discard());
|
||||||
|
|
||||||
// shreds_received should filter duplicate
|
// shreds_received should filter duplicate
|
||||||
ShredFetchStage::process_packet(
|
ShredFetchStage::process_packet(
|
||||||
|
@ -351,7 +351,7 @@ mod tests {
|
||||||
&|_p| {},
|
&|_p| {},
|
||||||
&hasher,
|
&hasher,
|
||||||
);
|
);
|
||||||
assert!(packet.meta.discard);
|
assert!(packet.meta.discard());
|
||||||
|
|
||||||
let shred = Shred::new_from_data(1_000_000, 3, 0, None, true, true, 0, 0, 0);
|
let shred = Shred::new_from_data(1_000_000, 3, 0, None, true, true, 0, 0, 0);
|
||||||
shred.copy_to_packet(&mut packet);
|
shred.copy_to_packet(&mut packet);
|
||||||
|
@ -367,7 +367,7 @@ mod tests {
|
||||||
&|_p| {},
|
&|_p| {},
|
||||||
&hasher,
|
&hasher,
|
||||||
);
|
);
|
||||||
assert!(packet.meta.discard);
|
assert!(packet.meta.discard());
|
||||||
|
|
||||||
let index = MAX_DATA_SHREDS_PER_SLOT as u32;
|
let index = MAX_DATA_SHREDS_PER_SLOT as u32;
|
||||||
let shred = Shred::new_from_data(5, index, 0, None, true, true, 0, 0, 0);
|
let shred = Shred::new_from_data(5, index, 0, None, true, true, 0, 0, 0);
|
||||||
|
@ -382,6 +382,6 @@ mod tests {
|
||||||
&|_p| {},
|
&|_p| {},
|
||||||
&hasher,
|
&hasher,
|
||||||
);
|
);
|
||||||
assert!(packet.meta.discard);
|
assert!(packet.meta.discard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ pub mod tests {
|
||||||
batches[0].packets[1].meta.size = shred.payload.len();
|
batches[0].packets[1].meta.size = shred.payload.len();
|
||||||
|
|
||||||
let rv = verifier.verify_batches(batches);
|
let rv = verifier.verify_batches(batches);
|
||||||
assert!(!rv[0].packets[0].meta.discard);
|
assert!(!rv[0].packets[0].meta.discard());
|
||||||
assert!(rv[0].packets[1].meta.discard);
|
assert!(rv[0].packets[1].meta.discard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,9 @@ impl SigVerifyStage {
|
||||||
}
|
}
|
||||||
for (_addr, indexes) in received_ips {
|
for (_addr, indexes) in received_ips {
|
||||||
for (batch_index, packet_index) in indexes {
|
for (batch_index, packet_index) in indexes {
|
||||||
batches[batch_index].packets[packet_index].meta.discard = true;
|
batches[batch_index].packets[packet_index]
|
||||||
|
.meta
|
||||||
|
.set_discard(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,7 +277,7 @@ mod tests {
|
||||||
batch
|
batch
|
||||||
.packets
|
.packets
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| if p.meta.discard { 0 } else { 1 })
|
.map(|p| if p.meta.discard() { 0 } else { 1 })
|
||||||
.sum::<usize>()
|
.sum::<usize>()
|
||||||
})
|
})
|
||||||
.sum::<usize>()
|
.sum::<usize>()
|
||||||
|
@ -291,7 +293,7 @@ mod tests {
|
||||||
let max = 3;
|
let max = 3;
|
||||||
SigVerifyStage::discard_excess_packets(&mut batches, max);
|
SigVerifyStage::discard_excess_packets(&mut batches, max);
|
||||||
assert_eq!(count_non_discard(&batches), max);
|
assert_eq!(count_non_discard(&batches), max);
|
||||||
assert!(!batches[0].packets[0].meta.discard);
|
assert!(!batches[0].packets[0].meta.discard());
|
||||||
assert!(!batches[0].packets[3].meta.discard);
|
assert!(!batches[0].packets[3].meta.discard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,7 +362,7 @@ where
|
||||||
let last_root = blockstore.last_root();
|
let last_root = blockstore.last_root();
|
||||||
let working_bank = bank_forks.read().unwrap().working_bank();
|
let working_bank = bank_forks.read().unwrap().working_bank();
|
||||||
let handle_packet = |packet: &Packet| {
|
let handle_packet = |packet: &Packet| {
|
||||||
if packet.meta.discard {
|
if packet.meta.discard() {
|
||||||
inc_new_counter_debug!("streamer-recv_window-invalid_or_unnecessary_packet", 1);
|
inc_new_counter_debug!("streamer-recv_window-invalid_or_unnecessary_packet", 1);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -375,7 +375,7 @@ where
|
||||||
if !shred_filter(&shred, working_bank.clone(), last_root) {
|
if !shred_filter(&shred, working_bank.clone(), last_root) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if packet.meta.repair {
|
if packet.meta.repair() {
|
||||||
let repair_info = RepairMeta {
|
let repair_info = RepairMeta {
|
||||||
_from_addr: packet.meta.addr(),
|
_from_addr: packet.meta.addr(),
|
||||||
// If can't parse the nonce, dump the packet.
|
// If can't parse the nonce, dump the packet.
|
||||||
|
|
|
@ -549,7 +549,7 @@ pub fn start_verify_transactions(
|
||||||
);
|
);
|
||||||
let verified = packet_batches
|
let verified = packet_batches
|
||||||
.iter()
|
.iter()
|
||||||
.all(|batch| batch.packets.iter().all(|p| !p.meta.discard));
|
.all(|batch| batch.packets.iter().all(|p| !p.meta.discard()));
|
||||||
verify_time.stop();
|
verify_time.stop();
|
||||||
(verified, verify_time.as_us())
|
(verified, verify_time.as_us())
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub fn verify_shred_cpu(packet: &Packet, slot_leaders: &HashMap<u64, [u8; 32]>)
|
||||||
let slot_start = sig_end + size_of::<ShredType>();
|
let slot_start = sig_end + size_of::<ShredType>();
|
||||||
let slot_end = slot_start + size_of::<u64>();
|
let slot_end = slot_start + size_of::<u64>();
|
||||||
let msg_start = sig_end;
|
let msg_start = sig_end;
|
||||||
if packet.meta.discard {
|
if packet.meta.discard() {
|
||||||
return Some(0);
|
return Some(0);
|
||||||
}
|
}
|
||||||
trace!("slot start and end {} {}", slot_start, slot_end);
|
trace!("slot start and end {} {}", slot_start, slot_end);
|
||||||
|
@ -58,7 +58,7 @@ pub fn verify_shred_cpu(packet: &Packet, slot_leaders: &HashMap<u64, [u8; 32]>)
|
||||||
return Some(0);
|
return Some(0);
|
||||||
}
|
}
|
||||||
let slot: u64 = limited_deserialize(&packet.data[slot_start..slot_end]).ok()?;
|
let slot: u64 = limited_deserialize(&packet.data[slot_start..slot_end]).ok()?;
|
||||||
let msg_end = if packet.meta.repair {
|
let msg_end = if packet.meta.repair() {
|
||||||
packet.meta.size.saturating_sub(SIZE_OF_NONCE)
|
packet.meta.size.saturating_sub(SIZE_OF_NONCE)
|
||||||
} else {
|
} else {
|
||||||
packet.meta.size
|
packet.meta.size
|
||||||
|
@ -119,7 +119,7 @@ fn slot_key_data_for_gpu<
|
||||||
.map(|packet| {
|
.map(|packet| {
|
||||||
let slot_start = size_of::<Signature>() + size_of::<ShredType>();
|
let slot_start = size_of::<Signature>() + size_of::<ShredType>();
|
||||||
let slot_end = slot_start + size_of::<u64>();
|
let slot_end = slot_start + size_of::<u64>();
|
||||||
if packet.meta.size < slot_end || packet.meta.discard {
|
if packet.meta.size < slot_end || packet.meta.discard() {
|
||||||
return std::u64::MAX;
|
return std::u64::MAX;
|
||||||
}
|
}
|
||||||
let slot: Option<u64> =
|
let slot: Option<u64> =
|
||||||
|
@ -204,7 +204,7 @@ fn shred_gpu_offsets(
|
||||||
let sig_start = pubkeys_end;
|
let sig_start = pubkeys_end;
|
||||||
let sig_end = sig_start + size_of::<Signature>();
|
let sig_end = sig_start + size_of::<Signature>();
|
||||||
let msg_start = sig_end;
|
let msg_start = sig_end;
|
||||||
let msg_end = if packet.meta.repair {
|
let msg_end = if packet.meta.repair() {
|
||||||
sig_start + packet.meta.size.saturating_sub(SIZE_OF_NONCE)
|
sig_start + packet.meta.size.saturating_sub(SIZE_OF_NONCE)
|
||||||
} else {
|
} else {
|
||||||
sig_start + packet.meta.size
|
sig_start + packet.meta.size
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! The `packet` module defines data structures and methods to pull data from the network.
|
//! The `packet` module defines data structures and methods to pull data from the network.
|
||||||
pub use solana_sdk::packet::{Meta, Packet, PACKET_DATA_SIZE};
|
pub use solana_sdk::packet::{Meta, Packet, PacketFlags, PACKET_DATA_SIZE};
|
||||||
use {
|
use {
|
||||||
crate::{cuda_runtime::PinnedVec, recycler::Recycler},
|
crate::{cuda_runtime::PinnedVec, recycler::Recycler},
|
||||||
bincode::config::Options,
|
bincode::config::Options,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use solana_sdk::transaction::Transaction;
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
cuda_runtime::PinnedVec,
|
cuda_runtime::PinnedVec,
|
||||||
packet::{Packet, PacketBatch},
|
packet::{Packet, PacketBatch, PacketFlags},
|
||||||
perf_libs,
|
perf_libs,
|
||||||
recycler::Recycler,
|
recycler::Recycler,
|
||||||
},
|
},
|
||||||
|
@ -114,17 +114,17 @@ fn verify_packet(packet: &mut Packet, reject_non_vote: bool) {
|
||||||
let msg_start = packet_offsets.msg_start as usize;
|
let msg_start = packet_offsets.msg_start as usize;
|
||||||
|
|
||||||
// If this packet was already marked as discard, drop it
|
// If this packet was already marked as discard, drop it
|
||||||
if packet.meta.discard {
|
if packet.meta.discard() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if packet_offsets.sig_len == 0 {
|
if packet_offsets.sig_len == 0 {
|
||||||
packet.meta.discard = true;
|
packet.meta.set_discard(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if packet.meta.size <= msg_start {
|
if packet.meta.size <= msg_start {
|
||||||
packet.meta.discard = true;
|
packet.meta.set_discard(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,15 +142,15 @@ fn verify_packet(packet: &mut Packet, reject_non_vote: bool) {
|
||||||
&packet.data[pubkey_start..pubkey_end],
|
&packet.data[pubkey_start..pubkey_end],
|
||||||
&packet.data[msg_start..msg_end],
|
&packet.data[msg_start..msg_end],
|
||||||
) {
|
) {
|
||||||
packet.meta.discard = true;
|
packet.meta.set_discard(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for tracer pubkey
|
// Check for tracer pubkey
|
||||||
if !packet.meta.is_tracer_tx
|
if !packet.meta.is_tracer_tx()
|
||||||
&& &packet.data[pubkey_start..pubkey_end] == TRACER_KEY.as_ref()
|
&& &packet.data[pubkey_start..pubkey_end] == TRACER_KEY.as_ref()
|
||||||
{
|
{
|
||||||
packet.meta.is_tracer_tx = true;
|
packet.meta.flags |= PacketFlags::TRACER_TX;
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey_start = pubkey_end;
|
pubkey_start = pubkey_end;
|
||||||
|
@ -289,7 +289,7 @@ fn get_packet_offsets(
|
||||||
let unsanitized_packet_offsets = do_get_packet_offsets(packet, current_offset);
|
let unsanitized_packet_offsets = do_get_packet_offsets(packet, current_offset);
|
||||||
if let Ok(offsets) = unsanitized_packet_offsets {
|
if let Ok(offsets) = unsanitized_packet_offsets {
|
||||||
check_for_simple_vote_transaction(packet, &offsets, current_offset).ok();
|
check_for_simple_vote_transaction(packet, &offsets, current_offset).ok();
|
||||||
if !reject_non_vote || packet.meta.is_simple_vote_tx {
|
if !reject_non_vote || packet.meta.is_simple_vote_tx() {
|
||||||
return offsets;
|
return offsets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ fn check_for_simple_vote_transaction(
|
||||||
if &packet.data[instruction_program_id_start..instruction_program_id_end]
|
if &packet.data[instruction_program_id_start..instruction_program_id_end]
|
||||||
== solana_sdk::vote::program::id().as_ref()
|
== solana_sdk::vote::program::id().as_ref()
|
||||||
{
|
{
|
||||||
packet.meta.is_simple_vote_tx = true;
|
packet.meta.flags |= PacketFlags::SIMPLE_VOTE_TX;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -441,7 +441,7 @@ pub fn ed25519_verify_disabled(batches: &mut [PacketBatch]) {
|
||||||
batch
|
batch
|
||||||
.packets
|
.packets
|
||||||
.par_iter_mut()
|
.par_iter_mut()
|
||||||
.for_each(|p| p.meta.discard = false)
|
.for_each(|p| p.meta.set_discard(false))
|
||||||
});
|
});
|
||||||
inc_new_counter_debug!("ed25519_verify_disabled", packet_count);
|
inc_new_counter_debug!("ed25519_verify_disabled", packet_count);
|
||||||
}
|
}
|
||||||
|
@ -498,11 +498,11 @@ pub fn get_checked_scalar(scalar: &[u8; 32]) -> Result<[u8; 32], PacketError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_disabled(batches: &mut [PacketBatch], r: &[Vec<u8>]) {
|
pub fn mark_disabled(batches: &mut [PacketBatch], r: &[Vec<u8>]) {
|
||||||
batches.iter_mut().zip(r).for_each(|(b, v)| {
|
for (batch, v) in batches.iter_mut().zip(r) {
|
||||||
b.packets.iter_mut().zip(v).for_each(|(p, f)| {
|
for (pkt, f) in batch.packets.iter_mut().zip(v) {
|
||||||
p.meta.discard = *f == 0;
|
pkt.meta.set_discard(*f == 0);
|
||||||
})
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ed25519_verify(
|
pub fn ed25519_verify(
|
||||||
|
@ -629,9 +629,9 @@ mod tests {
|
||||||
batch.packets.push(Packet::default());
|
batch.packets.push(Packet::default());
|
||||||
let mut batches: Vec<PacketBatch> = vec![batch];
|
let mut batches: Vec<PacketBatch> = vec![batch];
|
||||||
mark_disabled(&mut batches, &[vec![0]]);
|
mark_disabled(&mut batches, &[vec![0]]);
|
||||||
assert!(batches[0].packets[0].meta.discard);
|
assert!(batches[0].packets[0].meta.discard());
|
||||||
mark_disabled(&mut batches, &[vec![1]]);
|
mark_disabled(&mut batches, &[vec![1]]);
|
||||||
assert!(!batches[0].packets[0].meta.discard);
|
assert!(!batches[0].packets[0].meta.discard());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -730,12 +730,12 @@ mod tests {
|
||||||
assert_eq!(res, Err(PacketError::InvalidPubkeyLen));
|
assert_eq!(res, Err(PacketError::InvalidPubkeyLen));
|
||||||
|
|
||||||
verify_packet(&mut packet, false);
|
verify_packet(&mut packet, false);
|
||||||
assert!(packet.meta.discard);
|
assert!(packet.meta.discard());
|
||||||
|
|
||||||
packet.meta.discard = false;
|
packet.meta.set_discard(false);
|
||||||
let mut batches = generate_packet_batches(&packet, 1, 1);
|
let mut batches = generate_packet_batches(&packet, 1, 1);
|
||||||
ed25519_verify(&mut batches);
|
ed25519_verify(&mut batches);
|
||||||
assert!(batches[0].packets[0].meta.discard);
|
assert!(batches[0].packets[0].meta.discard());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -766,12 +766,12 @@ mod tests {
|
||||||
assert_eq!(res, Err(PacketError::InvalidPubkeyLen));
|
assert_eq!(res, Err(PacketError::InvalidPubkeyLen));
|
||||||
|
|
||||||
verify_packet(&mut packet, false);
|
verify_packet(&mut packet, false);
|
||||||
assert!(packet.meta.discard);
|
assert!(packet.meta.discard());
|
||||||
|
|
||||||
packet.meta.discard = false;
|
packet.meta.set_discard(false);
|
||||||
let mut batches = generate_packet_batches(&packet, 1, 1);
|
let mut batches = generate_packet_batches(&packet, 1, 1);
|
||||||
ed25519_verify(&mut batches);
|
ed25519_verify(&mut batches);
|
||||||
assert!(batches[0].packets[0].meta.discard);
|
assert!(batches[0].packets[0].meta.discard());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -972,7 +972,7 @@ mod tests {
|
||||||
assert!(batches
|
assert!(batches
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|batch| &batch.packets)
|
.flat_map(|batch| &batch.packets)
|
||||||
.all(|p| p.meta.discard == should_discard));
|
.all(|p| p.meta.discard() == should_discard));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ed25519_verify(batches: &mut [PacketBatch]) {
|
fn ed25519_verify(batches: &mut [PacketBatch]) {
|
||||||
|
@ -995,7 +995,7 @@ mod tests {
|
||||||
assert!(batches
|
assert!(batches
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|batch| &batch.packets)
|
.flat_map(|batch| &batch.packets)
|
||||||
.all(|p| p.meta.discard));
|
.all(|p| p.meta.discard()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1041,9 +1041,9 @@ mod tests {
|
||||||
.zip(ref_vec.into_iter().flatten())
|
.zip(ref_vec.into_iter().flatten())
|
||||||
.all(|(p, discard)| {
|
.all(|(p, discard)| {
|
||||||
if discard == 0 {
|
if discard == 0 {
|
||||||
p.meta.discard
|
p.meta.discard()
|
||||||
} else {
|
} else {
|
||||||
!p.meta.discard
|
!p.meta.discard()
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -1196,7 +1196,7 @@ mod tests {
|
||||||
let mut packet = sigverify::make_packet_from_transaction(tx);
|
let mut packet = sigverify::make_packet_from_transaction(tx);
|
||||||
let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap();
|
let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap();
|
||||||
check_for_simple_vote_transaction(&mut packet, &packet_offsets, 0).ok();
|
check_for_simple_vote_transaction(&mut packet, &packet_offsets, 0).ok();
|
||||||
assert!(!packet.meta.is_simple_vote_tx);
|
assert!(!packet.meta.is_simple_vote_tx());
|
||||||
}
|
}
|
||||||
|
|
||||||
// single vote tx is
|
// single vote tx is
|
||||||
|
@ -1206,7 +1206,7 @@ mod tests {
|
||||||
let mut packet = sigverify::make_packet_from_transaction(tx);
|
let mut packet = sigverify::make_packet_from_transaction(tx);
|
||||||
let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap();
|
let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap();
|
||||||
check_for_simple_vote_transaction(&mut packet, &packet_offsets, 0).ok();
|
check_for_simple_vote_transaction(&mut packet, &packet_offsets, 0).ok();
|
||||||
assert!(packet.meta.is_simple_vote_tx);
|
assert!(packet.meta.is_simple_vote_tx());
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiple mixed tx is not
|
// multiple mixed tx is not
|
||||||
|
@ -1227,7 +1227,7 @@ mod tests {
|
||||||
let mut packet = sigverify::make_packet_from_transaction(tx);
|
let mut packet = sigverify::make_packet_from_transaction(tx);
|
||||||
let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap();
|
let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap();
|
||||||
check_for_simple_vote_transaction(&mut packet, &packet_offsets, 0).ok();
|
check_for_simple_vote_transaction(&mut packet, &packet_offsets, 0).ok();
|
||||||
assert!(!packet.meta.is_simple_vote_tx);
|
assert!(!packet.meta.is_simple_vote_tx());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1253,9 +1253,9 @@ mod tests {
|
||||||
let packet_offsets = do_get_packet_offsets(packet, current_offset).unwrap();
|
let packet_offsets = do_get_packet_offsets(packet, current_offset).unwrap();
|
||||||
check_for_simple_vote_transaction(packet, &packet_offsets, current_offset).ok();
|
check_for_simple_vote_transaction(packet, &packet_offsets, current_offset).ok();
|
||||||
if index == 1 {
|
if index == 1 {
|
||||||
assert!(packet.meta.is_simple_vote_tx);
|
assert!(packet.meta.is_simple_vote_tx());
|
||||||
} else {
|
} else {
|
||||||
assert!(!packet.meta.is_simple_vote_tx);
|
assert!(!packet.meta.is_simple_vote_tx());
|
||||||
}
|
}
|
||||||
|
|
||||||
current_offset = current_offset.saturating_add(size_of::<Packet>());
|
current_offset = current_offset.saturating_add(size_of::<Packet>());
|
||||||
|
|
|
@ -3395,6 +3395,7 @@ dependencies = [
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"base64 0.13.0",
|
"base64 0.13.0",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
"bitflags",
|
||||||
"borsh",
|
"borsh",
|
||||||
"bs58 0.4.0",
|
"bs58 0.4.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
|
@ -39,6 +39,7 @@ full = [
|
||||||
[dependencies]
|
[dependencies]
|
||||||
assert_matches = { version = "1.5.0", optional = true }
|
assert_matches = { version = "1.5.0", optional = true }
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
|
bitflags = "1.3.1"
|
||||||
bytemuck = { version = "1.7.3", features = ["derive"] }
|
bytemuck = { version = "1.7.3", features = ["derive"] }
|
||||||
borsh = "0.9.0"
|
borsh = "0.9.0"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use {
|
use {
|
||||||
bincode::Result,
|
bincode::Result,
|
||||||
|
bitflags::bitflags,
|
||||||
serde::Serialize,
|
serde::Serialize,
|
||||||
std::{
|
std::{
|
||||||
fmt, io,
|
fmt, io,
|
||||||
|
@ -13,17 +14,24 @@ use {
|
||||||
/// 8 bytes is the size of the fragment header
|
/// 8 bytes is the size of the fragment header
|
||||||
pub const PACKET_DATA_SIZE: usize = 1280 - 40 - 8;
|
pub const PACKET_DATA_SIZE: usize = 1280 - 40 - 8;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PacketFlags: u8 {
|
||||||
|
const DISCARD = 0b00000001;
|
||||||
|
const FORWARDED = 0b00000010;
|
||||||
|
const REPAIR = 0b00000100;
|
||||||
|
const SIMPLE_VOTE_TX = 0b00001000;
|
||||||
|
const TRACER_TX = 0b00010000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Meta {
|
pub struct Meta {
|
||||||
pub size: usize,
|
pub size: usize,
|
||||||
pub forwarded: bool,
|
|
||||||
pub repair: bool,
|
|
||||||
pub discard: bool,
|
|
||||||
pub addr: IpAddr,
|
pub addr: IpAddr,
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub is_tracer_tx: bool,
|
pub flags: PacketFlags,
|
||||||
pub is_simple_vote_tx: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -98,19 +106,45 @@ impl Meta {
|
||||||
self.addr = socket_addr.ip();
|
self.addr = socket_addr.ip();
|
||||||
self.port = socket_addr.port();
|
self.port = socket_addr.port();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn discard(&self) -> bool {
|
||||||
|
self.flags.contains(PacketFlags::DISCARD)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_discard(&mut self, discard: bool) {
|
||||||
|
self.flags.set(PacketFlags::DISCARD, discard);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn forwarded(&self) -> bool {
|
||||||
|
self.flags.contains(PacketFlags::FORWARDED)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn repair(&self) -> bool {
|
||||||
|
self.flags.contains(PacketFlags::REPAIR)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_simple_vote_tx(&self) -> bool {
|
||||||
|
self.flags.contains(PacketFlags::SIMPLE_VOTE_TX)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_tracer_tx(&self) -> bool {
|
||||||
|
self.flags.contains(PacketFlags::TRACER_TX)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Meta {
|
impl Default for Meta {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
size: 0,
|
size: 0,
|
||||||
forwarded: false,
|
|
||||||
repair: false,
|
|
||||||
discard: false,
|
|
||||||
addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
||||||
port: 0,
|
port: 0,
|
||||||
is_tracer_tx: false,
|
flags: PacketFlags::empty(),
|
||||||
is_simple_vote_tx: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue