Trusting Blockstack nodes for name resolution

As far as I’ve understood, the ‘resolve’ part of Blockstack simply looks like this:

  1. Application ask a hardcoded blockstack node to resolve bar.foo.id
  2. Blockstack node responds with some JSON
  3. Application trusts the Blockstack node’s response

The Blockstack node is free to respond with anything. There’s no real verification that is done on the user end. I don’t understand how this can be secure. Q. What’s the lightest way for my users to verify a Blockstack node’s response?

Quoting from this article:

Blockstack and ENS are two examples of naming systems that will not see real usage for their intended purposes. Let me explain why. In order to resolve a domain using either, a user is required to run a fully validating node. Now why would I want to do that when all I need to do to open a webpage is query Google’s DNS resolver through my browser?

There’s no way my users can run ‘fully validating node/infrastructure’.

1 Like

Some related topics and quotes -

[1 - Possible trust loss and details of Blockstack's SNV]

So I guess this comes down to asking some (random) servers for their view and comparing the results to get a neutral and decentral-derived view? How many Blockstack nodes are there? And how many run “independently” from yours?

[2 - How do lightweight blockstack nodes operate a SNV protocol)]

b) is the problem. Bitcoin’s spv works without any “trusted hash” and so would Namecoin’s. Adding a concept of trust in such a way makes the whole idea of decentralized dns useless.

The article is based on outdated information. Blockstack names are meant primarily for users, not DNS hosts. Usernames has been the main use-case for 2+ years.

Right now, the state of Blockstack names is like the Bitcoin UTXO set – you need to run a full node to make sure your copy of the name state is consistent with the blockchain data, because Blockstack (a) does not currently have mining of its own and (b) does not require nodes to cryptographically commit to the materialized view of the system state. You can use the SNV protocol to determine whether or not a particular transaction happened in the past, given a later trusted Blockstack transaction (more specifically, the consensus hash from that transaction).

That said, Stacks v2 addresses both limitations – it not only grows through mining, but also requires miners to cryptographically commit to the materialized view of the blockchain state. This will let you not only get a Merkle proof of inclusion for any name/pubkey+zonefile pair from a block header, but also for any smart contract persistent state. The specification for this is documented here, and the implementation is here.

Also, our data structure (the merklized adaptive radix forest, or MARF) has better asymptotic performance than Handshake’s Urkel tree (we’re O(1) for inserts and queries on the longest fork, whereas Urkel trees are O(log n) for n records).

1 Like

Granted it’d be pretty cool if it was also used as a DNS, but maybe we can do that once the Stacks chain is in full swing?


Also, honestly, if you don’t trust Blockstack PBC’s core node, then run your own and have users use that instead. While it will never be fully feasible to for every end-user to run their own node, neither is it in Bitcoin (wasn’t it Satoshi’s idea that eventually most clients would just connect to trusted networks that would balance each other out?), and so instead it’s up to the community to boot up their own servers and gain a reputation of trust themselves if they so desire…


edit:

Also this is hilarious, from what you quoted:

Let me explain why. In order to resolve a domain using either, a user is required to run a fully validating node. Now why would I want to do that when all I need to do to open a webpage is query Google’s DNS resolver through my browser?

You stated that you wanted to verify what the core node responds, but then the quote you pulled out says all they have to do is have faith in Google’s DNS resolver to return something positive? How do you trust that? By running your own full DNS node right…?

(Granted, maybe I quoted your quote out of context, but this is all quite tiresome).

1 Like

Thanks for your responses. Just for some background, my use-case in a nutshell is -
"Resolve human readable name foo.bar.id to a Public Key"

As you’re going through my reply, please consider that I’m looking at Blockstack as a name service. Not a “decentralised computing network”.
Maybe Blockstack is not intended to solve my use case at all, please do let me know if you feel that is the case.

@jude

You can use the SNV protocol to determine whether or not a particular transaction happened in the past, given a later trusted Blockstack transaction (more specifically, the consensus hash from that transaction).

It seems like this might not be a critical part for most apps on Blockstack - since references to SPV are few and documentation very sparse, but for my use case it is very important.
Where can I find details about this process? I mean code/documentation/instructions.

That said, Stacks v2 addresses both limitations

Will certainly go though your documents to understand how it works :slight_smile:

@MichaelFedora

While it will never be fully feasible to for every end-user to run their own node, neither is it in Bitcoin

I don’t think that’s a fair comparison mate

=>Bitcoin
Bitcoin’s function is to transfer value from A to B, and store it at B securely

A is sending money to B via TRUSTED_NODE_1 -> Low risk (maybe TRUSTED_NODE_1 can drop A’s transaction. not much more)
B is checking address transactions via TRUSTED_NODE_2 -> Low Risk (maybe TRUSTED_NODE_2 incorrect tells B about a fake transaction)

