filter invalid repair requests by size (#30951)
This commit is contained in:
parent
aa7baaff29
commit
b5bb5c6da1
|
@ -258,6 +258,25 @@ pub enum RepairProtocol {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const REPAIR_REQUEST_PONG_SERIALIZED_BYTES: usize = PUBKEY_BYTES + HASH_BYTES + SIGNATURE_BYTES;
|
||||||
|
const REPAIR_REQUEST_MIN_BYTES: usize = REPAIR_REQUEST_PONG_SERIALIZED_BYTES;
|
||||||
|
|
||||||
|
fn discard_malformed_repair_requests(
|
||||||
|
batch: &mut PacketBatch,
|
||||||
|
stats: &mut ServeRepairStats,
|
||||||
|
) -> usize {
|
||||||
|
let mut well_formed_requests = 0;
|
||||||
|
for packet in batch.iter_mut() {
|
||||||
|
if packet.meta().size < REPAIR_REQUEST_MIN_BYTES {
|
||||||
|
stats.err_malformed += 1;
|
||||||
|
packet.meta_mut().set_discard(true);
|
||||||
|
} else {
|
||||||
|
well_formed_requests += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
well_formed_requests
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, AbiEnumVisitor, AbiExample, Deserialize, Serialize)]
|
#[derive(Debug, AbiEnumVisitor, AbiExample, Deserialize, Serialize)]
|
||||||
#[frozen_abi(digest = "CkffjyMPCwuJgk9NiCMELXLCecAnTPZqpKEnUCb3VyVf")]
|
#[frozen_abi(digest = "CkffjyMPCwuJgk9NiCMELXLCecAnTPZqpKEnUCb3VyVf")]
|
||||||
pub(crate) enum RepairResponse {
|
pub(crate) enum RepairResponse {
|
||||||
|
@ -603,7 +622,12 @@ impl ServeRepair {
|
||||||
}
|
}
|
||||||
result.ok()
|
result.ok()
|
||||||
};
|
};
|
||||||
reqs_v.iter().flatten().filter_map(decode_packet).collect()
|
reqs_v
|
||||||
|
.iter()
|
||||||
|
.flatten()
|
||||||
|
.filter(|packet| !packet.meta().discard())
|
||||||
|
.filter_map(decode_packet)
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process messages from the network
|
/// Process messages from the network
|
||||||
|
@ -637,12 +661,20 @@ impl ServeRepair {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dropped_requests = 0;
|
let mut dropped_requests = 0;
|
||||||
while let Ok(more) = requests_receiver.try_recv() {
|
let mut well_formed_requests = discard_malformed_repair_requests(&mut reqs_v[0], stats);
|
||||||
|
for mut more in requests_receiver.try_iter() {
|
||||||
total_requests += more.len();
|
total_requests += more.len();
|
||||||
if total_requests > max_buffered_packets {
|
if well_formed_requests > max_buffered_packets {
|
||||||
|
// Already exceeded max. Don't waste time discarding
|
||||||
dropped_requests += more.len();
|
dropped_requests += more.len();
|
||||||
} else {
|
continue;
|
||||||
|
}
|
||||||
|
let retained = discard_malformed_repair_requests(&mut more, stats);
|
||||||
|
well_formed_requests += retained;
|
||||||
|
if retained > 0 && well_formed_requests <= max_buffered_packets {
|
||||||
reqs_v.push(more);
|
reqs_v.push(more);
|
||||||
|
} else {
|
||||||
|
dropped_requests += more.len();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1402,6 +1434,82 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn repair_request_header_for_tests() -> RepairRequestHeader {
|
||||||
|
RepairRequestHeader {
|
||||||
|
signature: Signature::default(),
|
||||||
|
sender: Pubkey::default(),
|
||||||
|
recipient: Pubkey::default(),
|
||||||
|
timestamp: timestamp(),
|
||||||
|
nonce: Nonce::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_check_well_formed_repair_request() {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let keypair = Keypair::new();
|
||||||
|
let ping = ping_pong::Ping::<[u8; 32]>::new_rand(&mut rng, &keypair).unwrap();
|
||||||
|
let pong = Pong::new(&ping, &keypair).unwrap();
|
||||||
|
let request = RepairProtocol::Pong(pong);
|
||||||
|
let mut pkt = Packet::from_data(None, &request).unwrap();
|
||||||
|
let mut batch = PacketBatch::new(vec![pkt.clone()]);
|
||||||
|
let mut stats = ServeRepairStats::default();
|
||||||
|
let num_well_formed = discard_malformed_repair_requests(&mut batch, &mut stats);
|
||||||
|
assert_eq!(num_well_formed, 1);
|
||||||
|
pkt.meta_mut().size = 5;
|
||||||
|
let mut batch = PacketBatch::new(vec![pkt]);
|
||||||
|
let mut stats = ServeRepairStats::default();
|
||||||
|
let num_well_formed = discard_malformed_repair_requests(&mut batch, &mut stats);
|
||||||
|
assert_eq!(num_well_formed, 0);
|
||||||
|
assert_eq!(stats.err_malformed, 1);
|
||||||
|
|
||||||
|
let request = RepairProtocol::WindowIndex {
|
||||||
|
header: repair_request_header_for_tests(),
|
||||||
|
slot: 123,
|
||||||
|
shred_index: 456,
|
||||||
|
};
|
||||||
|
let mut pkt = Packet::from_data(None, &request).unwrap();
|
||||||
|
let mut batch = PacketBatch::new(vec![pkt.clone()]);
|
||||||
|
let mut stats = ServeRepairStats::default();
|
||||||
|
let num_well_formed = discard_malformed_repair_requests(&mut batch, &mut stats);
|
||||||
|
assert_eq!(num_well_formed, 1);
|
||||||
|
pkt.meta_mut().size = 8;
|
||||||
|
let mut batch = PacketBatch::new(vec![pkt]);
|
||||||
|
let mut stats = ServeRepairStats::default();
|
||||||
|
let num_well_formed = discard_malformed_repair_requests(&mut batch, &mut stats);
|
||||||
|
assert_eq!(num_well_formed, 0);
|
||||||
|
assert_eq!(stats.err_malformed, 1);
|
||||||
|
|
||||||
|
let request = RepairProtocol::AncestorHashes {
|
||||||
|
header: repair_request_header_for_tests(),
|
||||||
|
slot: 123,
|
||||||
|
};
|
||||||
|
let mut pkt = Packet::from_data(None, &request).unwrap();
|
||||||
|
let mut batch = PacketBatch::new(vec![pkt.clone()]);
|
||||||
|
let mut stats = ServeRepairStats::default();
|
||||||
|
let num_well_formed = discard_malformed_repair_requests(&mut batch, &mut stats);
|
||||||
|
assert_eq!(num_well_formed, 1);
|
||||||
|
pkt.meta_mut().size = 1;
|
||||||
|
let mut batch = PacketBatch::new(vec![pkt]);
|
||||||
|
let mut stats = ServeRepairStats::default();
|
||||||
|
let num_well_formed = discard_malformed_repair_requests(&mut batch, &mut stats);
|
||||||
|
assert_eq!(num_well_formed, 0);
|
||||||
|
assert_eq!(stats.err_malformed, 1);
|
||||||
|
|
||||||
|
let request = RepairProtocol::LegacyOrphan(LegacyContactInfo::default(), 123);
|
||||||
|
let mut pkt = Packet::from_data(None, &request).unwrap();
|
||||||
|
let mut batch = PacketBatch::new(vec![pkt.clone()]);
|
||||||
|
let mut stats = ServeRepairStats::default();
|
||||||
|
let num_well_formed = discard_malformed_repair_requests(&mut batch, &mut stats);
|
||||||
|
assert_eq!(num_well_formed, 1);
|
||||||
|
pkt.meta_mut().size = 3;
|
||||||
|
let mut batch = PacketBatch::new(vec![pkt]);
|
||||||
|
let mut stats = ServeRepairStats::default();
|
||||||
|
let num_well_formed = discard_malformed_repair_requests(&mut batch, &mut stats);
|
||||||
|
assert_eq!(num_well_formed, 0);
|
||||||
|
assert_eq!(stats.err_malformed, 1);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_deserialize_signed_request() {
|
fn test_serialize_deserialize_signed_request() {
|
||||||
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
||||||
|
|
Loading…
Reference in New Issue