diff --git a/docs/design/fips-bloom-filters.md b/docs/design/fips-bloom-filters.md index 1e7f2ca..d0fce16 100644 --- a/docs/design/fips-bloom-filters.md +++ b/docs/design/fips-bloom-filters.md @@ -360,14 +360,14 @@ control socket and `fipstop` dashboard. (See `compute_mesh_size()` in The estimator refuses to produce a value when any contributing filter is above the antipoison FPR cap (`node.bloom.max_inbound_fpr`, -default `0.10`); a partial aggregate would silently underestimate. +default `0.20`); a partial aggregate would silently underestimate. Consumers handle the resulting `None` by displaying an "unknown" state rather than a misleading number. ## Antipoison: Inbound FPR Cap Inbound `FilterAnnounce` payloads are checked against -`node.bloom.max_inbound_fpr` (default `0.10`). Filters whose +`node.bloom.max_inbound_fpr` (default `0.20`). Filters whose estimated false positive rate exceeds the cap are dropped silently (no NACK on the wire) — they would otherwise inflate downstream candidate evaluation cost without contributing useful discrimination. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index f8de395..35d1f4b 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -277,7 +277,7 @@ Controls tree construction and parent selection. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `node.bloom.update_debounce_ms` | u64 | `500` | Debounce interval for filter update propagation | -| `node.bloom.max_inbound_fpr` | f64 | `0.10` | Antipoison cap: reject inbound `FilterAnnounce` frames whose advertised false-positive rate exceeds this value. Valid range `(0.0, 1.0)`. The default `0.10` corresponds to fill 0.631 at k=5 (≈1,630 entries on the 1 KB filter); a saturated/poisoned filter is still ~100% FPR and rejected | +| `node.bloom.max_inbound_fpr` | f64 | `0.20` | Antipoison cap: reject inbound `FilterAnnounce` frames whose advertised false-positive rate exceeds this value. Valid range `(0.0, 1.0)`. The default `0.20` corresponds to fill 0.7248 at k=5 (≈2,114 entries on the 1 KB filter); a saturated/poisoned filter is still ~100% FPR and rejected | Bloom filter size (1 KB), hash count (5), and size classes are protocol constants and not configurable. @@ -944,7 +944,7 @@ node: flap_dampening_secs: 120 # extended hold-down on flap bloom: update_debounce_ms: 500 - max_inbound_fpr: 0.10 # antipoison cap on inbound FilterAnnounce FPR + max_inbound_fpr: 0.20 # antipoison cap on inbound FilterAnnounce FPR session: default_ttl: 64 pending_packets_per_dest: 16 diff --git a/src/config/node.rs b/src/config/node.rs index 3b1a8bd..f791071 100644 --- a/src/config/node.rs +++ b/src/config/node.rs @@ -635,8 +635,8 @@ pub struct BloomConfig { pub update_debounce_ms: u64, /// Antipoison cap: reject inbound FilterAnnounce whose FPR exceeds /// this value (`node.bloom.max_inbound_fpr`). Valid range `(0.0, 1.0)`. - /// Default `0.10` ≈ fill 0.631 at k=5 ≈ ~1,630 entries on the 1 KB - /// filter (Swamidass–Baldi). Raised from 0.05 so aggregates that are + /// Default `0.20` ≈ fill 0.7248 at k=5 ≈ ~2,114 entries on the 1 KB + /// filter (Swamidass–Baldi). Raised from 0.10 so aggregates that are /// legitimately near their operating ceiling are not rejected before /// the network reaches the fixed-filter capacity limit; conceptually /// distinct from future autoscaling hysteresis setpoints — same unit, @@ -648,8 +648,8 @@ pub struct BloomConfig { impl Default for BloomConfig { fn default() -> Self { Self { - update_debounce_ms: 500, - max_inbound_fpr: 0.10, + update_debounce_ms: Self::default_update_debounce_ms(), + max_inbound_fpr: Self::default_max_inbound_fpr(), } } } @@ -659,7 +659,7 @@ impl BloomConfig { 500 } fn default_max_inbound_fpr() -> f64 { - 0.10 + 0.20 } }