feat: populate BootstrapManager cache from client peer interactions#48
Conversation
The quote, chunk PUT, and chunk GET paths now feed a shared helper that upserts peers on success via add_discovered_peer and records latency/success on both outcomes via update_peer_metrics. Cold-start clients can now load real, quality-scored peers from the persisted bootstrap cache instead of always restarting from the 7 bundled peers. Failures never insert, so unreachable peers don't consume cache quota. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Solid pull — the plumbing shape is right, the helper is scoped correctly, and the failure-path comment captures the intent. A couple of correctness issues though, and the test story doesn't actually prove the headline claim yet. What I'd want before merging
P2 — polish
Nits
(1) and (2) are blockers for me. (3) is a blocker if we ever want to use the RTTs for anything downstream; if the current consumer just needs success/failure, feel free to mark it P2 and file a follow-up. |
Blockers: - Plumb explicit `success: bool` from each call site's `Ok` branch instead of inferring from error variants. Previously `Err::Protocol`, `::Payment`, `::Serialization`, `::InvalidData`, and remote PutResponse::Error all fired `add_discovered_peer` + wrote an RTT — the opposite of the stated "failures never insert" invariant. - Drop RTT on the PUT path. `chunk_put_with_proof` wraps a ~4 MB payload upload, so the wall-clock was dominated by the uploader's uplink rather than the peer's responsiveness. Quote-path and GET-path RTTs still feed quality scoring. - Add a cold-start-from-disk test that populates a BootstrapManager (via `add_peer_trusted` to skip the /24 rate limiter), saves, drops, reopens against the same cache_dir, and asserts peers reload. Closes the loop on the cold-start value prop. Polish: - Prefer globally-routable socket addresses when picking a peer's cache key. Previously a peer advertising `[10.0.0.5, 203.0.113.1]` would be keyed under the RFC1918 address and metrics recorded over the public address would land on a stale entry. - Fold the weak "after_download >= before_download" assertion into the main test (now performs PUT + GET + asserts cache grew). The /24 rate limiter saturates during the PUT, so a standalone download assertion carries no information. Nits: - Use `as u64` for elapsed millis (saturates only after ~584M years). - Move `record_peer_outcome` out of `client/mod.rs` into its own `client/peer_cache.rs` module. - Doc now notes that both upstream calls silently discard errors. Test comment on the 3-peer ceiling is rewritten to describe both Sybil mechanisms accurately: `BootstrapIpLimiter` (IP diversity, exempted for loopback) and `JoinRateLimiter` (temporal, NOT exempted) — the latter is what caps /24 inserts at 3/hour. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Addressed in Blockers
P2
Nits
One correction worth flaggingThe test comment's attribution to the /24 rate limiter is correct — not the IP-diversity limiter. Verified by reading both:
So the observed ceiling of 3 peers in the cache is the temporal rate limiter biting on the single |
`203.0.113.0/24` (TEST-NET-3) and `2001:db8::/32` are documentation prefixes that `is_documentation()` / my v6 approximation correctly reject. The previous test asserted the opposite on those ranges, which passed locally on Windows but failed on Linux/macOS CI. Use `8.8.8.8` and `2606:4700:4700::1111` instead, and add an assertion that the TEST-NET-3 range IS rejected (that's the behaviour we actually want). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
add_discovered_peer+update_peer_metricsso saorsa-core's BootstrapManager cache fills with real, quality-scored peers during normal activityTest plan
e2e_bootstrap_cachetests (upload + download) prove cache grows after peer interactionse2e_chunkregression (9/9) — directly exercises modifiedchunk_put_with_proofandchunk_get_from_peere2e_data(6/6),e2e_file(4/4),e2e_huge_file::64mb_round_tripin isolation — higher-level coveragedaemon_integration(5/5)cargo clippy --workspace --all-targets --all-features -- -D warningscleancargo fmt --checkcleanbootstrap_cache.jsonappears on a live multi-subnet testnet after ≥5 min activity (post-merge)🤖 Generated with Claude Code