mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 16:24:45 +00:00
Derive each peer's npub once instead of once per tick
The per-tick stats snapshot ran a bech32 encode for every tracked peer, and for the common mesh peer — one with no hosts-file entry and no configured alias — it ran a second one, because the display-name fallback chain bottoms out in the same encode. At 240 peers that was 14.1 ms per tick, a third of the tick body and its second largest cost, all of it recomputing values that cannot change. Cache the npub and the shortened npub on the peer at construction. An npub is a pure function of the peer's public key, and the identity is never mutated after construction: there is no setter, no identity_mut, and no assignment to the field anywhere in the tree, so the cache cannot go stale. The display name itself is deliberately NOT cached. Two of its inputs do mutate at runtime — the alias map and the host map, the latter reloaded on this same tick — so a resolved name stored on the peer would go stale on an alias change or a hosts reload. Only the immutable component is memoized. Tests cover both constructors, that the cached npub matches the identity, and that the display name still tracks an alias change. The memoization itself is asserted by pointer stability rather than by timing, so it is deterministic under load. Three deliberate breaks were each caught by exactly one test: re-deriving instead of memoizing, populating one constructor's cache from the wrong source, and reordering the display-name fallback so it stops honoring aliases.
This commit is contained in:
@@ -2119,3 +2119,49 @@ fn test_transport_drop_state_steady_counter_fires_once() {
|
||||
assert!(!s.observe_drops(7));
|
||||
assert!(!s.observe_drops(7));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peer_display_name_uses_cached_short_npub() {
|
||||
// Path 3 of `peer_display_name` (no host entry, no alias) reads the
|
||||
// per-peer cached short npub; it must still equal the value derived
|
||||
// from the peer's identity.
|
||||
let mut node = make_node();
|
||||
let peer_identity_full = Identity::generate();
|
||||
let peer_addr = *peer_identity_full.node_addr();
|
||||
let peer_identity = PeerIdentity::from_pubkey(peer_identity_full.pubkey());
|
||||
node.peers
|
||||
.insert(peer_addr, ActivePeer::new(peer_identity, LinkId::new(1), 0));
|
||||
|
||||
assert_eq!(
|
||||
node.peer_display_name(&peer_addr),
|
||||
peer_identity.short_npub()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peer_display_name_tracks_alias_change() {
|
||||
// The display name is NOT cached on the peer: `peer_aliases` is a
|
||||
// runtime-mutable map (`update_peers` inserts and removes entries), so
|
||||
// a cached name would go stale. Caching only the immutable short npub
|
||||
// must leave that tracking intact.
|
||||
let mut node = make_node();
|
||||
let peer_identity_full = Identity::generate();
|
||||
let peer_addr = *peer_identity_full.node_addr();
|
||||
let peer_identity = PeerIdentity::from_pubkey(peer_identity_full.pubkey());
|
||||
node.peers
|
||||
.insert(peer_addr, ActivePeer::new(peer_identity, LinkId::new(1), 0));
|
||||
|
||||
assert_eq!(
|
||||
node.peer_display_name(&peer_addr),
|
||||
peer_identity.short_npub()
|
||||
);
|
||||
|
||||
node.peer_aliases.insert(peer_addr, "gateway".to_string());
|
||||
assert_eq!(node.peer_display_name(&peer_addr), "gateway");
|
||||
|
||||
node.peer_aliases.remove(&peer_addr);
|
||||
assert_eq!(
|
||||
node.peer_display_name(&peer_addr),
|
||||
peer_identity.short_npub()
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user