adversarial review (against simplex-chat) fix

This commit is contained in:
Alain Brenzikofer
2026-09-06 18:35:02 +02:00
parent c99cc61b69
commit 5c480277d6
6 changed files with 21 additions and 19 deletions
+5 -6
View File
@@ -177,10 +177,9 @@ premium that halves each day until it reaches zero. A name in that window
reports `auction` instead of `expired`, with `premium` (attoUSD as a decimal
string, since no JSON number holds a 256-bit integer) and `auctionEnds`.
The premium depends only on when the registration lapsed, not on the label, so a
labelhash query gets it too. The base price does depend on the label's length,
which a hashed query does not carry, so `premium` is the surcharge alone and the
client adds the base price.
`premium` is the surcharge alone: it depends only on when the registration
lapsed, so a labelhash query gets it, but the base price depends on the label's
length, which a hash does not carry. The client adds that.
The oracle comes from the controller's `prices()`, so no extra configuration is
needed. Its window is read from the chain; zero days switches the auction off.
@@ -208,10 +207,10 @@ English sentence for a human reading this API. Clients should branch on
| `offensive` | reserved as an offensive name |
| `internal` | reserved for SimpleX |
| `premium` | reserved as a premium name |
| `unknown` | a reason added to the contract after this resolver; still reserved |
A controller from before reasons existed stores a boolean; its `true` reads as
`unspecified`, so nothing needs migrating. An unknown code also reads as
`unspecified` — the name stays reserved either way.
`unspecified`, so nothing needs migrating.
### Querying by labelhash
+3 -1
View File
@@ -115,6 +115,8 @@ RESERVED_REASONS = {
5: ("internal", "reserved for SimpleX"),
6: ("premium", "reserved as a premium name"),
}
# a Reason added to the contract after this resolver: still reserved, unworded
UNKNOWN_REASON = ("unknown", "reserved")
# SLIP-44 coin types (https://github.com/satoshilabs/slips/blob/master/slip-0044.md)
COIN_ETH = 60
@@ -305,7 +307,7 @@ def name_status(name: str):
if status in ("unregistered", "expired"):
code = reservation_reason(tld, token)
if code:
status, reason = "reserved", RESERVED_REASONS.get(code, RESERVED_REASONS[1])
status, reason = "reserved", RESERVED_REASONS.get(code, UNKNOWN_REASON)
elif status == "expired":
auction_ends, premium = auction(tld, expires + grace, now)
if auction_ends:
@@ -485,11 +485,12 @@ class ReservedReasonTests(unittest.TestCase):
self.assertEqual(reg["reason"], "reserved for a brand or public interest")
def test_an_enum_value_this_resolver_predates_is_not_dropped(self):
"""A new Reason still reads as reserved; only the wording falls back."""
"""A new Reason still reads as reserved, and says it is unknown rather
than claiming the chain recorded none."""
snrc.eth_call = self._reserved_as(99)
reg = snrc.name_status("acme.testing")
self.assertEqual(reg["status"], "reserved")
self.assertEqual(reg["reasonCode"], "unspecified")
self.assertEqual(reg["reasonCode"], "unknown")
def test_a_reserved_name_carries_the_reason(self):
snrc.eth_call = self._chain(0, True)
@@ -601,17 +602,13 @@ class AuctionTests(unittest.TestCase):
return self.now - self.GRACE - 1 - days_into_auction * 86400
def test_a_name_just_past_grace_is_in_auction_not_merely_expired(self):
snrc.eth_call = self._chain(self._lapsed(0))
expires = self._lapsed(0)
snrc.eth_call = self._chain(expires)
reg = snrc.name_status("acme.testing")
self.assertEqual(reg["status"], "auction")
self.assertEqual(
reg["premium"], str(self.START_PREMIUM - (self.START_PREMIUM >> self.TOTAL_DAYS))
)
def test_the_auction_ends_a_full_window_after_grace(self):
expires = self._lapsed(0)
snrc.eth_call = self._chain(expires)
reg = snrc.name_status("acme.testing")
self.assertEqual(reg["graceEnds"], expires + self.GRACE)
self.assertEqual(
reg["auctionEnds"], expires + self.GRACE + self.TOTAL_DAYS * 86400