Skip to content

HIP018 re-record Add narrow Rerecord A and AAAA support - #955

Open
shadstoneofficial wants to merge 1 commit into
handshake-org:masterfrom
shadstoneofficial:codex/rerecord-hip018
Open

HIP018 re-record Add narrow Rerecord A and AAAA support#955
shadstoneofficial wants to merge 1 commit into
handshake-org:masterfrom
shadstoneofficial:codex/rerecord-hip018

Conversation

@shadstoneofficial

@shadstoneofficial shadstoneofficial commented May 12, 2026

Copy link
Copy Markdown

Summary

Implements a narrow HIP018 / Rerecord v1 path for hsd.

This adds support for TLD-level A and AAAA resource records so a Handshake TLD owner can point the bare TLD directly at IPv4/IPv6 addresses without running a separate nameserver.

Scope

This PR intentionally keeps the scope small:

  • Adds A = 7
  • Adds AAAA = 8
  • Keeps resource serialization version 0
  • Keeps the existing 512-byte resource limit
  • Answers bare-TLD A/AAAA queries only when the name is not delegated by NS records
  • Keeps NS delegation/referral behavior authoritative when NS records exist
  • Adds NSEC bitmap coverage for mixed TXT/A/AAAA resources
  • Adds tests for resource encoding, DNS answers, delegated suppression, NSEC proofs, and unknown-record ordering

Out Of Scope

This is not the broader #952 proposal.

This PR does not include:

  • Supply or locked-fund reallocation
  • Foundation or treasury changes
  • Tokenomics changes
  • Tree interval changes
  • Resource-size increase
  • Arbitrary zone-file expansion
  • Subdomain/LABEL support
  • TLSA, CNAME, MX, SRV, HTTPS/SVCB, or RAW records

Compatibility

Current resource version 0 decoding stops at the first unknown record type.

To preserve the best legacy behavior, writers should continue serializing legacy-known records first, then A/AAAA after them.

Example:

{
  "records": [
    {"type": "TXT", "txt": ["legacy-compatible data first"]},
    {"type": "A", "address": "203.0.113.10"},
    {"type": "AAAA", "address": "2001:db8::10"}
  ]
}

Older software should decode the known prefix and stop at the unknown record type. Upgraded software decodes the full resource.

DNS Behavior

If a resource has no NS delegation, hsd can answer A/AAAA at the TLD apex:

example. A    203.0.113.10
example. AAAA 2001:db8::10

If a resource has NS delegation, referral behavior wins and A/AAAA are not answered directly from the root resource.

Tests

Passed:

npm run test-file -- test/resource-test.js
8 passing

Passed:

npm run test-file -- test/ns-test.js
24 passing

Full test suite was attempted locally:

npm test
3153 passing
23 pending
14 failing

The local full-suite failures appear environmental: Bob was already listening on 127.0.0.1:12037, causing EADDRINUSE and downstream SPV timeouts. The focused Rerecord/resource/resolver tests passed cleanly.

Review Questions

  • Is the conservative NS-delegation rule correct?
  • Is keeping version 0 the preferred compatibility path?
  • Are A = 7 and AAAA = 8 acceptable type assignments?
  • Should this remain A/AAAA only for v1?

@2drewlee

Copy link
Copy Markdown

Thank you for putting this together. Excited about this!

@H4ckB4s3

Copy link
Copy Markdown

Approved. Also please add TLSA and MX records

@erwingroen

Copy link
Copy Markdown

I like this idea!

@MycophileHNS

Copy link
Copy Markdown

love to see this happen, what does it take to get this live?

@jonpostel

Copy link
Copy Markdown

I really like this proposal. I hope the administrator can review and merge this proposal.

@Falci

Falci commented May 12, 2026

Copy link
Copy Markdown
Member

Thanks for submitting this change.

My only concern is about the undocumented necessary order in the record types.

If a domain has A/AAAA and other record type, the A/AAAA needs to appear last.

But than we merge and release a new version of HSD, a few weeks later someone else creates a PR to support MX, which needs to be new latest. After that a new PR for TLSA.

None of them break the version rule and old nodes will parse as much as they know before stopping.
This will create a strict order that records needs to be placed so the resolver can parse most of them. And there's no clear documentation in which order they needs to be added.

This is not a deal break, just a concern point.

@MycophileHNS

Copy link
Copy Markdown

+1 on the ordering concern. It’s a valid long-term issue with the v0 extension approach.

Suggestion: Since this PR is already adding new record types, would it make sense to also include the next likely ones (MX and TLSA) in the same change? That would let us define the canonical ordering rule now instead of rediscovering it with every future record-type PR.

Proposed type numbers