=> Blockstack Naming Service
Blockstack’s function is to map a public key and arbitrary data to a human readable name.

A creates a name A_NAME via TRUSTED_NODE_1 -> Low Risk (Maybe TRUSTED_NODE_1 can drop the name registration)
B resolves A_NAME via TRUSTED_NODE_2 -> Extremely High Risk! This is the core functionality of BNS.

Moreover - Bitcoin has an economic mechanism to encourage Network diversity. BNS nodes have no such thing.

but then the quote you pulled out says all they have to do is have faith in Google’s DNS resolver to return something positive? How do you trust that? By running your own full DNS node right…?

I think the point that the author (and I) were trying to emphasise is - in both DNS and in Blockstack, there is a similar deficiency of having to trust one single resolver and having no way to prove the result.

But at least in DNS there are other mechanisms HTTPS which works because of assumed trust in centralised CAs to make web browsing secure. And specs like DNSSEC also help in some scenarios.

If my users can locally verify the BNS response using just a trusted Bitcoin node, that would be a reasonable tradeoff. The problem is that right now they also need

  1. A separate trusted BNS node to get the consensus hash
  2. A separate trusted node which runs the SPV process and communicates with the Bitcoin Node.

That’s a big ask don’t you think?

Can you explain to me how the risk is different here? Lets say you’re a storefront and need to verify a transaction went through. How do you trust the node to say “yes it went through” and not double charge the user, or that the user isn’t double spending on you? It’s just as extremely high of a risk as trusting the node to serve you the correct zonefile and/or correct address-from-username!

I will grant you that there is more things going on in Blockstack, i.e. with the Atlas Network offering another variable, but that is reduced because the hash of said zonefile is in the blockchain, so it’s verified by the node before serving (afaik). So then you are reduced down to only one point of communication being problematic (if you trust the CA system for HTTPS when doing the API calls, at least), which is the RPC communication between the bitcoin node and the BNS node – then again, any time you are calling an API for bitcoin information, they have to do the same communication there as well.

So regardless if you’re asking for transaction information or asking for a BNS resolution, it’s the same security issues you have to deal with – trust in the host.


If you are already running a bitcoin node, I don’t think it’s that much more processing power to also run a (BNS) Core node. Maybe one day someone could make an app in the future that could just verify calls via consensus hash without being connected to the Atlas network (stacks chain?), but that’s not the case right now.

I don’t think any apps make use of the feature. However, there is a reference client implementation here with lots of in-line documentation.

If my users can locally verify the BNS response using just a trusted Bitcoin node, that would be a reasonable tradeoff. The problem is that right now they also need

Your users would need to use a Bitcoin node and a co-located BNS node – the BNS node gets the blocks and block headers from the Bitcoin node to parse the on-chain name operations. Once you have a trusted consensus hash, you do NOT need a trusted BNS node – the SNV protocol is constructed so the BNS node is NOT part of the trusted computing base, since at each step, the client uses the trusted consensus hash (or some data derived from it) to authenticate the responses from the BNS node.

The BNS nodes authenticate and process all zone file data, but the zone file data is not committed to by the consensus hash. This is because the consensus hash is calculated for each block by hashing the block’s operations in order, whereas zone files cannot be processed in order since they may not even arrive in order (or ever).

However, this is not necessary for security if all you’re going to do is validate the name’s public key. The reason this works is because there’s a subtle but important detail on off-chain name processing: for reasons described in the design of the subdomain registrar, all updates to a name’s public key MUST be broadcast by the on-chain name that registered it.

To use SNV to verify the public key of an off-chain name, your client would:

  1. use SNV to authenticate each of the on-chain name’s NAME_UPDATE transactions
  2. fetch each available zone file for the NAME_UPDATEs (these can be had from any BNS node), and authenticate them from the hash in the NAME_UPDATE transaction
  3. extract the name-specific operations from the zone files
  4. replay them locally to derive the latest authentic public key for the name

A lot of this complexity is going away in Stacks v2, since each block in Stacks v2 will commit to the materialized view of the set of names and smart contract state. This will let you not only query a name’s latest public key, but also receive a O(log^2 F) Merkle proof that the key is the latest such key, that the state is in a fork of length F, and that the key was mined in a particular Bitcoin block (with a given number of Bitcoins destroyed and a given number of sortitions confirmed since then). For added security, you can also fetch the Bitcoin block headers and fetch Merkle proofs for all proof-of-burn transactions that make up the F-long fork. The proof-of-burn transactions themselves fully describe the Stacks v2 fork structure, so you can confirm that the fork is indeed F blocks long (per SIP 001, fork length is the fork quality parameter).

EDIT: corrected the proof complexity description.

1 Like