Files
swaitsandClaude Opus 4.7 7e39781318 Initial release: v0.1.0
Passphrase-based peer rendezvous for iroh-gossip swarms over the public
Mainline DHT. Two nodes that share a passphrase + application salt find
each other and join the same gossip topic — no bootstrap server, no
prior knowledge of peer addresses.

The algorithm is a clock-free variant of HyParView-style partition
healing on BEP 44 mutable items, with K-sharded slots, logical aging
with random-tie eviction, vouching of up to V neighbors at age 1, and
a two-layer AEAD record envelope. Full spec in PROTOCOL.md.

Ships with:

* 119 tests (unit / property / integration / doctest) all green
* 100% mutation-testing catch rate (cargo-mutants)
* cargo-fuzz harnesses for the parse surface
* Kani proofs of no-UB / no-panic on crypto::epoch_of and
  wire::decode_entries across their full symbolic input spaces
* Stateright distributed-system model: safety invariants S1 + S2
  proved exhaustively for N ≤ 6, K ≤ 3; liveness witness under weak
  fairness
* Miri green on the synchronous modules
* cargo-deny + cargo-audit clean
* criterion benches
* Full-matrix CI (Linux + macOS + Windows × stable + MSRV 1.93.0)
* Dedicated nightly lane for Miri / mutation / fuzz / Kani / Stateright

Pinned iroh 0.98.x. License MIT.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 22:52:46 -06:00

77 lines
2.3 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Keeps `PROTOCOL.md §2` parameter defaults and `§3` wire-format constants
//! in sync with the code. Changing any number in the spec or the code
//! without updating the other fails this test.
use std::time::Duration;
use iroh_gossip_rendezvous::defaults::{
DEFAULT_EPOCH_WRITES, DEFAULT_HEAL_PERIOD, DEFAULT_JITTER, DEFAULT_MAX_AGE,
DEFAULT_MAX_ENTRIES, DEFAULT_MAX_VOUCHES, DEFAULT_SHARDS, DEFAULT_WRITE_PERIOD,
};
// ── §2 Parameter defaults ──────────────────────────────────────────────
#[test]
fn spec_section_2_default_shards_is_3() {
// PROTOCOL.md §2 table: K = 3.
assert_eq!(DEFAULT_SHARDS, 3);
}
#[test]
fn spec_section_2_default_max_entries_is_27() {
// PROTOCOL.md §2 table + §3 byte budget: B = 27.
assert_eq!(DEFAULT_MAX_ENTRIES, 27);
}
#[test]
fn spec_section_2_default_max_age_is_27() {
// PROTOCOL.md §2 table + §7 (A_max = B): A_max = 27.
assert_eq!(DEFAULT_MAX_AGE, 27);
}
#[test]
fn spec_section_2_default_max_vouches_is_3() {
// PROTOCOL.md §2 table: V = 3.
assert_eq!(DEFAULT_MAX_VOUCHES, 3);
}
#[test]
fn spec_section_2_default_epoch_writes_is_64() {
// PROTOCOL.md §2 table: E = 64 writes per wrapper-key epoch.
assert_eq!(DEFAULT_EPOCH_WRITES, 64);
}
#[test]
fn spec_section_2_default_write_period_is_5_minutes() {
// PROTOCOL.md §2 table: T_w = 5 min.
assert_eq!(DEFAULT_WRITE_PERIOD, Duration::from_secs(300));
}
#[test]
fn spec_section_2_default_heal_period_is_30_seconds() {
// PROTOCOL.md §2 table: T_h = 30 s.
assert_eq!(DEFAULT_HEAL_PERIOD, Duration::from_secs(30));
}
#[test]
fn spec_section_2_default_jitter_is_half() {
// PROTOCOL.md §2 table: σ = ±50% → factor 0.5.
assert!((DEFAULT_JITTER - 0.5_f32).abs() < f32::EPSILON);
}
#[test]
fn spec_section_7_a_max_equals_b() {
// PROTOCOL.md §7: "Age cap equals size cap. A_max = B."
assert_eq!(DEFAULT_MAX_AGE as usize, DEFAULT_MAX_ENTRIES);
}
#[test]
fn spec_section_7_t_h_is_one_tenth_t_w() {
// PROTOCOL.md §7: "Heal-loop period T_h ≪ T_w. T_h/T_w = 1/10 is the knee."
let ratio = DEFAULT_HEAL_PERIOD.as_secs_f32() / DEFAULT_WRITE_PERIOD.as_secs_f32();
assert!(
(ratio - 0.1).abs() < 0.001,
"T_h/T_w should be ≈ 0.1, got {ratio}"
);
}