DS:     0
NS:     1
GLUE4:  2
GLUE6:  3
SYNTH4: 4
SYNTH6: 5
TXT:    6
A:      7
AAAA:   8
MX:     9
TLSA:   10

Recommended rule to document

Always serialize records in ascending type-ID order.

This gives older nodes the best compatibility: they parse as many records as they understand and stop cleanly at the first unknown type.

Example:

{
  "records": [
    { "type": "TXT", "txt": ["v=spf1 ..."] },
    { "type": "A", "address": "192.0.2.1" },
    { "type": "AAAA", "address": "2001:db8::1" },
    { "type": "MX", "preference": 10, "exchange": "mail.example." },
    { "type": "TLSA", "usage": 3, "selector": 1, "matchingType": 1, "certificate": "d2abde..." }
  ]
}

Benefits

  • Makes the ordering rule explicit going forward.
  • Avoids future ambiguity.
  • Preserves the intended v0 backward-compatibility behavior.
  • Delivers useful email + DANE support if the maintainers are open to slightly larger scope.

If adding MX/TLSA is out of scope here, then this PR should at least clearly document the “ascending type-ID order” rule and ideally include a helper like Resource.sortForWire() to enforce it before serialization.

What do you think?

@michelini

Copy link
Copy Markdown

this is what we've been waiting for ! I do not recall anyone over the years against this - this gives more value and usage to onchain transactions

@shadstoneofficial

shadstoneofficial commented May 13, 2026

Copy link
Copy Markdown
Author

Thanks, this is a very fair concern. I agree the v0 extension path needs a clear ordering rule, otherwise every future record-type PR can accidentally create a new compatibility edge case.

My preference for this PR is to keep the implementation narrow at A/AAAA only, then document and test the forward-compatibility rule explicitly:

  • resource version stays 0
  • A and AAAA use the next type IDs after TXT
  • records should be serialized in ascending type-ID order
  • old nodes parse known records until the first unknown type, then stop cleanly
  • new record types like MX/TLSA should come after A/AAAA in type-ID order

I think adding MX/TLSA is valuable, but I would rather not expand this PR yet. The goal here is to make the smallest useful HIP018 step that gives direct apex A/AAAA resolution without mixing in email/DANE semantics, additional validation rules, or a larger review surface.

That said, I agree this PR should not leave ordering implicit. A good next update here would be:

  1. Add a documented canonical order: ascending resource type ID.
  2. Add/keep compatibility fixtures proving old decoders still parse known lower-numbered records before an unknown higher-numbered record.
  3. Consider adding a helper such as Resource.sortForWire() or equivalent serialization normalization so wallet/UI layers do not have to hand-maintain the order.

For MX/TLSA, I think those should be a follow-up HIP018 extension PR using the same rule, for example:

DS:     0
NS:     1
GLUE4:  2
GLUE6:  3
SYNTH4: 4
SYNTH6: 5
TXT:    6
A:      7
AAAA:   8
MX:     9
TLSA:   10

So I am supportive of MX/TLSA, but I think A/AAAA should land first as the conservative base layer.

@shadstoneofficial

Copy link
Copy Markdown
Author

re: what does it take to go live

The practical path is:

  1. Maintainer review of the narrow A/AAAA implementation.
  2. CI approval/run on this PR.
  3. Agreement on the v0 ordering rule, preferably documented as ascending type-ID order.
  4. Any requested test/doc cleanup.
  5. Merge into hsd, then Bob Wallet / LearnHNS can provide the UX so users do not need to hand-write resource JSON.

This PR intentionally avoids the broader PR #952-style changes. No supply/foundation/fund changes, no tree interval changes, just the narrow A/AAAA Rerecord path.

@DIPMR

DIPMR commented May 13, 2026

Copy link
Copy Markdown

I guess it should have been implemented much earlier. I don't see any negative in this from usage point of view. Those who are not in favor or opposing this, what's their point ?

@michelini

Copy link
Copy Markdown

I guess it should have been implemented much earlier. I don't see any negative in this from usage point of view. Those who are not in favor or opposing this, what's their point ?

===> I am also in favor of this - but to put the other side of the argument :

I believe I had heard from JJ or someone - back in 2018 when the chain was being outlined, a DNS representative visited them for a long day session and explained there is no need for these records on the root - that it was meant for the TLD owners to then host these. More like ICANN is now.

The second reason is this will add more space on the chain to host - but I feel that is negligible and it gives more utility and mining fees to the chain.

@v1xingyue

Copy link
Copy Markdown

I this this feature is cool!
It can help much more DNS record written with HNS blockchain,also help HNS name system much more decentralized.

@NamerTips

Copy link
Copy Markdown

