perf(relay): drop per-request hex encode from the membership hot path

Dawn's re-review notes on #3844, both trivial ones:

- check_relay_membership computed hex::encode(pubkey_bytes) before the
  cache lookup, but the only remaining users are the two log lines in
  the NIP-OA branch — a 64-byte heap allocation per authenticated
  request on the cache-hit fast path this PR exists to make cheap. The
  binding now lives inside the auth-tag branch.
- The struct-field doc (state.rs) and the pubsub variant doc
  (cache_invalidation.rs) still enumerated four mutation flows; both
  now list ownership transfer like the fn docstring already did.

Verified: cargo test -p buzz-relay --lib (803/0), invite suite vs
local Postgres (12/0), -p buzz-pubsub (25/0), clippy --all-targets
-D warnings clean, fmt clean.

Co-authored-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
This commit is contained in:
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d
2026-07-31 10:11:13 -04:00
parent 6259b175a4
commit 6c8990b5fa
3 changed files with 3 additions and 3 deletions

View File

@@ -78,7 +78,7 @@ pub enum CacheInvalidation {
ChannelDeleted,
/// Drop one pubkey's relay-membership entry. Mirrors
/// `invalidate_relay_membership` (invite claim, admin add/remove,
/// self-leave).
/// self-leave, ownership transfer).
RelayMembership {
/// Affected member's pubkey bytes.
pubkey: Vec<u8>,

View File

@@ -68,7 +68,6 @@ pub mod relay_members {
return Ok(MembershipDecision::OpenRelay);
}
let pubkey_hex = hex::encode(pubkey_bytes);
let is_member = state
.is_relay_member_cached(community, pubkey_bytes)
.await
@@ -79,6 +78,7 @@ pub mod relay_members {
if state.config.allow_nip_oa_auth {
if let Some(tag_json) = auth_tag_header {
let pubkey_hex = hex::encode(pubkey_bytes);
let agent_pubkey = nostr::PublicKey::from_slice(pubkey_bytes)
.map_err(|e| format!("invalid agent pubkey for NIP-OA check: {e}"))?;

View File

@@ -546,7 +546,7 @@ pub struct AppState {
/// Relay membership cache: (community_id, pubkey_bytes) → is_relay_member.
/// Short TTL (10s) — checked on every authenticated HTTP request and WS
/// AUTH, so this keeps the hot auth path off the writer pool. Invalidated
/// on invite claim, admin add/remove, and self-leave.
/// on invite claim, admin add/remove, self-leave, and ownership transfer.
pub relay_membership_cache: Arc<moka::sync::Cache<(CommunityId, Vec<u8>), bool>>,
/// Accessible channel IDs cache: (community_id, pubkey_bytes) → channel UUIDs.
/// Short TTL (10s) — invalidated on membership or channel visibility changes.