Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sponsored names: Implement instantaneous sponsored name registrar #750

Closed
jcnelson opened this issue Feb 16, 2018 · 12 comments
Closed

Sponsored names: Implement instantaneous sponsored name registrar #750

jcnelson opened this issue Feb 16, 2018 · 12 comments
Assignees

Comments

@jcnelson
Copy link
Member

jcnelson commented Feb 16, 2018

TL;DR: It is possible to register and use sponsored names instantaneously, without having to wait for the blockchain record.

NOTE: "subdomain" is an older term for "sponsored name."

Background

Subdomains provide a cheap way to on-board lots of users at once, because a single NAME_UPDATE transaction can instantiate up to 120 subdomains. At a rate of ~8 transactions per block, the system can on-board ~115,000 users per day. However, a subdomain will not exist in the eyes of a Blockstack Core node until (1) the transaction is confirmed, and (2) it receives the zone file with the subdomain records.

Proposal

TL;DR: We have clients send subdomain queries to the subdomain registrar that creates them if they do not yet exist on the Core node.

The subdomain registrar has the "latest state" of all subdomains. It not only knows which subdomains it registered (since this is known to all Blockstack Core nodes), but also it knows which subdomains it has not yet announced. Since the subdomain registrar broadcasts zone files under the same name over and over, it can provide a special resource record in its zone files with a URL to a resolver endpoint. This resolver endpoint would answer queries from Blockstack Core clients for subdomains that are still pending.

For example, suppose personal.id was a Blockstack ID that a subdomain registrar used to onboard users. Suppose that the subdomain registrar for personal.id had an API endpoint at https://subdomains.blockstack.org/personal.id. Then, when it sends out a zone file, it would include this resource record:

_resolver URI 10 1 "https://subdomain.blockstack.org/personal.id"

Suppose that jude.personal.id is a subdomain that is queued for registration, but its NAME_UPDATE transaction hasn't been processed yet. When a client attempts to resolve jude.personal.id on the Blockstack Core node at node.blockstack.org, the following steps would be taken:

In order to attempt to resolve the subdomain jude.personal.id, the client would first get the zone file and public key for personal.id from the Core node (steps 3-4). If the zone file has a _resolver resource record, the client attempts to fetch the record for jude.persoanl.id from the record's URL.

When the resolver receives the request, it checks its queue (7). It replies the pending subdomain record for jude.personal.id, and signs it with its private key (8). The client verifies the record's authenticity (step 9) with the public key it got for personal.id in (4), and if the signature matches, it returns the subdomain record.

Eventually, the subdomain registrar will send the information for jude.personal.id to the blockchain, in which case, step (1) will have succeeded.

EDIT: latest diagram is here:

client                                  core node    subdomain registrar                                                                                                                                                                                                                                                      
------                                 ---------    -------------------
  |                                        |                 |
  |                                        |                 |
  | (1) GET /v1/names/jude.personal.id     |                 |
  |------------------------------------->  |                 |
  | (2) HTTP 301 _resolver URL             |                 |
  |  <-------------------------------------|                 |
  |                                        |                 |
  | (3) GET /v1/names/jude.personal.id     |                 |
  |----------------------------------------^-------------->  |
  |                                        |                 |
  |                                        | (4) check queue |
  | (5)       jude.personal.id: <...>      |                 |
  |  <-------------------------------------^-----------------|
  | success!                               |                 |

The Core node should keep track of the resolver for each subdomain registrar, and should be able to redirect clients to the registrar to resolve pending subdomains (2). The subdomain registrar needs to be able to handle queries against its pending queue (4), so it can service requests to subdomains instantly using the same API endpoint (/v1/names) that Core uses (5).

Advantages

A subdomain would be usable and resolvable soon as it is put into the subdomain registrar's queue. Blockstack applications would be able to work with it immediately, including multi-reader applications.

Caveats and Limitations

This proposal is only for resolving subdomains that are in the process of being registered. It is not meant for resolving subdomains that are in the process of being updated or transferred.