This proposal is logical and appropriate. If implemented, it would also broaden the use-case potential for every name on the chain. As for adding other records like mx and tsla, please do so. Now is the moment to address records in general.

@shadstoneofficial

Copy link
Copy Markdown
Author

Thanks everyone. Reading the comments, I think there is clear support for the core HIP018/Rerecord direction, and I also hear the concern that approval cycles are slow enough that we should not create unnecessary follow-up bottlenecks.

My current view is:

  • A/AAAA are the minimum useful base layer.
  • MX/TLSA are also reasonable next records, especially for mail and DANE.
  • The most important thing to settle now is the compatibility rule: v0 records should be serialized in ascending type-ID order so older nodes parse all known lower-numbered records and stop cleanly at the first unknown higher-numbered record.

So I am open to either path, depending on what maintainers prefer:

  1. Merge this PR as the narrow A/AAAA base, with the ordering rule documented and tested, then open MX/TLSA immediately as a follow-up PR using the same type-ID order.
  2. Expand this PR now to include MX/TLSA as well, if maintainers prefer one broader review cycle for the first HIP018 record expansion.

The proposed type order would be:

DS:     0
NS:     1
GLUE4:  2
GLUE6:  3
SYNTH4: 4
SYNTH6: 5
TXT:    6
A:      7
AAAA:   8
MX:     9
TLSA:   10

Either way, I think we should treat the ascending type-ID order as the blanket compatibility rule for v0 resource extensions. That lets us move A/AAAA now and gives MX/TLSA a clear path without reopening the same ordering discussion every time.

This remains separate from PR #952-style changes. No supply/foundation/fund changes, no tree interval changes, and no tokenomics changes are being proposed here.

@Falci

Falci commented May 18, 2026

Copy link
Copy Markdown
Member

When hsd is parsing the DNS records, it stops at the first unknown record and don't parse anything else. Don't throw an error, just returns the previous records.

This creates a problem where a DNS record could be hidden under a new record type.
Eg:

example. IN DS ....
example. IN A 1.1.1.1 ;NEW
example. IN TXT "Only new hsd version can see this"

Which could cause wrong NSEC/NSEC3 signatures: a new hsd resolver would return the TXT and sign the records while an old hsd would not return and sign confirming it doesn't exists.
It is not a catastrophic failure but not ideal neither.

I'm not sure what would be the consequence if the DS record appear last, or a second DS record appear last.
I don't know how bns would handle it, and no idea if there's a RFC to be followed.

My suggestion is: we need to ensure the records are parsed only if they respect the order.
Using the previous example (DS A TXT), the new parser should drop the TXT. It's fine to parse the A but it should not accept records from previous version anymore.
This would ensure no records hidden under newer record types.


Note: TLSA isn't that useful, since its only use is for DANE, which also needs name like _443._tcp.example and we don't support record names (subdomains) on chain (yet).


Edit: addressing the previous comment: my suggestion is:

  1. address all the records at once (include the MX, ignore TLSA)
  2. add a .sort() to Resource
  3. call resource.sort() before adding to a transaction
  4. respect the version order when parsing the records.

I'd say all at once, but 2 and 3 could be extract to a new PR, as long as we merge it first.

@shadstoneofficial

Copy link
Copy Markdown
Author

This makes sense, thanks for spelling it out. I agree this is more than just a documentation issue.

The hidden-record example is a good reason to enforce the ordering rule in code, not only recommend it for wallets/UIs. If an older node stops at the first unknown type, then a newer node should not keep accepting lower-numbered/older record types that appear after a newer type. Otherwise the two versions can disagree about which records exist, including denial/NSEC behavior.

So I think the right rule is:

  • resource records have a canonical ascending type-ID order;
  • serialization should sort into that order;
  • transaction creation should normalize resources before putting them on chain;
  • parsing should respect the same forward-only order and stop/drop records once the order is violated or an unknown future type is reached.

Using your example, DS A TXT should allow the new parser to see DS and A, but it should not accept the later TXT, because TXT belongs before A in the canonical order.

I also agree TLSA can wait. Without on-chain record owner names/subdomains like _443._tcp.example, TLSA is probably less useful right now and could create extra semantics to review.

So a revised path could be:

  1. Add Resource.sort() or equivalent canonical sorting.
  2. Call it before resources are committed in name update/register transactions.
  3. Enforce forward-only type order while parsing.
  4. Add fixtures/tests for hidden-record cases like DS A TXT.
  5. Include A/AAAA and possibly MX in this record expansion.
  6. Leave TLSA for a later PR when subdomain/owner-name support is better defined.

That seems like a better compatibility rule than just documenting the preferred order.

@marioo-lab

Copy link
Copy Markdown

