derive NameRegistration JSON the same way on every build

sumTypeJSON switches to the _owsf form on swift builds, but this JSON is
  the RNAME payload and the resolver's HTTP contract, so a swift client and
  a Linux relay would disagree on every field. taggedObjectJSON is what it
  already resolves to everywhere else.

  The label modifier keeps the reservedReason_ collision escape out of the
  API, as AgentWorkersDetails does: both arms now say reservedReason.
This commit is contained in:
Alain Brenzikofer committed 2026-09-10 14:05:09 +02:00
1 parent 50fc0466e0
commit 288978a181
4 files changed
+13 -7

No files matched your search

+2 -2
View File
@@ -1549,7 +1549,7 @@ seconds since the Unix epoch. Lengths are characters.
|---|---|---|---|
| `expires` | `registered` | number | absent only from a v20/v21 router, which sent the record alone |
| `graceUntil` | `registered` | number | after `expires`; until here only the owner may renew. Absent on the same condition as `expires` |
| `reservedReason_` | `registered` | string | a reason word, present only when the name is held back as well |
| `reservedReason` | `registered` | string | a reason word, present only when the name is held back as well |
| `nameRecord` | `registered` | object | the record, schema below |
| `pricing` | `available` | object | `registrationPrices`, `basePrice` and `minLabelLength`, below |
| `reservedReason` | `reserved` | string | a reason word |
@@ -1566,7 +1566,7 @@ JSON and in a client's own API.
`available` alone means registrable: a name the registry holds back answers
`reserved` instead, so a client has no flags to combine. A reservation on a name
that *is* registered is carried in `reservedReason_`, and is why that name will
that *is* registered is carried in `reservedReason`, and is why that name will
not free up when it expires.
There is no separate answer for an auction. A name past its grace period answers
+1 -1
View File
@@ -744,7 +744,7 @@ def registration(name: str):
"type": "registered",
"expires": reg["expires"],
"graceUntil": reg["graceEnds"],
"reservedReason_": reg["reasonCode"],
"reservedReason": reg["reasonCode"],
"nameRecord": name_record(name),
}
if reg["reasonCode"]:
+8 -2
View File
@@ -23,7 +23,7 @@ import Data.Int (Int64)
import Data.Map.Strict (Map)
import Data.Text (Text)
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, sumTypeJSON)
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, taggedObjectJSON)
import Simplex.Messaging.SystemTime (SystemSeconds)
-- | Resolved name record returned by the names role. JSON keys match the
@@ -132,4 +132,10 @@ oldRegistration nameRecord =
$(JQ.deriveJSON defaultJSON ''NamePricing)
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "NR") ''NameRegistration)
-- taggedObjectJSON, not sumTypeJSON: this JSON is the RNAME payload and the
-- resolver contract, so it must not vary with the swift build flag. The label
-- modifier keeps the reservedReason_ collision escape out of the API.
$( JQ.deriveJSON
(taggedObjectJSON $ dropPrefix "NR") {J.fieldLabelModifier = takeWhile (/= '_')}
''NameRegistration
)
+2 -2
View File
@@ -54,7 +54,7 @@ testNameRecord =
-- from the Haskell value: the literal JSON is the contract with the resolver.
registeredBody :: NameRecord -> LB.ByteString
registeredBody nameRec =
"{\"type\":\"registered\",\"expires\":1813853483,\"graceUntil\":1821629483,\"reservedReason_\":null,\"nameRecord\":" <> J.encode nameRec <> "}"
"{\"type\":\"registered\",\"expires\":1813853483,\"graceUntil\":1821629483,\"reservedReason\":null,\"nameRecord\":" <> J.encode nameRec <> "}"
availableBody :: LB.ByteString
availableBody = "{\"type\":\"available\",\"pricing\":{\"registrationPrices\":{\"3\":12793,\"4\":3198},\"basePrice\":100,\"minLabelLength\":3}}"
@@ -177,7 +177,7 @@ availabilitySpec = do
J.encode NRRTrademark `shouldBe` "\"trademark\""
where
heldBackBody =
"{\"type\":\"registered\",\"expires\":1813853483,\"graceUntil\":1821629483,\"reservedReason_\":\"internal\",\"nameRecord\":" <> J.encode testNameRecord <> "}"
"{\"type\":\"registered\",\"expires\":1813853483,\"graceUntil\":1821629483,\"reservedReason\":\"internal\",\"nameRecord\":" <> J.encode testNameRecord <> "}"
answers body a =
withResolverServer (resolveResp status200 body) $ \port _ -> do
env <- newNamesEnv (testNamesConfig port)