You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

586 lines
22 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Begin Jekyll SEO tag v2.5.0 -->
<title>BNS Forks | Blockstack</title>
<meta name="generator" content="Jekyll v3.8.3" />
<meta property="og:title" content="BNS Forks" />
<meta name="author" content="Blockstack" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="BNS Forks" />
<meta property="og:description" content="BNS Forks" />
<link rel="canonical" href="https://zbabystack.netlify.com/core/naming/forks.html" />
<meta property="og:url" content="https://zbabystack.netlify.com/core/naming/forks.html" />
<meta property="og:site_name" content="Blockstack" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2018-08-28T14:54:31-07:00" />
<script type="application/ld+json">
{"description":"BNS Forks","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/core/naming/forks.html","headline":"BNS Forks","dateModified":"2018-08-28T14:54:31-07:00","datePublished":"2018-08-28T14:54:31-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/core/naming/forks.html"},"@context":"http://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<!-- <meta property="og:image" content="https://zbabystack.netlify.com/assets/posts/logo.png"/> -->
<meta property="og:image" content="/assets/posts/logo.png"/>
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="/assets/img/favicon.png" >
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
<script src="/assets/js/main.js"></script>
</head>
<body>
<header class="uk-background-secondary">
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
<nav class="uk-navbar-container">
<div class="uk-container">
<div data-uk-navbar>
<div class="uk-navbar-left">
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="https://zbabystack.netlify.com/assets/posts/logo.png" alt="Docs"></a> -->
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav uk-visible@m">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div>
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
</form>
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
</div>
</div>
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('searchBox'),
resultsContainer: document.getElementById('searchBox-results'),
noResultsText: '<li>No results found</li>',
searchResultTemplate: '<li><a href="{url}">{title}</a></li>',
json: '/search.json'
});
</script>
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
</div>
</div>
</div>
</nav>
</div>
</header>
<div class="uk-section">
<div class="uk-container">
<div class="uk-grid-large" data-uk-grid>
<div class="sidebar-fixed-width uk-visible@m">
<div class="sidebar-docs uk-position-fixed">
<h5>Overview</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class=""><a href="/core/naming/introduction.html">Blockstack Naming Service (BNS)</a></li>
<!-- -->
<li class=""><a href="/core/naming/architecture.html">Understand the Architecture</a></li>
<!-- -->
<li class=""><a href="/core/naming/namespaces.html">Understand Namespaces</a></li>
</ul>
<h5>Tutorials</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class=""><a href="/core/naming/creation_tutorial.html">Creating a Namespace</a></li>
</ul>
<h5>How to use BNS</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class=""><a href="/core/naming/pickname.html">Choose a name</a></li>
<!-- -->
<li class=""><a href="/core/naming/resolving.html">Resolve a name</a></li>
<!-- -->
<li class=""><a href="/core/naming/register.html">Register a name</a></li>
<!-- -->
<li class=""><a href="/core/naming/manage.html">Manage BNS Names</a></li>
<!-- -->
<li class=""><a href="/core/naming/subdomains.html">BNS Subdomains</a></li>
</ul>
<h5>Other topics</h5>
<ul class="uk-nav uk-nav-default doc-nav">
<!-- -->
<li class="uk-active"><a href="/core/naming/forks.html">BNS Forks</a></li>
<!-- -->
<li class=""><a href="/core/naming/did.html">DID Encoding for Subdomains</a></li>
<!-- -->
<li class=""><a href="/core/naming/comparison.html">Naming system feature comparison</a></li>
</ul>
</div>
</div>
<div class="uk-width-1-1 uk-width-expand@m">
<article class="uk-article">
<h1 class="uk-article-title">BNS Forks</h1>
<div class="uk-article-meta uk-margin-top uk-margin-medium-bottom">
<!-- <img class="avatar avatar-small" alt="Blockstack" width="32" height="32" data-proofer-ignore="true" src="https://avatars2.githubusercontent.com/Blockstack?v=3&s=32" srcset="https://avatars2.githubusercontent.com/Blockstack?v=3&s=32 1x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=64 2x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=96 3x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=128 4x" /> -->
<!-- Written by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Blockstack</span></span><br> -->
<time datetime="2018-08-28T14:54:31-07:00" itemprop="datePublished">
<a "target="_blank" href="https://github.com/moxiegirl/docs-new/blob/master/_core/naming/forks.md" class="btn btn-default githubEditButton" role="button"><span data-uk-icon="icon: pencil; ratio: 1.2"></span> Edit this page on Github</a>
<span style="font-family:Wingdings">&#119;</span> Aug 28, 2018
</time>
</div>
<div class="article-content">
<p>BNS effectively uses a public blockchain to store a database log. A BNS peer
bootstraps itself by downloading and replaying the database log from the
blockchain, and in doing so, will calculate the same name database state as
every other (honest) BNS peer that has the same view of the blockchain.</p>
<p>Crucially, BNS is built on top of a public blockchain that is <em>unaware</em> of BNS’s existence.
This means that the blockchain peers do not validate BNS transactions. Instead,
the BNS peer needs to do so, and must know how to <em>reject</em> both invalid transactions
as well as well-formed transactions from dishonest peers (i.e. peers that do not
follow the same consensus rules).</p>
<p>BNS nodes do not directly communicate with one another—by design, the set of
BNS peers is not enumerable. The only shared communication medium between BNS
peers is the blockchain.</p>
<p>To identify and reject invalid and malicious transactions without the blockchain’s help,
the log of name operations embedded in the blockchain is constructed as a
<a href="http://www.scs.stanford.edu/~jinyuan/bft2f.pdf">fork*-consistent</a> database
log. Fork*-consistency is a <a href="https://en.wikipedia.org/wiki/Consistency_model">consistency
model</a> whereby the state
replicas in all of the nodes exhibit the following properties:</p>
<ul>
<li>
<p>Each correct peer maintains a history of well-formed, valid state operations. In this
case, each correct BNS node maintains a copy of the history blockchain transactions
that encoded well-formed, valid name operations.</p>
</li>
<li>
<p>Each honest peer’s history contains the sequence of all operations that it
sent. That is, a user’s BNS peer’s transaction log will contain the sequence of all valid
transactions that the user’s client wrote to the blockchain.</p>
</li>
<li>
<p>If two peers accept operations <em>op</em> and <em>op’</em> from the same correct client,
then both of their logs will have the both operations in the same order. If
<em>op’</em> was accepted before <em>op</em>, then both peers’ logs are identical up to <em>op’</em>.
In BNS, this means that if two peers both accept a given transaction, then it
means that they have accepted the same sequence of prior transactions.</p>
</li>
</ul>
<p>This means that unlike with blockchains,
there can be <em>multiple long-lived conflicting forks</em> of the BNS database log.
However, due to fork*-consistency, a correct BNS peer will only process <em>one</em>
of these forks, and will <em>ignore</em> transactions from peers in other forks. In other words,
fork*-consistency partitions the set of BNS peers into different <strong>fork-sets</strong>,
where all peers in a fork-set process each other’s transactions, but the
completely ignore peers in other fork-sets.</p>
<p>BNS nodes identify which fork set they belong to using a <strong>consensus hash</strong>. The
consensus hash is a cryptographic digest of a node’s operation
history. Each BNS peer calculates a new consensus hash each time it processes a
new block, and stores the history of consensus hashes for each block it
processed.</p>
<p>Two honest BNS peers can quickly determine if they are in the same fork-set by querying
each other’s consensus hashes for a given block. If they match, then they are
in the same fork-set (assming no hash collisions).</p>
<p>A BNS client executes a name operation on a specific fork-set by including a
recent consensus hash from that fork-set in the blockchain transaction.
At the same time, the BNS consensus rules state that a transaction can only be
accepted if it included a recent valid consensus hash.
This means that all BNS nodes in the client’s desired fork-set will accept
the transaction, and all other BNS nodes not in the fork-set will ignore it.
You can see where the consensus hash is included in blockchain transactions by reading
the <a href="wire-format.md">transaction wire format</a> document.</p>
<h2 id="fork-set-selection">Fork-set Selection</h2>
<p>The blockchain linearizes the history of transactions, which means that
in general, there exists a fork-set for each distinct set of BNS
consensus rules. For example, the Blockstack Core <a href="release_notes/changelog-0.14.md">2016 hard fork</a>
and <a href="release_notes/changelog-0.17.md">2017 hard fork</a> both introduced new consensus
rules, which means at the time of this writing there are three possible fork-sets:
the pre-2016 fork-set, the 2016-2017 fork-set, and the post-2017 fork-set.
The <a href="https://node.blockstack.org:6263">public BNS nodes</a> are always running
in the fork-set with the latest consensus rules.</p>
<p>BNS clients are incentivized to communicate with peers in the fork-set that has
the most use, since this fork-set’s name database will encode name/state
bindings that are the most widely-accepted and understood by users.
To identify this fork-set, a BNS client needs to learn one of
its recent consensus hashes. Once it has a recent consensus hash, it can
query an <em>untrusted</em> BNS node for a copy of
its name database, and use the consensus hash to verify that the name database
was used to generate it.</p>
<p>How does a BNS node determine whether or not a consensus hash corresponds to the
most widely-used fork-set? There are two strategies:</p>
<ul>
<li>
<p>Determine whether or not a <em>characteristic transaction</em> was accepted by the
widely-used fork-set. If a client knows that a specific transaction belongs to
the widely-used fork-set and not others, then they can use the consensus hash to
efficiently determine whether or not a given node belongs to this fork-set.</p>
</li>
<li>
<p>Determine how much “economic activity” exists in a fork-set by inspecting
the blockchain for burned cryptocurrency tokens. Namespace and name
registrations are structured in a way that sends cryptocurrency tokens to either
a well-known burn address, or to an easily-queried pay-to-namespace-creator
address.</p>
</li>
</ul>
<p>Both strategies rely on the fact that the consensus hash is calculated as a
<a href="https://github.com/blockstack/blockstack-core/issues/146">Merkle skip-list</a>
over the BNS node’s accepted transactions. A client can use a consensus hash to
determine whether or not a transaction <em>T</em> was accepted by a node with <em>O(log
n)</em> time and space complexity. We call the protocol for resolving a consensus hash to a specific transaction
<strong>Simplified Name Verification</strong> (SNV). See our <a href="https://blockstack.org/virtualchain_dccl16.pdf">paper on the subject</a>
for details of how SNV works under the hood.</p>
<p>If the client has a consensus hash and knows of a characteristic transaction in the widely-used fork-set,
it can use SNV to determine whether or not a node belongs to the fork-set that accepted it.</p>
<p>If the client knows about multiple conflicting consensus hashes,
they can still use SNV to determine which one corresponds
to the most-used fork-set. To do so, the client would use a
<a href="https://explorer.blockstack.org">blockchain explorer</a> to find the
list of transactions that burned cryptocurrency tokens. Each of these
transactions will be treated as potential characteristic transactions:
the client would first select the subset of transactions that are well-formed
BNS transactions, and then use SNV to determine which of them correspond to which
consensus hashes. The client chooses the consensus hash that corresponds
to the fork-set with the highest cumulative burn.</p>
<p>Work is currently underway to automate this process.</p>
<div class="share uk-text-center">
<a href="https://twitter.com/intent/tweet?text=BNS Forks&url=https://zbabystack.netlify.com/core/naming/forks.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fcore%2Fnaming%2Fforks.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
</div>
</div>
<hr class="uk-margin-medium">
<div class="uk-margin-large-top">
<h3>Related Articles</h3>
<ul class="uk-list">
</ul>
</div>
</article>
<script>
// Table of contents scroll to
UIkit.scroll('#markdown-toc a', {
duration: 400,
offset: 120
});
</script>
</div>
</div>
</div>
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
<ul class="uk-nav uk-nav-default">
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="https://zbabystack.netlify.com/assets/posts/logo.png" alt="Docs"></a></li> -->
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
</div>
</div>
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
<div class="uk-container uk-container-small">
<div>
<ul class="uk-subnav uk-flex-center">
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
</ul>
</div>
<div class="uk-margin-medium">
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
<div class="uk-first-column">
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
<div>
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
</div>
</div>
</div>
<div class="uk-margin-medium uk-text-small copyright">Blockstack</div>
</div>
</footer>
<!-- <script type="text/javascript">
/* Create a configuration object */
var ss360Config = {
/* Your site id */
siteId: 'blockstack',
/* A CSS selector that points to your search box */
searchBox: {selector: '#searchBox'}
};
</script>
<script src="https://sitesearch360.com/cdn/sitesearch360-v11.min.js" async></script>
-->
</body>
</html>