Great initiative! Less dependencies of centralized infrastructure is always a good thing for Handshake.

@anneparalleled

Copy link
Copy Markdown

Excellent work keeping the scope focused while maintaining compatibility and clear delegation behavior. Looking forward to seeing HNS evolve further.

@rhymincymon

Copy link
Copy Markdown

This requires a new version, imo. Relying on the order of records is not desirable.

  • Version 0 remains as is, for delegation only.
  • Version 1 for direct resolution records (no NS, DS, GLUE).

There is no need to mix delegation with direct records and this allows for a clean separation.

Version 1 needs a new serialization format with optional subdomain label for each record. Perhaps also TTL handling.

A/AAAA is not really useful without TLSA record type for secure connections. Both should be added at the same time.

We should also consider adding other record types like HTTPS with ECH as a more forward-looking choice over A/AAAA and, most importantly, carefully vet all the details before adopting anything to ensure a durable implementation.

@shadstoneofficial

Copy link
Copy Markdown
Author

Thanks rhymincymon , this is a helpful framing. I agree that a true v1 resource format could be cleaner than continuing to stretch v0 forever, especially if we want owner labels/subdomains, TTLs, HTTPS/SVCB/ECH, TLSA, and a clean direct-resolution mode.

One small clarification: v0 is not purely delegation-only today. It already has TXT and synthetic records, and hsd can answer TXT directly when there is no NS delegation. But I agree with the larger point that delegation records and direct-resolution records are conceptually different and a v1 format could separate them more cleanly.

My concern is scope. A v1 format with optional labels, TTL handling, TLSA, HTTPS/ECH, and direct-vs-delegation rules is more than a small hsd patch. That sounds like a spec/HIP design pass first, then an implementation PR after the details are agreed.

So I think there are two possible paths:

  1. Treat this PR as the conservative v0-compatible step: A/AAAA only, no NS/DS/GLUE mixing for direct answers, canonical ordering/normalization, and tests for compatibility edge cases.
  2. Pause or supersede this PR with a proper v1 resource-format HIP that defines direct-resolution records, optional owner labels, TTL semantics, allowed record types, and how v0/v1 resolvers should behave.

I am open to either path if maintainers prefer it. I just want to avoid quietly turning this PR into a full v1 serialization redesign without a written spec everyone can review.

On TLSA/HTTPS/ECH: I agree they are worth discussing, but they seem to depend on the owner-label/subdomain model. For example TLSA commonly needs names like _443._tcp.example, and HTTPS/ECH also has more resolver/client behavior to define. That is exactly why I think they may belong in the v1 design track rather than being added casually to this PR.

@rhymincymon

Copy link
Copy Markdown

I'm all for the second path.

Without a TLSA record, A/AAAA records are essential unusable for anything security-conscious. It would impose a backwards-compatibility burden on every future client and increase implementation complexity and parsing cost permanently, for a feature that has no use in any serious deployment. It undermines the goal of keeping resolution as lightweight as possible.

@amgluck

amgluck commented May 30, 2026

Copy link
Copy Markdown

Thank you for keeping HNS alive and suggesting improvements. I will also be using the new Shakedex download that Mike made available to host my collection of foreign language domains.

@shadstoneofficial

Copy link
Copy Markdown
Author

Following up on the v1 / second-path discussion here, I opened a separate docs/spec PR for resource v1 direct resolution: #956

I kept it as a proposal rather than rewriting this implementation PR, so the larger design questions can be reviewed directly: version 1, direct-resolution vs delegation separation, owner labels, TTL handling, TLSA, HTTPS/SVCB/ECH considerations, and rollout/compatibility behavior.

If maintainers prefer the v1 path, #956 can supersede this narrow v0-compatible A/AAAA implementation path. If maintainers still prefer a staged implementation, this PR can remain the smaller prototype/reference.

@shadstoneofficial

Copy link
Copy Markdown
Author

Thanks again for the v1 framing here. To make this easier to review separately, I opened #956 as a docs/spec proposal for the second path rhymincymon suggested.

That proposal treats #955 as the narrow A/AAAA prototype/reference, but moves the broader path into a resource version 1 design discussion before any larger implementation work:

  • keep version 0 behavior unchanged;
  • define version 1 for direct-resolution records;
  • separate direct resolution from delegation records;
  • include owner labels for names like _443._tcp.example.;
  • define TTL handling explicitly;
  • review TLSA and HTTPS/SVCB/ECH as part of the initial v1 design surface;
  • settle compatibility and rollout behavior before coding the larger change.

If maintainers and reviewers prefer this second path, I think #956 is the better place to move that design forward, and #955 can remain useful as implementation context / proof of feasibility rather than being expanded into a full serialization redesign.

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.