Skip to content

extend SMP protocol to support name availability queries - #1863

Open
brenzi wants to merge 29 commits into
ab/snrc-resolver-expiry-and-availabilityfrom
ab/snrc-resolver-SMP-NAVL
Open

extend SMP protocol to support name availability queries#1863
brenzi wants to merge 29 commits into
ab/snrc-resolver-expiry-and-availabilityfrom
ab/snrc-resolver-SMP-NAVL

Conversation

@brenzi

@brenzi brenzi commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

Let users query name availability by labelhash (without revealing plaintext name unless it resolves)
They should get a precise answer with details in all possible cases (expired, grace, auction, reserved)

  • also lets resolver report auction info: Name is available, but at premium price - or wait.

Assumes these get merged and deployed for .simplex, but PR works against .testing names as well.

Comment thread src/Simplex/Messaging/Server/Names.hs Outdated
Comment thread src/Simplex/Messaging/Server/Names.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
brenzi and others added 7 commits September 7, 2026 14:20
Co-authored-by: Evgeny <evgeny@poberezkin.com>
Co-authored-by: Evgeny <evgeny@poberezkin.com>
Co-authored-by: Evgeny <evgeny@poberezkin.com>
Co-authored-by: Evgeny <evgeny@poberezkin.com>
Co-authored-by: Evgeny <evgeny@poberezkin.com>
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs Outdated
Comment thread src/Simplex/Messaging/Protocol.hs
Comment thread src/Simplex/Messaging/SimplexName.hs Outdated
Comment thread src/Simplex/Messaging/SimplexName.hs Outdated
Comment thread src/Simplex/Messaging/SimplexName.hs Outdated
@brenzi

brenzi commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

tested e2e locally with hardhat

mocked cases with dummy values:

  ghostname      | can be registered for $10.00 a year
  abc            | can be registered for $10000.00 a year     (tier 3)
  abcd           | can be registered for $1000.00 a year      (tier 4)
  abcde          | can be registered for $100.00 a year       (tier 5)
  abcdef         | can be registered for $10.00 a year        (base)
  ab             | is too short: names need at least 3 characters
  internalname   | is reserved for SimpleX
  trademarkname  | is reserved to protect a trademark
  communityname  | is reserved for the community
  lapsedname     | can be registered for $10.00 a year        (expired = registrable)
  heldlapsed     | is reserved to protect a trademark         (reservation survives expiry)
  gracename      | is registered to someone else, free to register from 2029-02-15

also, too short names can be resolved, just not registered publicly

  resolver  ab.simplex  -> HTTP 200  status=registered  expires=2177738883  contact=<alice's link>
  carol: /c @ab.simplex (2 chars, forced)  | alice: connection started
  carol: /c @xy.simplex (control)          | is too short: names need at least 3 characters
  carol: /c @abc.simplex (control, 3ch)    | can be registered for $10000.00 a year

caveat:

  • Messaging is now inconsistent as it mixes resolvability with registrability

@brenzi
brenzi marked this pull request as ready for review September 9, 2026 07:09
@brenzi
brenzi requested a review from spaced4ndy as a code owner September 9, 2026 07:09
else do
bs <- brReadSome (responseBody res) (maxResponseBytes + 1)
pure $ if BL.length bs > fromIntegral maxResponseBytes then Left BodyTooLarge else Right bs
bs <- brReadSome (responseBody res) (maxResponseBytes + 1)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why status check removed?

Comment on lines +173 to +175
-- | GET <baseUrl><path>, returning the response status and body bytes within the
-- size cap. Redirects are disabled and Authorization is attached only when
-- configured.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some spurious linebreak changes

resolveHttp env name =
(>>= first InvalidJson . J.eitherDecodeStrict . BL.toStrict)
<$> httpGet env ("/resolve/" <> B.unpack (urlEncode True (encodeUtf8 name)))
(>>= nameResp) <$> httpGet env ("/resolve/" <> B.unpack (urlEncode True (encodeUtf8 name)))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that looks like some drive-by refactoring. What is it doing and why?

(Nothing, Nothing) -> Left NOT_FOUND

-- | The resolver's status words. An unknown status is not an answer.
mapStatus :: Maybe NameRecord -> NameStatusResp -> Either NameErrorType NameRegistration

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very complex - what is the problem here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like translation between what resolver returns and what we want in protocol.

We cannot upgrade all servers at once so what resolver returns should be compatible, so splitting "status" to separate record kind of makes sense from this point of view.

But a better solution would have been exposing a different version endpoint in resolver that responds to old server what it wants and to new server what it wants - the same type we defined elsewhere. This would avoid this mapping entirely.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed the resolver and SMP relay get updated at the same time as they are shipped together. But yes, we could just introduce a new version in the url path and stay compatible with the old SMP relays. Anyway, I think it is a good idea to let the resolver respond with the data model that can be parsed straight into the SMP type

@brenzi brenzi Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, now I remember: only one light client and resolver for the cluster, right? Then I suggest we do it properly with a /v2/ path on the resolver

sendProtocolCommand c nm Nothing NoEntity (Cmd SResolver (RSLV name)) >>= \case
RNAME nr -> pure nr
| v >= namesSMPVersion =
sendProtocolCommand c nm Nothing NoEntity (Cmd SResolver (RSLV (nameQuery v name))) >>= \case

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this decision is already made during the protocol encoding - why are we doing it here as well?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like it's a knockdown effect of not putting the right type into the protocol. If we say that whether we use hash or name is version dependent, then RSLV should just accept SimplexDomain and compute its hash during encoding.

RFWD :: EncFwdTransmission -> Command ProxyService -- use CorrId as CbNonce, proxy to relay
-- Resolve SimpleX name.
RSLV :: SimplexDomain -> Command Resolver
RSLV :: NameQuery -> Command Resolver

@epoberezkin epoberezkin Sep 9, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment above - I think it should remain SimplexDomain?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not...

Comment thread src/Simplex/Messaging/Protocol.hs
-- hash, knows neither. The formula is in protocol/simplex-messaging.md.
data NamePricing = NamePricing
{ -- | US cents per year, for the lengths the registry prices specially
rentPrices :: Map Int USDCents,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rentPrices -> registrationPrices


-- | What RSLV asks about. Unlike SimplexDomain, which is always text, this may
-- name a label by its hash.
data NameQuery = NameQuery

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the main source of the messiness and spread of version is this type - instead of being a plain sum, where a name is either domain or hash of domain it tries to make some merged shape that only complicates things. E.g., we know that we never need to look up subdomains as hashes, but this type allows it.

A much simpler type would have been this:

data NameQuery = NQDomain SimplexDomain | NQHash SimplexTLD LabelHash

Then conversion from name to query is always version independent, it's just NQDomain.

Encoding then remains version dependent, and it can send hash only if 1) version supports it 2) it's second level name 3) it's not web name. This would avoid multiple decision points that are currently present about how to encode the name, hashing would become part of encoding.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also simplifies encodings, as it doesn't have to encode components separately - it only needs one-letter tag + either domain (that we already know how to encode) or TLD + hash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants