Repository navigation
feat: store repeater-reported node names (/names) and resolve by them - #17
Merged
Merged
Conversation
…/names CoreDrive RX v1.20.0 asks a repeater for its own name (ANON_REQ_TYPE_OWNER) when this instance has none for it, and publishes the answer as NODE_NAME on /names. Until now the ingestor dropped that subtopic. - New case "names" in the client topic switch (cmd/ingestor/main.go), gated on clientNodeNames.enabled, default off. - handleClientNodeNames (cmd/ingestor/client_names.go): target must be 64 hex (targetPubkeyRe, as on /regions). The name is trimmed of spaces and NUL padding and dropped when empty, over 31 runes (firmware node_name[32], CommonCLI.h:27), invalid UTF-8, or holding a control character. GPS optional. - Table client_node_names: observations, not state, UNIQUE(target, rx_pubkey, observed_at), indexed on (target, observed_at) and observed_at. - Retention retention.clientNodeNamesDays (0 = keep), startup prune plus the existing daily ticker. - Contract in docs/client-rx-coverage.md, keys in config.example.json. Tests: handler, validation cases, idempotent redelivery, newest observed_at wins, prune, gate on/off (off does not fall through to the observer path). Full ingestor suite passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A repeater asked for its name over /names usually has no nodes row, so /api/nodes/resolve and the coverage tooltips could not name it. lookupPrefixes (cmd/server/client_names.go) now counts candidates in nodes and in client_node_names, one LIMIT 2 term per source per key, still one query per chunk of 200 keys (400 compound terms, under SQLite's 500): - unique pubkey across both sources: name from nodes when non-empty, else the newest client-reported name (by observed_at) - different pubkeys across the sources: ambiguous, as before - blacklist and hidden name prefixes apply whichever source named it handleResolvePrefix and batchResolveHeardKeys both go through it, so the tooltips need no frontend change. The table is probed with a latch and re-probed while absent: the ingestor creates it, and a database without it resolves from nodes alone, as before. Tests: client-only node, nameless nodes row, advert name wins, cross-source ambiguity, hidden, blacklisted, absent-then-created table, 250 keys over two chunks. Full server suite passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The region-answers section said /regions is accepted under clientRxCoverage.enabled. The ingestor dispatches it on cfg.ClientRegionsEnabled() (cmd/ingestor/main.go, case "regions"), which is also what docs/client-regions.md tells operators to set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ncy test nodeNameMsg reads the clock, so building the message twice gave two observations a millisecond apart on the race-detector runner (rows = 2, run 38880444861). Build it once and hand it to the handler twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CoreDrive RX v1.20.0 asks a repeater for its own name (
ANON_REQ_TYPE_OWNER) when this instance has none for it, and publishes the answer asNODE_NAMEonmeshcore/client/{pk}/names. This stores those answers and uses them where a name is resolved.494583b9Ingestor: newnamessubtopic, gated onclientNodeNames.enabled(default off). It stores into a new tableclient_node_names(observations,UNIQUE(target, rx_pubkey, observed_at)).targetmust be 64 hex.node_name[32],src/helpers/CommonCLI.h:27), invalid UTF-8, or holding a control character.retention.clientNodeNamesDays(0 = keep).ef0a77b7Server:lookupPrefixescounts candidates innodesandclient_node_names./api/nodes/resolveandbatchResolveHeardKeys(coverage tooltips) both use it.observed_at.nodesalone, and the table is re-probed until the ingestor creates it.fab6dc78Docs: the/regionssection namedclientRxCoverage.enabledas its switch. The code usesclientRegions.enabled.Compatibility
/names: nothing changes for it./namessilently (nocase), so CoreDrive v1.20.0 works against either./api/nodes/resolvekeeps its response shape{prefix, pubkey?, name?, ambiguous}.Performance
lookupPrefixesadds oneLIKE prefix%term per key onclient_node_names, served byidx_cnn_target(target, observed_at). It is still one query per chunk of 200 keys, which is 400 compound terms, under SQLite's default 500. Covered byTestLookupPrefixesManyKeys(250 keys over two chunks). Not benchmarked: the table holds one row per answer, and the expected size is in the hundreds.Trust
Any companion the broker lets publish can report a name for any repeater, and the newest report wins. That is the same model as
/regions.clientRxCoverage.requireLinkedCompanionlimits it to linked companions.Test plan
go test ./...incmd/ingestorandcmd/server: passobserved_atwins, prune, gate on/off without observer-path fall-through, client-only node, namelessnodesrow, advert name wins, cross-source ambiguity, hidden, blacklisted, absent-then-created tableclientNodeNames.enabled, a real/namesmessage,/api/nodes/resolveand a coverage tooltip in the browserUpstream: fork-only for now. A clean PR against
upstream/mastercomes later.