mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 00:04:54 +00:00
Merge refactor-sans-io: converge next bloom onto v1-sans-IO
Forward-merge the master-line bloom relocation into the next line, discarding next's v1.5 bloom draft (RLE codec, XOR-diff delta, FilterNack/0x21, adaptive sizing) and converging both lines onto the identical proto/bloom v1-sans-IO module. This is a deliberate, temporary wire regression on the next line: the v2 bloom is rebuilt fresh, sans-IO from day one, on both lines later. Nothing outside the bloom feature depended on the v1.5-specific surface. proto/bloom is now byte-identical across both integration lines.
This commit is contained in:
@@ -455,8 +455,8 @@ async fn test_bloom_filter_split_horizon() {
|
||||
/// counted once, not the double-count fingerprint.
|
||||
#[test]
|
||||
fn compute_mesh_size_counts_each_peer_filter_once() {
|
||||
use crate::bloom::BloomFilter;
|
||||
use crate::peer::ActivePeer;
|
||||
use crate::proto::bloom::BloomFilter;
|
||||
use crate::proto::stp::ParentDeclaration;
|
||||
|
||||
let mut node = make_node();
|
||||
@@ -550,8 +550,8 @@ fn compute_mesh_size_counts_each_peer_filter_once() {
|
||||
/// `estimated_mesh_size` carries.
|
||||
#[test]
|
||||
fn compute_mesh_size_unions_overlapping_filters() {
|
||||
use crate::bloom::BloomFilter;
|
||||
use crate::peer::ActivePeer;
|
||||
use crate::proto::bloom::BloomFilter;
|
||||
|
||||
let mut node = make_node();
|
||||
|
||||
@@ -632,8 +632,8 @@ fn compute_mesh_size_unions_overlapping_filters() {
|
||||
/// removes the parent, and asserts the estimate does not collapse.
|
||||
#[test]
|
||||
fn compute_mesh_size_stable_across_parent_drop_with_cross_link() {
|
||||
use crate::bloom::BloomFilter;
|
||||
use crate::peer::ActivePeer;
|
||||
use crate::proto::bloom::BloomFilter;
|
||||
|
||||
let mut node = make_node();
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
//! Registry-counter coverage tests for the bloom-v2 metric counters that
|
||||
//! the mesh-lab suites do not reliably exercise.
|
||||
//!
|
||||
//! The send-path bloom counters (`deltas_sent`, `full_sends`,
|
||||
//! `total_compressed_bytes`, `total_raw_bytes`) fire on every filter
|
||||
//! announce and are covered by the steady-state suites. The three
|
||||
//! condition-dependent counters (`nacks_sent`, `nacks_received`,
|
||||
//! `size_changes`) only fire on out-of-sequence deltas, inbound NACKs,
|
||||
//! and adaptive resizes — none of which occur in the stable, lossless
|
||||
//! mesh-lab scenarios. These tests drive each of those paths directly and
|
||||
//! assert the registry counter increments.
|
||||
|
||||
use super::*;
|
||||
use crate::bloom::{BloomFilter, V1_SIZE_CLASS};
|
||||
use crate::peer::ActivePeer;
|
||||
use crate::protocol::{FilterAnnounce, FilterNack};
|
||||
|
||||
/// Inject a synthetic active peer with a known NodeAddr; returns it.
|
||||
fn inject_peer(node: &mut Node) -> NodeAddr {
|
||||
let peer_identity = make_peer_identity();
|
||||
let peer_addr = *peer_identity.node_addr();
|
||||
let peer = ActivePeer::new(peer_identity, LinkId::new(1), 0);
|
||||
node.peers.insert(peer_addr, peer);
|
||||
peer_addr
|
||||
}
|
||||
|
||||
/// Encode a FilterAnnounce to the payload format handle_filter_announce
|
||||
/// expects (msg_type byte stripped).
|
||||
fn encode_announce(announce: &FilterAnnounce) -> Vec<u8> {
|
||||
let (mut full, _stats) = announce.encode().unwrap();
|
||||
full.remove(0); // strip msg_type byte
|
||||
full
|
||||
}
|
||||
|
||||
/// An out-of-sequence delta to a peer with no stored filter makes the node
|
||||
/// send a NACK, bumping `nacks_sent`.
|
||||
#[tokio::test]
|
||||
async fn test_bloom_nacks_sent_counter() {
|
||||
let mut node = make_node();
|
||||
let peer_addr = inject_peer(&mut node);
|
||||
|
||||
// Fresh peer: filter_sequence == 0. A delta whose base_seq does not
|
||||
// match the expected base (0) is out-of-sequence → NACK.
|
||||
let announce = FilterAnnounce::delta(BloomFilter::new(), 2, 5, V1_SIZE_CLASS);
|
||||
let payload = encode_announce(&announce);
|
||||
|
||||
node.handle_filter_announce(&peer_addr, &payload).await;
|
||||
|
||||
assert_eq!(
|
||||
node.metrics().bloom.nacks_sent.get(),
|
||||
1,
|
||||
"registry nacks_sent must increment on out-of-sequence delta"
|
||||
);
|
||||
}
|
||||
|
||||
/// An inbound FilterNack bumps `nacks_received`.
|
||||
#[tokio::test]
|
||||
async fn test_bloom_nacks_received_counter() {
|
||||
let mut node = make_node();
|
||||
let peer_addr = inject_peer(&mut node);
|
||||
|
||||
let mut payload = FilterNack { expected_seq: 7 }.encode();
|
||||
payload.remove(0); // strip msg_type byte (decode expects the seq only)
|
||||
|
||||
node.handle_filter_nack(&peer_addr, &payload).await;
|
||||
|
||||
assert_eq!(
|
||||
node.metrics().bloom.nacks_received.get(),
|
||||
1,
|
||||
"registry nacks_received must increment on inbound NACK"
|
||||
);
|
||||
}
|
||||
|
||||
/// A fresh Full node starts at V1_SIZE_CLASS with a nearly empty outgoing
|
||||
/// filter (just its own addr), so the first adaptive-sizing pass steps the
|
||||
/// size class down, bumping `size_changes`.
|
||||
#[tokio::test]
|
||||
async fn test_bloom_size_changes_counter() {
|
||||
let mut node = make_node();
|
||||
// check_adaptive_sizing needs at least one peer for the representative
|
||||
// outgoing-filter computation.
|
||||
let _peer = inject_peer(&mut node);
|
||||
|
||||
assert_eq!(
|
||||
node.bloom_state.size_class(),
|
||||
V1_SIZE_CLASS,
|
||||
"fresh node starts at the v1 size class"
|
||||
);
|
||||
|
||||
node.check_bloom_state().await;
|
||||
|
||||
assert_eq!(
|
||||
node.metrics().bloom.size_changes.get(),
|
||||
1,
|
||||
"registry size_changes must increment on adaptive resize"
|
||||
);
|
||||
assert_eq!(
|
||||
node.bloom_state.size_class(),
|
||||
V1_SIZE_CLASS - 1,
|
||||
"near-empty outgoing filter steps the size class down"
|
||||
);
|
||||
}
|
||||
@@ -7,9 +7,9 @@
|
||||
//! bloom.rs.
|
||||
|
||||
use super::*;
|
||||
use crate::bloom::{BloomFilter, DEFAULT_FILTER_SIZE_BITS, DEFAULT_HASH_COUNT};
|
||||
use crate::peer::ActivePeer;
|
||||
use crate::protocol::FilterAnnounce;
|
||||
use crate::proto::bloom::FilterAnnounce;
|
||||
use crate::proto::bloom::{BloomFilter, DEFAULT_FILTER_SIZE_BITS, DEFAULT_HASH_COUNT};
|
||||
|
||||
/// Inject a synthetic active peer into the node with a known NodeAddr.
|
||||
/// Returns the peer's NodeAddr.
|
||||
@@ -24,7 +24,7 @@ fn inject_peer(node: &mut Node) -> NodeAddr {
|
||||
/// Encode a FilterAnnounce to the payload format handle_filter_announce
|
||||
/// expects (msg_type byte stripped).
|
||||
fn encode_payload(announce: &FilterAnnounce) -> Vec<u8> {
|
||||
let (mut full, _stats) = announce.encode().unwrap();
|
||||
let mut full = announce.encode().unwrap();
|
||||
full.remove(0); // strip msg_type byte
|
||||
full
|
||||
}
|
||||
@@ -40,7 +40,7 @@ async fn test_m1_rejects_all_ones_filter_announce() {
|
||||
DEFAULT_HASH_COUNT,
|
||||
)
|
||||
.unwrap();
|
||||
let announce = FilterAnnounce::full(all_ones, 1, 1);
|
||||
let announce = FilterAnnounce::new(all_ones, 1);
|
||||
let payload = encode_payload(&announce);
|
||||
|
||||
let before_fill_exceeded = node.metrics().bloom.fill_exceeded.get();
|
||||
@@ -88,7 +88,7 @@ async fn test_m1_accepts_sub_cap_filter() {
|
||||
bytes[0] = i;
|
||||
filter.insert(&NodeAddr::from_bytes(bytes));
|
||||
}
|
||||
let announce = FilterAnnounce::full(filter, 1, 1);
|
||||
let announce = FilterAnnounce::new(filter, 1);
|
||||
let payload = encode_payload(&announce);
|
||||
|
||||
let before_fill_exceeded = node.metrics().bloom.fill_exceeded.get();
|
||||
@@ -135,7 +135,7 @@ async fn test_m1_sequence_not_advanced_allows_recovery() {
|
||||
DEFAULT_HASH_COUNT,
|
||||
)
|
||||
.unwrap();
|
||||
let bad_announce = FilterAnnounce::full(bad, 1, 1);
|
||||
let bad_announce = FilterAnnounce::new(bad, 1);
|
||||
node.handle_filter_announce(&peer_addr, &encode_payload(&bad_announce))
|
||||
.await;
|
||||
assert_eq!(
|
||||
@@ -152,7 +152,7 @@ async fn test_m1_sequence_not_advanced_allows_recovery() {
|
||||
bytes[0] = i;
|
||||
good.insert(&NodeAddr::from_bytes(bytes));
|
||||
}
|
||||
let good_announce = FilterAnnounce::full(good, 1, 1);
|
||||
let good_announce = FilterAnnounce::new(good, 1);
|
||||
node.handle_filter_announce(&peer_addr, &encode_payload(&good_announce))
|
||||
.await;
|
||||
|
||||
|
||||
@@ -1160,8 +1160,8 @@ async fn test_open_discovery_sweep_queues_eligible_skips_filtered() {
|
||||
/// that `initiate_lookup` ran fresh on each attempt.
|
||||
#[tokio::test]
|
||||
async fn test_check_pending_lookups_default_sequence_unreachable() {
|
||||
use crate::bloom::BloomFilter;
|
||||
use crate::peer::ActivePeer;
|
||||
use crate::proto::bloom::BloomFilter;
|
||||
use crate::proto::discovery::PendingLookup;
|
||||
use crate::transport::LinkId;
|
||||
use std::sync::mpsc;
|
||||
|
||||
@@ -8,7 +8,6 @@ mod acl;
|
||||
#[cfg(target_os = "linux")]
|
||||
mod ble;
|
||||
mod bloom;
|
||||
mod bloom_metrics;
|
||||
mod bloom_poison;
|
||||
mod bootstrap;
|
||||
mod decrypt_failure;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//! filter priority, greedy tree routing, and tie-breaking.
|
||||
|
||||
use super::*;
|
||||
use crate::bloom::BloomFilter;
|
||||
use crate::proto::bloom::BloomFilter;
|
||||
use crate::proto::stp::{ParentDeclaration, TreeCoordinate};
|
||||
use spanning_tree::{
|
||||
TestNode, cleanup_nodes, drain_all_packets, generate_random_edges, initiate_handshake,
|
||||
|
||||
Reference in New Issue
Block a user