diff --git a/Cargo.lock b/Cargo.lock index ad2627c94..1a993b5e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5641,6 +5641,7 @@ dependencies = [ "assert_matches", "base64 0.13.0", "bincode", + "bitflags", "borsh", "bs58 0.4.0", "bytemuck", diff --git a/core/benches/sigverify_stage.rs b/core/benches/sigverify_stage.rs index a0414fd76..6755db61e 100644 --- a/core/benches/sigverify_stage.rs +++ b/core/benches/sigverify_stage.rs @@ -54,7 +54,7 @@ fn bench_packet_discard(bencher: &mut Bencher) { SigVerifyStage::discard_excess_packets(&mut batches, 10_000); for batch in batches.iter_mut() { for p in batch.packets.iter_mut() { - p.meta.discard = false; + p.meta.set_discard(false); } } }); diff --git a/core/src/banking_stage.rs b/core/src/banking_stage.rs index 343b13354..b1bacfd98 100644 --- a/core/src/banking_stage.rs +++ b/core/src/banking_stage.rs @@ -406,7 +406,7 @@ impl BankingStage { let packet_vec: Vec<_> = packets .iter() .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)) } else { None @@ -1125,7 +1125,7 @@ impl BankingStage { .iter() .filter_map(|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; } @@ -1135,7 +1135,7 @@ impl BankingStage { let tx = SanitizedTransaction::try_create( tx, message_hash, - Some(p.meta.is_simple_vote_tx), + Some(p.meta.is_simple_vote_tx()), |_| Err(TransactionError::UnsupportedVersion), ) .ok()?; @@ -1306,15 +1306,8 @@ impl BankingStage { fn generate_packet_indexes(vers: &PinnedVec) -> Vec { vers.iter() .enumerate() - .filter_map( - |(index, ver)| { - if !ver.meta.discard { - Some(index) - } else { - None - } - }, - ) + .filter(|(_, pkt)| !pkt.meta.discard()) + .map(|(index, _)| index) .collect() } @@ -1492,7 +1485,7 @@ mod tests { get_tmp_ledger_path, leader_schedule_cache::LeaderScheduleCache, }, - solana_perf::packet::to_packet_batches, + solana_perf::packet::{to_packet_batches, PacketFlags}, solana_poh::{ poh_recorder::{create_test_recorder, Record, WorkingBankEntry}, poh_service::PohService, @@ -1638,7 +1631,7 @@ mod tests { b.packets .iter_mut() .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() } @@ -2843,7 +2836,7 @@ mod tests { const FWD_PACKET: u8 = 1; let forwarded_packet = { let mut packet = Packet::from_data(None, &[FWD_PACKET]).unwrap(); - packet.meta.forwarded = true; + packet.meta.flags |= PacketFlags::FORWARDED; packet }; @@ -3084,7 +3077,7 @@ mod tests { packet_indexes.push(index); } 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) } diff --git a/core/src/cluster_info_vote_listener.rs b/core/src/cluster_info_vote_listener.rs index 1ed08b0e7..728cc5080 100644 --- a/core/src/cluster_info_vote_listener.rs +++ b/core/src/cluster_info_vote_listener.rs @@ -308,7 +308,7 @@ impl ClusterInfoVoteListener { .filter(|(_, packet_batch)| { // to_packet_batches() above splits into 1 packet long batches assert_eq!(packet_batch.packets.len(), 1); - !packet_batch.packets[0].meta.discard + !packet_batch.packets[0].meta.discard() }) .filter_map(|(tx, packet_batch)| { let (vote_account_key, vote, _) = vote_transaction::parse_vote_transaction(&tx)?; diff --git a/core/src/fetch_stage.rs b/core/src/fetch_stage.rs index 1e78a0ddc..a560a5c28 100644 --- a/core/src/fetch_stage.rs +++ b/core/src/fetch_stage.rs @@ -8,7 +8,10 @@ use { solana_metrics::{inc_new_counter_debug, inc_new_counter_info}, solana_perf::{packet::PacketBatchRecycler, recycler::Recycler}, 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}, std::{ net::UdpSocket, @@ -84,7 +87,7 @@ impl FetchStage { poh_recorder: &Arc>, ) -> Result<()> { let mark_forwarded = |packet: &mut Packet| { - packet.meta.forwarded = true; + packet.meta.flags |= PacketFlags::FORWARDED; }; let mut packet_batch = recvr.recv()?; diff --git a/core/src/repair_response.rs b/core/src/repair_response.rs index 3c5c30aae..adefc3a57 100644 --- a/core/src/repair_response.rs +++ b/core/src/repair_response.rs @@ -56,7 +56,10 @@ mod test { shred::{Shred, Shredder}, sigverify_shreds::verify_shred_cpu, }, - solana_sdk::signature::{Keypair, Signer}, + solana_sdk::{ + packet::PacketFlags, + signature::{Keypair, Signer}, + }, std::{ collections::HashMap, net::{IpAddr, Ipv4Addr}, @@ -87,7 +90,7 @@ mod test { nonce, ) .unwrap(); - packet.meta.repair = true; + packet.meta.flags |= PacketFlags::REPAIR; let leader_slots = [(slot, keypair.pubkey().to_bytes())] .iter() diff --git a/core/src/retransmit_stage.rs b/core/src/retransmit_stage.rs index 3b5e03045..da678dac8 100644 --- a/core/src/retransmit_stage.rs +++ b/core/src/retransmit_stage.rs @@ -615,7 +615,7 @@ mod tests { let mut packet_batch = PacketBatch::new(vec![]); solana_streamer::packet::recv_from(&mut packet_batch, &me_retransmit, 1).unwrap(); assert_eq!(packet_batch.packets.len(), 1); - assert!(!packet_batch.packets[0].meta.repair); + assert!(!packet_batch.packets[0].meta.repair()); } #[test] diff --git a/core/src/shred_fetch_stage.rs b/core/src/shred_fetch_stage.rs index 787ae5c07..d231ae8b9 100644 --- a/core/src/shred_fetch_stage.rs +++ b/core/src/shred_fetch_stage.rs @@ -6,7 +6,7 @@ use { solana_ledger::shred::{get_shred_slot_index_type, ShredFetchStats}, solana_perf::{ cuda_runtime::PinnedVec, - packet::{Packet, PacketBatchRecycler}, + packet::{Packet, PacketBatchRecycler, PacketFlags}, recycler::Recycler, }, solana_runtime::bank_forks::BankForks, @@ -40,7 +40,7 @@ impl ShredFetchStage { ) where 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) { // Seems reasonable to limit shreds to 2 epochs away if slot > last_root && slot < (last_slot + 2 * slots_per_epoch) { @@ -50,7 +50,7 @@ impl ShredFetchStage { if shreds_received.get(&hash).is_none() { shreds_received.put(hash, ()); - p.meta.discard = false; + p.meta.set_discard(false); modify(p); } else { stats.duplicate_shred += 1; @@ -192,7 +192,7 @@ impl ShredFetchStage { recycler.clone(), bank_forks.clone(), "shred_fetch_tvu_forwards", - |p| p.meta.forwarded = true, + |p| p.meta.flags.insert(PacketFlags::FORWARDED), ); let (repair_receiver, repair_handler) = Self::packet_modifier( @@ -202,7 +202,7 @@ impl ShredFetchStage { recycler, bank_forks, "shred_fetch_repair", - |p| p.meta.repair = true, + |p| p.meta.flags.insert(PacketFlags::REPAIR), ); tvu_threads.extend(tvu_forwards_threads.into_iter()); @@ -266,7 +266,7 @@ mod tests { &|_p| {}, &hasher, ); - assert!(!packet.meta.discard); + assert!(!packet.meta.discard()); let coding = solana_ledger::shred::Shredder::generate_coding_shreds( &[shred], false, // is_last_in_slot @@ -283,7 +283,7 @@ mod tests { &|_p| {}, &hasher, ); - assert!(!packet.meta.discard); + assert!(!packet.meta.discard()); } #[test] @@ -310,7 +310,7 @@ mod tests { &hasher, ); 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); shred.copy_to_packet(&mut packet); @@ -325,7 +325,7 @@ mod tests { &|_p| {}, &hasher, ); - assert!(packet.meta.discard); + assert!(packet.meta.discard()); // Accepted for 1,3 ShredFetchStage::process_packet( @@ -338,7 +338,7 @@ mod tests { &|_p| {}, &hasher, ); - assert!(!packet.meta.discard); + assert!(!packet.meta.discard()); // shreds_received should filter duplicate ShredFetchStage::process_packet( @@ -351,7 +351,7 @@ mod tests { &|_p| {}, &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); shred.copy_to_packet(&mut packet); @@ -367,7 +367,7 @@ mod tests { &|_p| {}, &hasher, ); - assert!(packet.meta.discard); + assert!(packet.meta.discard()); let index = MAX_DATA_SHREDS_PER_SLOT as u32; let shred = Shred::new_from_data(5, index, 0, None, true, true, 0, 0, 0); @@ -382,6 +382,6 @@ mod tests { &|_p| {}, &hasher, ); - assert!(packet.meta.discard); + assert!(packet.meta.discard()); } } diff --git a/core/src/sigverify_shreds.rs b/core/src/sigverify_shreds.rs index 85078f510..626dc516f 100644 --- a/core/src/sigverify_shreds.rs +++ b/core/src/sigverify_shreds.rs @@ -162,7 +162,7 @@ pub mod tests { batches[0].packets[1].meta.size = shred.payload.len(); let rv = verifier.verify_batches(batches); - assert!(!rv[0].packets[0].meta.discard); - assert!(rv[0].packets[1].meta.discard); + assert!(!rv[0].packets[0].meta.discard()); + assert!(rv[0].packets[1].meta.discard()); } } diff --git a/core/src/sigverify_stage.rs b/core/src/sigverify_stage.rs index 2297c362c..62f190de8 100644 --- a/core/src/sigverify_stage.rs +++ b/core/src/sigverify_stage.rs @@ -163,7 +163,9 @@ impl SigVerifyStage { } for (_addr, indexes) in received_ips { 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 .packets .iter() - .map(|p| if p.meta.discard { 0 } else { 1 }) + .map(|p| if p.meta.discard() { 0 } else { 1 }) .sum::() }) .sum::() @@ -291,7 +293,7 @@ mod tests { let max = 3; SigVerifyStage::discard_excess_packets(&mut batches, max); assert_eq!(count_non_discard(&batches), max); - assert!(!batches[0].packets[0].meta.discard); - assert!(!batches[0].packets[3].meta.discard); + assert!(!batches[0].packets[0].meta.discard()); + assert!(!batches[0].packets[3].meta.discard()); } } diff --git a/core/src/window_service.rs b/core/src/window_service.rs index e77ab6f0b..7a3e2c5cb 100644 --- a/core/src/window_service.rs +++ b/core/src/window_service.rs @@ -362,7 +362,7 @@ where let last_root = blockstore.last_root(); let working_bank = bank_forks.read().unwrap().working_bank(); 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); return None; } @@ -375,7 +375,7 @@ where if !shred_filter(&shred, working_bank.clone(), last_root) { return None; } - if packet.meta.repair { + if packet.meta.repair() { let repair_info = RepairMeta { _from_addr: packet.meta.addr(), // If can't parse the nonce, dump the packet. diff --git a/entry/src/entry.rs b/entry/src/entry.rs index a0d5337b7..f02354225 100644 --- a/entry/src/entry.rs +++ b/entry/src/entry.rs @@ -549,7 +549,7 @@ pub fn start_verify_transactions( ); let verified = packet_batches .iter() - .all(|batch| batch.packets.iter().all(|p| !p.meta.discard)); + .all(|batch| batch.packets.iter().all(|p| !p.meta.discard())); verify_time.stop(); (verified, verify_time.as_us()) }); diff --git a/ledger/src/sigverify_shreds.rs b/ledger/src/sigverify_shreds.rs index a8e8868cf..3ad11e073 100644 --- a/ledger/src/sigverify_shreds.rs +++ b/ledger/src/sigverify_shreds.rs @@ -50,7 +50,7 @@ pub fn verify_shred_cpu(packet: &Packet, slot_leaders: &HashMap) let slot_start = sig_end + size_of::(); let slot_end = slot_start + size_of::(); let msg_start = sig_end; - if packet.meta.discard { + if packet.meta.discard() { return Some(0); } trace!("slot start and end {} {}", slot_start, slot_end); @@ -58,7 +58,7 @@ pub fn verify_shred_cpu(packet: &Packet, slot_leaders: &HashMap) return Some(0); } 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) } else { packet.meta.size @@ -119,7 +119,7 @@ fn slot_key_data_for_gpu< .map(|packet| { let slot_start = size_of::() + size_of::(); let slot_end = slot_start + size_of::(); - if packet.meta.size < slot_end || packet.meta.discard { + if packet.meta.size < slot_end || packet.meta.discard() { return std::u64::MAX; } let slot: Option = @@ -204,7 +204,7 @@ fn shred_gpu_offsets( let sig_start = pubkeys_end; let sig_end = sig_start + size_of::(); 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) } else { sig_start + packet.meta.size diff --git a/perf/src/packet.rs b/perf/src/packet.rs index d8c163a7a..7b2222a0f 100644 --- a/perf/src/packet.rs +++ b/perf/src/packet.rs @@ -1,5 +1,5 @@ //! 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 { crate::{cuda_runtime::PinnedVec, recycler::Recycler}, bincode::config::Options, diff --git a/perf/src/sigverify.rs b/perf/src/sigverify.rs index 3da88f9dd..8396bb529 100644 --- a/perf/src/sigverify.rs +++ b/perf/src/sigverify.rs @@ -9,7 +9,7 @@ use solana_sdk::transaction::Transaction; use { crate::{ cuda_runtime::PinnedVec, - packet::{Packet, PacketBatch}, + packet::{Packet, PacketBatch, PacketFlags}, perf_libs, 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; // If this packet was already marked as discard, drop it - if packet.meta.discard { + if packet.meta.discard() { return; } if packet_offsets.sig_len == 0 { - packet.meta.discard = true; + packet.meta.set_discard(true); return; } if packet.meta.size <= msg_start { - packet.meta.discard = true; + packet.meta.set_discard(true); return; } @@ -142,15 +142,15 @@ fn verify_packet(packet: &mut Packet, reject_non_vote: bool) { &packet.data[pubkey_start..pubkey_end], &packet.data[msg_start..msg_end], ) { - packet.meta.discard = true; + packet.meta.set_discard(true); return; } // 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.meta.is_tracer_tx = true; + packet.meta.flags |= PacketFlags::TRACER_TX; } pubkey_start = pubkey_end; @@ -289,7 +289,7 @@ fn get_packet_offsets( let unsanitized_packet_offsets = do_get_packet_offsets(packet, current_offset); if let Ok(offsets) = unsanitized_packet_offsets { 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; } } @@ -360,7 +360,7 @@ fn check_for_simple_vote_transaction( if &packet.data[instruction_program_id_start..instruction_program_id_end] == solana_sdk::vote::program::id().as_ref() { - packet.meta.is_simple_vote_tx = true; + packet.meta.flags |= PacketFlags::SIMPLE_VOTE_TX; } Ok(()) } @@ -441,7 +441,7 @@ pub fn ed25519_verify_disabled(batches: &mut [PacketBatch]) { batch .packets .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); } @@ -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]) { - batches.iter_mut().zip(r).for_each(|(b, v)| { - b.packets.iter_mut().zip(v).for_each(|(p, f)| { - p.meta.discard = *f == 0; - }) - }); + for (batch, v) in batches.iter_mut().zip(r) { + for (pkt, f) in batch.packets.iter_mut().zip(v) { + pkt.meta.set_discard(*f == 0); + } + } } pub fn ed25519_verify( @@ -629,9 +629,9 @@ mod tests { batch.packets.push(Packet::default()); let mut batches: Vec = vec![batch]; 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]]); - assert!(!batches[0].packets[0].meta.discard); + assert!(!batches[0].packets[0].meta.discard()); } #[test] @@ -730,12 +730,12 @@ mod tests { assert_eq!(res, Err(PacketError::InvalidPubkeyLen)); 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); ed25519_verify(&mut batches); - assert!(batches[0].packets[0].meta.discard); + assert!(batches[0].packets[0].meta.discard()); } #[test] @@ -766,12 +766,12 @@ mod tests { assert_eq!(res, Err(PacketError::InvalidPubkeyLen)); 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); ed25519_verify(&mut batches); - assert!(batches[0].packets[0].meta.discard); + assert!(batches[0].packets[0].meta.discard()); } #[test] @@ -972,7 +972,7 @@ mod tests { assert!(batches .iter() .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]) { @@ -995,7 +995,7 @@ mod tests { assert!(batches .iter() .flat_map(|batch| &batch.packets) - .all(|p| p.meta.discard)); + .all(|p| p.meta.discard())); } #[test] @@ -1041,9 +1041,9 @@ mod tests { .zip(ref_vec.into_iter().flatten()) .all(|(p, discard)| { if discard == 0 { - p.meta.discard + p.meta.discard() } else { - !p.meta.discard + !p.meta.discard() } })); } @@ -1196,7 +1196,7 @@ mod tests { let mut packet = sigverify::make_packet_from_transaction(tx); let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap(); 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 @@ -1206,7 +1206,7 @@ mod tests { let mut packet = sigverify::make_packet_from_transaction(tx); let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap(); 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 @@ -1227,7 +1227,7 @@ mod tests { let mut packet = sigverify::make_packet_from_transaction(tx); let packet_offsets = do_get_packet_offsets(&packet, 0).unwrap(); 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(); check_for_simple_vote_transaction(packet, &packet_offsets, current_offset).ok(); if index == 1 { - assert!(packet.meta.is_simple_vote_tx); + assert!(packet.meta.is_simple_vote_tx()); } else { - assert!(!packet.meta.is_simple_vote_tx); + assert!(!packet.meta.is_simple_vote_tx()); } current_offset = current_offset.saturating_add(size_of::()); diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index d7e816e1e..04e01ef9d 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -3395,6 +3395,7 @@ dependencies = [ "assert_matches", "base64 0.13.0", "bincode", + "bitflags", "borsh", "bs58 0.4.0", "bytemuck", diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 72888ece3..55f566f0b 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -39,6 +39,7 @@ full = [ [dependencies] assert_matches = { version = "1.5.0", optional = true } bincode = "1.3.3" +bitflags = "1.3.1" bytemuck = { version = "1.7.3", features = ["derive"] } borsh = "0.9.0" base64 = "0.13" diff --git a/sdk/src/packet.rs b/sdk/src/packet.rs index 0c99eb039..efea21904 100644 --- a/sdk/src/packet.rs +++ b/sdk/src/packet.rs @@ -1,5 +1,6 @@ use { bincode::Result, + bitflags::bitflags, serde::Serialize, std::{ fmt, io, @@ -13,17 +14,24 @@ use { /// 8 bytes is the size of the fragment header 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)] #[repr(C)] pub struct Meta { pub size: usize, - pub forwarded: bool, - pub repair: bool, - pub discard: bool, pub addr: IpAddr, pub port: u16, - pub is_tracer_tx: bool, - pub is_simple_vote_tx: bool, + pub flags: PacketFlags, } #[derive(Clone)] @@ -98,19 +106,45 @@ impl Meta { self.addr = socket_addr.ip(); 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 { fn default() -> Self { Self { size: 0, - forwarded: false, - repair: false, - discard: false, addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED), port: 0, - is_tracer_tx: false, - is_simple_vote_tx: false, + flags: PacketFlags::empty(), } } }