This algorithm only works if the subdomain registrar is trusted. The fact that the pending subdomain record is signed by the Blockstack ID owner ensures that the reply from the registrar won't be tampered with in-flight. However, the subdomain registrar could lie about the contents of the pending record. Clients that cannot trust the subdomain registrar must wait for the subdomain's Blockstack ID's transaction to confirm first.

Any/all feedback welcome on this proposal (cc @kantai @larrysalibra @shea256 @yknl)

@cwackerfuss
Copy link
Contributor

cwackerfuss commented Feb 16, 2018

Cool!

I'm not very familiar with whois, but in steps 1-4, if jude.personal.id is not found, would it make sense for core node to respond with an error plus the zonefile and pubkey of personal.id (e.g. "I can't find that subdomain, but here's the domain information").

It is not meant for resolving subdomains that are in the process of being updated or transferred

Will this solution require us to take additional precautions for subdomains that are updating or being transferred? Or will Step 1 always succeed in those cases?

@jcnelson
Copy link
Member Author

@cwackerfuss yes, that's an optimization we would likely end up implementing 🙂

Will this solution require us to take additional precautions for subdomains that are updating or being transferred? Or will Step 1 always succeed in those cases?

I don't think changing your subdomain's zone file or address has to be instantaneous, since unless there's something catastrophic going on (e.g. you know your private key is stolen, or your data providers are dead and gone), doing these things doesn't affect your ability to use apps. We'll have to keep a close eye on how frequently users want to do these things, and for what purposes.

@jcnelson
Copy link
Member Author

Related issue for the subdomain registrar: stacks-network/subdomain-registrar#7

@kantai
Copy link
Member

kantai commented Mar 15, 2018

I can work on this next sprint @jcnelson -- I'm imagining have core.blockstack.org be the designated _resolver for personal.id -- though that will require the registrar to communicate zonefiles to that node.

@jcnelson jcnelson changed the title Subdomains: Implement instantaneous subdomain registrar Sponsored names: Implement instantaneous sponsored name registrar Mar 15, 2018
@jcnelson
Copy link
Member Author

I'm curious why we can't just HTTP 302 clients to the sponsored name registrar? Are you worried about caching and load-balancing?

@kantai
Copy link
Member

kantai commented Mar 15, 2018

I'm curious why we can't just HTTP 302 clients to the sponsored name registrar? Are you worried about caching and load-balancing?

Pretty much. Right now, the registrar really just accepts / rejects registration requests, and isn't responsible for serving any content. The additional load of replying to a whois is basically nil (this information is already stored in the subdomain registrar's sqlite db), so I wouldn't be too opposed to this.

@jcnelson
Copy link
Member Author

Regardless of its role in sponsored name registration, I had been looking to add a GET endpoint to the sponsored name registrar anyway just so I can query whether or not a name was queued up or not (i.e. for testing purposes).

If we didn't have Core redirect to the sponsored name registrar, how were you thinking Core would obtain the pending name state? Would Core just act as a caching proxy to the registrar?

@kantai
Copy link
Member

kantai commented Mar 15, 2018

Regardless of its role in sponsored name registration, I had been looking to add a GET endpoint to the sponsored name registrar anyway just so I can query whether or not a name was queued up or not (i.e. for testing purposes).

The /status/ endpoint will answer that query.

If we didn't have Core redirect to the sponsored name registrar, how were you thinking Core would obtain the pending name state? Would Core just act as a caching proxy to the registrar?

I was thinking the subdomain registrar would relay the zonefiles to a core node, which would process them before they were announced. That is a much more complicated strategy though.

@jcnelson
Copy link
Member Author

Gotcha, thanks for clarifying. Want to do the redirection strategy then, in order to avoid a complex implementation?

@kantai
Copy link
Member

kantai commented Apr 26, 2018

@jcnelson -- looking at the proposal above, do you think we should implement this in blockstack.js rather than the /v1/names/ endpoint in blockstack-core ?

@jcnelson
Copy link
Member Author

Looking at the diagram above, the Core node should probably reply 301 or 302 to the client in order to point the client to the subdomain resolver. Will update the diagram.

@jcnelson
Copy link
Member Author

jcnelson commented May 4, 2018

This has shipped!

@jcnelson jcnelson closed this as completed May 4, 2018
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

No branches or pull requests

3 participants