Switch from pandoc to rst2html5.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2019-08-06 13:58:27 +01:00
parent 65af4c7de4
commit fcdde6f89a
17 changed files with 3798 additions and 3096 deletions

View File

@ -1,9 +1,10 @@
%.md: %.rst
pandoc -s -o $@ $<
# Dependencies:
# sudo apt-get install python-pip
# sudo pip install rst2html5
%.html: %.rst
$(eval TITLE=$(shell echo '$(basename $<)' | sed -r 's|zip-0{0,3}|ZIP |'): $(shell grep '^\s*Title: ' $< | sed 's|\s*Title: ||'))
pandoc --metadata pagetitle="$(TITLE)" -s -o $@ $<
rst2html5 -v --title="$(TITLE)" $< >$@
sed -i 's|</head>|<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>|' $@

View File

@ -1,19 +1,12 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 0: ZIP Process</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 0: ZIP Process</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 0
<section>
<pre>ZIP: 0
Title: ZIP Process
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Josh Cincinnati &lt;josh@zfnd.org&gt;
@ -21,208 +14,277 @@ Credits: Luke Dashjr
Status: Active
Category: Process
Created: 2019-02-16
License: BSD-2-Clause</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;MAY&quot;, &quot;RECOMMENDED&quot;, &quot;OPTIONAL&quot;, and &quot;REQUIRED&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The term &quot;network upgrade&quot; in this document is to be interpreted as described in ZIP 200.<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a></p>
<h1 id="abstract">Abstract</h1>
<p>A Zcash Improvement Proposal (ZIP) is a design document providing information to the Zcash community, or describing a new feature for Zcash or its processes or environment. The ZIP should provide a concise technical specification of the feature and a rationale for the feature.</p>
<p>We intend ZIPs to be the primary mechanism for proposing new features, for collecting community input on an issue, and for documenting the design decisions that have gone into Zcash. The Owner(s) of the ZIP (usually the authors(s)) are responsible for building consensus within the community and documenting dissenting opinions.</p>
<p>Because the ZIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal.</p>
<p>This document is based partly on the work done by Luke Dashjr with <a href="https://github.com/bitcoin/bips/blob/master/bip-0002.mediawiki">BIP 2</a>.</p>
<h1 id="zip-workflow">ZIP Workflow</h1>
<p>The ZIP process begins with a new idea for Zcash. Each potential ZIP must have a Owner -- someone who writes the ZIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. The ZIP Owner should first attempt to ascertain whether the idea is ZIP-able. Small enhancements or patches to a particular piece of software often don't require standardisation between multiple projects; these don't need a ZIP and should be injected into the relevant project-specific development workflow with a patch submission to the applicable issue tracker. Additionally, many ideas have been brought forward for changing Zcash that have been rejected for various reasons. The first step should be to search past discussions to see if an idea has been considered before, and if so, what issues arose in its progression. After investigating past work, the best way to proceed is by posting about the new idea to the <a href="https://forum.zcashcommunity.com/">Zcash Community Forum</a>.</p>
<p>Vetting an idea publicly before going as far as writing a ZIP is meant to save both the potential Owner and the wider community time. Asking the Zcash community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the Owner. Just because an idea sounds good to the Owner does not mean it will work for most people in most areas where Zcash is used.</p>
<p>Once the Owner has asked the Zcash community as to whether an idea has any chance of acceptance, a draft ZIP should be presented to the <a href="https://forum.zcashcommunity.com/">Zcash Community Forum</a>. This gives the Owner a chance to flesh out the draft ZIP to make it properly formatted, of high quality, and to address additional concerns about the proposal. Following a discussion, the proposal should be submitted to the <a href="https://github.com/zcash/zips">ZIPs git repository</a> as a pull request. This draft must be written in ZIP style as described below, and named with an alias such as <code>zip-zatoshizakamoto-42millionzec</code> until the ZIP Editors have assigned it a ZIP number (Owners MUST NOT self-assign ZIP numbers).</p>
<p>ZIP Owners are responsible for collecting community feedback on both the initial idea and the ZIP before submitting it for review. However, wherever possible, long open-ended discussions on forums should be avoided.</p>
<p>It is highly recommended that a single ZIP contain a single key proposal or new idea. The more focused the ZIP, the more successful it tends to be. If in doubt, split your ZIP into several well-focused ones.</p>
<p>When the ZIP draft is complete, the ZIP Editors will assign the ZIP a number, label it as Standards Track, Informational, or Process, and merge the pull request to the ZIPs git repository. The ZIP Editors will not unreasonably reject a ZIP. Reasons for rejecting ZIPs include duplication of effort, disregard for formatting rules, being too unfocused or too broad, being technically unsound, not providing proper motivation or not in keeping with the Zcash philosophy. For a ZIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly.</p>
<p>The ZIP Owner may update the draft as necessary in the git repository. Updates to drafts should also be submitted by the Owner as pull requests.</p>
<h2 id="transferring-zip-ownership">Transferring ZIP Ownership</h2>
<p>It occasionally becomes necessary to transfer ownership of ZIPs to a new Owner. In general, we'd like to retain the original Owner as a co-Owner of the transferred ZIP, but that's really up to the original Owner. A good reason to transfer ownership is because the original Owner no longer has the time or interest in updating it or following through with the ZIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the ZIP. We try to build consensus around a ZIP, but if that's not possible, you can always submit a competing ZIP.</p>
<p>If you are interested in assuming ownership of a ZIP, send a message asking to take over, addressed to both the original Owner and the ZIP Editors. If the original Owner doesn't respond to email in a timely manner, the ZIP Editors will make a unilateral decision (it's not like such decisions can't be reversed :).</p>
<p>If an author of a ZIP is no longer an Owner, an Original-Authors field SHOULD be added to the ZIP metadata indicating the original authorship, unless the original author(s) request otherwise.</p>
<h2 id="zip-editors">ZIP Editors</h2>
<p>The current ZIP Editors are Daira Hopwood, representing the Electric Coin Company, and Josh Cincinnati, representing the Zcash Foundation. Both can be reached at <a href="mailto:zips@z.cash">zips@z.cash</a> . The current design of the ZIP Process dictates that there are always at least two ZIP Editors: one from the Electric Coin Company and one from the Zcash Foundation. Additional Editors may be selected by consensus among the current Editors.</p>
<h2 id="zip-editor-responsibilities-workflow">ZIP Editor Responsibilities &amp; Workflow</h2>
<p>The ZIP Editors subscribe to the <a href="https://forum.zcashcommunity.com/">Zcash Community Forum.</a></p>
<p>For each new ZIP that comes in an Editor confirms the following:</p>
<ul>
<li>Read the ZIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to be accepted.</li>
<li>The title should accurately describe the content.</li>
<li>The ZIP draft must have been sent to the Zcash Community Forum or as a PR to the <a href="https://github.com/zcash/zips">ZIPs git repository</a></li>
<li>Motivation and backward compatibility (when applicable) must be addressed.</li>
<li>The licensing terms are acceptable for ZIPs.</li>
</ul>
<p>If the ZIP isn't ready, the editor will send it back to the Owner for revision, with specific instructions.</p>
<p>Once the ZIP is ready for the repository it should be submitted as a &quot;pull request&quot; to the <a href="https://github.com/zcash/zips">ZIPs git repository</a> where it may get further feedback. It should not contain a ZIP number, and should be labelled &quot;WIP&quot; in the pull request.</p>
<p>The ZIP Editors will:</p>
<ul>
<li>Assign a ZIP number in the pull request.</li>
<li>Merge the pull request when it is ready and remove the &quot;WIP&quot; label.</li>
</ul>
<p>The ZIP editors monitor ZIP changes and update ZIP headers as appropriate.</p>
<p>The ZIP Editors MAY reject a proposed ZIP or update to an existing ZIP for any of the following reasons:</p>
<ul>
<li>it violates the Zcash Code of Conduct<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a> ;</li>
<li>it appears too unfocused or broad;</li>
<li>it duplicates effort in other ZIPs without sufficient technical justification (however, alternative proposals to address similar or overlapping problems are not excluded for this reason);</li>
<li>it has manifest security flaws (including being unrealistically dependent on user vigilance to avoid security weaknesses);</li>
<li>it disregards compatibility with the existing Zcash blockchain or ecosystem;</li>
<li>it is manifestly unimplementable;</li>
<li>it includes buggy code, pseudocode, or algorithms;</li>
<li>it manifestly violates common expectations of a significant portion of the Zcash community;</li>
<li>it updates a Draft ZIP to Released when there is significant community opposition to its content (however, Draft ZIPs explicitly may describe proposals to which there is, or could be expected, significant community opposition);</li>
<li>in the case of a Released ZIP, the update makes a substantive change to which there is significant community opposition;</li>
<li>it is dependent on a patent that could potentially be an obstacle to adoption of the ZIP;</li>
<li>it includes commercial advertising or spam;</li>
<li>it disregards formatting rules;</li>
<li>it makes non-editorial edits to previous entries in a ZIP's Change history;</li>
<li>an update to an existing ZIP extends or changes its scope to an extent that would be better handled as a separate ZIP;</li>
<li>a new ZIP has been proposed for a category that does not reflect its content, or an update would change a ZIP to an inappropriate category;</li>
<li>it updates a Released ZIP to Draft when the specification is already implemented and has been in common use;</li>
<li>it violates any specific &quot;MUST&quot; or &quot;MUST NOT&quot; rule in this document;</li>
<li>the expressed political views of a Owner of the document are inimical to the Zcash Code of Conduct<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> (except in the case of an update removing that Owner);</li>
<li>it is not authorized by the stated ZIP Owners;</li>
<li>it removes an Owner without their consent (unless the reason for removal is directly related to a breach of the Code of Conduct by that Owner).</li>
</ul>
<p>The ZIP Editors MUST NOT unreasonably deny publication of a ZIP proposal or update that does not violate any of these criteria. If they refuse a proposal or update, they MUST give an explanation of which of the criteria were violated, with the exception that spam may be deleted without an explanation.</p>
<p>Note that it is not the primary responsibility of the ZIP Editors to review proposals for security, correctness, or implementability.</p>
<p>Please send all ZIP-related communications either by email to &lt;<a href="mailto:zips@z.cash">zips@z.cash</a>&gt;, or by opening an issue on the <a href="https://github.com/zcash/zips/issues">ZIPs issue tracker</a>. All communications should abide by the Zcash Code of Conduct<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a> and follow <a href="https://www.gnu.org/philosophy/kind-communication.en.html">the GNU Kind Communication Guidelines</a></p>
<h1 id="zip-format-and-structure">ZIP format and structure</h1>
<p>ZIPs SHOULD be written either in reStructuredText<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a> or LaTeX<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>. In the latter case, a Makefile MUST be provided to build (at least) a PDF version of the document.</p>
<p>Each ZIP SHOULD have the following parts:</p>
<ul>
<li>Preamble -- Headers containing metadata about the ZIP (<a href="#zip-header-preamble">see below</a>). The License field of the preamble indicates the licensing terms, which MUST be acceptable according to <a href="#zip-licensing">the ZIP licensing requirements</a>.</li>
<li>Terminology -- Definitions of technical or non-obvious terms used in the document.</li>
<li>Abstract -- A short (~200 word) description of the technical issue being addressed.</li>
<li>Motivation -- The motivation is critical for ZIPs that want to change the Zcash protocol. It should clearly explain why the existing protocol is inadequate to address the problem that the ZIP solves.</li>
<li>Specification -- The technical specification should describe the interface and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Zcash platforms.</li>
<li>Rationale -- The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work. The rationale should provide evidence of consensus within the community and discuss important objections or concerns raised during discussion.</li>
<li>Security and privacy considerations -- If applicable, security and privacy considerations should be explicitly described, particularly if the ZIP makes explicit trade-offs or assumptions. For guidance on this section consider <a href="https://tools.ietf.org/html/rfc3552">RFC 3552</a>. as a starting point.</li>
<li>Reference implementation -- Literal code implementing the ZIP's specification, and/or a link to the reference implementation of the ZIP's specification. The reference implementation must be completed before any ZIP is given status “Implemented” or “Final”, but it generally need not be completed before the ZIP is accepted into “Proposed”.</li>
</ul>
<h2 id="zip-header-preamble">ZIP header preamble</h2>
<p>Each ZIP must begin with an RFC 822-style header preamble. The following header fields are REQUIRED:</p>
<pre><code> ZIP:
 Title:
 Owners:
 Status:
 Category:
Created:
 License:</code></pre>
<p>The following additional header fields are OPTIONAL:</p>
<pre><code>Credits:
License: BSD-2-Clause</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "SHOULD", "SHOULD NOT", "MAY", "RECOMMENDED", "OPTIONAL", and "REQUIRED" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">1</a></p>
<p>The term "network upgrade" in this document is to be interpreted as described in ZIP 200. <a href="#zip-0200" id="id2" class="footnote_reference">2</a></p>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>A Zcash Improvement Proposal (ZIP) is a design document providing information to the Zcash community, or describing a new feature for Zcash or its processes or environment. The ZIP should provide a concise technical specification of the feature and a rationale for the feature.</p>
<p>We intend ZIPs to be the primary mechanism for proposing new features, for collecting community input on an issue, and for documenting the design decisions that have gone into Zcash. The Owner(s) of the ZIP (usually the authors(s)) are responsible for building consensus within the community and documenting dissenting opinions.</p>
<p>Because the ZIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal.</p>
<p>This document is based partly on the work done by Luke Dashjr with <a href="https://github.com/bitcoin/bips/blob/master/bip-0002.mediawiki">BIP 2</a>.</p>
</section>
<section id="zip-workflow">
<h2>ZIP Workflow</h2>
<p>The ZIP process begins with a new idea for Zcash. Each potential ZIP must have a Owner -- someone who writes the ZIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. The ZIP Owner should first attempt to ascertain whether the idea is ZIP-able. Small enhancements or patches to a particular piece of software often don't require standardisation between multiple projects; these don't need a ZIP and should be injected into the relevant project-specific development workflow with a patch submission to the applicable issue tracker. Additionally, many ideas have been brought forward for changing Zcash that have been rejected for various reasons. The first step should be to search past discussions to see if an idea has been considered before, and if so, what issues arose in its progression. After investigating past work, the best way to proceed is by posting about the new idea to the <a href="https://forum.zcashcommunity.com/">Zcash Community Forum</a>.</p>
<p>Vetting an idea publicly before going as far as writing a ZIP is meant to save both the potential Owner and the wider community time. Asking the Zcash community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the Owner. Just because an idea sounds good to the Owner does not mean it will work for most people in most areas where Zcash is used.</p>
<p>Once the Owner has asked the Zcash community as to whether an idea has any chance of acceptance, a draft ZIP should be presented to the <a href="https://forum.zcashcommunity.com/">Zcash Community Forum</a>. This gives the Owner a chance to flesh out the draft ZIP to make it properly formatted, of high quality, and to address additional concerns about the proposal. Following a discussion, the proposal should be submitted to the <a href="https://github.com/zcash/zips">ZIPs git repository</a> as a pull request. This draft must be written in ZIP style as described below, and named with an alias such as <code>zip-zatoshizakamoto-42millionzec</code> until the ZIP Editors have assigned it a ZIP number (Owners MUST NOT self-assign ZIP numbers).</p>
<p>ZIP Owners are responsible for collecting community feedback on both the initial idea and the ZIP before submitting it for review. However, wherever possible, long open-ended discussions on forums should be avoided.</p>
<p>It is highly recommended that a single ZIP contain a single key proposal or new idea. The more focused the ZIP, the more successful it tends to be. If in doubt, split your ZIP into several well-focused ones.</p>
<p>When the ZIP draft is complete, the ZIP Editors will assign the ZIP a number, label it as Standards Track, Informational, or Process, and merge the pull request to the ZIPs git repository. The ZIP Editors will not unreasonably reject a ZIP. Reasons for rejecting ZIPs include duplication of effort, disregard for formatting rules, being too unfocused or too broad, being technically unsound, not providing proper motivation or not in keeping with the Zcash philosophy. For a ZIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly.</p>
<p>The ZIP Owner may update the draft as necessary in the git repository. Updates to drafts should also be submitted by the Owner as pull requests.</p>
<section id="transferring-zip-ownership">
<h3>Transferring ZIP Ownership</h3>
<p>It occasionally becomes necessary to transfer ownership of ZIPs to a new Owner. In general, we'd like to retain the original Owner as a co-Owner of the transferred ZIP, but that's really up to the original Owner. A good reason to transfer ownership is because the original Owner no longer has the time or interest in updating it or following through with the ZIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the ZIP. We try to build consensus around a ZIP, but if that's not possible, you can always submit a competing ZIP.</p>
<p>If you are interested in assuming ownership of a ZIP, send a message asking to take over, addressed to both the original Owner and the ZIP Editors. If the original Owner doesn't respond to email in a timely manner, the ZIP Editors will make a unilateral decision (it's not like such decisions can't be reversed :).</p>
<p>If an author of a ZIP is no longer an Owner, an Original-Authors field SHOULD be added to the ZIP metadata indicating the original authorship, unless the original author(s) request otherwise.</p>
</section>
<section id="zip-editors">
<h3>ZIP Editors</h3>
<p>The current ZIP Editors are Daira Hopwood, representing the Electric Coin Company, and Josh Cincinnati, representing the Zcash Foundation. Both can be reached at <a href="mailto:zips@z.cash">zips@z.cash</a> . The current design of the ZIP Process dictates that there are always at least two ZIP Editors: one from the Electric Coin Company and one from the Zcash Foundation. Additional Editors may be selected by consensus among the current Editors.</p>
</section>
<section id="zip-editor-responsibilities-workflow">
<h3>ZIP Editor Responsibilities &amp; Workflow</h3>
<p>The ZIP Editors subscribe to the <a href="https://forum.zcashcommunity.com/">Zcash Community Forum.</a></p>
<p>For each new ZIP that comes in an Editor confirms the following:</p>
<ul>
<li>Read the ZIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to be accepted.</li>
<li>The title should accurately describe the content.</li>
<li>The ZIP draft must have been sent to the Zcash Community Forum or as a PR to the <a href="https://github.com/zcash/zips">ZIPs git repository</a></li>
<li>Motivation and backward compatibility (when applicable) must be addressed.</li>
<li>The licensing terms are acceptable for ZIPs.</li>
</ul>
<p>If the ZIP isn't ready, the editor will send it back to the Owner for revision, with specific instructions.</p>
<p>Once the ZIP is ready for the repository it should be submitted as a "pull request" to the <a href="https://github.com/zcash/zips">ZIPs git repository</a> where it may get further feedback. It should not contain a ZIP number, and should be labelled "WIP" in the pull request.</p>
<p>The ZIP Editors will:</p>
<ul>
<li>Assign a ZIP number in the pull request.</li>
<li>Merge the pull request when it is ready and remove the "WIP" label.</li>
</ul>
<p>The ZIP editors monitor ZIP changes and update ZIP headers as appropriate.</p>
<p>The ZIP Editors MAY reject a proposed ZIP or update to an existing ZIP for any of the following reasons:</p>
<ul>
<li>it violates the Zcash Code of Conduct <a href="#conduct" id="id3" class="footnote_reference">3</a> ;</li>
<li>it appears too unfocused or broad;</li>
<li>it duplicates effort in other ZIPs without sufficient technical justification (however, alternative proposals to address similar or overlapping problems are not excluded for this reason);</li>
<li>it has manifest security flaws (including being unrealistically dependent on user vigilance to avoid security weaknesses);</li>
<li>it disregards compatibility with the existing Zcash blockchain or ecosystem;</li>
<li>it is manifestly unimplementable;</li>
<li>it includes buggy code, pseudocode, or algorithms;</li>
<li>it manifestly violates common expectations of a significant portion of the Zcash community;</li>
<li>it updates a Draft ZIP to Released when there is significant community opposition to its content (however, Draft ZIPs explicitly may describe proposals to which there is, or could be expected, significant community opposition);</li>
<li>in the case of a Released ZIP, the update makes a substantive change to which there is significant community opposition;</li>
<li>it is dependent on a patent that could potentially be an obstacle to adoption of the ZIP;</li>
<li>it includes commercial advertising or spam;</li>
<li>it disregards formatting rules;</li>
<li>it makes non-editorial edits to previous entries in a ZIP's Change history;</li>
<li>an update to an existing ZIP extends or changes its scope to an extent that would be better handled as a separate ZIP;</li>
<li>a new ZIP has been proposed for a category that does not reflect its content, or an update would change a ZIP to an inappropriate category;</li>
<li>it updates a Released ZIP to Draft when the specification is already implemented and has been in common use;</li>
<li>it violates any specific "MUST" or "MUST NOT" rule in this document;</li>
<li>the expressed political views of a Owner of the document are inimical to the Zcash Code of Conduct <a href="#conduct" id="id4" class="footnote_reference">3</a> (except in the case of an update removing that Owner);</li>
<li>it is not authorized by the stated ZIP Owners;</li>
<li>it removes an Owner without their consent (unless the reason for removal is directly related to a breach of the Code of Conduct by that Owner).</li>
</ul>
<p>The ZIP Editors MUST NOT unreasonably deny publication of a ZIP proposal or update that does not violate any of these criteria. If they refuse a proposal or update, they MUST give an explanation of which of the criteria were violated, with the exception that spam may be deleted without an explanation.</p>
<p>Note that it is not the primary responsibility of the ZIP Editors to review proposals for security, correctness, or implementability.</p>
<p>Please send all ZIP-related communications either by email to &lt;<a href="mailto:zips@z.cash">zips@z.cash</a>&gt;, or by opening an issue on the <a href="https://github.com/zcash/zips/issues">ZIPs issue tracker</a>. All communications should abide by the Zcash Code of Conduct <a href="#conduct" id="id5" class="footnote_reference">3</a> and follow <a href="https://www.gnu.org/philosophy/kind-communication.en.html">the GNU Kind Communication Guidelines</a></p>
</section>
</section>
<section id="zip-format-and-structure">
<h2>ZIP format and structure</h2>
<p>ZIPs SHOULD be written either in reStructuredText <a href="#rst" id="id6" class="footnote_reference">4</a> or LaTeX <a href="#latex" id="id7" class="footnote_reference">5</a>. In the latter case, a <cite>Makefile</cite> MUST be provided to build (at least) a PDF version of the document.</p>
<p>Each ZIP SHOULD have the following parts:</p>
<ul>
<li>Preamble -- Headers containing metadata about the ZIP (<a href="#zip-header-preamble">see below</a>). The License field of the preamble indicates the licensing terms, which MUST be acceptable according to <a href="#zip-licensing">the ZIP licensing requirements</a>.</li>
<li>Terminology -- Definitions of technical or non-obvious terms used in the document.</li>
<li>Abstract -- A short (~200 word) description of the technical issue being addressed.</li>
<li>Motivation -- The motivation is critical for ZIPs that want to change the Zcash protocol. It should clearly explain why the existing protocol is inadequate to address the problem that the ZIP solves.</li>
<li>Specification -- The technical specification should describe the interface and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Zcash platforms.</li>
<li>Rationale -- The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work. The rationale should provide evidence of consensus within the community and discuss important objections or concerns raised during discussion.</li>
<li>Security and privacy considerations -- If applicable, security and privacy considerations should be explicitly described, particularly if the ZIP makes explicit trade-offs or assumptions. For guidance on this section consider <a href="https://tools.ietf.org/html/rfc3552">RFC 3552</a>. as a starting point.</li>
<li>Reference implementation -- Literal code implementing the ZIP's specification, and/or a link to the reference implementation of the ZIP's specification. The reference implementation must be completed before any ZIP is given status “Implemented” or “Final”, but it generally need not be completed before the ZIP is accepted into “Proposed”.</li>
</ul>
<section id="zip-header-preamble">
<h3>ZIP header preamble</h3>
<p>Each ZIP must begin with an RFC 822-style header preamble. The following header fields are REQUIRED:</p>
<pre>ZIP:
Title:
Owners:
Status:
Category:
Created:
License:</pre>
<p>The following additional header fields are OPTIONAL:</p>
<pre>Credits:
Original-Authors:
Discussions-To:
Network Upgrade:
Obsoleted by:
Updated by:
Obsoletes:
Updates:</code></pre>
<p>The Owners header lists the names and email addresses of all the Owners of the ZIP. The format of the Owners header value SHOULD be:</p>
<pre><code>Random J. User &lt;address@dom.ain&gt;</code></pre>
<p>If there are multiple Owners, each should be on a separate line.</p>
<p>While a ZIP is in private discussions (usually during the initial Draft phase), a Discussions-To header will indicate the URL where the ZIP is being discussed. No Discussions-To header is necessary if the ZIP is being discussed privately with the Owner.</p>
<p>The Category header specifies the type of ZIP: Consensus, Standards Track, Informational, or Process.</p>
<p>The Created header records the date that the ZIP was submitted. Dates should be in yyyy-mm-dd format, e.g. 2001-08-14.</p>
<h2 id="auxiliary-files">Auxiliary Files</h2>
<p>ZIPs may include auxiliary files such as diagrams. Auxiliary files should be included in a subdirectory for that ZIP; that is, for any ZIP that requires more than one file, all of the files SHOULD be in a subdirectory named zip-XXXX.</p>
<h1 id="zip-categories">ZIP categories</h1>
<p>There are several kinds of ZIP:</p>
<ul>
<li>A Consensus ZIP describes a change that affects the consensus protocol followed by all Zcash implementations.</li>
<li>A Standards Track ZIP describes any non-consensus change that affects most or all Zcash implementations, such as a change to the network protocol, or any change or addition that affects the interoperability of applications using Zcash.</li>
</ul>
<p>Consensus and Standards Track ZIPs consist of two parts: a design document and a reference implementation.</p>
<ul>
<li>An Informational ZIP describes Zcash design issues, or general guidelines or information for the Zcash community, that do not fall into either of the above categories. Informational ZIPs do not necessarily represent a Zcash community consensus or recommendation, so users and implementers are free to ignore Informational ZIPs or follow their advice.</li>
<li>A Process ZIP describes a process surrounding Zcash, or proposes a change to (or an event in) a process. Process ZIPs are like Standards Track ZIPs but apply to areas other than the Zcash protocol itself. They may propose an implementation, but not to Zcash's codebase; they often require community consensus; unlike Informational ZIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Zcash development.</li>
</ul>
<p>New categories may be added by consensus among the ZIP Editors.</p>
<h1 id="zip-status-field">ZIP Status Field</h1>
<ul>
<li>Draft: All initial ZIP submissions have this status.</li>
<li>Withdrawn: If the Owner decides to remove the ZIP from consideration by the community, they may set the status to Withdrawn.</li>
<li>Active: Typically only used for Process/Informational ZIPs, achieved once rough consensus is reached in PR/forum posts from Draft Process ZIP.</li>
<li>Proposed: Typically the stage after Draft, added to a ZIP after consideration, feedback, and rough consensus from the community. The ZIP Editors must validate this change before it is approved.</li>
<li>Rejected: The status when progress hasn't been made on the ZIP in one year. Can revert back to Draft/Proposed if the Owner resumes work or resolves issues preventing consensus.</li>
<li>Implemented: When a Consensus or Standards Track ZIP has a working reference implementation but before activation on the Zcash network.</li>
<li>Final: When a Consensus or Standards Track ZIP is both implemented and activated on the Zcash network.</li>
<li>Obsolete: The status when a ZIP is no longer relevant (typically when superseded by another ZIP).</li>
</ul>
<p>More details on the status workflow in the section below.</p>
<h2 id="specification">Specification</h2>
<p>Owners of a ZIP may decide on their own to change the status between Draft or Withdrawn.</p>
<p>A ZIP may only change status from Draft (or Rejected) to Proposed, when the Owner deems it is complete and there is rough consensus on the forums, validated by both the Electric Coin Company and Zcash Foundation Editors. One Editor will not suffice -- there needs to be consensus among the Editors. If it's a Standards Track ZIP, upon changing status to Proposed the Editors will add the optional <code>Network Upgrade</code> header to the preamble, indicating the intent for the ZIP to be implemented in the specified network upgrade. (All <code>Network Upgrade</code> schedules will be distributed via the Zcash Community Forum by the Editors.)</p>
<p>A Standards Track ZIP may only change status from Proposed to Implemented once the Owner provides an associated reference implementation, typically in the period after the network upgrade's specification freeze but before the implementation audit. If the Owner misses this deadline, the Editors or Owner(s) may choose to update the <code>Network Upgrade</code> header to target another upgrade, at their discretion.</p>
<p>ZIPs should be changed from Draft or Proposed status, to Rejected status, upon request by any person, if they have not made progress in one year. Such a ZIP may be changed to Draft status if the Owner provides revisions that meaningfully address public criticism of the proposal, or to Proposed status if it meets the criteria required as described in the previous paragraph.</p>
<p>A Consensus or Standards Track ZIP becomes Final when its associated network upgrade or other protocol change is activated on Zcash's mainnet.</p>
<p>A Process or Informational ZIP may change status from Draft to Active when it achieves rough consensus on the forum or PR. Such a proposal is said to have rough consensus if it has been open to discussion on the forum or GitHub PR for at least one month, and no person maintains any unaddressed substantiated objections to it. Addressed or obstructive objections may be ignored/overruled by general agreement that they have been sufficiently addressed, but clear reasoning must be given in such circumstances.</p>
<p>When an Active or Final ZIP is no longer relevant, its status may be changed to Obsolete. This change must also be objectively verifiable and/or discussed. Final ZIPs may be updated; the specification is still in force but modified by another specified ZIP or ZIPs (check the optional Updated-by header).</p>
<h1 id="zip-comments">ZIP Comments</h1>
<p>Comments from the community on the ZIP should occur on the Zcash Community Forum and the comment fields of the pull requests in any open ZIPs. Editors will use these sources to judge rough consensus.</p>
<h1 id="zip-licensing">ZIP licensing</h1>
<p>New ZIPs may be accepted with the following licenses. Each new ZIP MUST identify at least one acceptable license in its preamble. Each license MUST be referenced by their respective abbreviation given below.</p>
<p>For example, a preamble might include the following License header:</p>
<pre><code>License: BSD-2-Clause
   GNU-All-Permissive</code></pre>
<p>In this case, the ZIP text is fully licensed under both the OSI-approved BSD 2-clause license as well as the GNU All-Permissive License, and anyone may modify and redistribute the text provided they comply with the terms of <em>either</em> license. In other words, the license list is an &quot;OR choice&quot;, not an &quot;AND also&quot; requirement.</p>
<p>It is also possible to license source code differently from the ZIP text. This case SHOULD be indicated in the Reference Implementation section of the ZIP. Again, each license MUST be referenced by its respective abbreviation given below.</p>
<p>Statements of code licenses in ZIPs are only advisory; anyone intending to use the code should look for license statements in the code itself.</p>
<p>ZIPs are not required to be <em>exclusively</em> licensed under approved terms, and MAY also be licensed under unacceptable licenses <em>in addition to</em> at least one acceptable license. In this case, only the acceptable license(s) should be listed in the License header.</p>
<h2 id="recommended-licenses">Recommended licenses</h2>
<ul>
<li>MIT: <a href="https://opensource.org/licenses/MIT">Expat/MIT/X11 license</a></li>
<li>BSD-2-Clause: <a href="https://opensource.org/licenses/BSD-2-Clause">OSI-approved BSD 2-clause license</a></li>
<li>BSD-3-Clause: <a href="https://opensource.org/licenses/BSD-3-Clause">OSI-approved BSD 3-clause license</a></li>
<li>CC0-1.0: <a href="https://creativecommons.org/publicdomain/zero/1.0/">Creative Commons CC0 1.0 Universal</a></li>
<li>GNU-All-Permissive: <a href="http://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html">GNU All-Permissive License</a></li>
<li>Apache-2.0: <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, version 2.0</a></li>
</ul>
<p>In addition, it is RECOMMENDED that literal code included in the ZIP be dual-licensed under the same license terms as the project it modifies. For example, literal code intended for zcashd would ideally be dual-licensed under the MIT license terms as well as one of the above with the rest of the ZIP text.</p>
<h2 id="not-recommended-but-acceptable-licenses">Not recommended, but acceptable licenses</h2>
<ul>
<li>BSL-1.0: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, version 1.0</a></li>
<li>CC-BY-4.0: <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International</a></li>
<li>CC-BY-SA-4.0: <a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International</a></li>
<li>AGPL-3.0+: <a href="http://www.gnu.org/licenses/agpl-3.0.en.html">GNU Affero General Public License (AGPL), version 3 or newer</a></li>
<li>FDL-1.3: <a href="http://www.gnu.org/licenses/fdl-1.3.en.html">GNU Free Documentation License, version 1.3</a></li>
<li>GPL-2.0+: <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">GNU General Public License (GPL), version 2 or newer</a></li>
<li>LGPL-2.1+: <a href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html">GNU Lesser General Public License (LGPL), version 2.1 or newer</a></li>
</ul>
<h2 id="not-acceptable-licenses">Not acceptable licenses</h2>
<p>All licenses not explicitly included in the above lists are not acceptable terms for a Zcash Improvement Proposal.</p>
<h2 id="rationale">Rationale</h2>
<p>Bitcoin's BIP 1 allowed the Open Publication License or releasing into the public domain; was this insufficient?</p>
<ul>
<li>The OPL is generally regarded as obsolete, and not a license suitable for new publications.</li>
<li>The OPL license terms allowed for the author to prevent publication and derived works, which was widely considered inappropriate.</li>
<li>In some jurisdictions, releasing a work to the public domain is not recognised as a legitimate legal action, leaving the ZIP simply copyrighted with no redistribution or modification allowed at all.</li>
</ul>
<p>Why are there software licenses included?</p>
<ul>
<li>Some ZIPs, especially in the Consensus category, may include literal code in the ZIP itself which may not be available under the exact license terms of the ZIP.</li>
<li>Despite this, not all software licenses would be acceptable for content included in ZIPs.</li>
</ul>
<h1 id="see-also">See Also</h1>
<ul>
<li><a href="https://www.gnu.org/philosophy/kind-communication.en.html">The GNU Kind Communication Guidelines</a></li>
<li><a href="https://tools.ietf.org/html/rfc7282">RFC 7282: On Consensus and Humming in the IETF</a></li>
<li><a href="https://electriccoin.co/blog/the-zcash-network-upgrade-pipeline/">Zcash Network Upgrade Pipeline</a></li>
</ul>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zcash/blob/master/code_of_conduct.md">Zcash Code of Conduct</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zcash/blob/master/code_of_conduct.md">Zcash Code of Conduct</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zcash/blob/master/code_of_conduct.md">Zcash Code of Conduct</a><a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><p><a href="http://docutils.sourceforge.net/rst.html">reStructuredText documentation</a><a href="#fnref6" class="footnote-back"></a></p></li>
<li id="fn7"><p><a href="https://www.latex-project.org/">LaTeX -- a document preparation system</a><a href="#fnref7" class="footnote-back"></a></p></li>
</ol>
</section>
Updates:</pre>
<p>The Owners header lists the names and email addresses of all the Owners of the ZIP. The format of the Owners header value SHOULD be:</p>
<pre>Random J. User &lt;address@dom.ain&gt;</pre>
<p>If there are multiple Owners, each should be on a separate line.</p>
<p>While a ZIP is in private discussions (usually during the initial Draft phase), a Discussions-To header will indicate the URL where the ZIP is being discussed. No Discussions-To header is necessary if the ZIP is being discussed privately with the Owner.</p>
<p>The Category header specifies the type of ZIP: Consensus, Standards Track, Informational, or Process.</p>
<p>The Created header records the date that the ZIP was submitted. Dates should be in yyyy-mm-dd format, e.g. 2001-08-14.</p>
</section>
<section id="auxiliary-files">
<h3>Auxiliary Files</h3>
<p>ZIPs may include auxiliary files such as diagrams. Auxiliary files should be included in a subdirectory for that ZIP; that is, for any ZIP that requires more than one file, all of the files SHOULD be in a subdirectory named zip-XXXX.</p>
</section>
</section>
<section id="zip-categories">
<h2>ZIP categories</h2>
<p>There are several kinds of ZIP:</p>
<ul>
<li>A Consensus ZIP describes a change that affects the consensus protocol followed by all Zcash implementations.</li>
<li>A Standards Track ZIP describes any non-consensus change that affects most or all Zcash implementations, such as a change to the network protocol, or any change or addition that affects the interoperability of applications using Zcash.</li>
</ul>
<p>Consensus and Standards Track ZIPs consist of two parts: a design document and a reference implementation.</p>
<ul>
<li>An Informational ZIP describes Zcash design issues, or general guidelines or information for the Zcash community, that do not fall into either of the above categories. Informational ZIPs do not necessarily represent a Zcash community consensus or recommendation, so users and implementers are free to ignore Informational ZIPs or follow their advice.</li>
<li>A Process ZIP describes a process surrounding Zcash, or proposes a change to (or an event in) a process. Process ZIPs are like Standards Track ZIPs but apply to areas other than the Zcash protocol itself. They may propose an implementation, but not to Zcash's codebase; they often require community consensus; unlike Informational ZIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Zcash development.</li>
</ul>
<p>New categories may be added by consensus among the ZIP Editors.</p>
</section>
<section id="zip-status-field">
<h2>ZIP Status Field</h2>
<ul>
<li>Draft: All initial ZIP submissions have this status.</li>
<li>Withdrawn: If the Owner decides to remove the ZIP from consideration by the community, they may set the status to Withdrawn.</li>
<li>Active: Typically only used for Process/Informational ZIPs, achieved once rough consensus is reached in PR/forum posts from Draft Process ZIP.</li>
<li>Proposed: Typically the stage after Draft, added to a ZIP after consideration, feedback, and rough consensus from the community. The ZIP Editors must validate this change before it is approved.</li>
<li>Rejected: The status when progress hasn't been made on the ZIP in one year. Can revert back to Draft/Proposed if the Owner resumes work or resolves issues preventing consensus.</li>
<li>Implemented: When a Consensus or Standards Track ZIP has a working reference implementation but before activation on the Zcash network.</li>
<li>Final: When a Consensus or Standards Track ZIP is both implemented and activated on the Zcash network.</li>
<li>Obsolete: The status when a ZIP is no longer relevant (typically when superseded by another ZIP).</li>
</ul>
<p>More details on the status workflow in the section below.</p>
<section id="specification">
<h3>Specification</h3>
<p>Owners of a ZIP may decide on their own to change the status between Draft or Withdrawn.</p>
<p>A ZIP may only change status from Draft (or Rejected) to Proposed, when the Owner deems it is complete and there is rough consensus on the forums, validated by both the Electric Coin Company and Zcash Foundation Editors. One Editor will not suffice -- there needs to be consensus among the Editors. If it's a Standards Track ZIP, upon changing status to Proposed the Editors will add the optional <code>Network Upgrade</code> header to the preamble, indicating the intent for the ZIP to be implemented in the specified network upgrade. (All <code>Network Upgrade</code> schedules will be distributed via the Zcash Community Forum by the Editors.)</p>
<p>A Standards Track ZIP may only change status from Proposed to Implemented once the Owner provides an associated reference implementation, typically in the period after the network upgrade's specification freeze but before the implementation audit. If the Owner misses this deadline, the Editors or Owner(s) may choose to update the <code>Network Upgrade</code> header to target another upgrade, at their discretion.</p>
<p>ZIPs should be changed from Draft or Proposed status, to Rejected status, upon request by any person, if they have not made progress in one year. Such a ZIP may be changed to Draft status if the Owner provides revisions that meaningfully address public criticism of the proposal, or to Proposed status if it meets the criteria required as described in the previous paragraph.</p>
<p>A Consensus or Standards Track ZIP becomes Final when its associated network upgrade or other protocol change is activated on Zcash's mainnet.</p>
<p>A Process or Informational ZIP may change status from Draft to Active when it achieves rough consensus on the forum or PR. Such a proposal is said to have rough consensus if it has been open to discussion on the forum or GitHub PR for at least one month, and no person maintains any unaddressed substantiated objections to it. Addressed or obstructive objections may be ignored/overruled by general agreement that they have been sufficiently addressed, but clear reasoning must be given in such circumstances.</p>
<p>When an Active or Final ZIP is no longer relevant, its status may be changed to Obsolete. This change must also be objectively verifiable and/or discussed. Final ZIPs may be updated; the specification is still in force but modified by another specified ZIP or ZIPs (check the optional Updated-by header).</p>
</section>
</section>
<section id="zip-comments">
<h2>ZIP Comments</h2>
<p>Comments from the community on the ZIP should occur on the Zcash Community Forum and the comment fields of the pull requests in any open ZIPs. Editors will use these sources to judge rough consensus.</p>
</section>
<section id="zip-licensing">
<h2>ZIP licensing</h2>
<p>New ZIPs may be accepted with the following licenses. Each new ZIP MUST identify at least one acceptable license in its preamble. Each license MUST be referenced by their respective abbreviation given below.</p>
<p>For example, a preamble might include the following License header:</p>
<pre>License: BSD-2-Clause
   GNU-All-Permissive</pre>
<p>In this case, the ZIP text is fully licensed under both the OSI-approved BSD 2-clause license as well as the GNU All-Permissive License, and anyone may modify and redistribute the text provided they comply with the terms of <em>either</em> license. In other words, the license list is an "OR choice", not an "AND also" requirement.</p>
<p>It is also possible to license source code differently from the ZIP text. This case SHOULD be indicated in the Reference Implementation section of the ZIP. Again, each license MUST be referenced by its respective abbreviation given below.</p>
<p>Statements of code licenses in ZIPs are only advisory; anyone intending to use the code should look for license statements in the code itself.</p>
<p>ZIPs are not required to be <em>exclusively</em> licensed under approved terms, and MAY also be licensed under unacceptable licenses <em>in addition to</em> at least one acceptable license. In this case, only the acceptable license(s) should be listed in the License header.</p>
<section id="recommended-licenses">
<h3>Recommended licenses</h3>
<ul>
<li>MIT: <a href="https://opensource.org/licenses/MIT">Expat/MIT/X11 license</a></li>
<li>BSD-2-Clause: <a href="https://opensource.org/licenses/BSD-2-Clause">OSI-approved BSD 2-clause license</a></li>
<li>BSD-3-Clause: <a href="https://opensource.org/licenses/BSD-3-Clause">OSI-approved BSD 3-clause license</a></li>
<li>CC0-1.0: <a href="https://creativecommons.org/publicdomain/zero/1.0/">Creative Commons CC0 1.0 Universal</a></li>
<li>GNU-All-Permissive: <a href="http://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html">GNU All-Permissive License</a></li>
<li>Apache-2.0: <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, version 2.0</a></li>
</ul>
<p>In addition, it is RECOMMENDED that literal code included in the ZIP be dual-licensed under the same license terms as the project it modifies. For example, literal code intended for zcashd would ideally be dual-licensed under the MIT license terms as well as one of the above with the rest of the ZIP text.</p>
</section>
<section id="not-recommended-but-acceptable-licenses">
<h3>Not recommended, but acceptable licenses</h3>
<ul>
<li>BSL-1.0: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, version 1.0</a></li>
<li>CC-BY-4.0: <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International</a></li>
<li>CC-BY-SA-4.0: <a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International</a></li>
<li>AGPL-3.0+: <a href="http://www.gnu.org/licenses/agpl-3.0.en.html">GNU Affero General Public License (AGPL), version 3 or newer</a></li>
<li>FDL-1.3: <a href="http://www.gnu.org/licenses/fdl-1.3.en.html">GNU Free Documentation License, version 1.3</a></li>
<li>GPL-2.0+: <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">GNU General Public License (GPL), version 2 or newer</a></li>
<li>LGPL-2.1+: <a href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html">GNU Lesser General Public License (LGPL), version 2.1 or newer</a></li>
</ul>
</section>
<section id="not-acceptable-licenses">
<h3>Not acceptable licenses</h3>
<p>All licenses not explicitly included in the above lists are not acceptable terms for a Zcash Improvement Proposal.</p>
</section>
<section id="rationale">
<h3>Rationale</h3>
<p>Bitcoin's BIP 1 allowed the Open Publication License or releasing into the public domain; was this insufficient?</p>
<ul>
<li>The OPL is generally regarded as obsolete, and not a license suitable for new publications.</li>
<li>The OPL license terms allowed for the author to prevent publication and derived works, which was widely considered inappropriate.</li>
<li>In some jurisdictions, releasing a work to the public domain is not recognised as a legitimate legal action, leaving the ZIP simply copyrighted with no redistribution or modification allowed at all.</li>
</ul>
<p>Why are there software licenses included?</p>
<ul>
<li>Some ZIPs, especially in the Consensus category, may include literal code in the ZIP itself which may not be available under the exact license terms of the ZIP.</li>
<li>Despite this, not all software licenses would be acceptable for content included in ZIPs.</li>
</ul>
</section>
</section>
<section id="see-also">
<h2>See Also</h2>
<ul>
<li><a href="https://www.gnu.org/philosophy/kind-communication.en.html">The GNU Kind Communication Guidelines</a></li>
<li><a href="https://tools.ietf.org/html/rfc7282">RFC 7282: On Consensus and Humming in the IETF</a></li>
<li><a href="https://electriccoin.co/blog/the-zcash-network-upgrade-pipeline/">Zcash Network Upgrade Pipeline</a></li>
</ul>
</section>
<section id="references">
<h2>References</h2>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0200" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a></td>
</tr>
</tbody>
</table>
<table id="conduct" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zcash/blob/master/code_of_conduct.md">Zcash Code of Conduct</a></td>
</tr>
</tbody>
</table>
<table id="rst" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="http://docutils.sourceforge.net/rst.html">reStructuredText documentation</a></td>
</tr>
</tbody>
</table>
<table id="latex" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://www.latex-project.org/">LaTeX -- a document preparation system</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,19 +1,12 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 32: Shielded Hierarchical Deterministic Wallets</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 32: Shielded Hierarchical Deterministic Wallets</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 32
<section>
<pre>ZIP: 32
Title: Shielded Hierarchical Deterministic Wallets
Owners: Jack Grigg &lt;str4d@electriccoin.co&gt;
Daira Hopwood &lt;daira@electriccoin.co&gt;
@ -23,267 +16,389 @@ Credits: Pieter Wuille &lt;pieter.wuille@gmail.com&gt;
Status: Final
Category: Standards Track
Created: 2018-05-22
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119. <a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>&quot;Jubjub&quot; refers to the elliptic curve defined in<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a> section 5.4.8.3.</p>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines a mechanism for extending hierarchical deterministic wallets, as decribed in BIP 32 <a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>, to support Zcash's shielded addresses.</p>
<p>The specification has three parts. The first part defines a system for deriving a tree of Sapling key components from a single seed. The second part defines an equivalent, but independent, system for Sprout key components (which have a different internal construction). The third part shows how to use these trees in the context of existing BIP 44<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> wallets.</p>
<p>This specification complements the existing use by some Zcash wallets of BIP 32 and BIP 44 for transparent Zcash addresses, and is not intended to deprecate that usage (privacy risks of using transparent addresses notwithstanding).</p>
<h1 id="motivation">Motivation</h1>
<p>BIP 32<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a> is the standard mechanism by which wallets for Bitcoin and its derivatives (including Zcash's transparent addresses<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a>) generate keys and addresses deterministically. This has several advantages over random generation:</p>
<ul>
<li>Wallets only need to store a single seed (particularly useful for hardware wallets).</li>
<li>A one-time backup of the seed (usually stored as a word phrase<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>) can be used to recover funds from all future addresses.</li>
<li>Keys are arranged into a tree of chains, enabling wallets to represent &quot;accounts&quot; or other high-level structures.</li>
<li>View authority or spend authority can be delegated independently for sub-trees without compromising the master seed.</li>
</ul>
<p>At present, no such equivalent exists for Zcash's shielded addresses. This is of particular concern for hardware wallets; all currently-marketed devices only store a seed internally, and have trained their users to only backup that seed. Given that the Sapling upgrade will make it feasible to use hardware wallets with shielded addresses, it is desirable to have a standard mechanism for deriving them.</p>
<h1 id="conventions">Conventions</h1>
<p>Most of the notation and functions used in this ZIP are defined in the Sapling protocol specification <a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>. They are reproduced here for convenience:</p>
<ul>
<li>truncate<sub>k</sub>(<em>S</em>) means the sequence formed from the first <em>k</em> elements of <em>S</em>.</li>
<li><em>a</em> || <em>b</em> means the concatenation of sequences <em>a</em> then <em>b</em>.</li>
<li>[<em>k</em>] <em>P</em> means scalar multiplication of the elliptic curve point <em>P</em> by the scalar <em>k</em>.</li>
<li>LEOS2IP<sub>l</sub>(<em>S</em>) is the integer in range {0..2<sup>l</sup>-1} represented in little-endian order by the byte sequence <em>S</em> of length <em>l</em>/8.</li>
<li>I2LEBSP<sub>l</sub>(<em>k</em>) is the sequence of <em>l</em> bits representing <em>k</em> in little-endian order.</li>
<li>LEBS2OSP<sub>l</sub>(<em>B</em>) is defined as follows when <em>l</em> is a multiple of 8: convert each group of 8 bits in <em>B</em> to a byte value with the least significant bit first, and concatenate the resulting bytes in the same order as the groups.</li>
<li>repr<sub>𝕁</sub>(<em>P</em>) is the representation of the Jubjub elliptic curve point <em>P</em> as a bit sequence, defined in<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a> section 5.4.8.3.</li>
<li>BLAKE2b-256(<em>p</em>, <em>x</em>) refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of 32 bytes, 16-byte personalization string <em>p</em>, and input <em>x</em>.</li>
<li>BLAKE2b-512(<em>p</em>, <em>x</em>) refers to unkeyed BLAKE2b-512 in sequential mode, with an output digest length of 64 bytes, 16-byte personalization string <em>p</em>, and input <em>x</em>.</li>
<li>PRF<sup>expand</sup>(<em>sk</em>, <em>t</em>) := BLAKE2b-512(&quot;Zcash_ExpandSeed&quot;, <em>sk</em> || <em>t</em>)</li>
<li>ToScalar(<em>x</em>) := LEOS2IP<sub>512</sub>(<em>x</em>) (mod <em>r</em><sub>𝕁</sub>), where <em>r</em><sub>𝕁</sub> is the order of the Jubjub large prime subgroup.</li>
<li>DiversifyHash(<em>d</em>) maps a diversifier <em>d</em> to a base point on the Jubjub elliptic curve, or to ⊥ if the diversifier is invalid. It is instantiated in<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a> section 5.4.1.6.</li>
</ul>
<p>The following algorithm standardized in<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a> is used:</p>
<ul>
<li>FF1-AES256.Encrypt(<em>key</em>, <em>tweak</em>, <em>x</em>) refers to the FF1 encryption algorithm using AES with a 256-bit <em>key</em>, and parameters <em>radix</em> = 2, <em>minlen</em> = 88, <em>maxlen</em> = 88. It will be used only with the empty string &quot;&quot; as the <em>tweak</em>. <em>x</em> is a sequence of 88 bits, as is the output.</li>
</ul>
<p>We also define the following conversion function:</p>
<ul>
<li>I2LEOSP<sub>l</sub>(<em>k</em>) is the byte sequence <em>S</em> of length <em>l</em>/8 representing in little-endian order the integer <em>k</em> in range {0..2<sup>l</sup>-1}. It is the reverse operation of LEOS2IP<sub>l</sub>(<em>S</em>).</li>
</ul>
<p>Implementors should note that this ZIP is consistently little-endian (in keeping with the Sapling specification), which is the opposite of BIP 32.</p>
<p>We adapt the path notation of BIP 32<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a> to describe shielded HD paths, using apostrophes to indicate hardened derivation (i' = i + 2<sup>31</sup>) as in BIP 44<a href="#fn13" class="footnote-ref" id="fnref13"><sup>13</sup></a>:</p>
<ul>
<li>CDKsk(CDKsk(CDKsk(m<sub>Sprout</sub>, a'), b), c) is written as m<sub>Sprout</sub> / a' / b / c</li>
<li>CDKfvk(CDKfvk(CDKfvk(M<sub>Sapling</sub>, a), b), c) is written as M<sub>Sapling</sub> / a / b / c</li>
</ul>
<h1 id="specification-sapling-key-derivation">Specification: Sapling key derivation</h1>
<h2 id="sapling-extended-keys">Sapling extended keys</h2>
<p>BIP 32 defines a method to derive a number of child keys from a parent key. In order to prevent these from depending solely on the parent key itself, both the private and public keys are extended with a 32-byte chain code. We similarly extend Sapling keys with a chain code here. However, the concepts of &quot;private&quot; and &quot;public&quot; keys in BIP 32 do not map cleanly to Sapling's key components. We take the following approach:</p>
<ul>
<li>We derive child Sapling expanded spending keys, rather than Sapling spending keys. This enables us to implement both hardened and non-hardened derivation modes (the latter being incompatible with Sapling spending keys).</li>
<li>We do not derive Sapling public keys directly, as this would prevent the use of diversified addresses. Instead, we derive Sapling full viewing keys, from which payment addresses can be generated. This maintains the trust semantics of BIP 32: someone with access to a BIP 32 extended public key is able to view all transactions involving that address, which a Sapling full viewing key also enables.</li>
</ul>
<p>We represent a Sapling extended spending key as (<em>ask</em>, <em>nsk</em>, <em>ovk</em>, <em>dk</em>, <em>c</em>), where (<em>ask</em>, <em>nsk</em>, <em>ovk</em>) is the normal Sapling expanded spending key, <em>dk</em> is a diversifier key, and <em>c</em> is the chain code.</p>
<p>We represent a Sapling extended full viewing key as (<em>ak</em>, <em>nk</em>, <em>ovk</em>, <em>dk</em>, <em>c</em>), where (<em>ak</em>, <em>nk</em>, <em>ovk</em>) is the normal Sapling full viewing key, <em>dk</em> is the same diversifier key as above, and <em>c</em> is the chain code.</p>
<h2 id="helper-functions">Helper functions</h2>
<p>Define EncodeExtSKParts(<em>ask</em>, <em>nsk</em>, <em>ovk</em>, <em>dk</em>) := I2LEOSP<sub>256</sub>(<em>ask</em>) || I2LEOSP<sub>256</sub>(<em>nsk</em>) || <em>ovk</em> || <em>dk</em>.</p>
<p>Define EncodeExtFVKParts(<em>ak</em>, <em>nk</em>, <em>ovk</em>, <em>dk</em>) := LEBS2OSP<sub>256</sub>(repr<sub>𝕁</sub>(<em>ak</em>)) || LEBS2OSP<sub>256</sub>(repr<sub>𝕁</sub>(<em>nk</em>)) || <em>ovk</em> || <em>dk</em>.</p>
<h2 id="master-key-generation">Master key generation</h2>
<p>Let <em>S</em> be a seed byte sequence of a chosen length, which MUST be at least 32 bytes.</p>
<ul>
<li>Calculate <em>I</em> = BLAKE2b-512(&quot;ZcashIP32Sapling&quot;, <em>S</em>).</li>
<li>Split <em>I</em> into two 32-byte sequences, <em>I</em><sub>L</sub> and <em>I</em><sub>R</sub>.</li>
<li>Use <em>I</em><sub>L</sub> as the master spending key <em>sk</em><sub>m</sub>, and <em>I</em><sub>R</sub> as the master chain code <em>c</em><sub>m</sub>.</li>
<li>Calculate <em>ask</em><sub>m</sub>, <em>nsk</em><sub>m</sub>, and <em>ovk</em><sub>m</sub> via the standard Sapling derivation <a href="#fn14" class="footnote-ref" id="fnref14"><sup>14</sup></a>:
<ul>
<li><em>ask</em><sub>m</sub> = ToScalar(PRF<sup>expand</sup>(<em>sk</em><sub>m</sub>, [0x00]))</li>
<li><em>nsk</em><sub>m</sub> = ToScalar(PRF<sup>expand</sup>(<em>sk</em><sub>m</sub>, [0x01]))</li>
<li><em>ovk</em><sub>m</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>sk</em><sub>m</sub>, [0x02]))</li>
</ul></li>
<li>Calculate <em>dk</em><sub>m</sub> similarly:
<ul>
<li><em>dk</em><sub>m</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>sk</em><sub>m</sub>, [0x10]))</li>
</ul></li>
<li>Return (<em>ask</em><sub>m</sub>, <em>nsk</em><sub>m</sub>, <em>ovk</em><sub>m</sub>, <em>dk</em><sub>m</sub>, <em>c</em><sub>m</sub>) as the master extended spending key <em>m</em><sub>Sapling</sub>.</li>
</ul>
<h2 id="child-key-derivation">Child key derivation</h2>
<p>As in BIP 32, the method for deriving a child extended key, given a parent extended key and an index <em>i</em>, depends on the type of key being derived, and whether this is a hardened or non-hardened derivation.</p>
<h3 id="deriving-a-child-extended-spending-key">Deriving a child extended spending key</h3>
<p>CDKsk((<em>ask</em><sub>par</sub>, <em>nsk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>, <em>c</em><sub>par</sub>), <em>i</em>) → (<em>ask</em><sub>i</sub>, <em>nsk</em><sub>i</sub>, <em>ovk</em><sub>i</sub>, <em>dk</em><sub>i</sub>, <em>c</em><sub>i</sub>)</p>
<ul>
<li>Check whether <em>i</em> ≥ 2<sup>31</sup> (whether the child is a hardened key).
<ul>
<li>If so (hardened child): let <em>I</em> = PRF<sup>expand</sup>(<em>c</em><sub>par</sub>, [0x11] || EncodeExtSKParts(<em>ask</em><sub>par</sub>, <em>nsk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>) || I2LEOSP<sub>32</sub>(<em>i</em>))</li>
<li>If not (normal child): let <em>I</em> = PRF<sup>expand</sup>(<em>c</em><sub>par</sub>, [0x12] || EncodeExtFVKParts(<em>ak</em><sub>par</sub>, <em>nk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>) || I2LEOSP<sub>32</sub>(<em>i</em>)) where (<em>nk</em><sub>par</sub>, <em>ak</em><sub>par</sub>, <em>ovk</em><sub>par</sub>) is the full viewing key derived from (<em>ask</em><sub>par</sub>, <em>nsk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>) as described in<a href="#fn15" class="footnote-ref" id="fnref15"><sup>15</sup></a>.</li>
</ul></li>
<li>Split <em>I</em> into two 32-byte sequences, <em>I</em><sub>L</sub> and <em>I</em><sub>R</sub>.</li>
<li>Let <em>I</em><sub>ask</sub> = ToScalar(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x13]))</li>
<li>Let <em>I</em><sub>nsk</sub> = ToScalar(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x14]))</li>
<li>Return:
<ul>
<li><em>ask</em><sub>i</sub> = <em>I</em><sub>ask</sub> + <em>ask</em><sub>par</sub></li>
<li><em>nsk</em><sub>i</sub> = <em>I</em><sub>nsk</sub> + <em>nsk</em><sub>par</sub></li>
<li><em>ovk</em><sub>i</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x15] || <em>ovk</em><sub>par</sub>))</li>
<li><em>dk</em><sub>i</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x16] || <em>dk</em><sub>par</sub>))</li>
<li><em>c</em><sub>i</sub> = <em>I</em><sub>R</sub></li>
</ul></li>
</ul>
<h3 id="deriving-a-child-extended-full-viewing-key">Deriving a child extended full viewing key</h3>
<p>Let 𝓖 be as defined in<a href="#fn16" class="footnote-ref" id="fnref16"><sup>16</sup></a> section 5.4.6.1 and let 𝓗 be as defined in<a href="#fn17" class="footnote-ref" id="fnref17"><sup>17</sup></a>.</p>
<p>CDKfvk((<em>ak</em><sub>par</sub>, <em>nk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>, <em>c</em><sub>par</sub>), <em>i</em>) → (<em>ak</em><sub>i</sub>, <em>nk</em><sub>i</sub>, <em>ovk</em><sub>i</sub>, <em>dk</em><sub>i</sub>, <em>c</em><sub>i</sub>)</p>
<ul>
<li>Check whether <em>i</em> ≥ 2<sup>31</sup> (whether the child is a hardened key).
<ul>
<li>If so (hardened child): return failure</li>
<li>If not (normal child): let <em>I</em> = PRF<sup>expand</sup>(<em>c</em><sub>par</sub>, [0x12] || EncodeExtFVKParts(<em>ak</em><sub>par</sub>, <em>nk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>) || I2LEOSP<sub>32</sub>(<em>i</em>))</li>
</ul></li>
<li>Split <em>I</em> into two 32-byte sequences, <em>I</em><sub>L</sub> and <em>I</em><sub>R</sub>.</li>
<li>Let <em>I</em><sub>ask</sub> = ToScalar(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x13]))</li>
<li>Let <em>I</em><sub>nsk</sub> = ToScalar(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x14]))</li>
<li>Return:
<ul>
<li><em>ak</em><sub>i</sub> = [<em>I</em><sub>ask</sub>] 𝓖 + <em>ak</em><sub>par</sub></li>
<li><em>nk</em><sub>i</sub> = [<em>I</em><sub>nsk</sub>] 𝓗 + <em>nk</em><sub>par</sub></li>
<li><em>ovk</em><sub>i</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x15] || <em>ovk</em><sub>par</sub>))</li>
<li><em>dk</em><sub>i</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x16] || <em>dk</em><sub>par</sub>))</li>
<li><em>c</em><sub>i</sub> = <em>I</em><sub>R</sub></li>
</ul></li>
</ul>
<h2 id="diversifier-derivation">Diversifier derivation</h2>
<p>The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key <em>dk</em>. To prevent the diversifier leaking how many diversified addresses have already been generated for an account, we make the sequence of diversifiers pseudorandom and uncorrelated to that of any other account. In order to reach the maximum possible diversifier range without running into repetitions due to the birthday bound, we use FF1-AES256 as a Pseudo-Random Permutation as follows:</p>
<ul>
<li>Let <em>j</em> be the index of the desired diversifier, in the range 0 .. 2<sup>88</sup>-1.</li>
<li><em>d</em><sub>j</sub> = FF1-AES256.Encrypt(<em>dk</em>, &quot;&quot;, I2LEBSP<sub>88</sub>(<em>j</em>)).</li>
</ul>
<p>A valid diversifier <em>d</em><sub>j</sub> is one for which DiversifyHash(<em>d</em><sub>j</sub>) ≠ ⊥. For a given <em>dk</em>, approximately half of the possible values of <em>j</em> yield valid diversifiers.</p>
<p>The default diversifier for a Sapling extended key is defined to be <em>d</em><sub>j</sub>, where <em>j</em> is the least nonnegative integer yielding a valid diversifier.</p>
<h1 id="specification-sprout-key-derivation">Specification: Sprout key derivation</h1>
<p>For completeness, we define a system for deriving a tree of Sprout key components. It is unlikely that this will garner much usage once Sapling activates, but is presented for those users who may require it.</p>
<h2 id="sprout-extended-keys">Sprout extended keys</h2>
<p>Due to the way Sprout keys are constructed and used, it is not possible to derive incoming viewing keys or payment addresses in parallel with spending keys. Nor is it possible to implement non-hardened derivation. We therefore only define and derive Sprout extended spending keys.</p>
<p>We represent a Sprout extended spending key as (<em>a</em><sub>sk</sub>, <em>c</em>), where <em>a</em><sub>sk</sub> is the normal Sprout spending key, and <em>c</em> is the chain code.</p>
<h2 id="helper-functions-1">Helper functions</h2>
<p>Let EncodeASK(<em>a</em><sub>sk</sub>) be the 32-byte encoding of <em>a</em><sub>sk</sub> in the raw encoding of a Sprout spending key (excluding lead bytes) as specified in<a href="#fn18" class="footnote-ref" id="fnref18"><sup>18</sup></a> section 5.6.8.</p>
<p>Let DecodeASK(<em>ASK</em>) be the result of clearing the 4 most significant bits of the first byte of <em>ASK</em>, and decoding the 32-byte result according to the inverse of EncodeASK.</p>
<h2 id="master-key-generation-1">Master key generation</h2>
<p>Let <em>S</em> be a seed byte sequence of a chosen length, which MUST be at least 32 bytes.</p>
<ul>
<li>Calculate <em>I</em> = BLAKE2b-512(&quot;ZcashIP32_Sprout&quot;, <em>S</em>).</li>
<li>Split <em>I</em> into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.</li>
<li>Use DecodeASK(<em>I</em><sub>L</sub>) as the master spending key a<sub>sk,m</sub>.</li>
<li>Use <em>I</em><sub>R</sub> as the master chain code <em>c</em><sub>m</sub>.</li>
</ul>
<h2 id="child-key-derivation-1">Child key derivation</h2>
<p>CDKsk((<em>a</em><sub>sk,par</sub>, <em>c</em><sub>par</sub>), <em>i</em>) → (<em>a</em><sub>sk,i</sub>, <em>c</em><sub>i</sub>)</p>
<ul>
<li>Check whether <em>i</em> ≥ 2<sup>31</sup> (whether the child is a hardened key).
<ul>
<li>If so (hardened child): let <em>I</em> = PRF<sup>expand</sup>(<em>c</em><sub>par</sub>, [0x80] || EncodeASK(<em>a</em><sub>sk,par</sub>) || I2LEOSP<sub>32</sub>(<em>i</em>))</li>
<li>If not (normal child): return failure</li>
</ul></li>
<li>Split <em>I</em> into two 32-byte sequences, <em>I</em><sub>L</sub> and <em>I</em><sub>R</sub>.</li>
<li>Use DecodeASK(<em>I</em><sub>L</sub>) as the child spending key a<sub>sk,i</sub>.</li>
<li>Use <em>I</em><sub>R</sub> as the child chain code <em>c</em><sub>i</sub>.</li>
</ul>
<h1 id="specification-wallet-usage">Specification: Wallet usage</h1>
<p>Existing Zcash-supporting HD wallets all use BIP 44<a href="#fn19" class="footnote-ref" id="fnref19"><sup>19</sup></a> to organize their derived keys. In order to more easily mesh with existing user experiences, we broadly follow BIP 44's design here. However, we have altered the design where it makes sense to leverage features of shielded addresses.</p>
<h2 id="key-path-levels">Key path levels</h2>
<p>Both Sprout and Sapling key paths have the following three path levels at the top, all of which use hardened derivation:</p>
<ul>
<li><code>purpose</code>: a constant set to 32' (or 0x80000020) following the BIP 43 recommendation. It indicates that the subtree of this node is used according to this specification.</li>
<li><code>coin_type</code>: a constant identifying the cybercoin that this subtree's keys are used with. For compatibility with existing BIP 44 implementations, we use the same constants as defined in SLIP 44 <a href="#fn20" class="footnote-ref" id="fnref20"><sup>20</sup></a>. Note that in keeping with that document, all cybercoin testnets share <code>coin_type</code> index 1.</li>
<li><code>account</code>: numbered from index 0 in sequentially increasing manner. Defined as in BIP 44<a href="#fn21" class="footnote-ref" id="fnref21"><sup>21</sup></a>.</li>
</ul>
<p>Unlike BIP 44, neither Sprout nor Sapling have a change path level. The use of change addresses in Bitcoin is a (failed) attempt to increase the difficulty of tracking users on the transaction graph, by segregating external and internal address usage. Shielded addresses are never publicly visible in transactions, which means that sending change back to the originating address is indistinguishable from using a change address.</p>
<h2 id="sapling-key-path">Sapling key path</h2>
<p>Sapling provides a mechanism to allow the efficient creation of diversified payment addresses with the same spending authority. A group of such addresses shares the same full viewing key and incoming viewing key, and so creating as many unlinkable addresses as needed does not increase the cost of scanning the block chain for relevant transactions.</p>
<p>The above key path levels include an account identifier, which in all user interfaces is represented as a &quot;bucket of funds&quot; under the control of a single spending authority. Therefore, wallets implementing Sapling ZIP 32 derivation MUST support the following path for any account in range {0..2<sup>31</sup>-1}:</p>
<pre><code>m_Sapling / purpose&#39; / coin_type&#39; / account&#39;</code></pre>
<p>Furthermore, wallets MUST support generating the default payment address (corresponding to the default diversifier as defined above) for any account they support. They MAY also support generating a stream of payment addresses for a given account, if they wish to maintain the user experience of giving a unique address to each recipient.</p>
<p>Note that a given account can have a maximum of approximately 2<sup>87</sup> payment addresses, because each diversifier has around a 50% chance of being invalid.</p>
<p>If in certain circumstances a wallet needs to derive independent spend authorities within a single account, they MAY additionally support a non-hardened <code>address_index</code> path level as in<a href="#fn22" class="footnote-ref" id="fnref22"><sup>22</sup></a>:</p>
<pre><code>m_Sapling / purpose&#39; / coin_type&#39; / account&#39; / address_index</code></pre>
<h2 id="sprout-key-path">Sprout key path</h2>
<p>Wallets implementing Sprout ZIP 32 derivation MUST support the following path:</p>
<pre><code>m_Sprout / purpose&#39; / coin_type&#39; / account&#39; / address_index</code></pre>
<h1 id="specification-fingerprints-and-tags">Specification: Fingerprints and Tags</h1>
<h2 id="sapling-full-viewing-key-fingerprints-and-tags">Sapling Full Viewing Key Fingerprints and Tags</h2>
<p>A &quot;Sapling full viewing key fingerprint&quot; of a full viewing key with raw encoding <em>FVK</em> (as specified in<a href="#fn23" class="footnote-ref" id="fnref23"><sup>23</sup></a> section 5.6.7) is given by:</p>
<blockquote>
<p>BLAKE2b-256(&quot;ZcashSaplingFVFP&quot;, <em>FVK</em>)</p>
</blockquote>
<p>It MAY be used to uniquely identify a particular Sapling full viewing key.</p>
<p>A &quot;Sapling full viewing key tag&quot; is the first 4 bytes of the corresponding Sapling full viewing key fingerprint. It is intended for optimizing performance of key lookups, and MUST NOT be assumed to uniquely identify a particular key.</p>
<h2 id="sprout-address-fingerprints-and-tags">Sprout Address Fingerprints and Tags</h2>
<p>A &quot;Sprout address fingerprint&quot; of a Sprout payment address with raw encoding <em>ADDR</em> (as specified in <a href="#fn24" class="footnote-ref" id="fnref24"><sup>24</sup></a> section 5.6.3, including the lead bytes) is given by:</p>
<blockquote>
<p>BLAKE2b-256(&quot;Zcash_Sprout_AFP&quot;, <em>ADDR</em>)</p>
</blockquote>
<p>It MAY be used to uniquely identify a particular Sprout payment address.</p>
<p>A &quot;Sprout address tag&quot; is the first 4 bytes of the corresponding Sprout address fingerprint. It is intended for optimizing performance of address lookups, and MUST NOT be assumed to uniquely identify a particular address.</p>
<h2 id="seed-fingerprints">Seed Fingerprints</h2>
<p>A &quot;seed fingerprint&quot; for the master seed <em>S</em> of a hierarchical deterministic wallet is given by:</p>
<blockquote>
<p>BLAKE2b-256(&quot;Zcash_HD_Seed_FP&quot;, <em>S</em>)</p>
</blockquote>
<p>It MAY be used to uniquely identify a particular hierarchical deterministic wallet.</p>
<p>No corresponding short tag is defined.</p>
<h1 id="specification-key-encodings">Specification: Key Encodings</h1>
<p>The following encodings are analogous to the <code>xprv</code> and <code>xpub</code> encodings defined in BIP 32 for transparent keys and addresses. Each key type has a raw representation and a Bech32<a href="#fn25" class="footnote-ref" id="fnref25"><sup>25</sup></a> encoding.</p>
<h2 id="sapling-extended-spending-keys">Sapling extended spending keys</h2>
<p>A Sapling extended spending key (<em>ask</em>, <em>nsk</em>, <em>ovk</em>, <em>dk</em>, <em>c</em>), at depth <em>depth</em>, with parent full viewing key tag <em>parent_fvk_tag</em> and child number <em>i</em>, is represented as a byte sequence:</p>
<blockquote>
<p>I2LEOSP<sub>8</sub>(<em>depth</em>) || <em>parent_fvk_tag</em> || I2LEOSP<sub>32</sub>(<em>i</em>) || <em>c</em> || EncodeExtSKParts(<em>ask</em>, <em>nsk</em>, <em>ovk</em>, <em>dk</em>)</p>
</blockquote>
<p>For the master extended spending key, <em>depth</em> is 0, <em>parent_fvk_tag</em> is 4 zero bytes, and <em>i</em> is 0.</p>
<p>When encoded as Bech32, the Human-Readable Part is <code>secret-extended-key-main</code> for the production network, or <code>secret-extended-key-test</code> for the test network.</p>
<h2 id="sapling-extended-full-viewing-keys">Sapling extended full viewing keys</h2>
<p>A Sapling extended full viewing key (<em>ak</em>, <em>nk</em>, <em>ovk</em>, <em>dk</em>, <em>c</em>), at depth <em>depth</em>, with parent full viewing key tag <em>parent_fvk_tag</em> and child number <em>i</em>, is represented as a byte sequence:</p>
<blockquote>
<p>I2LEOSP<sub>8</sub>(<em>depth</em>) || <em>parent_fvk_tag</em> || I2LEOSP<sub>32</sub>(<em>i</em>) || <em>c</em> || EncodeExtFVKParts(<em>ak</em>, <em>nk</em>, <em>ovk</em>, <em>dk</em>)</p>
</blockquote>
<p>For the master extended full viewing key, <em>depth</em> is 0, <em>parent_fvk_tag</em> is 4 zero bytes, and <em>i</em> is 0.</p>
<p>When encoded as Bech32, the Human-Readable Part is <code>zxviews</code> for the production network, or <code>zxviewtestsapling</code> for the test network.</p>
<h2 id="sprout-extended-spending-keys">Sprout extended spending keys</h2>
<p>A Sprout extended spending key (<em>a</em><sub>sk</sub>, <em>c</em>), at depth <em>depth</em>, with parent address tag <em>parent_addr_tag</em> and child number <em>i</em>, is represented as a byte sequence:</p>
<blockquote>
<p>I2LEOSP<sub>8</sub>(<em>depth</em>) || <em>parent_addr_tag</em> || I2LEOSP<sub>32</sub>(<em>i</em>) || <em>c</em> || EncodeASK(<em>a</em><sub>sk</sub>)</p>
</blockquote>
<p>For the master extended spending key, <em>depth</em> is 0, <em>parent_addr_tag</em> is 4 zero bytes, and <em>i</em> is 0.</p>
<p>When encoded as Bech32, the Human-Readable Part is <code>zxsprout</code> for the production network, or <code>zxtestsprout</code> for the test network. Sprout extended spending keys are encoded using Bech32 even though other Sprout keys and addresses are encoded using Base58Check.</p>
<h1 id="test-vectors">Test Vectors</h1>
<p>TBC</p>
<h1 id="reference-implementation">Reference Implementation</h1>
<ul>
<li><a href="https://github.com/zcash-hackworks/zip32" class="uri">https://github.com/zcash-hackworks/zip32</a></li>
<li><a href="https://github.com/zcash/librustzcash/pull/29" class="uri">https://github.com/zcash/librustzcash/pull/29</a></li>
<li><a href="https://github.com/zcash/zcash/pull/3447" class="uri">https://github.com/zcash/zcash/pull/3447</a></li>
<li><a href="https://github.com/zcash/zcash/pull/3492" class="uri">https://github.com/zcash/zcash/pull/3492</a></li>
</ul>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">BIP 32: Hierarchical Deterministic Wallets</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP 44: Multi-Account Hierarchy for Deterministic Wallets</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">BIP 32: Hierarchical Deterministic Wallets</a><a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><p><a href="https://github.com/satoshilabs/slips/blob/master/slip-0044.md">SLIP 44: Registered coin types for BIP-0044</a><a href="#fnref6" class="footnote-back"></a></p></li>
<li id="fn7"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">BIP 39: Mnemonic code for generating deterministic keys</a><a href="#fnref7" class="footnote-back"></a></p></li>
<li id="fn8"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref8" class="footnote-back"></a></p></li>
<li id="fn9"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref9" class="footnote-back"></a></p></li>
<li id="fn10"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref10" class="footnote-back"></a></p></li>
<li id="fn11"><p><a href="https://dx.doi.org/10.6028/NIST.SP.800-38G">NIST Special Publication 800-38G -- Recommendation for Block Cipher Modes of Operation: Methods for Format-Preserving Encryption</a><a href="#fnref11" class="footnote-back"></a></p></li>
<li id="fn12"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">BIP 32: Hierarchical Deterministic Wallets</a><a href="#fnref12" class="footnote-back"></a></p></li>
<li id="fn13"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP 44: Multi-Account Hierarchy for Deterministic Wallets</a><a href="#fnref13" class="footnote-back"></a></p></li>
<li id="fn14"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Section 4.2.2: Sapling Key Components. Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref14" class="footnote-back"></a></p></li>
<li id="fn15"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Section 4.2.2: Sapling Key Components. Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref15" class="footnote-back"></a></p></li>
<li id="fn16"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref16" class="footnote-back"></a></p></li>
<li id="fn17"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Section 4.2.2: Sapling Key Components. Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref17" class="footnote-back"></a></p></li>
<li id="fn18"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref18" class="footnote-back"></a></p></li>
<li id="fn19"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP 44: Multi-Account Hierarchy for Deterministic Wallets</a><a href="#fnref19" class="footnote-back"></a></p></li>
<li id="fn20"><p><a href="https://github.com/satoshilabs/slips/blob/master/slip-0044.md">SLIP 44: Registered coin types for BIP-0044</a><a href="#fnref20" class="footnote-back"></a></p></li>
<li id="fn21"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP 44: Multi-Account Hierarchy for Deterministic Wallets</a><a href="#fnref21" class="footnote-back"></a></p></li>
<li id="fn22"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP 44: Multi-Account Hierarchy for Deterministic Wallets</a><a href="#fnref22" class="footnote-back"></a></p></li>
<li id="fn23"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref23" class="footnote-back"></a></p></li>
<li id="fn24"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a><a href="#fnref24" class="footnote-back"></a></p></li>
<li id="fn25"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki">BIP 173: Base32 address format for native v0-16 witness outputs</a><a href="#fnref25" class="footnote-back"></a></p></li>
</ol>
</section>
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "MUST NOT", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">1</a></p>
<p>"Jubjub" refers to the elliptic curve defined in <a href="#sapling-spec" id="id2" class="footnote_reference">8</a> section 5.4.8.3.</p>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal defines a mechanism for extending hierarchical deterministic wallets, as decribed in BIP 32 <a href="#bip-0032" id="id3" class="footnote_reference">2</a>, to support Zcash's shielded addresses.</p>
<p>The specification has three parts. The first part defines a system for deriving a tree of Sapling key components from a single seed. The second part defines an equivalent, but independent, system for Sprout key components (which have a different internal construction). The third part shows how to use these trees in the context of existing BIP 44 <a href="#bip-0044" id="id4" class="footnote_reference">5</a> wallets.</p>
<p>This specification complements the existing use by some Zcash wallets of BIP 32 and BIP 44 for transparent Zcash addresses, and is not intended to deprecate that usage (privacy risks of using transparent addresses notwithstanding).</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>BIP 32 <a href="#bip-0032" id="id5" class="footnote_reference">2</a> is the standard mechanism by which wallets for Bitcoin and its derivatives (including Zcash's transparent addresses <a href="#slip-0044" id="id6" class="footnote_reference">6</a>) generate keys and addresses deterministically. This has several advantages over random generation:</p>
<ul>
<li>Wallets only need to store a single seed (particularly useful for hardware wallets).</li>
<li>A one-time backup of the seed (usually stored as a word phrase <a href="#bip-0039" id="id7" class="footnote_reference">3</a>) can be used to recover funds from all future addresses.</li>
<li>Keys are arranged into a tree of chains, enabling wallets to represent "accounts" or other high-level structures.</li>
<li>View authority or spend authority can be delegated independently for sub-trees without compromising the master seed.</li>
</ul>
<p>At present, no such equivalent exists for Zcash's shielded addresses. This is of particular concern for hardware wallets; all currently-marketed devices only store a seed internally, and have trained their users to only backup that seed. Given that the Sapling upgrade will make it feasible to use hardware wallets with shielded addresses, it is desirable to have a standard mechanism for deriving them.</p>
</section>
<section id="conventions">
<h2>Conventions</h2>
<p>Most of the notation and functions used in this ZIP are defined in the Sapling protocol specification <a href="#sapling-spec" id="id8" class="footnote_reference">8</a>. They are reproduced here for convenience:</p>
<ul>
<li>truncate<sub>k</sub>(<em>S</em>) means the sequence formed from the first <em>k</em> elements of <em>S</em>.</li>
<li><em>a</em> || <em>b</em> means the concatenation of sequences <em>a</em> then <em>b</em>.</li>
<li>[<em>k</em>] <em>P</em> means scalar multiplication of the elliptic curve point <em>P</em> by the scalar <em>k</em>.</li>
<li>LEOS2IP<sub>l</sub>(<em>S</em>) is the integer in range {0..2<sup>l</sup>-1} represented in little-endian order by the byte sequence <em>S</em> of length <em>l</em>/8.</li>
<li>I2LEBSP<sub>l</sub>(<em>k</em>) is the sequence of <em>l</em> bits representing <em>k</em> in little-endian order.</li>
<li>LEBS2OSP<sub>l</sub>(<em>B</em>) is defined as follows when <em>l</em> is a multiple of 8: convert each group of 8 bits in <em>B</em> to a byte value with the least significant bit first, and concatenate the resulting bytes in the same order as the groups.</li>
<li>repr<sub>𝕁</sub>(<em>P</em>) is the representation of the Jubjub elliptic curve point <em>P</em> as a bit sequence, defined in <a href="#sapling-spec" id="id9" class="footnote_reference">8</a> section 5.4.8.3.</li>
<li>BLAKE2b-256(<em>p</em>, <em>x</em>) refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of 32 bytes, 16-byte personalization string <em>p</em>, and input <em>x</em>.</li>
<li>BLAKE2b-512(<em>p</em>, <em>x</em>) refers to unkeyed BLAKE2b-512 in sequential mode, with an output digest length of 64 bytes, 16-byte personalization string <em>p</em>, and input <em>x</em>.</li>
<li>PRF<sup>expand</sup>(<em>sk</em>, <em>t</em>) := BLAKE2b-512("Zcash_ExpandSeed", <em>sk</em> || <em>t</em>)</li>
<li>ToScalar(<em>x</em>) := LEOS2IP<sub>512</sub>(<em>x</em>) (mod <em>r</em><sub>𝕁</sub>), where <em>r</em><sub>𝕁</sub> is the order of the Jubjub large prime subgroup.</li>
<li>DiversifyHash(<em>d</em>) maps a diversifier <em>d</em> to a base point on the Jubjub elliptic curve, or to ⊥ if the diversifier is invalid. It is instantiated in <a href="#sapling-spec" id="id10" class="footnote_reference">8</a> section 5.4.1.6.</li>
</ul>
<p>The following algorithm standardized in <a href="#nist-sp-800-38g" id="id11" class="footnote_reference">10</a> is used:</p>
<ul>
<li>FF1-AES256.Encrypt(<em>key</em>, <em>tweak</em>, <em>x</em>) refers to the FF1 encryption algorithm using AES with a 256-bit <em>key</em>, and parameters <em>radix</em> = 2, <em>minlen</em> = 88, <em>maxlen</em> = 88. It will be used only with the empty string "" as the <em>tweak</em>. <em>x</em> is a sequence of 88 bits, as is the output.</li>
</ul>
<p>We also define the following conversion function:</p>
<ul>
<li>I2LEOSP<sub>l</sub>(<em>k</em>) is the byte sequence <em>S</em> of length <em>l</em>/8 representing in little-endian order the integer <em>k</em> in range {0..2<sup>l</sup>-1}. It is the reverse operation of LEOS2IP<sub>l</sub>(<em>S</em>).</li>
</ul>
<p>Implementors should note that this ZIP is consistently little-endian (in keeping with the Sapling specification), which is the opposite of BIP 32.</p>
<p>We adapt the path notation of BIP 32 <a href="#bip-0032" id="id12" class="footnote_reference">2</a> to describe shielded HD paths, using apostrophes to indicate hardened derivation (i' = i + 2<sup>31</sup>) as in BIP 44 <a href="#bip-0044" id="id13" class="footnote_reference">5</a>:</p>
<ul>
<li>CDKsk(CDKsk(CDKsk(m<sub>Sprout</sub>, a'), b), c) is written as m<sub>Sprout</sub> / a' / b / c</li>
<li>CDKfvk(CDKfvk(CDKfvk(M<sub>Sapling</sub>, a), b), c) is written as M<sub>Sapling</sub> / a / b / c</li>
</ul>
</section>
<section id="specification-sapling-key-derivation">
<h2>Specification: Sapling key derivation</h2>
<section id="sapling-extended-keys">
<h3>Sapling extended keys</h3>
<p>BIP 32 defines a method to derive a number of child keys from a parent key. In order to prevent these from depending solely on the parent key itself, both the private and public keys are extended with a 32-byte chain code. We similarly extend Sapling keys with a chain code here. However, the concepts of "private" and "public" keys in BIP 32 do not map cleanly to Sapling's key components. We take the following approach:</p>
<ul>
<li>We derive child Sapling expanded spending keys, rather than Sapling spending keys. This enables us to implement both hardened and non-hardened derivation modes (the latter being incompatible with Sapling spending keys).</li>
<li>We do not derive Sapling public keys directly, as this would prevent the use of diversified addresses. Instead, we derive Sapling full viewing keys, from which payment addresses can be generated. This maintains the trust semantics of BIP 32: someone with access to a BIP 32 extended public key is able to view all transactions involving that address, which a Sapling full viewing key also enables.</li>
</ul>
<p>We represent a Sapling extended spending key as (<em>ask</em>, <em>nsk</em>, <em>ovk</em>, <em>dk</em>, <em>c</em>), where (<em>ask</em>, <em>nsk</em>, <em>ovk</em>) is the normal Sapling expanded spending key, <em>dk</em> is a diversifier key, and <em>c</em> is the chain code.</p>
<p>We represent a Sapling extended full viewing key as (<em>ak</em>, <em>nk</em>, <em>ovk</em>, <em>dk</em>, <em>c</em>), where (<em>ak</em>, <em>nk</em>, <em>ovk</em>) is the normal Sapling full viewing key, <em>dk</em> is the same diversifier key as above, and <em>c</em> is the chain code.</p>
</section>
<section id="sapling-helper-functions">
<h3>Sapling helper functions</h3>
<p>Define EncodeExtSKParts(<em>ask</em>, <em>nsk</em>, <em>ovk</em>, <em>dk</em>) := I2LEOSP<sub>256</sub>(<em>ask</em>) || I2LEOSP<sub>256</sub>(<em>nsk</em>) || <em>ovk</em> || <em>dk</em>.</p>
<p>Define EncodeExtFVKParts(<em>ak</em>, <em>nk</em>, <em>ovk</em>, <em>dk</em>) := LEBS2OSP<sub>256</sub>(repr<sub>𝕁</sub>(<em>ak</em>)) || LEBS2OSP<sub>256</sub>(repr<sub>𝕁</sub>(<em>nk</em>)) || <em>ovk</em> || <em>dk</em>.</p>
</section>
<section id="sapling-master-key-generation">
<h3>Sapling master key generation</h3>
<p>Let <em>S</em> be a seed byte sequence of a chosen length, which MUST be at least 32 bytes.</p>
<ul>
<li>Calculate <em>I</em> = BLAKE2b-512("ZcashIP32Sapling", <em>S</em>).</li>
<li>Split <em>I</em> into two 32-byte sequences, <em>I</em><sub>L</sub> and <em>I</em><sub>R</sub>.</li>
<li>Use <em>I</em><sub>L</sub> as the master spending key <em>sk</em><sub>m</sub>, and <em>I</em><sub>R</sub> as the master chain code <em>c</em><sub>m</sub>.</li>
<li>Calculate <em>ask</em><sub>m</sub>, <em>nsk</em><sub>m</sub>, and <em>ovk</em><sub>m</sub> via the standard Sapling derivation <a href="#sapling-key-components" id="id14" class="footnote_reference">9</a>:
<ul>
<li><em>ask</em><sub>m</sub> = ToScalar(PRF<sup>expand</sup>(<em>sk</em><sub>m</sub>, [0x00]))</li>
<li><em>nsk</em><sub>m</sub> = ToScalar(PRF<sup>expand</sup>(<em>sk</em><sub>m</sub>, [0x01]))</li>
<li><em>ovk</em><sub>m</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>sk</em><sub>m</sub>, [0x02]))</li>
</ul>
</li>
<li>Calculate <em>dk</em><sub>m</sub> similarly:
<ul>
<li><em>dk</em><sub>m</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>sk</em><sub>m</sub>, [0x10]))</li>
</ul>
</li>
<li>Return (<em>ask</em><sub>m</sub>, <em>nsk</em><sub>m</sub>, <em>ovk</em><sub>m</sub>, <em>dk</em><sub>m</sub>, <em>c</em><sub>m</sub>) as the master extended spending key <em>m</em><sub>Sapling</sub>.</li>
</ul>
</section>
<section id="sapling-child-key-derivation">
<h3>Sapling child key derivation</h3>
<p>As in BIP 32, the method for deriving a child extended key, given a parent extended key and an index <em>i</em>, depends on the type of key being derived, and whether this is a hardened or non-hardened derivation.</p>
<section id="deriving-a-child-extended-spending-key">
<h4>Deriving a child extended spending key</h4>
<p>CDKsk((<em>ask</em><sub>par</sub>, <em>nsk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>, <em>c</em><sub>par</sub>), <em>i</em>) → (<em>ask</em><sub>i</sub>, <em>nsk</em><sub>i</sub>, <em>ovk</em><sub>i</sub>, <em>dk</em><sub>i</sub>, <em>c</em><sub>i</sub>)</p>
<ul>
<li>Check whether <em>i</em> ≥ 2<sup>31</sup> (whether the child is a hardened key).
<ul>
<li>If so (hardened child): let <em>I</em> = PRF<sup>expand</sup>(<em>c</em><sub>par</sub>, [0x11] || EncodeExtSKParts(<em>ask</em><sub>par</sub>, <em>nsk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>) || I2LEOSP<sub>32</sub>(<em>i</em>))</li>
<li>If not (normal child): let <em>I</em> = PRF<sup>expand</sup>(<em>c</em><sub>par</sub>, [0x12] || EncodeExtFVKParts(<em>ak</em><sub>par</sub>, <em>nk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>) || I2LEOSP<sub>32</sub>(<em>i</em>)) where (<em>nk</em><sub>par</sub>, <em>ak</em><sub>par</sub>, <em>ovk</em><sub>par</sub>) is the full viewing key derived from (<em>ask</em><sub>par</sub>, <em>nsk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>) as described in <a href="#sapling-key-components" id="id15" class="footnote_reference">9</a>.</li>
</ul>
</li>
<li>Split <em>I</em> into two 32-byte sequences, <em>I</em><sub>L</sub> and <em>I</em><sub>R</sub>.</li>
<li>Let <em>I</em><sub>ask</sub> = ToScalar(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x13]))</li>
<li>Let <em>I</em><sub>nsk</sub> = ToScalar(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x14]))</li>
<li>Return:
<ul>
<li><em>ask</em><sub>i</sub> = <em>I</em><sub>ask</sub> + <em>ask</em><sub>par</sub></li>
<li><em>nsk</em><sub>i</sub> = <em>I</em><sub>nsk</sub> + <em>nsk</em><sub>par</sub></li>
<li><em>ovk</em><sub>i</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x15] || <em>ovk</em><sub>par</sub>))</li>
<li><em>dk</em><sub>i</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x16] || <em>dk</em><sub>par</sub>))</li>
<li><em>c</em><sub>i</sub> = <em>I</em><sub>R</sub></li>
</ul>
</li>
</ul>
</section>
<section id="deriving-a-child-extended-full-viewing-key">
<h4>Deriving a child extended full viewing key</h4>
<p>Let 𝓖 be as defined in <a href="#sapling-spec" id="id16" class="footnote_reference">8</a> section 5.4.6.1 and let 𝓗 be as defined in <a href="#sapling-key-components" id="id17" class="footnote_reference">9</a>.</p>
<p>CDKfvk((<em>ak</em><sub>par</sub>, <em>nk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>, <em>c</em><sub>par</sub>), <em>i</em>) → (<em>ak</em><sub>i</sub>, <em>nk</em><sub>i</sub>, <em>ovk</em><sub>i</sub>, <em>dk</em><sub>i</sub>, <em>c</em><sub>i</sub>)</p>
<ul>
<li>Check whether <em>i</em> ≥ 2<sup>31</sup> (whether the child is a hardened key).
<ul>
<li>If so (hardened child): return failure</li>
<li>If not (normal child): let <em>I</em> = PRF<sup>expand</sup>(<em>c</em><sub>par</sub>, [0x12] || EncodeExtFVKParts(<em>ak</em><sub>par</sub>, <em>nk</em><sub>par</sub>, <em>ovk</em><sub>par</sub>, <em>dk</em><sub>par</sub>) || I2LEOSP<sub>32</sub>(<em>i</em>))</li>
</ul>
</li>
<li>Split <em>I</em> into two 32-byte sequences, <em>I</em><sub>L</sub> and <em>I</em><sub>R</sub>.</li>
<li>Let <em>I</em><sub>ask</sub> = ToScalar(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x13]))</li>
<li>Let <em>I</em><sub>nsk</sub> = ToScalar(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x14]))</li>
<li>Return:
<ul>
<li><em>ak</em><sub>i</sub> = [<em>I</em><sub>ask</sub>] 𝓖 + <em>ak</em><sub>par</sub></li>
<li><em>nk</em><sub>i</sub> = [<em>I</em><sub>nsk</sub>] 𝓗 + <em>nk</em><sub>par</sub></li>
<li><em>ovk</em><sub>i</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x15] || <em>ovk</em><sub>par</sub>))</li>
<li><em>dk</em><sub>i</sub> = truncate<sub>32</sub>(PRF<sup>expand</sup>(<em>I</em><sub>L</sub>, [0x16] || <em>dk</em><sub>par</sub>))</li>
<li><em>c</em><sub>i</sub> = <em>I</em><sub>R</sub></li>
</ul>
</li>
</ul>
</section>
</section>
<section id="diversifier-derivation">
<h3>Diversifier derivation</h3>
<p>The 88-bit diversifiers for a Sapling extended key are derived from its diversifier key <em>dk</em>. To prevent the diversifier leaking how many diversified addresses have already been generated for an account, we make the sequence of diversifiers pseudorandom and uncorrelated to that of any other account. In order to reach the maximum possible diversifier range without running into repetitions due to the birthday bound, we use FF1-AES256 as a Pseudo-Random Permutation as follows:</p>
<ul>
<li>Let <em>j</em> be the index of the desired diversifier, in the range 0 .. 2<sup>88</sup>-1.</li>
<li><em>d</em><sub>j</sub> = FF1-AES256.Encrypt(<em>dk</em>, "", I2LEBSP<sub>88</sub>(<em>j</em>)).</li>
</ul>
<p>A valid diversifier <em>d</em><sub>j</sub> is one for which DiversifyHash(<em>d</em><sub>j</sub>) ≠ ⊥. For a given <em>dk</em>, approximately half of the possible values of <em>j</em> yield valid diversifiers.</p>
<p>The default diversifier for a Sapling extended key is defined to be <em>d</em><sub>j</sub>, where <em>j</em> is the least nonnegative integer yielding a valid diversifier.</p>
</section>
</section>
<section id="specification-sprout-key-derivation">
<h2>Specification: Sprout key derivation</h2>
<p>For completeness, we define a system for deriving a tree of Sprout key components. It is unlikely that this will garner much usage once Sapling activates, but is presented for those users who may require it.</p>
<section id="sprout-extended-keys">
<h3>Sprout extended keys</h3>
<p>Due to the way Sprout keys are constructed and used, it is not possible to derive incoming viewing keys or payment addresses in parallel with spending keys. Nor is it possible to implement non-hardened derivation. We therefore only define and derive Sprout extended spending keys.</p>
<p>We represent a Sprout extended spending key as (<em>a</em><sub>sk</sub>, <em>c</em>), where <em>a</em><sub>sk</sub> is the normal Sprout spending key, and <em>c</em> is the chain code.</p>
</section>
<section id="sprout-helper-functions">
<h3>Sprout helper functions</h3>
<p>Let EncodeASK(<em>a</em><sub>sk</sub>) be the 32-byte encoding of <em>a</em><sub>sk</sub> in the raw encoding of a Sprout spending key (excluding lead bytes) as specified in <a href="#sapling-spec" id="id18" class="footnote_reference">8</a> section 5.6.8.</p>
<p>Let DecodeASK(<em>ASK</em>) be the result of clearing the 4 most significant bits of the first byte of <em>ASK</em>, and decoding the 32-byte result according to the inverse of EncodeASK.</p>
</section>
<section id="sprout-master-key-generation">
<h3>Sprout master key generation</h3>
<p>Let <em>S</em> be a seed byte sequence of a chosen length, which MUST be at least 32 bytes.</p>
<ul>
<li>Calculate <em>I</em> = BLAKE2b-512("ZcashIP32_Sprout", <em>S</em>).</li>
<li>Split <em>I</em> into two 32-byte sequences, I<sub>L</sub> and I<sub>R</sub>.</li>
<li>Use DecodeASK(<em>I</em><sub>L</sub>) as the master spending key a<sub>sk,m</sub>.</li>
<li>Use <em>I</em><sub>R</sub> as the master chain code <em>c</em><sub>m</sub>.</li>
</ul>
</section>
<section id="sprout-child-key-derivation">
<h3>Sprout child key derivation</h3>
<p>CDKsk((<em>a</em><sub>sk,par</sub>, <em>c</em><sub>par</sub>), <em>i</em>) → (<em>a</em><sub>sk,i</sub>, <em>c</em><sub>i</sub>)</p>
<ul>
<li>Check whether <em>i</em> ≥ 2<sup>31</sup> (whether the child is a hardened key).
<ul>
<li>If so (hardened child): let <em>I</em> = PRF<sup>expand</sup>(<em>c</em><sub>par</sub>, [0x80] || EncodeASK(<em>a</em><sub>sk,par</sub>) || I2LEOSP<sub>32</sub>(<em>i</em>))</li>
<li>If not (normal child): return failure</li>
</ul>
</li>
<li>Split <em>I</em> into two 32-byte sequences, <em>I</em><sub>L</sub> and <em>I</em><sub>R</sub>.</li>
<li>Use DecodeASK(<em>I</em><sub>L</sub>) as the child spending key a<sub>sk,i</sub>.</li>
<li>Use <em>I</em><sub>R</sub> as the child chain code <em>c</em><sub>i</sub>.</li>
</ul>
</section>
</section>
<section id="specification-wallet-usage">
<h2>Specification: Wallet usage</h2>
<p>Existing Zcash-supporting HD wallets all use BIP 44 <a href="#bip-0044" id="id19" class="footnote_reference">5</a> to organize their derived keys. In order to more easily mesh with existing user experiences, we broadly follow BIP 44's design here. However, we have altered the design where it makes sense to leverage features of shielded addresses.</p>
<section id="key-path-levels">
<h3>Key path levels</h3>
<p>Both Sprout and Sapling key paths have the following three path levels at the top, all of which use hardened derivation:</p>
<ul>
<li><code>purpose</code>: a constant set to 32' (or 0x80000020) following the BIP 43 recommendation. It indicates that the subtree of this node is used according to this specification.</li>
<li><code>coin_type</code>: a constant identifying the cybercoin that this subtree's keys are used with. For compatibility with existing BIP 44 implementations, we use the same constants as defined in SLIP 44 <a href="#slip-0044" id="id20" class="footnote_reference">6</a>. Note that in keeping with that document, all cybercoin testnets share <code>coin_type</code> index 1.</li>
<li><code>account</code>: numbered from index 0 in sequentially increasing manner. Defined as in BIP 44 <a href="#bip-0044" id="id21" class="footnote_reference">5</a>.</li>
</ul>
<p>Unlike BIP 44, neither Sprout nor Sapling have a <cite>change</cite> path level. The use of change addresses in Bitcoin is a (failed) attempt to increase the difficulty of tracking users on the transaction graph, by segregating external and internal address usage. Shielded addresses are never publicly visible in transactions, which means that sending change back to the originating address is indistinguishable from using a change address.</p>
</section>
<section id="sapling-key-path">
<h3>Sapling key path</h3>
<p>Sapling provides a mechanism to allow the efficient creation of diversified payment addresses with the same spending authority. A group of such addresses shares the same full viewing key and incoming viewing key, and so creating as many unlinkable addresses as needed does not increase the cost of scanning the block chain for relevant transactions.</p>
<p>The above key path levels include an account identifier, which in all user interfaces is represented as a "bucket of funds" under the control of a single spending authority. Therefore, wallets implementing Sapling ZIP 32 derivation MUST support the following path for any account in range {0..2<sup>31</sup>-1}:</p>
<pre>m_Sapling / purpose' / coin_type' / account'</pre>
<p>Furthermore, wallets MUST support generating the default payment address (corresponding to the default diversifier as defined above) for any account they support. They MAY also support generating a stream of payment addresses for a given account, if they wish to maintain the user experience of giving a unique address to each recipient.</p>
<p>Note that a given account can have a maximum of approximately 2<sup>87</sup> payment addresses, because each diversifier has around a 50% chance of being invalid.</p>
<p>If in certain circumstances a wallet needs to derive independent spend authorities within a single account, they MAY additionally support a non-hardened <code>address_index</code> path level as in <a href="#bip-0044" id="id22" class="footnote_reference">5</a>:</p>
<pre>m_Sapling / purpose' / coin_type' / account' / address_index</pre>
</section>
<section id="sprout-key-path">
<h3>Sprout key path</h3>
<p>Wallets implementing Sprout ZIP 32 derivation MUST support the following path:</p>
<pre>m_Sprout / purpose' / coin_type' / account' / address_index</pre>
</section>
</section>
<section id="specification-fingerprints-and-tags">
<h2>Specification: Fingerprints and Tags</h2>
<section id="sapling-full-viewing-key-fingerprints-and-tags">
<h3>Sapling Full Viewing Key Fingerprints and Tags</h3>
<p>A "Sapling full viewing key fingerprint" of a full viewing key with raw encoding <em>FVK</em> (as specified in <a href="#sapling-spec" id="id23" class="footnote_reference">8</a> section 5.6.7) is given by:</p>
<blockquote>
<p>BLAKE2b-256("ZcashSaplingFVFP", <em>FVK</em>)</p>
</blockquote>
<p>It MAY be used to uniquely identify a particular Sapling full viewing key.</p>
<p>A "Sapling full viewing key tag" is the first 4 bytes of the corresponding Sapling full viewing key fingerprint. It is intended for optimizing performance of key lookups, and MUST NOT be assumed to uniquely identify a particular key.</p>
</section>
<section id="sprout-address-fingerprints-and-tags">
<h3>Sprout Address Fingerprints and Tags</h3>
<p>A "Sprout address fingerprint" of a Sprout payment address with raw encoding <em>ADDR</em> (as specified in <a href="#sapling-spec" id="id24" class="footnote_reference">8</a> section 5.6.3, including the lead bytes) is given by:</p>
<blockquote>
<p>BLAKE2b-256("Zcash_Sprout_AFP", <em>ADDR</em>)</p>
</blockquote>
<p>It MAY be used to uniquely identify a particular Sprout payment address.</p>
<p>A "Sprout address tag" is the first 4 bytes of the corresponding Sprout address fingerprint. It is intended for optimizing performance of address lookups, and MUST NOT be assumed to uniquely identify a particular address.</p>
</section>
<section id="seed-fingerprints">
<h3>Seed Fingerprints</h3>
<p>A "seed fingerprint" for the master seed <em>S</em> of a hierarchical deterministic wallet is given by:</p>
<blockquote>
<p>BLAKE2b-256("Zcash_HD_Seed_FP", <em>S</em>)</p>
</blockquote>
<p>It MAY be used to uniquely identify a particular hierarchical deterministic wallet.</p>
<p>No corresponding short tag is defined.</p>
</section>
</section>
<section id="specification-key-encodings">
<h2>Specification: Key Encodings</h2>
<p>The following encodings are analogous to the <code>xprv</code> and <code>xpub</code> encodings defined in BIP 32 for transparent keys and addresses. Each key type has a raw representation and a Bech32 <a href="#bip-0173" id="id25" class="footnote_reference">7</a> encoding.</p>
<section id="sapling-extended-spending-keys">
<h3>Sapling extended spending keys</h3>
<p>A Sapling extended spending key (<em>ask</em>, <em>nsk</em>, <em>ovk</em>, <em>dk</em>, <em>c</em>), at depth <em>depth</em>, with parent full viewing key tag <em>parent_fvk_tag</em> and child number <em>i</em>, is represented as a byte sequence:</p>
<blockquote>
<p>I2LEOSP<sub>8</sub>(<em>depth</em>) || <em>parent_fvk_tag</em> || I2LEOSP<sub>32</sub>(<em>i</em>) || <em>c</em> || EncodeExtSKParts(<em>ask</em>, <em>nsk</em>, <em>ovk</em>, <em>dk</em>)</p>
</blockquote>
<p>For the master extended spending key, <em>depth</em> is 0, <em>parent_fvk_tag</em> is 4 zero bytes, and <em>i</em> is 0.</p>
<p>When encoded as Bech32, the Human-Readable Part is <code>secret-extended-key-main</code> for the production network, or <code>secret-extended-key-test</code> for the test network.</p>
</section>
<section id="sapling-extended-full-viewing-keys">
<h3>Sapling extended full viewing keys</h3>
<p>A Sapling extended full viewing key (<em>ak</em>, <em>nk</em>, <em>ovk</em>, <em>dk</em>, <em>c</em>), at depth <em>depth</em>, with parent full viewing key tag <em>parent_fvk_tag</em> and child number <em>i</em>, is represented as a byte sequence:</p>
<blockquote>
<p>I2LEOSP<sub>8</sub>(<em>depth</em>) || <em>parent_fvk_tag</em> || I2LEOSP<sub>32</sub>(<em>i</em>) || <em>c</em> || EncodeExtFVKParts(<em>ak</em>, <em>nk</em>, <em>ovk</em>, <em>dk</em>)</p>
</blockquote>
<p>For the master extended full viewing key, <em>depth</em> is 0, <em>parent_fvk_tag</em> is 4 zero bytes, and <em>i</em> is 0.</p>
<p>When encoded as Bech32, the Human-Readable Part is <code>zxviews</code> for the production network, or <code>zxviewtestsapling</code> for the test network.</p>
</section>
<section id="sprout-extended-spending-keys">
<h3>Sprout extended spending keys</h3>
<p>A Sprout extended spending key (<em>a</em><sub>sk</sub>, <em>c</em>), at depth <em>depth</em>, with parent address tag <em>parent_addr_tag</em> and child number <em>i</em>, is represented as a byte sequence:</p>
<blockquote>
<p>I2LEOSP<sub>8</sub>(<em>depth</em>) || <em>parent_addr_tag</em> || I2LEOSP<sub>32</sub>(<em>i</em>) || <em>c</em> || EncodeASK(<em>a</em><sub>sk</sub>)</p>
</blockquote>
<p>For the master extended spending key, <em>depth</em> is 0, <em>parent_addr_tag</em> is 4 zero bytes, and <em>i</em> is 0.</p>
<p>When encoded as Bech32, the Human-Readable Part is <code>zxsprout</code> for the production network, or <code>zxtestsprout</code> for the test network. Sprout extended spending keys are encoded using Bech32 even though other Sprout keys and addresses are encoded using Base58Check.</p>
</section>
</section>
<section id="test-vectors">
<h2>Test Vectors</h2>
<p>TBC</p>
</section>
<section id="reference-implementation">
<h2>Reference Implementation</h2>
<ul>
<li><a href="https://github.com/zcash-hackworks/zip32">https://github.com/zcash-hackworks/zip32</a></li>
<li><a href="https://github.com/zcash/librustzcash/pull/29">https://github.com/zcash/librustzcash/pull/29</a></li>
<li><a href="https://github.com/zcash/zcash/pull/3447">https://github.com/zcash/zcash/pull/3447</a></li>
<li><a href="https://github.com/zcash/zcash/pull/3492">https://github.com/zcash/zcash/pull/3492</a></li>
</ul>
</section>
<section id="references">
<h2>References</h2>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="bip-0032" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">BIP 32: Hierarchical Deterministic Wallets</a></td>
</tr>
</tbody>
</table>
<table id="bip-0039" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">BIP 39: Mnemonic code for generating deterministic keys</a></td>
</tr>
</tbody>
</table>
<table id="bip-0043" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki">BIP 43: Purpose Field for Deterministic Wallets</a></td>
</tr>
</tbody>
</table>
<table id="bip-0044" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP 44: Multi-Account Hierarchy for Deterministic Wallets</a></td>
</tr>
</tbody>
</table>
<table id="slip-0044" class="footnote">
<tbody>
<tr>
<th>6</th>
<td><a href="https://github.com/satoshilabs/slips/blob/master/slip-0044.md">SLIP 44: Registered coin types for BIP-0044</a></td>
</tr>
</tbody>
</table>
<table id="bip-0173" class="footnote">
<tbody>
<tr>
<th>7</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki">BIP 173: Base32 address format for native v0-16 witness outputs</a></td>
</tr>
</tbody>
</table>
<table id="sapling-spec" class="footnote">
<tbody>
<tr>
<th>8</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a></td>
</tr>
</tbody>
</table>
<table id="sapling-key-components" class="footnote">
<tbody>
<tr>
<th>9</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Section 4.2.2: Sapling Key Components. Zcash Protocol Specification, Version 2018.0-beta-25 or later [Overwinter+Sapling]</a></td>
</tr>
</tbody>
</table>
<table id="nist-sp-800-38g" class="footnote">
<tbody>
<tr>
<th>10</th>
<td><a href="https://dx.doi.org/10.6028/NIST.SP.800-38G">NIST Special Publication 800-38G -- Recommendation for Block Cipher Modes of Operation: Methods for Format-Preserving Encryption</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,190 +1,191 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 200: Network Upgrade Mechanism</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
{ position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
{ content: attr(title);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; pointer-events: all; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<title>ZIP 200: Network Upgrade Mechanism</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 200
<section>
<pre>ZIP: 200
Title: Network Upgrade Mechanism
Owners: Jack Grigg &lt;str4d@electriccoin.co&gt;
Status: Final
Category: Consensus
Created: 2018-01-08
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Block chain</dt>
<dd><p>A sequence of blocks starting at the genesis block, where the header of each block refers to the previous block in the sequence.</p>
</dd>
<dt>Consensus rule set</dt>
<dd><p>A set of validation rules that determine which block chains are considered valid.</p>
</dd>
<dt>Consensus rule change</dt>
<dd><p>A change in the consensus rule set of the network, such that nodes that do not recognize the new rules will follow a different block chain.</p>
</dd>
<dt>Branch</dt>
<dd><p>A block chain with a common consensus rule set, where the first block in the chain is either the genesis block, or the child of a parent block created under an older set of consensus rules (i.e. the parent block is a member of a different branch). By definition, every block belongs to at most one branch.</p>
</dd>
<dt>Network upgrade</dt>
<dd><p>An intentional consensus rule change undertaken by the community in order to improve the network.</p>
</dd>
</dl>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines a mechanism for coordinating upgrades of the Zcash network, in order to remove ambiguity about when network upgrades will activate, provide defined periods in which users should upgrade their local software, and minimize the risks to both the upgrading network and any users opting out of the changes.</p>
<h1 id="motivation">Motivation</h1>
<p>Zcash is a <em>consensual currency</em>: nobody is ever going to force someone to use a specific software implementation or a specific branch of Zcash.<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a> As such, different sub-communities will always have the freedom to choose different variants or branches which offer different design trade-offs.</p>
<p>The current Zcash software includes an <em>auto-senescence</em> feature, causing nodes running a particular version to automatically shut down approximately 16 weeks after that version was released (specifically, at the block height <code>DEPRECATION_HEIGHT</code> defined in the source code for that version). This was implemented for several reasons:<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a></p>
<ul>
<li>It gives the same systemic advantage of removing old software as auto-upgrade behavior.</li>
<li>It requires users to individually choose one of the following options:
<ul>
<li>Upgrade to a more recent software release from the main network.</li>
<li>Upgrade to an alternative release.</li>
<li>Modify their node in order to keep running the older software.</li>
</ul></li>
</ul>
<p>Developers can rely on this cadence for coordinating network upgrades. Once the last pre-upgrade software version has been deprecated, they can reasonably assume that all node operators on the network either support the upgraded rules, or have explicitly chosen not to follow them.</p>
<p>However, this behaviour is not sufficient for performing network upgrades. A globally-understood on-chain activation mechanism is necessary so that nodes can unambiguously know at what point the changes from an upgrade come into effect (and can enforce consensus rule changes, for example).</p>
<h1 id="specification">Specification</h1>
<p>The following constants are defined for every network upgrade:</p>
<dl>
<dt>BRANCH_ID</dt>
<dd><p>A globally-unique non-zero 32-bit identifier.</p>
<p>Implementations MAY use a value of zero in branch ID fields to indicate the absence of any upgrade (i.e. that the Sprout consensus rules apply).</p>
</dd>
<dt>ACTIVATION_HEIGHT</dt>
<dd><p>The non-zero block height at which the network upgrade rules will come into effect, and be enforced as part of the block chain consensus.</p>
<p>For removal of ambiguity, the block at height <code>ACTIVATION_HEIGHT - 1</code> is subject to the pre-upgrade consensus rules, and would be the last common block in the event of a persistent pre-upgrade branch.</p>
<p>It MUST be greater than the value of <code>DEPRECATION_HEIGHT</code> in the last software version that will not contain support for the network upgrade. It SHOULD be chosen to be reached approximately three months after the first software version containing support for the network upgrade is released, for the following reason:</p>
<ul>
<li>As of the time of writing (the 1.0.15 release), the release cycle is six weeks long, and nodes undergo auto-senescence 16 weeks after release. Thus, if version <code>X</code> contains support for a network upgrade, version <code>X-1</code> will be deprecated 10 weeks after the release of version <code>X</code>, which is about 2.3 months. A three-month window provides ample time for users to upgrade their nodes after auto-senescence, and re-integrate into the network prior to activation of the network upgrade.</li>
</ul>
</dd>
</dl>
<p>The relationship between <code>BRANCH_ID</code> and <code>ACTIVATION_HEIGHT</code> is many-to-one: it is possible for many distinct branches to descend from the same parent block (and thus have the same <code>ACTIVATION_HEIGHT</code>), but a specific branch can only have one parent block. Concretely, this means that if the <code>ACTIVATION_HEIGHT</code> of a network upgrade is changed for any reason (e.g. security vulnerabilities or consensus bugs are discovered), the <code>BRANCH_ID</code> MUST also be changed.</p>
<h2 id="activation-mechanism">Activation mechanism</h2>
<p>The Zcash block chain is broken into &quot;epochs&quot; of block height intervals <code>[ACTIVATION_HEIGHT_N, ACTIVATION_HEIGHT_{N+1})</code> (i.e. including <code>ACTIVATION_HEIGHT_N</code> and excluding <code>ACTIVATION_HEIGHT_{N+1}</code>), on which consensus rule sets are defined.</p>
<p>When a consensus rule depends on activation of a particular upgrade, its implementation (and that of any network behavior or surrounding code that depends on it) MUST be gated by a block height check. For example:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb2-1" title="1"><span class="cf">if</span> (CurrentEpoch(chainActive.Height(), Params().GetConsensus()) == Consensus::UPGRADE_OVERWINTER) {</a>
<a class="sourceLine" id="cb2-2" title="2"> <span class="co">// Overwinter-specific logic</span></a>
<a class="sourceLine" id="cb2-3" title="3">} <span class="cf">else</span> {</a>
<a class="sourceLine" id="cb2-4" title="4"> <span class="co">// Non-Overwinter logic</span></a>
<a class="sourceLine" id="cb2-5" title="5">}</a>
<a class="sourceLine" id="cb2-6" title="6"></a>
<a class="sourceLine" id="cb2-7" title="7"><span class="co">// ...</span></a>
<a class="sourceLine" id="cb2-8" title="8"></a>
<a class="sourceLine" id="cb2-9" title="9"><span class="cf">if</span> (NetworkUpgradeActive(pindex-&gt;nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {</a>
<a class="sourceLine" id="cb2-10" title="10"> <span class="co">// Overwinter consensus rules applied to block</span></a>
<a class="sourceLine" id="cb2-11" title="11">} <span class="cf">else</span> {</a>
<a class="sourceLine" id="cb2-12" title="12"> <span class="co">// Pre-Overwinter consensus rules applied to block</span></a>
<a class="sourceLine" id="cb2-13" title="13">}</a></code></pre></div>
<h3 id="block-validation">Block validation</h3>
<p>Incoming blocks known to have a particular height (due to their parent chain being entirely known) MUST be validated under the consensus rules corresponding to the expected branch ID for that height.</p>
<p>Incoming blocks with unknown heights (because at least one block header in their parent chain is unknown) MAY be cached, so that they can be reconsidered in the future after all their parents have been received.</p>
<h3 id="chain-reorganization">Chain reorganization</h3>
<p>It is possible for a reorganization to occur that rolls back from after the activation height, to before that height. This can handled in the same way as any regular chain orphaning or reorganization, as long as the new chain is valid.</p>
<h3 id="post-activation-upgrading">Post-activation upgrading</h3>
<p>If a user does not upgrade their node to a compatible software version before <code>ACTIVATION_HEIGHT</code> is reached, their node will follow any pre-upgrade branch that persists, and may download blocks that are incompatible with the post-upgrade branch. If the user subsequently upgrades their node to a compatible software version, the node will consider these blocks to be invalid, and if there are a significant number of invalid blocks it SHOULD shut down and alert the user of the issue.</p>
<h2 id="memory-pool">Memory pool</h2>
<p>While the current chain tip height is below <code>ACTIVATION_HEIGHT</code>, nodes SHOULD NOT accept transactions that will only be valid on the post-upgrade branch.</p>
<p>When the current chain tip height reaches <code>ACTIVATION_HEIGHT</code>, the node's local transaction memory pool SHOULD be cleared of transactions that will never be valid on the post-upgrade branch.</p>
<h2 id="two-way-replay-protection">Two-way replay protection</h2>
<p>Before the Overwinter network upgrade, two-way replay protection is ensured by enforcing post-upgrade that the most significant bit of the transaction version is set to 1.<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> From the perspective of old nodes, the transactions will have a negative version number, which is invalid under the old consensus rules. Enforcing this rule trivially makes old transactions invalid on the Overwinter branch.</p>
<p>After the Overwinter network upgrade, two-way replay protection is ensured by transaction signatures committing to a specific <code>BRANCH_ID</code>.<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a></p>
<h2 id="wipe-out-protection">Wipe-out protection</h2>
<p>Nodes running upgrade-aware software versions will enforce the upgraded consensus rules from <code>ACTIVATION_HEIGHT</code>. The chain from that height will not reorganize to a pre-upgrade branch if any block in that branch would violate the new consensus rules.</p>
<p>Care must be taken, however, to account for possible edge cases where the old and new consensus rules do not differ. For example, if the non-upgraded chain only contained empty blocks from <code>ACTIVATION_HEIGHT</code>, and the coinbase transactions were valid under both the old and new consensus rules, a wipe-out could occur. The Overwinter network upgrade is not susceptible to this because all previous transaction versions will become invalid, meaning that the coinbase transactions must use the newer transaction version. More generally, this issue could be addressed in a future network upgrade by modifying the block header to include a commitment to the <code>BRANCH_ID</code>.</p>
<h1 id="deployment">Deployment</h1>
<p>This proposal will be deployed with the Overwinter network upgrade.<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a></p>
<h1 id="backward-compatibility">Backward compatibility</h1>
<p>This proposal intentionally creates what is known as a &quot;bilateral consensus rule change&quot;. Use of this mechanism requires that all network participants upgrade their software to a compatible version within the upgrade window. Older software will treat post-upgrade blocks as invalid, and will follow any pre-upgrade branch that persists.</p>
<h1 id="reference-implementation">Reference Implementation</h1>
<p><a href="https://github.com/zcash/zcash/pull/2898" class="uri">https://github.com/zcash/zcash/pull/2898</a></p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://electriccoin.co/blog/consensual-currency/" class="uri">https://electriccoin.co/blog/consensual-currency/</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p>- <a href="https://electriccoin.co/blog/release-cycle-and-lifetimes/" class="uri">https://electriccoin.co/blog/release-cycle-and-lifetimes/</a> - <a href="https://electriccoin.co/blog/release-cycle-update/" class="uri">https://electriccoin.co/blog/release-cycle-update/</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/zip-0143.rst">ZIP 143: Transaction Signature Verification for Overwinter</a><a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref6" class="footnote-back"></a></p></li>
</ol>
</section>
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "SHOULD", "SHOULD NOT", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">1</a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Block chain</dt>
<dd>A sequence of blocks starting at the genesis block, where the header of each block refers to the previous block in the sequence.</dd>
<dt>Consensus rule set</dt>
<dd>A set of validation rules that determine which block chains are considered valid.</dd>
<dt>Consensus rule change</dt>
<dd>A change in the consensus rule set of the network, such that nodes that do not recognize the new rules will follow a different block chain.</dd>
<dt>Branch</dt>
<dd>A block chain with a common consensus rule set, where the first block in the chain is either the genesis block, or the child of a parent block created under an older set of consensus rules (i.e. the parent block is a member of a different branch). By definition, every block belongs to at most one branch.</dd>
<dt>Network upgrade</dt>
<dd>An intentional consensus rule change undertaken by the community in order to improve the network.</dd>
</dl>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal defines a mechanism for coordinating upgrades of the Zcash network, in order to remove ambiguity about when network upgrades will activate, provide defined periods in which users should upgrade their local software, and minimize the risks to both the upgrading network and any users opting out of the changes.</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>Zcash is a <em>consensual currency</em>: nobody is ever going to force someone to use a specific software implementation or a specific branch of Zcash. <a href="#consensual-currency" id="id2" class="footnote_reference">2</a> As such, different sub-communities will always have the freedom to choose different variants or branches which offer different design trade-offs.</p>
<p>The current Zcash software includes an <em>auto-senescence</em> feature, causing nodes running a particular version to automatically shut down approximately 16 weeks after that version was released (specifically, at the block height <code>DEPRECATION_HEIGHT</code> defined in the source code for that version). This was implemented for several reasons: <a href="#release-lifecycle" id="id3" class="footnote_reference">3</a></p>
<ul>
<li>It gives the same systemic advantage of removing old software as auto-upgrade behavior.</li>
<li>It requires users to individually choose one of the following options:
<ul>
<li>Upgrade to a more recent software release from the main network.</li>
<li>Upgrade to an alternative release.</li>
<li>Modify their node in order to keep running the older software.</li>
</ul>
</li>
</ul>
<p>Developers can rely on this cadence for coordinating network upgrades. Once the last pre-upgrade software version has been deprecated, they can reasonably assume that all node operators on the network either support the upgraded rules, or have explicitly chosen not to follow them.</p>
<p>However, this behaviour is not sufficient for performing network upgrades. A globally-understood on-chain activation mechanism is necessary so that nodes can unambiguously know at what point the changes from an upgrade come into effect (and can enforce consensus rule changes, for example).</p>
</section>
<section id="specification">
<h2>Specification</h2>
<p>The following constants are defined for every network upgrade:</p>
<dl>
<dt>BRANCH_ID</dt>
<dd>
<p>A globally-unique non-zero 32-bit identifier.</p>
<p>Implementations MAY use a value of zero in branch ID fields to indicate the absence of any upgrade (i.e. that the Sprout consensus rules apply).</p>
</dd>
<dt>ACTIVATION_HEIGHT</dt>
<dd>
<p>The non-zero block height at which the network upgrade rules will come into effect, and be enforced as part of the block chain consensus.</p>
<p>For removal of ambiguity, the block at height <code>ACTIVATION_HEIGHT - 1</code> is subject to the pre-upgrade consensus rules, and would be the last common block in the event of a persistent pre-upgrade branch.</p>
<p>It MUST be greater than the value of <code>DEPRECATION_HEIGHT</code> in the last software version that will not contain support for the network upgrade. It SHOULD be chosen to be reached approximately three months after the first software version containing support for the network upgrade is released, for the following reason:</p>
<ul>
<li>As of the time of writing (the 1.0.15 release), the release cycle is six weeks long, and nodes undergo auto-senescence 16 weeks after release. Thus, if version <code>X</code> contains support for a network upgrade, version <code>X-1</code> will be deprecated 10 weeks after the release of version <code>X</code>, which is about 2.3 months. A three-month window provides ample time for users to upgrade their nodes after auto-senescence, and re-integrate into the network prior to activation of the network upgrade.</li>
</ul>
</dd>
</dl>
<p>The relationship between <code>BRANCH_ID</code> and <code>ACTIVATION_HEIGHT</code> is many-to-one: it is possible for many distinct branches to descend from the same parent block (and thus have the same <code>ACTIVATION_HEIGHT</code>), but a specific branch can only have one parent block. Concretely, this means that if the <code>ACTIVATION_HEIGHT</code> of a network upgrade is changed for any reason (e.g. security vulnerabilities or consensus bugs are discovered), the <code>BRANCH_ID</code> MUST also be changed.</p>
<section id="activation-mechanism">
<h3>Activation mechanism</h3>
<p>The Zcash block chain is broken into "epochs" of block height intervals <code>[ACTIVATION_HEIGHT_N, ACTIVATION_HEIGHT_{N+1})</code> (i.e. including <code>ACTIVATION_HEIGHT_N</code> and excluding <code>ACTIVATION_HEIGHT_{N+1}</code>), on which consensus rule sets are defined.</p>
<p>When a consensus rule depends on activation of a particular upgrade, its implementation (and that of any network behavior or surrounding code that depends on it) MUST be gated by a block height check. For example:</p>
<pre data-language="cpp"><span class="k">if</span> <span class="p">(</span><span class="n">CurrentEpoch</span><span class="p">(</span><span class="n">chainActive</span><span class="p">.</span><span class="n">Height</span><span class="p">(),</span> <span class="n">Params</span><span class="p">().</span><span class="n">GetConsensus</span><span class="p">())</span> <span class="o">==</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">UPGRADE_OVERWINTER</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Overwinter-specific logic</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="c1">// Non-Overwinter logic</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="k">if</span> <span class="p">(</span><span class="n">NetworkUpgradeActive</span><span class="p">(</span><span class="n">pindex</span><span class="o">-&gt;</span><span class="n">nHeight</span><span class="p">,</span> <span class="n">Params</span><span class="p">().</span><span class="n">GetConsensus</span><span class="p">(),</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">UPGRADE_OVERWINTER</span><span class="p">))</span> <span class="p">{</span>
<span class="c1">// Overwinter consensus rules applied to block</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="c1">// Pre-Overwinter consensus rules applied to block</span>
<span class="p">}</span></pre>
<section id="block-validation">
<h4>Block validation</h4>
<p>Incoming blocks known to have a particular height (due to their parent chain being entirely known) MUST be validated under the consensus rules corresponding to the expected branch ID for that height.</p>
<p>Incoming blocks with unknown heights (because at least one block header in their parent chain is unknown) MAY be cached, so that they can be reconsidered in the future after all their parents have been received.</p>
</section>
<section id="chain-reorganization">
<h4>Chain reorganization</h4>
<p>It is possible for a reorganization to occur that rolls back from after the activation height, to before that height. This can handled in the same way as any regular chain orphaning or reorganization, as long as the new chain is valid.</p>
</section>
<section id="post-activation-upgrading">
<h4>Post-activation upgrading</h4>
<p>If a user does not upgrade their node to a compatible software version before <code>ACTIVATION_HEIGHT</code> is reached, their node will follow any pre-upgrade branch that persists, and may download blocks that are incompatible with the post-upgrade branch. If the user subsequently upgrades their node to a compatible software version, the node will consider these blocks to be invalid, and if there are a significant number of invalid blocks it SHOULD shut down and alert the user of the issue.</p>
</section>
</section>
<section id="memory-pool">
<h3>Memory pool</h3>
<p>While the current chain tip height is below <code>ACTIVATION_HEIGHT</code>, nodes SHOULD NOT accept transactions that will only be valid on the post-upgrade branch.</p>
<p>When the current chain tip height reaches <code>ACTIVATION_HEIGHT</code>, the node's local transaction memory pool SHOULD be cleared of transactions that will never be valid on the post-upgrade branch.</p>
</section>
<section id="two-way-replay-protection">
<h3>Two-way replay protection</h3>
<p>Before the Overwinter network upgrade, two-way replay protection is ensured by enforcing post-upgrade that the most significant bit of the transaction version is set to 1. <a href="#zip-0202" id="id4" class="footnote_reference">6</a> From the perspective of old nodes, the transactions will have a negative version number, which is invalid under the old consensus rules. Enforcing this rule trivially makes old transactions invalid on the Overwinter branch.</p>
<p>After the Overwinter network upgrade, two-way replay protection is ensured by transaction signatures committing to a specific <code>BRANCH_ID</code>. <a href="#zip-0143" id="id5" class="footnote_reference">4</a></p>
</section>
<section id="wipe-out-protection">
<h3>Wipe-out protection</h3>
<p>Nodes running upgrade-aware software versions will enforce the upgraded consensus rules from <code>ACTIVATION_HEIGHT</code>. The chain from that height will not reorganize to a pre-upgrade branch if any block in that branch would violate the new consensus rules.</p>
<p>Care must be taken, however, to account for possible edge cases where the old and new consensus rules do not differ. For example, if the non-upgraded chain only contained empty blocks from <code>ACTIVATION_HEIGHT</code>, and the coinbase transactions were valid under both the old and new consensus rules, a wipe-out could occur. The Overwinter network upgrade is not susceptible to this because all previous transaction versions will become invalid, meaning that the coinbase transactions must use the newer transaction version. More generally, this issue could be addressed in a future network upgrade by modifying the block header to include a commitment to the <code>BRANCH_ID</code>.</p>
</section>
</section>
<section id="deployment">
<h2>Deployment</h2>
<p>This proposal will be deployed with the Overwinter network upgrade. <a href="#zip-0201" id="id6" class="footnote_reference">5</a></p>
</section>
<section id="backward-compatibility">
<h2>Backward compatibility</h2>
<p>This proposal intentionally creates what is known as a "bilateral consensus rule change". Use of this mechanism requires that all network participants upgrade their software to a compatible version within the upgrade window. Older software will treat post-upgrade blocks as invalid, and will follow any pre-upgrade branch that persists.</p>
</section>
<section id="reference-implementation">
<h2>Reference Implementation</h2>
<p><a href="https://github.com/zcash/zcash/pull/2898">https://github.com/zcash/zcash/pull/2898</a></p>
</section>
<section id="references">
<h2>References</h2>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="consensual-currency" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://electriccoin.co/blog/consensual-currency/">https://electriccoin.co/blog/consensual-currency/</a></td>
</tr>
</tbody>
</table>
<table id="release-lifecycle" class="footnote">
<tbody>
<tr>
<th>3</th>
<td>
<ul>
<li><a href="https://electriccoin.co/blog/release-cycle-and-lifetimes/">https://electriccoin.co/blog/release-cycle-and-lifetimes/</a></li>
<li><a href="https://electriccoin.co/blog/release-cycle-update/">https://electriccoin.co/blog/release-cycle-update/</a></li>
</ul>
</td>
</tr>
</tbody>
</table>
<table id="zip-0143" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0143.rst">ZIP 143: Transaction Signature Verification for Overwinter</a></td>
</tr>
</tbody>
</table>
<table id="zip-0201" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a></td>
</tr>
</tbody>
</table>
<table id="zip-0202" class="footnote">
<tbody>
<tr>
<th>6</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,106 +1,108 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 201: Network Peer Management for Overwinter</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 201: Network Peer Management for Overwinter</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 201
<section>
<pre>ZIP: 201
Title: Network Peer Management for Overwinter
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Original-Authors: Simon Liu &lt;simon@bitcartel.com&gt;
Status: Final
Category: Network
Created: 2018-01-15
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;SHOULD&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The terms &quot;branch&quot; and &quot;network upgrade&quot; in this document are to be interpreted as described in ZIP 200.<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Overwinter</dt>
<dd><p>Code-name for the first Zcash network upgrade, also known as Network Upgrade Zero.</p>
</dd>
</dl>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines an upgrade to the network handshake and peer management required for network upgrades following the Network Upgrade Activation Mechanism<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>.</p>
<p>Related to:</p>
<ul>
<li>Transaction Signature Verification for Overwinter<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a>.</li>
<li>Version 3 Transaction Format for Overwinter<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>.</li>
<li>Transaction Expiry<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a>.</li>
</ul>
<h1 id="motivation">Motivation</h1>
<p>With scheduled network upgrades, at the activation height, nodes on each branch should disconnect from nodes on other branches and only accept new incoming connections from nodes on the same branch.</p>
<h1 id="specification">Specification</h1>
<p>When a new inbound connection is received or an outbound connection created, a CNode object is instantiated with the version field set to INIT_PROTO_VERSION which has a value of 209. This value is not transmitted across the network, but for legacy reasons and technical debt beyond the scope of this ZIP, this value will not be changed.</p>
<p>Once the two nodes have connected and started the handshake to negotiate the protocol version, the version field of CNode will be updated. The handshake<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a> involves &quot;version&quot; and &quot;verack&quot; messages being exchanged.:</p>
<pre><code>L -&gt; R: Send version message with the local peer&#39;s version
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">1</a></p>
<p>The terms "branch" and "network upgrade" in this document are to be interpreted as described in ZIP 200. <a href="#zip-0200" id="id2" class="footnote_reference">3</a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Overwinter</dt>
<dd>Code-name for the first Zcash network upgrade, also known as Network Upgrade Zero.</dd>
</dl>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal defines an upgrade to the network handshake and peer management required for network upgrades following the Network Upgrade Activation Mechanism <a href="#zip-0200" id="id3" class="footnote_reference">3</a>.</p>
<p>Related to:</p>
<ul>
<li>Transaction Signature Verification for Overwinter <a href="#zip-0143" id="id4" class="footnote_reference">2</a>.</li>
<li>Version 3 Transaction Format for Overwinter <a href="#zip-0202" id="id5" class="footnote_reference">4</a>.</li>
<li>Transaction Expiry <a href="#zip-0203" id="id6" class="footnote_reference">5</a>.</li>
</ul>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>With scheduled network upgrades, at the activation height, nodes on each branch should disconnect from nodes on other branches and only accept new incoming connections from nodes on the same branch.</p>
</section>
<section id="specification">
<h2>Specification</h2>
<p>When a new inbound connection is received or an outbound connection created, a CNode object is instantiated with the version field set to INIT_PROTO_VERSION which has a value of 209. This value is not transmitted across the network, but for legacy reasons and technical debt beyond the scope of this ZIP, this value will not be changed.</p>
<p>Once the two nodes have connected and started the handshake to negotiate the protocol version, the version field of CNode will be updated. The handshake <a href="#bitcoin-version-handshake" id="id7" class="footnote_reference">8</a> involves "version" and "verack" messages being exchanged.:</p>
<pre>L -&gt; R: Send version message with the local peer's version
R -&gt; L: Send version message back
R -&gt; L: Send verack message
R: Sets version to the minimum of the 2 versions
L -&gt; R: Send verack message after receiving version message from R
L: Sets version to the minimum of the 2 versions</code></pre>
<p>To send a version message, the node will invoke <code>PushVersion()</code>:</p>
<pre><code>void CNode::PushVersion() {
L: Sets version to the minimum of the 2 versions</pre>
<p>To send a version message, the node will invoke <code>PushVersion()</code>:</p>
<pre>void CNode::PushVersion() {
...
PushMessage(&quot;version&quot;, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, ...);
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, ...);
...
}</code></pre>
<p>where <code>PROTOCOL_VERSION</code> is the highest protocol version supported by the node.</p>
<h2 id="rejecting-pre-overwinter-connections">Rejecting Pre-Overwinter Connections</h2>
<p>Currently, nodes will reject connections from peers with an advertised protocol version lower than the other node's minimum supported protocol version.</p>
<p>This value is defined as:</p>
<pre><code>//! disconnect from peers older than this proto version
static const int MIN_PEER_PROTO_VERSION = 170002;</code></pre>
<p>With rejection implemented as:</p>
<pre><code>if (pfrom-&gt;nVersion &lt; MIN_PEER_PROTO_VERSION)
}</pre>
<p>where <code>PROTOCOL_VERSION</code> is the highest protocol version supported by the node.</p>
<section id="rejecting-pre-overwinter-connections">
<h3>Rejecting Pre-Overwinter Connections</h3>
<p>Currently, nodes will reject connections from peers with an advertised protocol version lower than the other node's minimum supported protocol version.</p>
<p>This value is defined as:</p>
<pre>//! disconnect from peers older than this proto version
static const int MIN_PEER_PROTO_VERSION = 170002;</pre>
<p>With rejection implemented as:</p>
<pre>if (pfrom-&gt;nVersion &lt; MIN_PEER_PROTO_VERSION)
{
// disconnect from old peers running protocol version we don&#39;t support.</code></pre>
<p>Activation of Overwinter will take place first on testnet, and if successful, followed by mainnet.</p>
<p>To prepare for testnet activation, Overwinter nodes will contain the following constants:</p>
<pre><code>static const int PROTOCOL_VERSION = 170003;
static const int MIN_PEER_PROTO_VERSION = 170002;</code></pre>
<p>Nodes running protocol version 170003 have a testnet activation height set, but do not have a mainnet activation height set.</p>
<p>On testnet, a pre-Overwinter node is defined to be a node for which the highest supported protocol version is &lt;= 170002.</p>
<p>These constants allow pre-Overwinter nodes that support protocol version 170002, and Overwinter nodes (which support both protocol versions 170002 and 170003 before Overwinter activation) to remain connected until the activation.</p>
<p>To prepare for mainnet activation, Overwinter nodes will contain the following constants:</p>
<pre><code>static const int PROTOCOL_VERSION = 170005;
static const int MIN_PEER_PROTO_VERSION = 170002;</code></pre>
<p>On mainnet, a pre-Overwinter node is defined to be a node for which the highest supported protocol version is &lt;= 170004. (Nodes running protocol version 170003 or 170004 do not have a mainnet activation height set. The intermediate protocol version 170004 is used to indicate support for the <code>NODE_BLOOM</code> service bit defined in<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>.)</p>
<p>These constants allow pre-Overwinter nodes that support protocol versions 170002 to 170004 inclusive, and Overwinter nodes (which support protocol versions 170002 to 170005 inclusive before Overwinter activation) to remain connected until the activation.</p>
<p>As these constants cannot be changed at run-time, once Overwinter activates on testnet or mainnet, Overwinter nodes should take steps to:</p>
<ul>
<li>reject new connections from pre-Overwinter nodes;</li>
<li>disconnect any existing connections to pre-Overwinter nodes.</li>
</ul>
<h2 id="network-coalescence">Network Coalescence</h2>
<p>Prior to the activation of Overwinter, nodes running a pre-Overwinter protocol version (e.g. 170002) and the Overwinter protocol version (170003 for testnet; 170005 for mainnet) remain connected with the same consensus rules, but it is desirable for nodes supporting Overwinter to connect preferentially to other nodes supporting Overwinter.</p>
<p>This is intended to help the network partition smoothly, since nodes should already be connected to (a majority of) peers running the same protocol version. Otherwise an Overwinter node may find their connections to Sprout nodes dropped suddenly at the activation height, potentially leaving them isolated and susceptible to eclipse attacks.<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a></p>
<p>To assist network coalescence before the activation height, we update the eviction process to place a higher priority on evicting Sprout nodes.</p>
<p>Currently, an eviction process takes place when new inbound connections arrive, but the node has already connected to the maximum number of inbound peers:</p>
<pre><code>if (nInbound &gt;= nMaxInbound)
// disconnect from old peers running protocol version we don't support.</pre>
<p>Activation of Overwinter will take place first on testnet, and if successful, followed by mainnet.</p>
<p>To prepare for testnet activation, Overwinter nodes will contain the following constants:</p>
<pre>static const int PROTOCOL_VERSION = 170003;
static const int MIN_PEER_PROTO_VERSION = 170002;</pre>
<p>Nodes running protocol version 170003 have a testnet activation height set, but do not have a mainnet activation height set.</p>
<p>On testnet, a pre-Overwinter node is defined to be a node for which the highest supported protocol version is &lt;= 170002.</p>
<p>These constants allow pre-Overwinter nodes that support protocol version 170002, and Overwinter nodes (which support both protocol versions 170002 and 170003 before Overwinter activation) to remain connected until the activation.</p>
<p>To prepare for mainnet activation, Overwinter nodes will contain the following constants:</p>
<pre>static const int PROTOCOL_VERSION = 170005;
static const int MIN_PEER_PROTO_VERSION = 170002;</pre>
<p>On mainnet, a pre-Overwinter node is defined to be a node for which the highest supported protocol version is &lt;= 170004. (Nodes running protocol version 170003 or 170004 do not have a mainnet activation height set. The intermediate protocol version 170004 is used to indicate support for the <code>NODE_BLOOM</code> service bit defined in <a href="#bip-0111" id="id8" class="footnote_reference">6</a>.)</p>
<p>These constants allow pre-Overwinter nodes that support protocol versions 170002 to 170004 inclusive, and Overwinter nodes (which support protocol versions 170002 to 170005 inclusive before Overwinter activation) to remain connected until the activation.</p>
<p>As these constants cannot be changed at run-time, once Overwinter activates on testnet or mainnet, Overwinter nodes should take steps to:</p>
<ul>
<li>reject new connections from pre-Overwinter nodes;</li>
<li>disconnect any existing connections to pre-Overwinter nodes.</li>
</ul>
</section>
<section id="network-coalescence">
<h3>Network Coalescence</h3>
<p>Prior to the activation of Overwinter, nodes running a pre-Overwinter protocol version (e.g. 170002) and the Overwinter protocol version (170003 for testnet; 170005 for mainnet) remain connected with the same consensus rules, but it is desirable for nodes supporting Overwinter to connect preferentially to other nodes supporting Overwinter.</p>
<p>This is intended to help the network partition smoothly, since nodes should already be connected to (a majority of) peers running the same protocol version. Otherwise an Overwinter node may find their connections to Sprout nodes dropped suddenly at the activation height, potentially leaving them isolated and susceptible to eclipse attacks. <a href="#eclipse-attack" id="id9" class="footnote_reference">9</a></p>
<p>To assist network coalescence before the activation height, we update the eviction process to place a higher priority on evicting Sprout nodes.</p>
<p>Currently, an eviction process takes place when new inbound connections arrive, but the node has already connected to the maximum number of inbound peers:</p>
<pre>if (nInbound &gt;= nMaxInbound)
{
if (!AttemptToEvictConnection(whitelisted)) {
// No connection to evict, disconnect the new connection
LogPrint(&quot;net&quot;, &quot;failed to find an eviction candidate - connection dropped (full)\n&quot;);
LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
CloseSocket(hSocket);
return;
}
}</code></pre>
<p>We update this process by adding behaviour so that the set of eviction candidates will prefer pre-Overwinter nodes, when the chain tip is in a period N blocks before the activation block height, where N is defined as:</p>
<pre><code>/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;</code></pre>
<p>The eviction candidates can be modified as so:</p>
<pre><code>static bool AttemptToEvictConnection(bool fPreferNewConnection) {
}</pre>
<p>We update this process by adding behaviour so that the set of eviction candidates will prefer pre-Overwinter nodes, when the chain tip is in a period N blocks before the activation block height, where N is defined as:</p>
<pre>/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;</pre>
<p>The eviction candidates can be modified as so:</p>
<pre>static bool AttemptToEvictConnection(bool fPreferNewConnection) {
...
// Protect connections with certain characteristics
...
@ -111,7 +113,7 @@ if (nActivationHeight &gt; 0 &amp;&amp;
height &lt; nActivationHeight &amp;&amp;
height &gt;= nActivationHeight - NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD)
{
// Find any nodes which don&#39;t support Overwinter protocol version
// Find any nodes which don't support Overwinter protocol version
BOOST_FOREACH(const CNodeRef &amp;node, vEvictionCandidates) {
if (node-&gt;nVersion &lt; params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion) {
vTmpEvictionCandidates.push_back(node);
@ -122,16 +124,18 @@ if (nActivationHeight &gt; 0 &amp;&amp;
if (vTmpEvictionCandidates.size() &gt; 0) {
vEvictionCandidates = vTmpEvictionCandidates;
}
}</code></pre>
<p>The existing method of disconnecting a candidate remains:</p>
<blockquote>
<p>vEvictionCandidates[0]-&gt;fDisconnect = true;</p>
</blockquote>
<p>The existing eviction process will classify and divide eviction candidates into buckets called netgroups. If a netgroup only has one peer, it will not be evicted. This means at least one pre-Overwinter node will remain connected upto the activation block height, barring any network issues or a high ban score.</p>
<h2 id="disconnecting-existing-connections">Disconnecting Existing Connections</h2>
<p>At the activation block height, an Overwinter node may still remain connected to pre-Overwinter nodes. Currently, when connecting, a node can only perform the networking handshake once, where it sends the version message before any other messages are processed. To disconnect existing pre-Overwinter connections, <code>ProcessMessage</code> is modified so that once Overwinter activates, if necessary, the protocol version of an existing peer is validated when inbound messages arrive.</p>
<p>Example code:</p>
<pre><code>bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream&amp; vRecv, int64_t nTimeReceived)
}</pre>
<p>The existing method of disconnecting a candidate remains:</p>
<blockquote>
<p>vEvictionCandidates[0]-&gt;fDisconnect = true;</p>
</blockquote>
<p>The existing eviction process will classify and divide eviction candidates into buckets called netgroups. If a netgroup only has one peer, it will not be evicted. This means at least one pre-Overwinter node will remain connected upto the activation block height, barring any network issues or a high ban score.</p>
</section>
<section id="disconnecting-existing-connections">
<h3>Disconnecting Existing Connections</h3>
<p>At the activation block height, an Overwinter node may still remain connected to pre-Overwinter nodes. Currently, when connecting, a node can only perform the networking handshake once, where it sends the version message before any other messages are processed. To disconnect existing pre-Overwinter connections, <code>ProcessMessage</code> is modified so that once Overwinter activates, if necessary, the protocol version of an existing peer is validated when inbound messages arrive.</p>
<p>Example code:</p>
<pre>bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream&amp; vRecv, int64_t nTimeReceived)
...
else if (pfrom-&gt;nVersion == 0)
{
@ -139,7 +143,7 @@ if (nActivationHeight &gt; 0 &amp;&amp;
Misbehaving(pfrom-&gt;GetId(), 1);
return false;
}
else if (strCommand == &quot;verack&quot;)
else if (strCommand == "verack")
{
...
}
@ -151,56 +155,128 @@ if (nActivationHeight &gt; 0 &amp;&amp;
else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER)
&amp;&amp; (pfrom-&gt;nVersion &lt; chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion))
{
LogPrintf(&quot;peer=%d using obsolete version %i; disconnecting\n&quot;, pfrom-&gt;id, pfrom-&gt;nVersion);
pfrom-&gt;PushMessage(&quot;reject&quot;, strCommand, REJECT_OBSOLETE,
strprintf(&quot;Version must be %d or greater&quot;,
LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom-&gt;id, pfrom-&gt;nVersion);
pfrom-&gt;PushMessage("reject", strCommand, REJECT_OBSOLETE,
strprintf("Version must be %d or greater",
chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
pfrom-&gt;fDisconnect = true;
return false;
}</code></pre>
<h1 id="deployment-of-overwinter">Deployment of Overwinter</h1>
<p>The Overwinter network upgrade defines the following network upgrade constants<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>:</p>
<dl>
<dt>BRANCH_ID</dt>
<dd><p><code>0x5ba81b19</code></p>
</dd>
<dt>ACTIVATION_HEIGHT</dt>
<dd><p>Testnet: 207500</p>
<p>Mainnet: 347500</p>
</dd>
</dl>
<p>The following ZIPs are deployed by Overwinter:</p>
<ul>
<li>ZIP 200<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a></li>
<li>ZIP 201 (this ZIP)</li>
<li>ZIP 202<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a></li>
<li>ZIP 203<a href="#fn13" class="footnote-ref" id="fnref13"><sup>13</sup></a></li>
<li>ZIP 143<a href="#fn14" class="footnote-ref" id="fnref14"><sup>14</sup></a></li>
</ul>
<h1 id="backward-compatibility">Backward compatibility</h1>
<p>Prior to the network upgrade activating, Overwinter and pre-Overwinter nodes are compatible and can connect to each other. However, Overwinter nodes will have a preference for connecting to other Overwinter nodes, so pre-Overwinter nodes will gradually be disconnected in the run up to activation.</p>
<p>Once the network upgrades, even though pre-Overwinter nodes can still accept the numerically larger protocol version used by Overwinter as being valid, Overwinter nodes will always disconnect peers using lower protocol versions.</p>
<h1 id="reference-implementation">Reference Implementation</h1>
<p><a href="https://github.com/zcash/zcash/pull/2919" class="uri">https://github.com/zcash/zcash/pull/2919</a></p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zips/blob/master/zip-0143.rst">ZIP 143: Transaction Signature Verification for Overwinter</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a><a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><p><a href="https://github.com/zcash/zips/blob/master/zip-0203.rst">ZIP 203: Transaction Expiry</a><a href="#fnref6" class="footnote-back"></a></p></li>
<li id="fn7"><p><a href="https://en.bitcoin.it/wiki/Version_Handshake" class="uri">https://en.bitcoin.it/wiki/Version_Handshake</a><a href="#fnref7" class="footnote-back"></a></p></li>
<li id="fn8"><p><a href="https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki">BIP 111: NODE_BLOOM service bit</a><a href="#fnref8" class="footnote-back"></a></p></li>
<li id="fn9"><p><a href="https://eprint.iacr.org/2015/263">Eclipse Attacks on Bitcoins Peer-to-Peer Network</a><a href="#fnref9" class="footnote-back"></a></p></li>
<li id="fn10"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref10" class="footnote-back"></a></p></li>
<li id="fn11"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref11" class="footnote-back"></a></p></li>
<li id="fn12"><p><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a><a href="#fnref12" class="footnote-back"></a></p></li>
<li id="fn13"><p><a href="https://github.com/zcash/zips/blob/master/zip-0203.rst">ZIP 203: Transaction Expiry</a><a href="#fnref13" class="footnote-back"></a></p></li>
<li id="fn14"><p><a href="https://github.com/zcash/zips/blob/master/zip-0143.rst">ZIP 143: Transaction Signature Verification for Overwinter</a><a href="#fnref14" class="footnote-back"></a></p></li>
</ol>
</section>
}</pre>
</section>
</section>
<section id="deployment-of-overwinter">
<h2>Deployment of Overwinter</h2>
<p>The Overwinter network upgrade defines the following network upgrade constants <a href="#zip-0200" id="id10" class="footnote_reference">3</a>:</p>
<dl>
<dt>BRANCH_ID</dt>
<dd><code>0x5ba81b19</code></dd>
<dt>ACTIVATION_HEIGHT</dt>
<dd>
<p>Testnet: 207500</p>
<p>Mainnet: 347500</p>
</dd>
</dl>
<p>The following ZIPs are deployed by Overwinter:</p>
<ul>
<li>ZIP 200 <a href="#zip-0200" id="id11" class="footnote_reference">3</a></li>
<li>ZIP 201 (this ZIP)</li>
<li>ZIP 202 <a href="#zip-0202" id="id12" class="footnote_reference">4</a></li>
<li>ZIP 203 <a href="#zip-0203" id="id13" class="footnote_reference">5</a></li>
<li>ZIP 143 <a href="#zip-0143" id="id14" class="footnote_reference">2</a></li>
</ul>
</section>
<section id="backward-compatibility">
<h2>Backward compatibility</h2>
<p>Prior to the network upgrade activating, Overwinter and pre-Overwinter nodes are compatible and can connect to each other. However, Overwinter nodes will have a preference for connecting to other Overwinter nodes, so pre-Overwinter nodes will gradually be disconnected in the run up to activation.</p>
<p>Once the network upgrades, even though pre-Overwinter nodes can still accept the numerically larger protocol version used by Overwinter as being valid, Overwinter nodes will always disconnect peers using lower protocol versions.</p>
</section>
<section id="reference-implementation">
<h2>Reference Implementation</h2>
<p><a href="https://github.com/zcash/zcash/pull/2919">https://github.com/zcash/zcash/pull/2919</a></p>
</section>
<section id="references">
<h2>References</h2>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0143" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0143.rst">ZIP 143: Transaction Signature Verification for Overwinter</a></td>
</tr>
</tbody>
</table>
<table id="zip-0200" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a></td>
</tr>
</tbody>
</table>
<table id="zip-0202" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0202.rst">ZIP 202: Version 3 Transaction Format for Overwinter</a></td>
</tr>
</tbody>
</table>
<table id="zip-0203" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0203.rst">ZIP 203: Transaction Expiry</a></td>
</tr>
</tbody>
</table>
<table id="bip-0111" class="footnote">
<tbody>
<tr>
<th>6</th>
<td><a href="https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki">BIP 111: NODE_BLOOM service bit</a></td>
</tr>
</tbody>
</table>
<table id="bitcoin-verson" class="footnote">
<tbody>
<tr>
<th>7</th>
<td><a href="https://en.bitcoin.it/wiki/Protocol_documentation#version">https://en.bitcoin.it/wiki/Protocol_documentation#version</a></td>
</tr>
</tbody>
</table>
<table id="bitcoin-version-handshake" class="footnote">
<tbody>
<tr>
<th>8</th>
<td><a href="https://en.bitcoin.it/wiki/Version_Handshake">https://en.bitcoin.it/wiki/Version_Handshake</a></td>
</tr>
</tbody>
</table>
<table id="eclipse-attack" class="footnote">
<tbody>
<tr>
<th>9</th>
<td><a href="https://eprint.iacr.org/2015/263">Eclipse Attacks on Bitcoins Peer-to-Peer Network</a></td>
</tr>
</tbody>
</table>
<table id="partition-discussion" class="footnote">
<tbody>
<tr>
<th>10</th>
<td><a href="https://github.com/zcash/zcash/issues/2775">Partition nodes with old protocol version from network in advance of hard fork</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,339 +1,401 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 202: Version 3 Transaction Format for Overwinter</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 202: Version 3 Transaction Format for Overwinter</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 202
<section>
<pre>ZIP: 202
Title: Version 3 Transaction Format for Overwinter
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Original-Authors: Simon Liu &lt;simon@bitcartel.com&gt;
Status: Final
Category: Consensus
Created: 2018-01-10
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The terms &quot;branch&quot;, &quot;network upgrade&quot;, and &quot;consensus rule change&quot; in this document are to be interpreted as described in ZIP 200.<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a></p>
<p>The term &quot;Overwinter&quot; in this document is to be interpreted as described in ZIP 201.<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a></p>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines a new transaction format required for Network Upgrade Activation Mechanism<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> and Transaction Expiry<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>.</p>
<h1 id="motivation">Motivation</h1>
<p>Zcash launched with support for upstream Bitcoin version 1 transactions and defined a new version 2 transaction format which added fields required for shielded transactions.</p>
<table>
<thead>
<tr class="header">
<th>Version</th>
<th>Field</th>
<th>Description</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>&gt;= 1</td>
<td><code>version</code></td>
<td>positive value</td>
<td><code>int32</code></td>
</tr>
<tr class="even">
<td>&gt;= 1</td>
<td><code>tx_in_count</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr class="odd">
<td>&gt;= 1</td>
<td><code>tx_in</code></td>
<td>list of inputs</td>
<td><code>vector</code></td>
</tr>
<tr class="even">
<td>&gt;= 1</td>
<td><code>tx_out_count</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr class="odd">
<td>&gt;= 1</td>
<td><code>tx_out</code></td>
<td>list of outputs</td>
<td><code>vector</code></td>
</tr>
<tr class="even">
<td>&gt;= 1</td>
<td><code>lock_time</code></td>
<td>block height or timestamp</td>
<td><code>uint32</code></td>
</tr>
<tr class="odd">
<td>&gt;= 2</td>
<td><code>nJoinSplit</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr class="even">
<td>&gt;= 2</td>
<td><code>vJoinSplit</code></td>
<td>list of joinsplits</td>
<td><code>vector</code></td>
</tr>
<tr class="odd">
<td>&gt;= 2</td>
<td><code>joinSplitPubKey</code></td>
<td>joinsplit_sig public key</td>
<td>32 bytes</td>
</tr>
<tr class="even">
<td>&gt;= 2</td>
<td><code>joinSplitSig</code></td>
<td>signature</td>
<td>64 bytes</td>
</tr>
</tbody>
</table>
<p>A new transaction format is required to:</p>
<ul>
<li>support safe network upgrades as specified in Network Upgrade Activation Mechanism<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a>;</li>
<li>provide replay protection between pre-Overwinter and Overwinter branches during upgrades;</li>
<li>provide replay protection between different branches post-Overwinter;</li>
<li>enable a branch to support multiple transaction version formats;</li>
<li>ensure transaction formats are parsed uniquely across parallel branches;</li>
<li>support transaction expiry<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>.</li>
</ul>
<h1 id="specification">Specification</h1>
<h2 id="transaction-format-version-3">Transaction format version 3</h2>
<p>A new version 3 transaction format will be introduced for Overwinter.</p>
<p>The version 3 format differs from the version 2 format in the following ways:</p>
<ul>
<li>header (first four bytes, little-endian encoded)
<ul>
<li><code>fOverwintered</code> flag : bit 31, must be set</li>
<li><code>nVersion</code> : bits 30-0, positive integer</li>
</ul></li>
<li><code>nVersionGroupId</code></li>
<li><code>nExpiryHeight</code></li>
</ul>
<table>
<thead>
<tr class="header">
<th>Version</th>
<th>Field</th>
<th>Description</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><p>&gt;= 3</p></td>
<td><p>header</p></td>
<td><p>contains:</p>
<ul>
<li><code>fOverwintered</code> flag (bit 31, always set)</li>
<li><code>nVersion</code> (bits 30-0)</li>
</ul></td>
<td><p><code>uint32</code></p></td>
</tr>
<tr class="even">
<td>&gt;= 3</td>
<td><code>nVersionGroupId</code></td>
<td>version group id (not zero)</td>
<td><code>uint32</code></td>
</tr>
<tr class="odd">
<td>&gt;= 1</td>
<td><code>tx_in_count</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr class="even">
<td>&gt;= 1</td>
<td><code>tx_in</code></td>
<td>list of inputs</td>
<td><code>vector</code></td>
</tr>
<tr class="odd">
<td>&gt;= 1</td>
<td><code>tx_out_count</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr class="even">
<td>&gt;= 1</td>
<td><code>tx_out</code></td>
<td>list of outputs</td>
<td><code>vector</code></td>
</tr>
<tr class="odd">
<td>&gt;= 1</td>
<td><code>lock_time</code></td>
<td>block height or timestamp</td>
<td><code>uint32</code></td>
</tr>
<tr class="even">
<td>&gt;= 3</td>
<td><code>expiryHeight</code></td>
<td>block height</td>
<td><code>uint32</code></td>
</tr>
<tr class="odd">
<td>&gt;= 2</td>
<td><code>nJoinSplit</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr class="even">
<td>&gt;= 2</td>
<td><code>vJoinSplit</code></td>
<td>list of joinsplits</td>
<td><code>vector</code></td>
</tr>
<tr class="odd">
<td>&gt;= 2</td>
<td><code>joinSplitPubKey</code></td>
<td>joinsplit_sig public key</td>
<td>32 bytes</td>
</tr>
<tr class="even">
<td>&gt;= 2</td>
<td><code>joinSplitSig</code></td>
<td>signature</td>
<td>64 bytes</td>
</tr>
</tbody>
</table>
<h2 id="header-field">Header Field</h2>
<p>The first four bytes of pre-Overwinter and Overwinter transactions are little-endian encoded.</p>
<p>Version 1 transaction (txid 5c6ba844e1ca1c8083cd53e29971bd82f1f9eea1f86c1763a22dd4ca183ae061 <a href="https://zcash.blockexplorer.com/tx/5c6ba844e1ca1c8083cd53e29971bd82f1f9eea1f86c1763a22dd4ca183ae061" class="uri">https://zcash.blockexplorer.com/tx/5c6ba844e1ca1c8083cd53e29971bd82f1f9eea1f86c1763a22dd4ca183ae061</a>)</p>
<ul>
<li>begins with little-endian byte sequence [0x01, 0x00, 0x00, 0x00];</li>
<li>deserialized as 32-bit signed integer with decimal value of 1.</li>
</ul>
<p>Version 2 transaction (txid 4435bf8064e74f01262cb1725fd9b53e600fa285950163fd961bed3a64260d8b <a href="https://zcash.blockexplorer.com/tx/4435bf8064e74f01262cb1725fd9b53e600fa285950163fd961bed3a64260d8b" class="uri">https://zcash.blockexplorer.com/tx/4435bf8064e74f01262cb1725fd9b53e600fa285950163fd961bed3a64260d8b</a>)</p>
<ul>
<li>begins with little-endian byte sequence [0x02, 0x00, 0x00, 0x00];</li>
<li>deserialized as 32-bit signed integer with decimal value of 2.</li>
</ul>
<p>Transaction parsers for versions of Zcash prior to Overwinter, and for most other Bitcoin forks, require the transaction version number to be positive.</p>
<p>With the version 3 transaction format, the first four bytes of a serialized transaction, the 32-bit header, are made up of two fields as shown in the table above:</p>
<ul>
<li>1-bit <code>fOverwintered</code> flag, must be set;</li>
<li>31-bit unsigned int for the version.</li>
</ul>
<p>Pre-Overwinter parsers will deserialize these four bytes as a 32-bit signed integer. With two's complement integers, the most significant bit indicates whether an integer is positive or negative. With the Overwinter flag set, the transaction version will be negative, resulting in pre-Overwinter parsers rejecting the transaction as invalid. This provides transaction replay protection between pre-Overwinter and Overwinter software.</p>
<p>Consider the following example of a serialized version 3 transaction.</p>
<p>Pre-Overwinter parser:</p>
<ul>
<li>data begins with little-endian byte sequence: [0x03, 0x00, 0x00, 0x80];</li>
<li>deserialized as 32-bit signed integer.
<ul>
<li>with hexadecimal value of 0x80000003 (most significant bit is set);</li>
<li>decimal value of -2147483645.</li>
</ul></li>
</ul>
<p>Legacy parsers will expect the version to be a positive value, such as 1 or 2, and will thus reject the Overwinter transaction as invalid.</p>
<p>Overwinter parser:</p>
<ul>
<li>data begins with little-endian byte sequence: [0x03, 0x00, 0x00, 0x80];</li>
<li>deserialized as 32-bit unsigned integer
<ul>
<li>with binary value of 0b10000000000000000000000000000011;</li>
</ul></li>
<li>the 32-bits are decomposed into two fields:
<ul>
<li><code>fOverwintered</code> flag (bit 31) as a boolean, expected to be set;</li>
<li>version (bits 30 - bit 0) as an unsigned integer, expected to have a decimal value of 3.</li>
</ul></li>
</ul>
<p>Overwinter parsers will accept the transaction as valid as the most significant bit of the header has been set. By masking off (unsetting) the most significant bit, the parser can retrieve the transaction version number:</p>
<pre><code>0x80000003 &amp; 0x7FFFFFFF = 0x00000003 = 3</code></pre>
<h2 id="version-group-id">Version Group Id</h2>
<p>The version group id is a non-zero, random and unique identifier, of type <code>uint32</code>, assigned to a transaction format version, or a group of soft-forking transaction format versions. The version group id helps nodes disambiguate between branches using the same version number.</p>
<p>That is, it prevents a client on one branch of the network from attempting to parse transactions intended for another branch, in the situation where the transactions share the same format version number but are actually specified differently. For example, Zcash and a clone of Zcash might both define their own custom v3 transaction formats, but each will have its own unique version group id, so that they can reject v3 transactions with unknown version group ids.</p>
<p>The combination of transaction version and version group id, <code>nVersion || nVersionGroupId</code>, uniquely defines the transaction format, thus enabling parsers to reject transactions from outside the client's chain which cannot be parsed.</p>
<p>By convention, it is expected that when introducing a new transaction version requiring a network upgrade, a new unique version group id will be assigned to that transaction version.</p>
<p>However, if a new transaction version can be correctly parsed according to the format of a preceding version (that is, it only restricts the format, or defines fields that were previously reserved and which old parsers can safely ignore), then the same version group id MAY be re-used.</p>
<h2 id="expiry-height">Expiry Height</h2>
<p>The expiry height field, as defined in the Transaction Expiry ZIP<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>, stores the block height after which a transaction can no longer be mined.</p>
<h1 id="transaction-validation">Transaction Validation</h1>
<p>A valid Overwinter transaction intended for Zcash MUST have:</p>
<ul>
<li>version number 3; and</li>
<li>version group id 0x03C48270<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a>; and</li>
<li><code>fOverwintered</code> flag set.</li>
</ul>
<p>Overwinter validators MUST reject transactions for violating consensus rules if:</p>
<ul>
<li>the <code>fOverwintered</code> flag is not set; or</li>
<li>the version group id is unknown; or</li>
<li>the version number is unknown.</li>
</ul>
<p>Validation of version 3 transactions MUST use the signature verification process detailed in the Transaction Signature Verification for Overwinter ZIP<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>.</p>
<h1 id="implementation">Implementation</h1>
<p>The comments and code samples in this section apply to the reference C++ implementation of Zcash. Other implementations may vary.</p>
<h2 id="transaction-version">Transaction Version</h2>
<p>Transaction version remains a positive value. The main Zcash chain will follow convention and continue to order transaction versions in an ascending order.</p>
<p>Tests can continue to check for the existence of forwards-compatible transaction fields by checking the transaction version using comparison operators:</p>
<pre><code>if (tx.nVersion &gt;= 2) {
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "MUST NOT", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">1</a></p>
<p>The terms "branch", "network upgrade", and "consensus rule change" in this document are to be interpreted as described in ZIP 200. <a href="#zip-0200" id="id2" class="footnote_reference">3</a></p>
<p>The term "Overwinter" in this document is to be interpreted as described in ZIP 201. <a href="#zip-0201" id="id3" class="footnote_reference">4</a></p>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal defines a new transaction format required for Network Upgrade Activation Mechanism <a href="#zip-0200" id="id4" class="footnote_reference">3</a> and Transaction Expiry <a href="#zip-0203" id="id5" class="footnote_reference">5</a>.</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>Zcash launched with support for upstream Bitcoin version 1 transactions and defined a new version 2 transaction format which added fields required for shielded transactions.</p>
<table>
<thead>
<tr>
<th>Version</th>
<th>Field</th>
<th>Description</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>&gt;= 1</td>
<td><code>version</code></td>
<td>positive value</td>
<td><code>int32</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>tx_in_count</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>tx_in</code></td>
<td>list of inputs</td>
<td><code>vector</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>tx_out_count</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>tx_out</code></td>
<td>list of outputs</td>
<td><code>vector</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>lock_time</code></td>
<td>block height or timestamp</td>
<td><code>uint32</code></td>
</tr>
<tr>
<td>&gt;= 2</td>
<td><code>nJoinSplit</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr>
<td>&gt;= 2</td>
<td><code>vJoinSplit</code></td>
<td>list of joinsplits</td>
<td><code>vector</code></td>
</tr>
<tr>
<td>&gt;= 2</td>
<td><code>joinSplitPubKey</code></td>
<td>joinsplit_sig public key</td>
<td>32 bytes</td>
</tr>
<tr>
<td>&gt;= 2</td>
<td><code>joinSplitSig</code></td>
<td>signature</td>
<td>64 bytes</td>
</tr>
</tbody>
</table>
<p>A new transaction format is required to:</p>
<ul>
<li>support safe network upgrades as specified in Network Upgrade Activation Mechanism <a href="#zip-0200" id="id6" class="footnote_reference">3</a>;</li>
<li>provide replay protection between pre-Overwinter and Overwinter branches during upgrades;</li>
<li>provide replay protection between different branches post-Overwinter;</li>
<li>enable a branch to support multiple transaction version formats;</li>
<li>ensure transaction formats are parsed uniquely across parallel branches;</li>
<li>support transaction expiry <a href="#zip-0203" id="id7" class="footnote_reference">5</a>.</li>
</ul>
</section>
<section id="specification">
<h2>Specification</h2>
<section id="transaction-format-version-3">
<h3>Transaction format version 3</h3>
<p>A new version 3 transaction format will be introduced for Overwinter.</p>
<p>The version 3 format differs from the version 2 format in the following ways:</p>
<ul>
<li>header (first four bytes, little-endian encoded)
<ul>
<li><code>fOverwintered</code> flag : bit 31, must be set</li>
<li><code>nVersion</code> : bits 30-0, positive integer</li>
</ul>
</li>
<li><code>nVersionGroupId</code></li>
<li><code>nExpiryHeight</code></li>
</ul>
<table>
<thead>
<tr>
<th>Version</th>
<th>Field</th>
<th>Description</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>&gt;= 3</td>
<td>header</td>
<td>
<p>contains:</p>
<ul>
<li><code>fOverwintered</code> flag (bit 31, always set)</li>
<li><code>nVersion</code> (bits 30-0)</li>
</ul>
</td>
<td><code>uint32</code></td>
</tr>
<tr>
<td>&gt;= 3</td>
<td><code>nVersionGroupId</code></td>
<td>version group id (not zero)</td>
<td><code>uint32</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>tx_in_count</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>tx_in</code></td>
<td>list of inputs</td>
<td><code>vector</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>tx_out_count</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>tx_out</code></td>
<td>list of outputs</td>
<td><code>vector</code></td>
</tr>
<tr>
<td>&gt;= 1</td>
<td><code>lock_time</code></td>
<td>block height or timestamp</td>
<td><code>uint32</code></td>
</tr>
<tr>
<td>&gt;= 3</td>
<td><code>expiryHeight</code></td>
<td>block height</td>
<td><code>uint32</code></td>
</tr>
<tr>
<td>&gt;= 2</td>
<td><code>nJoinSplit</code></td>
<td>variable-length integer</td>
<td><code>compactSize</code></td>
</tr>
<tr>
<td>&gt;= 2</td>
<td><code>vJoinSplit</code></td>
<td>list of joinsplits</td>
<td><code>vector</code></td>
</tr>
<tr>
<td>&gt;= 2</td>
<td><code>joinSplitPubKey</code></td>
<td>joinsplit_sig public key</td>
<td>32 bytes</td>
</tr>
<tr>
<td>&gt;= 2</td>
<td><code>joinSplitSig</code></td>
<td>signature</td>
<td>64 bytes</td>
</tr>
</tbody>
</table>
</section>
<section id="header-field">
<h3>Header Field</h3>
<p>The first four bytes of pre-Overwinter and Overwinter transactions are little-endian encoded.</p>
<p>Version 1 transaction (txid 5c6ba844e1ca1c8083cd53e29971bd82f1f9eea1f86c1763a22dd4ca183ae061 <a href="https://zcash.blockexplorer.com/tx/5c6ba844e1ca1c8083cd53e29971bd82f1f9eea1f86c1763a22dd4ca183ae061">https://zcash.blockexplorer.com/tx/5c6ba844e1ca1c8083cd53e29971bd82f1f9eea1f86c1763a22dd4ca183ae061</a>)</p>
<ul>
<li>begins with little-endian byte sequence [0x01, 0x00, 0x00, 0x00];</li>
<li>deserialized as 32-bit signed integer with decimal value of 1.</li>
</ul>
<p>Version 2 transaction (txid 4435bf8064e74f01262cb1725fd9b53e600fa285950163fd961bed3a64260d8b <a href="https://zcash.blockexplorer.com/tx/4435bf8064e74f01262cb1725fd9b53e600fa285950163fd961bed3a64260d8b">https://zcash.blockexplorer.com/tx/4435bf8064e74f01262cb1725fd9b53e600fa285950163fd961bed3a64260d8b</a>)</p>
<ul>
<li>begins with little-endian byte sequence [0x02, 0x00, 0x00, 0x00];</li>
<li>deserialized as 32-bit signed integer with decimal value of 2.</li>
</ul>
<p>Transaction parsers for versions of Zcash prior to Overwinter, and for most other Bitcoin forks, require the transaction version number to be positive.</p>
<p>With the version 3 transaction format, the first four bytes of a serialized transaction, the 32-bit header, are made up of two fields as shown in the table above:</p>
<ul>
<li>1-bit <code>fOverwintered</code> flag, must be set;</li>
<li>31-bit unsigned int for the version.</li>
</ul>
<p>Pre-Overwinter parsers will deserialize these four bytes as a 32-bit signed integer. With two's complement integers, the most significant bit indicates whether an integer is positive or negative. With the Overwinter flag set, the transaction version will be negative, resulting in pre-Overwinter parsers rejecting the transaction as invalid. This provides transaction replay protection between pre-Overwinter and Overwinter software.</p>
<p>Consider the following example of a serialized version 3 transaction.</p>
<p>Pre-Overwinter parser:</p>
<ul>
<li>data begins with little-endian byte sequence: [0x03, 0x00, 0x00, 0x80];</li>
<li>deserialized as 32-bit signed integer.
<ul>
<li>with hexadecimal value of 0x80000003 (most significant bit is set);</li>
<li>decimal value of -2147483645.</li>
</ul>
</li>
</ul>
<p>Legacy parsers will expect the version to be a positive value, such as 1 or 2, and will thus reject the Overwinter transaction as invalid.</p>
<p>Overwinter parser:</p>
<ul>
<li>data begins with little-endian byte sequence: [0x03, 0x00, 0x00, 0x80];</li>
<li>deserialized as 32-bit unsigned integer
<ul>
<li>with binary value of 0b10000000000000000000000000000011;</li>
</ul>
</li>
<li>the 32-bits are decomposed into two fields:
<ul>
<li><code>fOverwintered</code> flag (bit 31) as a boolean, expected to be set;</li>
<li>version (bits 30 - bit 0) as an unsigned integer, expected to have a decimal value of 3.</li>
</ul>
</li>
</ul>
<p>Overwinter parsers will accept the transaction as valid as the most significant bit of the header has been set. By masking off (unsetting) the most significant bit, the parser can retrieve the transaction version number:</p>
<pre>0x80000003 &amp; 0x7FFFFFFF = 0x00000003 = 3</pre>
</section>
<section id="version-group-id">
<h3>Version Group Id</h3>
<p>The version group id is a non-zero, random and unique identifier, of type <code>uint32</code>, assigned to a transaction format version, or a group of soft-forking transaction format versions. The version group id helps nodes disambiguate between branches using the same version number.</p>
<p>That is, it prevents a client on one branch of the network from attempting to parse transactions intended for another branch, in the situation where the transactions share the same format version number but are actually specified differently. For example, Zcash and a clone of Zcash might both define their own custom v3 transaction formats, but each will have its own unique version group id, so that they can reject v3 transactions with unknown version group ids.</p>
<p>The combination of transaction version and version group id, <code>nVersion || nVersionGroupId</code>, uniquely defines the transaction format, thus enabling parsers to reject transactions from outside the client's chain which cannot be parsed.</p>
<p>By convention, it is expected that when introducing a new transaction version requiring a network upgrade, a new unique version group id will be assigned to that transaction version.</p>
<p>However, if a new transaction version can be correctly parsed according to the format of a preceding version (that is, it only restricts the format, or defines fields that were previously reserved and which old parsers can safely ignore), then the same version group id MAY be re-used.</p>
</section>
<section id="expiry-height">
<h3>Expiry Height</h3>
<p>The expiry height field, as defined in the Transaction Expiry ZIP <a href="#zip-0203" id="id8" class="footnote_reference">5</a>, stores the block height after which a transaction can no longer be mined.</p>
</section>
</section>
<section id="transaction-validation">
<h2>Transaction Validation</h2>
<p>A valid Overwinter transaction intended for Zcash MUST have:</p>
<ul>
<li>version number 3; and</li>
<li>version group id 0x03C48270 <a href="#versiongroupid" id="id9" class="footnote_reference">6</a>; and</li>
<li><code>fOverwintered</code> flag set.</li>
</ul>
<p>Overwinter validators MUST reject transactions for violating consensus rules if:</p>
<ul>
<li>the <code>fOverwintered</code> flag is not set; or</li>
<li>the version group id is unknown; or</li>
<li>the version number is unknown.</li>
</ul>
<p>Validation of version 3 transactions MUST use the signature verification process detailed in the Transaction Signature Verification for Overwinter ZIP <a href="#zip-0143" id="id10" class="footnote_reference">2</a>.</p>
</section>
<section id="implementation">
<h2>Implementation</h2>
<p>The comments and code samples in this section apply to the reference C++ implementation of Zcash. Other implementations may vary.</p>
<section id="transaction-version">
<h3>Transaction Version</h3>
<p>Transaction version remains a positive value. The main Zcash chain will follow convention and continue to order transaction versions in an ascending order.</p>
<p>Tests can continue to check for the existence of forwards-compatible transaction fields by checking the transaction version using comparison operators:</p>
<pre>if (tx.nVersion &gt;= 2) {
for (int js = 0; js &lt; joinsplits; js++) {
...
}
}</code></pre>
<p>When (de)serializing v3 transactions, the version group id must also be checked in case the transaction is intended for a branch which has a different format for its version 3 transaction:</p>
<pre><code>if (tx.nVersion == 3 &amp;&amp; tx.nVersionGroupId == OVERWINTER_VERSION_GROUP_ID) {
}</pre>
<p>When (de)serializing v3 transactions, the version group id must also be checked in case the transaction is intended for a branch which has a different format for its version 3 transaction:</p>
<pre>if (tx.nVersion == 3 &amp;&amp; tx.nVersionGroupId == OVERWINTER_VERSION_GROUP_ID) {
auto expiryHeight = tx.nExpiryHeight;
}</code></pre>
<p>Tests can continue to set the version to zero as an error condition:</p>
<pre><code>mtx.nVersion = 0</code></pre>
<h2 id="overwinter-validation">Overwinter Validation</h2>
<p>To test if the format of an Overwinter transaction is v3 or not:</p>
<pre><code>if (tx.fOverwintered &amp;&amp; tx.nVersion == 3) {
}</pre>
<p>Tests can continue to set the version to zero as an error condition:</p>
<pre>mtx.nVersion = 0</pre>
</section>
<section id="overwinter-validation">
<h3>Overwinter Validation</h3>
<p>To test if the format of an Overwinter transaction is v3 or not:</p>
<pre>if (tx.fOverwintered &amp;&amp; tx.nVersion == 3) {
// Valid v3 format transaction
}</code></pre>
<p>This only tests that the format of the transaction matches the v3 specification described above.</p>
<p>To test if the format of an Overwinter transaction is both v3 and the transaction itself is intended for the client's chain:</p>
<pre><code>if (tx.fOverwintered &amp;&amp;
}</pre>
<p>This only tests that the format of the transaction matches the v3 specification described above.</p>
<p>To test if the format of an Overwinter transaction is both v3 and the transaction itself is intended for the client's chain:</p>
<pre>if (tx.fOverwintered &amp;&amp;
tx.nVersionGroupId == OVERWINTER_VERSION_GROUP_ID) &amp;&amp;
tx.nVersion == 3) {
// Valid v3 format transaction intended for this client&#39;s chain
}</code></pre>
<p>It is expected that this test involving <code>nVersionGroupId</code> is only required when a transaction is being constructed or deserialized e.g. when an external transaction enters the system.</p>
<p>However, it's possible that a clone of Zcash is using the same version group id and passes the conditional.</p>
<p>Ultimately, a client can determine if a transaction is truly intended for the client's chain or not by following the signature verification process detailed in the Transaction Signature Verification for Overwinter ZIP<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>.</p>
<h1 id="deployment">Deployment</h1>
<p>This proposal will be deployed with the Overwinter network upgrade. The activation block height proposal is in<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a>.</p>
<h1 id="backwards-compatibility">Backwards compatibility</h1>
<p>This proposal intentionally creates what is known as a &quot;bilateral consensus rule change&quot;<a href="#fn13" class="footnote-ref" id="fnref13"><sup>13</sup></a> between pre-Overwinter software and Overwinter-compatible software. Use of this new transaction format requires that all network participants upgrade their software to a compatible version within the upgrade window. Pre-Overwinter software will treat Overwinter transactions as invalid.</p>
<p>Once Overwinter has activated, Overwinter-compatible software will reject version 1 and version 2 transactions, and will only accept transactions based upon supported transaction version numbers and recognized version group ids.</p>
<h1 id="reference-implementation">Reference Implementation</h1>
<p><a href="https://github.com/zcash/zcash/pull/2925" class="uri">https://github.com/zcash/zcash/pull/2925</a></p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Handshaking for Overwinter</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/zip-0203.rst">ZIP 203: Transaction Expiry</a><a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref6" class="footnote-back"></a></p></li>
<li id="fn7"><p><a href="https://github.com/zcash/zips/blob/master/zip-0203.rst">ZIP 203: Transaction Expiry</a><a href="#fnref7" class="footnote-back"></a></p></li>
<li id="fn8"><p><a href="https://github.com/zcash/zips/blob/master/zip-0203.rst">ZIP 203: Transaction Expiry</a><a href="#fnref8" class="footnote-back"></a></p></li>
<li id="fn9"><p><a href="https://github.com/zcash/zcash/pull/2925/files#diff-5cb8d9decaa15620a8f98b0c6c44da9bR311">OVERWINTER_VERSION_GROUP_ID</a><a href="#fnref9" class="footnote-back"></a></p></li>
<li id="fn10"><p><a href="https://github.com/zcash/zips/blob/master/zip-0143.rst">ZIP 143: Transaction Signature Verification for Overwinter</a><a href="#fnref10" class="footnote-back"></a></p></li>
<li id="fn11"><p><a href="https://github.com/zcash/zips/blob/master/zip-0143.rst">ZIP 143: Transaction Signature Verification for Overwinter</a><a href="#fnref11" class="footnote-back"></a></p></li>
<li id="fn12"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Handshaking for Overwinter</a><a href="#fnref12" class="footnote-back"></a></p></li>
<li id="fn13"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref13" class="footnote-back"></a></p></li>
</ol>
</section>
// Valid v3 format transaction intended for this client's chain
}</pre>
<p>It is expected that this test involving <code>nVersionGroupId</code> is only required when a transaction is being constructed or deserialized e.g. when an external transaction enters the system.</p>
<p>However, it's possible that a clone of Zcash is using the same version group id and passes the conditional.</p>
<p>Ultimately, a client can determine if a transaction is truly intended for the client's chain or not by following the signature verification process detailed in the Transaction Signature Verification for Overwinter ZIP <a href="#zip-0143" id="id11" class="footnote_reference">2</a>.</p>
</section>
</section>
<section id="deployment">
<h2>Deployment</h2>
<p>This proposal will be deployed with the Overwinter network upgrade. The activation block height proposal is in <a href="#zip-0201" id="id12" class="footnote_reference">4</a>.</p>
</section>
<section id="backwards-compatibility">
<h2>Backwards compatibility</h2>
<p>This proposal intentionally creates what is known as a "bilateral consensus rule change" <a href="#zip-0200" id="id13" class="footnote_reference">3</a> between pre-Overwinter software and Overwinter-compatible software. Use of this new transaction format requires that all network participants upgrade their software to a compatible version within the upgrade window. Pre-Overwinter software will treat Overwinter transactions as invalid.</p>
<p>Once Overwinter has activated, Overwinter-compatible software will reject version 1 and version 2 transactions, and will only accept transactions based upon supported transaction version numbers and recognized version group ids.</p>
</section>
<section id="reference-implementation">
<h2>Reference Implementation</h2>
<p><a href="https://github.com/zcash/zcash/pull/2925">https://github.com/zcash/zcash/pull/2925</a></p>
</section>
<section id="references">
<h2>References</h2>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0143" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0143.rst">ZIP 143: Transaction Signature Verification for Overwinter</a></td>
</tr>
</tbody>
</table>
<table id="zip-0200" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a></td>
</tr>
</tbody>
</table>
<table id="zip-0201" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Handshaking for Overwinter</a></td>
</tr>
</tbody>
</table>
<table id="zip-0203" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0203.rst">ZIP 203: Transaction Expiry</a></td>
</tr>
</tbody>
</table>
<table id="versiongroupid" class="footnote">
<tbody>
<tr>
<th>6</th>
<td><a href="https://github.com/zcash/zcash/pull/2925/files#diff-5cb8d9decaa15620a8f98b0c6c44da9bR311">OVERWINTER_VERSION_GROUP_ID</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,62 +1,80 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 203: Transaction Expiry</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 203: Transaction Expiry</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 203
<section>
<pre>ZIP: 203
Title: Transaction Expiry
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Original-Authors: Jay Graber
Status: Final
Category: Consensus
Created: 2018-01-09
License: MIT</code></pre>
<h1 id="abstract">Abstract</h1>
<p>This is a Standards ZIP describing a new consensus rule to set an expiration time after which a transaction cannot be mined. If it is not mined within that time, the transaction will be removed from nodes' mempools.</p>
<h1 id="motivation">Motivation</h1>
<p>Transactions that have insufficient fees are often not mined. This indeterminism is a source of confusion for users and wallets. Allowing a transaction to set a block height after which it cannot be mined would provide certainty around how long a transaction has to confirm before it is rejected by the network and must be re-sent.</p>
<p>Advantages include optimizing mempool performance by removing transactions that will not be mined, and potentially simplifying bidirectional payment channels by reducing the need to store and compress revocations for past states, since transactions not committed to the chain could expire and become invalid after a period of time.</p>
<p>If the expiry is at block height N, then the transaction must be included in block N or earlier. Block N+1 will be too late, and the transaction will be removed from the mempool.</p>
<p>The new consensus rule will enforce that the transaction will not be considered valid if included in block of height greater than N, and blocks that include expired transactions will not be considered valid.</p>
<h1 id="specification">Specification</h1>
<p>Transactions will have a new field, <code>nExpiryHeight</code>, which will set the block height after which transactions will be removed from the mempool if they have not been mined.</p>
<p>The data type for <code>nExpiryHeight</code> will be <code>uint32_t</code>. If used in combination with <code>nLockTime</code>, both <code>nLockTime</code> and <code>nExpiryHeight</code> must be block heights. <code>nExpiryHeight</code> will never be a UNIX timestamp, unlike <code>nLockTime</code> values, and thus the maximum expiry height will be 499999999.</p>
<p>For the example below, the last block that the transaction below could possibly be included in is 3539. After that, it will be removed from the mempool.</p>
<p><code>` &quot;txid&quot;: &quot;17561b98cc77cd5a984bb959203e073b5f33cf14cbce90eb32b95ae2c796723f&quot;, &quot;version&quot;: 3, &quot;locktime&quot;: 2089, &quot;expiryheight&quot;: 3539,</code>`</p>
<p>Default: 20 blocks, or about 1 hour assuming 2.5 minute block times. A configuration option can be used to set the user's default. Minimum: No minimum Maximum: 499999999, about 380 years No limit: To set no limit on transactions (so that they do not expire), <code>nExpiryHeight</code> should be set to 0. Coinbase: <code>nExpiryHeight</code> on coinbase transactions is ignored, and is set to 0 by convention.</p>
<p>Every time a transaction expires and should be removed from the mempool, so should all of its dependent transactions.</p>
<h2 id="wallet-behavior-and-ui">Wallet behavior and UI</h2>
<p>With the addition of this feature, zero-confirmation transactions with an expiration block height set will have even less guarantee of inclusion. This means that UIs and services must never rely on zero-confirmation transactions in Zcash.</p>
<p>Wallet should notify the user of expired transactions that must be re-sent.</p>
<h2 id="rpc">RPC</h2>
<p>To make changes to the sendtoaddress and z_sendmany commands backwards compatible for future changes, keyword arguments should be accepted by the RPC interface.</p>
<p>For Overwinter, tx expiry will be set to a default that can be overridden by a flag txexpirydelta set in the config file.</p>
<p>-txexpirydelta= set the number of blocks after which a transaction that has not been mined will become invalid</p>
<p>To view: listtransactions has a new filter attribute, showing expired transactions only: listtransactions &quot;*&quot; 10 0 &quot;expired&quot;</p>
<p>WalletTxToJSON shows a boolean expired true/false.</p>
<h2 id="config">Config</h2>
<p>The default will be user-configurable with the option txexpirydelta.</p>
<p>--txexpirydelta=100</p>
<h2 id="deployment">Deployment</h2>
<p>This feature will be deployed with Overwinter. The activation blockheight proposal is in<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>.</p>
<h1 id="reference-implementation">Reference Implementation</h1>
<p><a href="https://github.com/zcash/zcash/pull/2874" class="uri">https://github.com/zcash/zcash/pull/2874</a></p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref1" class="footnote-back"></a></p></li>
</ol>
</section>
License: MIT</pre>
<section id="abstract">
<h2>Abstract</h2>
<p>This is a Standards ZIP describing a new consensus rule to set an expiration time after which a transaction cannot be mined. If it is not mined within that time, the transaction will be removed from nodes' mempools.</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>Transactions that have insufficient fees are often not mined. This indeterminism is a source of confusion for users and wallets. Allowing a transaction to set a block height after which it cannot be mined would provide certainty around how long a transaction has to confirm before it is rejected by the network and must be re-sent.</p>
<p>Advantages include optimizing mempool performance by removing transactions that will not be mined, and potentially simplifying bidirectional payment channels by reducing the need to store and compress revocations for past states, since transactions not committed to the chain could expire and become invalid after a period of time.</p>
<p>If the expiry is at block height N, then the transaction must be included in block N or earlier. Block N+1 will be too late, and the transaction will be removed from the mempool.</p>
<p>The new consensus rule will enforce that the transaction will not be considered valid if included in block of height greater than N, and blocks that include expired transactions will not be considered valid.</p>
</section>
<section id="specification">
<h2>Specification</h2>
<p>Transactions will have a new field, <code>nExpiryHeight</code>, which will set the block height after which transactions will be removed from the mempool if they have not been mined.</p>
<p>The data type for <code>nExpiryHeight</code> will be <code>uint32_t</code>. If used in combination with <code>nLockTime</code>, both <code>nLockTime</code> and <code>nExpiryHeight</code> must be block heights. <code>nExpiryHeight</code> will never be a UNIX timestamp, unlike <code>nLockTime</code> values, and thus the maximum expiry height will be 499999999.</p>
<p>For the example below, the last block that the transaction below could possibly be included in is 3539. After that, it will be removed from the mempool.</p>
<pre>"txid": "17561b98cc77cd5a984bb959203e073b5f33cf14cbce90eb32b95ae2c796723f",
"version": 3,
"locktime": 2089,
"expiryheight": 3539,</pre>
<p>Default: 20 blocks, or about 1 hour assuming 2.5 minute block times. A configuration option can be used to set the user's default. Minimum: No minimum Maximum: 499999999, about 380 years No limit: To set no limit on transactions (so that they do not expire), <code>nExpiryHeight</code> should be set to 0. Coinbase: <code>nExpiryHeight</code> on coinbase transactions is ignored, and is set to 0 by convention.</p>
<p>Every time a transaction expires and should be removed from the mempool, so should all of its dependent transactions.</p>
<section id="wallet-behavior-and-ui">
<h3>Wallet behavior and UI</h3>
<p>With the addition of this feature, zero-confirmation transactions with an expiration block height set will have even less guarantee of inclusion. This means that UIs and services must never rely on zero-confirmation transactions in Zcash.</p>
<p>Wallet should notify the user of expired transactions that must be re-sent.</p>
</section>
<section id="rpc">
<h3>RPC</h3>
<p>To make changes to the sendtoaddress and z_sendmany commands backwards compatible for future changes, keyword arguments should be accepted by the RPC interface.</p>
<p>For Overwinter, tx expiry will be set to a default that can be overridden by a flag <cite>txexpirydelta</cite> set in the config file.</p>
<p>-txexpirydelta= set the number of blocks after which a transaction that has not been mined will become invalid</p>
<p>To view: <cite>listtransactions</cite> has a new filter attribute, showing expired transactions only:</p>
<pre>listtransactions "*" 10 0 "expired"</pre>
<p>WalletTxToJSON shows a boolean expired true/false.</p>
</section>
<section id="config">
<h3>Config</h3>
<p>The default will be user-configurable with the option <cite>txexpirydelta</cite>.</p>
<p><cite>--txexpirydelta=100</cite></p>
</section>
<section id="deployment">
<h3>Deployment</h3>
<p>This feature will be deployed with Overwinter. The activation blockheight proposal is in <a href="#zip-0201" id="id1" class="footnote_reference">1</a>.</p>
</section>
</section>
<section id="reference-implementation">
<h2>Reference Implementation</h2>
<p><a href="https://github.com/zcash/zcash/pull/2874">https://github.com/zcash/zcash/pull/2874</a></p>
</section>
<section id="references">
<h2>References</h2>
<table id="zip-0201" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,94 +1,127 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 205: Deployment of the Sapling Network Upgrade</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 205: Deployment of the Sapling Network Upgrade</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 205
<section>
<pre>ZIP: 205
Title: Deployment of the Sapling Network Upgrade
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Credits: Simon Liu &lt;simon@bitcartel.com&gt;
Status: Final
Category: Consensus
Created: 2018-10-08
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;SHOULD&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The terms &quot;branch&quot; and &quot;network upgrade&quot; in this document are to be interpreted as described in ZIP 200.<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Sapling</dt>
<dd><p>Code-name for the second Zcash network upgrade, also known as Network Upgrade 1.</p>
</dd>
</dl>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines the deployment of the Sapling network upgrade. In addition, it describes a hard fork that occurred on testnet to allow &quot;minimum-difficulty&quot; blocks.</p>
<h1 id="specification">Specification</h1>
<h2 id="sapling-deployment">Sapling deployment</h2>
<p>The primary sources of information about Sapling consensus protocol changes are:</p>
<ul>
<li>The Zcash Protocol Specification<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>.</li>
<li>Transaction Signature Verification for Sapling<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a>.</li>
<li>Network Upgrade Activation Mechanism<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>.</li>
</ul>
<p>The network handshake and peer management mechanisms defined in<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a> also apply to this upgrade.</p>
<p>The following network upgrade constants<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a> are defined for the Sapling upgrade:</p>
<dl>
<dt>BRANCH_ID</dt>
<dd><p><code>0x76b809bb</code></p>
</dd>
<dt>ACTIVATION_HEIGHT (Sapling)</dt>
<dd><p>Testnet: 280000</p>
<p>Mainnet: 419200</p>
</dd>
</dl>
<p>On testnet, Sapling had activated prior to this height, but that branch was rolled back. A subsequent hard fork occurred on testnet, changing the difficulty algorithm to accept &quot;minimum-difficulty&quot; blocks under certain conditions starting at block height 299188.</p>
<p>On both mainnet and testnet, Sapling-compatible nodes MUST advertise protocol version 170007 or later. The minimum peer protocol version that Sapling-compatible nodes will connect to, remains 170002.</p>
<p>Pre-Sapling nodes are defined as nodes advertising a protocol version less than 170007.</p>
<p>Approximately three days (defined in terms of block height) before the Sapling activation height, Sapling-compatible nodes will change the behaviour of their peer connection logic in order to prefer pre-Sapling peers for eviction from the set of peer connections.</p>
<blockquote>
<p>/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). <em>/ static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24</em> 24 * 3;</p>
</blockquote>
<p>The implementation is similar to that for Overwinter which was described in <a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>.</p>
<p>Once Sapling activates on testnet or mainnet, Sapling nodes should take steps to:</p>
<ul>
<li>reject new connections from pre-Sapling nodes;</li>
<li>disconnect any existing connections to pre-Sapling nodes.</li>
</ul>
<h2 id="change-to-difficulty-adjustment-on-testnet">Change to difficulty adjustment on testnet</h2>
<p>Section 7.6.3 of<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a> describes the algorithm used to adjust the difficulty of a block (defined in terms of a &quot;target threshold&quot;) based on the <code>nTime</code> and <code>nBits</code> fields of preceding blocks.</p>
<p>This algorithm changed on testnet, starting from block 299188, to allow &quot;minimum-difficulty&quot; blocks. If the block time of a block from this height onward is at least 15 minutes after that of the preceding block, then the block is a minimum-difficulty block, and its target threshold is set to the value of PoWLimit for testnet (see<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a> section 5.3). However, its <code>nBits</code> field is still computed according to the original difficulty adjustment algorithm.</p>
<p>This does not affect how the minimum-difficulty block is treated for subsequent difficulty adjustments. In particular, only the <code>nBits</code> field computed by the original algorithm is used for the purpose of computing the MeanTarget values from which subsequent difficulty changes are calculated.</p>
<p>This change does not affect mainnet.</p>
<h1 id="backward-compatibility">Backward compatibility</h1>
<p>Prior to the network upgrade activating, Sapling and pre-Sapling nodes are compatible and can connect to each other. However, Sapling nodes will have a preference for connecting to other Sapling nodes, so pre-Sapling nodes will gradually be disconnected in the run up to activation.</p>
<p>Once the network upgrades, even though pre-Sapling nodes can still accept the numerically larger protocol version used by Sapling as being valid, Sapling nodes will always disconnect peers using lower protocol versions.</p>
<h1 id="support-in-zcashd">Support in zcashd</h1>
<p>Support for Sapling consensus rules was implemented in zcashd version 2.0.0. The majority of support for RPC calls and persistence of Sapling z-addresses was implemented in version 2.0.1. Both of these versions advertise protocol version 170007.</p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-37 [Overwinter+Sapling]</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zips/blob/master/zip-0243.rst">ZIP 243: Transaction Signature Verification for Sapling</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref6" class="footnote-back"></a></p></li>
<li id="fn7"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref7" class="footnote-back"></a></p></li>
<li id="fn8"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref8" class="footnote-back"></a></p></li>
<li id="fn9"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-37 [Overwinter+Sapling]</a><a href="#fnref9" class="footnote-back"></a></p></li>
<li id="fn10"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-37 [Overwinter+Sapling]</a><a href="#fnref10" class="footnote-back"></a></p></li>
</ol>
</section>
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">2</a></p>
<p>The terms "branch" and "network upgrade" in this document are to be interpreted as described in ZIP 200. <a href="#zip-0200" id="id2" class="footnote_reference">3</a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Sapling</dt>
<dd>Code-name for the second Zcash network upgrade, also known as Network Upgrade 1.</dd>
</dl>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal defines the deployment of the Sapling network upgrade. In addition, it describes a hard fork that occurred on testnet to allow "minimum-difficulty" blocks.</p>
</section>
<section id="specification">
<h2>Specification</h2>
<section id="sapling-deployment">
<h3>Sapling deployment</h3>
<p>The primary sources of information about Sapling consensus protocol changes are:</p>
<ul>
<li>The Zcash Protocol Specification <a href="#protocol" id="id3" class="footnote_reference">1</a>.</li>
<li>Transaction Signature Verification for Sapling <a href="#zip-0243" id="id4" class="footnote_reference">5</a>.</li>
<li>Network Upgrade Activation Mechanism <a href="#zip-0200" id="id5" class="footnote_reference">3</a>.</li>
</ul>
<p>The network handshake and peer management mechanisms defined in <a href="#zip-0201" id="id6" class="footnote_reference">4</a> also apply to this upgrade.</p>
<p>The following network upgrade constants <a href="#zip-0200" id="id7" class="footnote_reference">3</a> are defined for the Sapling upgrade:</p>
<dl>
<dt>BRANCH_ID</dt>
<dd><code>0x76b809bb</code></dd>
<dt>ACTIVATION_HEIGHT (Sapling)</dt>
<dd>
<p>Testnet: 280000</p>
<p>Mainnet: 419200</p>
</dd>
</dl>
<p>On testnet, Sapling had activated prior to this height, but that branch was rolled back. A subsequent hard fork occurred on testnet, changing the difficulty algorithm to accept "minimum-difficulty" blocks under certain conditions starting at block height 299188.</p>
<p>On both mainnet and testnet, Sapling-compatible nodes MUST advertise protocol version 170007 or later. The minimum peer protocol version that Sapling-compatible nodes will connect to, remains 170002.</p>
<p>Pre-Sapling nodes are defined as nodes advertising a protocol version less than 170007.</p>
<p>Approximately three days (defined in terms of block height) before the Sapling activation height, Sapling-compatible nodes will change the behaviour of their peer connection logic in order to prefer pre-Sapling peers for eviction from the set of peer connections.</p>
<pre>/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;</pre>
<p>The implementation is similar to that for Overwinter which was described in <a href="#zip-0201" id="id8" class="footnote_reference">4</a>.</p>
<p>Once Sapling activates on testnet or mainnet, Sapling nodes should take steps to:</p>
<ul>
<li>reject new connections from pre-Sapling nodes;</li>
<li>disconnect any existing connections to pre-Sapling nodes.</li>
</ul>
</section>
<section id="change-to-difficulty-adjustment-on-testnet">
<h3>Change to difficulty adjustment on testnet</h3>
<p>Section 7.6.3 of <a href="#protocol" id="id9" class="footnote_reference">1</a> describes the algorithm used to adjust the difficulty of a block (defined in terms of a "target threshold") based on the <code>nTime</code> and <code>nBits</code> fields of preceding blocks.</p>
<p>This algorithm changed on testnet, starting from block 299188, to allow "minimum-difficulty" blocks. If the block time of a block from this height onward is at least 15 minutes after that of the preceding block, then the block is a minimum-difficulty block, and its target threshold is set to the value of PoWLimit for testnet (see <a href="#protocol" id="id10" class="footnote_reference">1</a> section 5.3). However, its <code>nBits</code> field is still computed according to the original difficulty adjustment algorithm.</p>
<p>This does not affect how the minimum-difficulty block is treated for subsequent difficulty adjustments. In particular, only the <code>nBits</code> field computed by the original algorithm is used for the purpose of computing the MeanTarget values from which subsequent difficulty changes are calculated.</p>
<p>This change does not affect mainnet.</p>
</section>
</section>
<section id="backward-compatibility">
<h2>Backward compatibility</h2>
<p>Prior to the network upgrade activating, Sapling and pre-Sapling nodes are compatible and can connect to each other. However, Sapling nodes will have a preference for connecting to other Sapling nodes, so pre-Sapling nodes will gradually be disconnected in the run up to activation.</p>
<p>Once the network upgrades, even though pre-Sapling nodes can still accept the numerically larger protocol version used by Sapling as being valid, Sapling nodes will always disconnect peers using lower protocol versions.</p>
</section>
<section id="support-in-zcashd">
<h2>Support in zcashd</h2>
<p>Support for Sapling consensus rules was implemented in zcashd version 2.0.0. The majority of support for RPC calls and persistence of Sapling z-addresses was implemented in version 2.0.1. Both of these versions advertise protocol version 170007.</p>
</section>
<section id="references">
<h2>References</h2>
<table id="protocol" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-37 [Overwinter+Sapling]</a></td>
</tr>
</tbody>
</table>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0200" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a></td>
</tr>
</tbody>
</table>
<table id="zip-0201" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a></td>
</tr>
</tbody>
</table>
<table id="zip-0243" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0243.rst">ZIP 243: Transaction Signature Verification for Sapling</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,93 +1,123 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 206: Deployment of the Blossom Network Upgrade</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 206: Deployment of the Blossom Network Upgrade</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 206
<section>
<pre>ZIP: 206
Title: Deployment of the Blossom Network Upgrade
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Credits: Simon Liu &lt;simon@bitcartel.com&gt;
Status: Draft
Category: Consensus
Created: 2019-07-29
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;SHOULD&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The term &quot;network upgrade&quot; in this document is to be interpreted as described in ZIP 200.<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Blossom</dt>
<dd><p>Code-name for the third Zcash network upgrade, also known as Network Upgrade 2.</p>
</dd>
<dt>Testnet</dt>
<dd><p>The Zcash test network, as defined in<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>.</p>
</dd>
<dt>Mainnet</dt>
<dd><p>The Zcash production network, as defined in<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a>.</p>
</dd>
</dl>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines the deployment of the Blossom network upgrade.</p>
<h1 id="specification">Specification</h1>
<h2 id="blossom-deployment">Blossom deployment</h2>
<p>The primary sources of information about Blossom consensus protocol changes are:</p>
<ul>
<li>The Zcash Protocol Specification<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>.</li>
<li>Shorter Block Target Spacing<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a>.</li>
<li>Network Upgrade Activation Mechanism<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>.</li>
</ul>
<p>The network handshake and peer management mechanisms defined in<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a> also apply to this upgrade.</p>
<p>The following network upgrade constants<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a> are defined for the Blossom upgrade:</p>
<dl>
<dt>BRANCH_ID</dt>
<dd><p><code>0xXXXXXXXX</code></p>
</dd>
<dt>ACTIVATION_HEIGHT (Blossom)</dt>
<dd><p>Testnet: XXXXXX</p>
<p>Mainnet: XXXXXX</p>
</dd>
</dl>
<p>Nodes compatible with Blossom activation on testnet MUST advertise protocol version 170008 or later. Nodes compatible with Blossom activation on mainnet MUST advertise protocol version 170009 or later. The minimum peer protocol version that Blossom-compatible nodes will connect to will be 170007.</p>
<p>Pre-Blossom testnet nodes are defined as nodes on testnet advertising a protocol version less than 170008. Pre-Blossom mainnet nodes are defined as nodes on mainnet advertising a protocol version less than 170009.</p>
<p>For each network (testnet and mainnet), approximately three days (defined in terms of block height) before the corresponding Blossom activation height, nodes compatible with Blossom activation on that network will change the behaviour of their peer connection logic in order to prefer pre-Blossom peers on that network for eviction from the set of peer connections:</p>
<pre><code>/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;</code></pre>
<p>The implementation is similar to that for Overwinter which was described in <a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>.</p>
<p>Once Blossom activates on testnet or mainnet, Blossom nodes should take steps to:</p>
<ul>
<li>reject new connections from pre-Blossom nodes on that network;</li>
<li>disconnect any existing connections to pre-Blossom nodes on that network.</li>
</ul>
<h1 id="backward-compatibility">Backward compatibility</h1>
<p>Prior to the network upgrade activating on each network, Blossom and pre-Blossom nodes are compatible and can connect to each other. However, Blossom nodes will have a preference for connecting to other Blossom nodes, so pre-Blossom nodes will gradually be disconnected in the run up to activation.</p>
<p>Once the network upgrades, even though pre-Blossom nodes can still accept the numerically larger protocol version used by Blossom as being valid, Blossom nodes will always disconnect peers using lower protocol versions.</p>
<h1 id="support-in-zcashd">Support in zcashd</h1>
<p>Support for Blossom on testnet will be implemented in <code>zcashd</code> version 2.0.7, which will advertise protocol version 170008. Support for Blossom on mainnet will be implemented in <code>zcashd</code> version 2.1.0, which will advertise protocol version 170009.</p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2019.0.4 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2019.0.4 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2019.0.4 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><p><a href="https://github.com/zcash/zips/blob/master/zip-0208.rst">ZIP 208: Shorter Block Target Spacing</a><a href="#fnref6" class="footnote-back"></a></p></li>
<li id="fn7"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref7" class="footnote-back"></a></p></li>
<li id="fn8"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref8" class="footnote-back"></a></p></li>
<li id="fn9"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref9" class="footnote-back"></a></p></li>
<li id="fn10"><p><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a><a href="#fnref10" class="footnote-back"></a></p></li>
</ol>
</section>
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">2</a></p>
<p>The term "network upgrade" in this document is to be interpreted as described in ZIP 200. <a href="#zip-0200" id="id2" class="footnote_reference">3</a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Blossom</dt>
<dd>Code-name for the third Zcash network upgrade, also known as Network Upgrade 2.</dd>
<dt>Testnet</dt>
<dd>The Zcash test network, as defined in <a href="#protocol" id="id3" class="footnote_reference">1</a>.</dd>
<dt>Mainnet</dt>
<dd>The Zcash production network, as defined in <a href="#protocol" id="id4" class="footnote_reference">1</a>.</dd>
</dl>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal defines the deployment of the Blossom network upgrade.</p>
</section>
<section id="specification">
<h2>Specification</h2>
<section id="blossom-deployment">
<h3>Blossom deployment</h3>
<p>The primary sources of information about Blossom consensus protocol changes are:</p>
<ul>
<li>The Zcash Protocol Specification <a href="#protocol" id="id5" class="footnote_reference">1</a>.</li>
<li>Shorter Block Target Spacing <a href="#zip-0208" id="id6" class="footnote_reference">5</a>.</li>
<li>Network Upgrade Activation Mechanism <a href="#zip-0200" id="id7" class="footnote_reference">3</a>.</li>
</ul>
<p>The network handshake and peer management mechanisms defined in <a href="#zip-0201" id="id8" class="footnote_reference">4</a> also apply to this upgrade.</p>
<p>The following network upgrade constants <a href="#zip-0200" id="id9" class="footnote_reference">3</a> are defined for the Blossom upgrade:</p>
<dl>
<dt>BRANCH_ID</dt>
<dd><code>0xXXXXXXXX</code></dd>
<dt>ACTIVATION_HEIGHT (Blossom)</dt>
<dd>
<p>Testnet: XXXXXX</p>
<p>Mainnet: XXXXXX</p>
</dd>
</dl>
<p>Nodes compatible with Blossom activation on testnet MUST advertise protocol version 170008 or later. Nodes compatible with Blossom activation on mainnet MUST advertise protocol version 170009 or later. The minimum peer protocol version that Blossom-compatible nodes will connect to will be 170007.</p>
<p>Pre-Blossom testnet nodes are defined as nodes on testnet advertising a protocol version less than 170008. Pre-Blossom mainnet nodes are defined as nodes on mainnet advertising a protocol version less than 170009.</p>
<p>For each network (testnet and mainnet), approximately three days (defined in terms of block height) before the corresponding Blossom activation height, nodes compatible with Blossom activation on that network will change the behaviour of their peer connection logic in order to prefer pre-Blossom peers on that network for eviction from the set of peer connections:</p>
<pre>/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */
static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;</pre>
<p>The implementation is similar to that for Overwinter which was described in <a href="#zip-0201" id="id10" class="footnote_reference">4</a>.</p>
<p>Once Blossom activates on testnet or mainnet, Blossom nodes should take steps to:</p>
<ul>
<li>reject new connections from pre-Blossom nodes on that network;</li>
<li>disconnect any existing connections to pre-Blossom nodes on that network.</li>
</ul>
</section>
</section>
<section id="backward-compatibility">
<h2>Backward compatibility</h2>
<p>Prior to the network upgrade activating on each network, Blossom and pre-Blossom nodes are compatible and can connect to each other. However, Blossom nodes will have a preference for connecting to other Blossom nodes, so pre-Blossom nodes will gradually be disconnected in the run up to activation.</p>
<p>Once the network upgrades, even though pre-Blossom nodes can still accept the numerically larger protocol version used by Blossom as being valid, Blossom nodes will always disconnect peers using lower protocol versions.</p>
</section>
<section id="support-in-zcashd">
<h2>Support in zcashd</h2>
<p>Support for Blossom on testnet will be implemented in <code>zcashd</code> version 2.0.7, which will advertise protocol version 170008. Support for Blossom on mainnet will be implemented in <code>zcashd</code> version 2.1.0, which will advertise protocol version 170009.</p>
</section>
<section id="references">
<h2>References</h2>
<table id="protocol" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2019.0.4 or later [Overwinter+Sapling+Blossom]</a></td>
</tr>
</tbody>
</table>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0200" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a></td>
</tr>
</tbody>
</table>
<table id="zip-0201" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0201.rst">ZIP 201: Network Peer Management for Overwinter</a></td>
</tr>
</tbody>
</table>
<table id="zip-0208" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0208.rst">ZIP 208: Shorter Block Target Spacing</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,12 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 208: Shorter Block Target Spacing</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 208: Shorter Block Target Spacing</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 208
<section>
<pre>ZIP: 208
Title: Shorter Block Target Spacing
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Original-Authors: Daira Hopwood &lt;daira@electriccoin.co&gt;
@ -21,137 +14,172 @@ Original-Authors: Daira Hopwood &lt;daira@electriccoin.co&gt;
Status: Implemented
Category: Consensus
Created: 2019-01-10
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The terms &quot;block chain&quot;, &quot;consensus rule change&quot;, &quot;branch&quot;, and &quot;network upgrade&quot; are to be interpreted as defined in<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>.</p>
<p>The term &quot;block target spacing&quot; means the time interval between blocks targeted by the difficulty adjustment algorithm in a given branch. It is normally measured in seconds. (This is also sometimes called the &quot;target block time&quot;, but &quot;block target spacing&quot; is the term used in<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>.)</p>
<h1 id="abstract">Abstract</h1>
<p>This proposal specifies a change in the block target spacing, to take effect in the Blossom network upgrade<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a>.</p>
<p>The emission schedule of mined ZEC will be approximately the same in terms of time, but this requires the emission per block to be adjusted to take account of the changed block target spacing.</p>
<h1 id="motivation">Motivation</h1>
<p>The motivations for decreasing the block target spacing are:</p>
<ul>
<li>Reduced latency for considering transactions to be sufficiently confirmed;</li>
<li>Greater throughput of transactions in unit time.</li>
</ul>
<p>The latter goal could alternatively be achieved by increasing the block size limit, but that would not also achieve the former goal.</p>
<p>Note that, for a given security requirement (in terms of the expected cost distribution of a rollback attack), the number of confirmations needed increases more slowly than the decrease in block time, and so, up to a point, decreasing the block target spacing can provide a better trade-off between latency and security. This argument assumes that the verification and propagation time for a block remain small compared to the block target spacing. See<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a> for further analysis in various attack models.</p>
<h1 id="specification">Specification</h1>
<p>The changes described in this section are to be made in<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a>, relative to the pre-Blossom specification in [#preblossom-protocol].</p>
<h2 id="consensus-changes">Consensus changes</h2>
<p>Throughout the specification, rename HalvingInterval to PreBlossomHalvingInterval, and rename PoWTargetSpacing to PreBlossomTargetSpacing. These constants retain their values from<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a> of 840000 (blocks) and 150 (seconds) respectively.</p>
<p>In section 2 (Notation), add BlossomActivationHeight and PostBlossomPoWTargetSpacing to the list of integer constants.</p>
<p>In section 5.3 (Constants), define PostBlossomPoWTargetSpacing := 75 seconds.</p>
<p>For a given network (production or test), define BlossomActivationHeight as the height at which Blossom activates on that network, as specified in<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>.</p>
<p>In section 7.6.3 (Difficulty adjustment), make the following changes:</p>
<p>Define IsBlossomActivated(<em>height</em>) to return true if <em>height</em> ≥ BlossomActivationHeight, otherwise false.</p>
<p>This specification assumes that BlossomActivationHeight ≥ SlowStartInterval.</p>
<p>Define:</p>
<ul>
<li>BlossomPoWTargetSpacingRatio := PreBlossomPoWTargetSpacing / PostBlossomPoWTargetSpacing</li>
<li>PostBlossomHalvingInterval := floor(PreBlossomHalvingInterval · BlossomPoWTargetSpacingRatio).</li>
</ul>
<p>In the same section, redefine PoWTargetSpacing as a function taking a <em>height</em> parameter, as follows:</p>
<ul>
<li>PoWTargetSpacing(<em>height</em>) :=
<ul>
<li>PreBlossomPoWTargetSpacing, if not IsBlossomActivated(<em>height</em>)</li>
<li>PostBlossomPoWTargetSpacing, otherwise.</li>
</ul></li>
</ul>
<p>Also redefine AveragingWindowTimespan, MinActualTimespan, MaxActualTimespan, ActualTimespanDamped, ActualTimespanBounded, and Threshold as follows:</p>
<ul>
<li>add a <em>height</em> parameter to each of these functions that does not already have one;</li>
<li>ensure that each reference to any of these values, or to PoWTargetSpacing, are replaced with a function call passing the <em>height</em> parameter.</li>
</ul>
<p>In<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a> section 7.7 (Calculation of Block Subsidy and Founders Reward), redefine the Halving and BlockSubsidy functions as follows:</p>
<ul>
<li>Halving(<em>height</em>) :=
<ul>
<li>floor((<em>height</em> - SlowStartShift) / PreBlossomHalvingInterval), if not IsBlossomActivated(<em>height</em>)</li>
<li>floor((BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (<em>height</em> - BlossomActivationHeight) / PostBlossomHalvingInterval), otherwise</li>
</ul></li>
<li>BlockSubsidy(<em>height</em>) :=
<ul>
<li>SlowStartRate · <em>height</em>, if <em>height</em> &lt; SlowStartInterval / 2</li>
<li>SlowStartRate · (<em>height</em> + 1), if SlowStartInterval / 2 ≤ <em>height</em> and <em>height</em> &lt; SlowStartInterval</li>
<li>floor(MaxBlockSubsidy / 2<sup>Halving(*height*)</sup>), if SlowStartInterval ≤ <em>height</em> and not IsBlossomActivated(<em>height</em>)</li>
<li>floor(MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio · 2<sup>Halving(*height*)</sup>)), otherwise</li>
</ul></li>
</ul>
<p>TODO: ideally, BlossomActivationHeight, PostBlossomHalvingInterval, and PostBlossomTargetSpacing should be chosen so that:</p>
<ul>
<li>(BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (<em>height</em> - BlossomActivationHeight) / PostBlossomHalvingInterval) is exactly 1 for some integer <em>height</em>.</li>
<li>MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio · 2<sup>Halving(*height*)</sup>) is an integer for the next few periods.</li>
</ul>
<p>In<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a> section 7.8 (Payment of Founders Reward), define:</p>
<ul>
<li>FounderAddressAdjustedHeight(<em>height</em>) :=
<ul>
<li><em>height</em>, if not IsBlossomActivated(<em>height</em>)</li>
<li>BlossomActivationHeight + floor((<em>height</em> - BlossomActivationHeight) / BlossomPoWTargetSpacingRatio), otherwise</li>
</ul></li>
</ul>
<p>and in the definition of FounderAddressIndex, replace the use of <em>height</em> with FounderAddressAdjustedHeight(<em>height</em>).</p>
<p>Also define:</p>
<ul>
<li>FoundersRewardLastBlockHeight := max({ <em>height</em> ⦂ N | Halving(<em>height</em>) &lt; 1 })</li>
</ul>
<p>Replace the first note in that section with:</p>
<ul>
<li>No Founders Reward is required to be paid for <em>height</em> &gt; FoundersRewardLastBlockHeight (i.e. after the first halving), or for <em>height</em> = 0 (i.e. the genesis block).</li>
</ul>
<p>and in the second note, replace SlowStartShift + PreBlossomHalvingInterval - 1 with FoundersRewardLastBlockHeight.</p>
<h2 id="effect-on-difficulty-adjustment">Effect on difficulty adjustment</h2>
<p>The difficulty adjustment parameters PoWAveragingWindow and PoWMedianBlockSpan refer to numbers of blocks, but do <em>not</em> change at Blossom activation. This is because the amount of damping/averaging required is expected to be roughly the same, in terms of the number of blocks, after the change in block target spacing.</p>
<p>The change in the effective value of PoWTargetSpacing will cause the block spacing to adjust to the new target, at the normal rate for a difficulty adjustment. The results of simulations are consistent with this expected behaviour.</p>
<p>Note that the change in AveragingWindowTimespan(height) takes effect immediately when calculating the target difficulty starting from the block at the Blossom activation height, even though the difficulty of the preceding PoWAveragingWindow blocks will have been adjusted using the pre-Blossom target spacing. Therefore it is likely that the difficulty adjustment for the first few blocks after activation will be limited by PoWMaxAdjustDown. This is not anticipated to cause any problem.</p>
<h3 id="minimum-difficulty-blocks-on-the-test-network">Minimum difficulty blocks on the test network</h3>
<p>On the test network from block height 299188 onward, the difficulty adjustment algorithm allows minimum-difficulty blocks, as described in<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>, when the block time exceeds a given threshold. This specification changes this threshold to be proportional to the block target spacing.</p>
<p>That is, if the block time of a block at height <em>height</em> ≥ 299188 is at least 6 · PoWTargetSpacing(<em>height</em>) seconds after that of the preceding block, then the block is a minimum-difficulty block, and its target threshold is set to the value of PoWLimit for testnet (see<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a> section 5.3).</p>
<p>As before, the <code>nBits</code> field of a minimum-difficulty block is still computed according to the original difficulty adjustment algorithm, and only this field is used for the purpose of computing the MeanTarget values from which subsequent difficulty changes are calculated.</p>
<h2 id="non-consensus-node-behaviour">Non-consensus node behaviour</h2>
<h3 id="end-of-service-halt">End-of-Service halt</h3>
<p>zcashd implements an &quot;End-of-Service halt&quot; behaviour that halts the node at a block height that corresponds approximately to a given time after release. This interval SHOULD be adjusted in releases where the End-of-Service halt time will follow Blossom activation.</p>
<h3 id="default-expiry-delta">Default expiry delta</h3>
<p>When not overridden by the -txexpirydelta option, zcashd RPC calls that create transactions use a default value for the number of blocks after which a transaction will expire. The default in recent versions of zcashd is 20 blocks, which at the pre-Blossom block target spacing corresponds to roughly 50 minutes.</p>
<p>This default SHOULD change to BlossomPoWTargetSpacingRatio · 20 blocks after Blossom activation, to maintain the approximate expiry time of 50 minutes.</p>
<p>If the -txexpirydelta option is set, then the set value SHOULD be used both before and after Blossom activation.</p>
<h3 id="fingerprinting-mitigation">Fingerprinting mitigation</h3>
<p>A &quot;fingerprinting attack&quot; is a network analysis technique in which nodes are identified across network sessions, for example using information about which blocks they request or send.</p>
<p><code>zcashd</code> inherits from Bitcoin Core the following behaviour, described in a comment in <code>main.cpp</code>, intended as a fingerprinting mitigation:</p>
<pre><code>// To prevent fingerprinting attacks, only send blocks outside of the active
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "SHOULD", "SHOULD NOT", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">3</a></p>
<p>The terms "block chain", "consensus rule change", "branch", and "network upgrade" are to be interpreted as defined in <a href="#zip-0200" id="id2" class="footnote_reference">4</a>.</p>
<p>The term "block target spacing" means the time interval between blocks targeted by the difficulty adjustment algorithm in a given branch. It is normally measured in seconds. (This is also sometimes called the "target block time", but "block target spacing" is the term used in <a href="#latest-protocol" id="id3" class="footnote_reference">1</a>.)</p>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal specifies a change in the block target spacing, to take effect in the Blossom network upgrade <a href="#zip-0206" id="id4" class="footnote_reference">6</a>.</p>
<p>The emission schedule of mined ZEC will be approximately the same in terms of time, but this requires the emission per block to be adjusted to take account of the changed block target spacing.</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>The motivations for decreasing the block target spacing are:</p>
<ul>
<li>Reduced latency for considering transactions to be sufficiently confirmed;</li>
<li>Greater throughput of transactions in unit time.</li>
</ul>
<p>The latter goal could alternatively be achieved by increasing the block size limit, but that would not also achieve the former goal.</p>
<p>Note that, for a given security requirement (in terms of the expected cost distribution of a rollback attack), the number of confirmations needed increases more slowly than the decrease in block time, and so, up to a point, decreasing the block target spacing can provide a better trade-off between latency and security. This argument assumes that the verification and propagation time for a block remain small compared to the block target spacing. See <a href="#slowfastblocks" id="id5" class="footnote_reference">7</a> for further analysis in various attack models.</p>
</section>
<section id="specification">
<h2>Specification</h2>
<p>The changes described in this section are to be made in <a href="#latest-protocol" id="id6" class="footnote_reference">1</a>, relative to the pre-Blossom specification in [#preblossom-protocol].</p>
<section id="consensus-changes">
<h3>Consensus changes</h3>
<p>Throughout the specification, rename HalvingInterval to PreBlossomHalvingInterval, and rename PoWTargetSpacing to PreBlossomTargetSpacing. These constants retain their values from <a href="#preblossom-protocol" id="id7" class="footnote_reference">2</a> of 840000 (blocks) and 150 (seconds) respectively.</p>
<p>In section 2 (Notation), add BlossomActivationHeight and PostBlossomPoWTargetSpacing to the list of integer constants.</p>
<p>In section 5.3 (Constants), define PostBlossomPoWTargetSpacing := 75 seconds.</p>
<p>For a given network (production or test), define BlossomActivationHeight as the height at which Blossom activates on that network, as specified in <a href="#zip-0206" id="id8" class="footnote_reference">6</a>.</p>
<p>In section 7.6.3 (Difficulty adjustment), make the following changes:</p>
<p>Define IsBlossomActivated(<em>height</em>) to return true if <em>height</em> ≥ BlossomActivationHeight, otherwise false.</p>
<p>This specification assumes that BlossomActivationHeight ≥ SlowStartInterval.</p>
<p>Define:</p>
<ul>
<li>BlossomPoWTargetSpacingRatio := PreBlossomPoWTargetSpacing / PostBlossomPoWTargetSpacing</li>
<li>PostBlossomHalvingInterval := floor(PreBlossomHalvingInterval · BlossomPoWTargetSpacingRatio).</li>
</ul>
<p>In the same section, redefine PoWTargetSpacing as a function taking a <em>height</em> parameter, as follows:</p>
<ul>
<li>PoWTargetSpacing(<em>height</em>) :=
<ul>
<li>PreBlossomPoWTargetSpacing, if not IsBlossomActivated(<em>height</em>)</li>
<li>PostBlossomPoWTargetSpacing, otherwise.</li>
</ul>
</li>
</ul>
<p>Also redefine AveragingWindowTimespan, MinActualTimespan, MaxActualTimespan, ActualTimespanDamped, ActualTimespanBounded, and Threshold as follows:</p>
<ul>
<li>add a <em>height</em> parameter to each of these functions that does not already have one;</li>
<li>ensure that each reference to any of these values, or to PoWTargetSpacing, are replaced with a function call passing the <em>height</em> parameter.</li>
</ul>
<p>In <a href="#latest-protocol" id="id9" class="footnote_reference">1</a> section 7.7 (Calculation of Block Subsidy and Founders Reward), redefine the Halving and BlockSubsidy functions as follows:</p>
<ul>
<li>Halving(<em>height</em>) :=
<ul>
<li>floor((<em>height</em> - SlowStartShift) / PreBlossomHalvingInterval), if not IsBlossomActivated(<em>height</em>)</li>
<li>floor((BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (<em>height</em> - BlossomActivationHeight) / PostBlossomHalvingInterval), otherwise</li>
</ul>
</li>
<li>BlockSubsidy(<em>height</em>) :=
<ul>
<li>SlowStartRate · <em>height</em>, if <em>height</em> &lt; SlowStartInterval / 2</li>
<li>SlowStartRate · (<em>height</em> + 1), if SlowStartInterval / 2 ≤ <em>height</em> and <em>height</em> &lt; SlowStartInterval</li>
<li>floor(MaxBlockSubsidy / 2<sup>Halving(*height*)</sup>), if SlowStartInterval ≤ <em>height</em> and not IsBlossomActivated(<em>height</em>)</li>
<li>floor(MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio · 2<sup>Halving(*height*)</sup>)), otherwise</li>
</ul>
</li>
</ul>
<p>TODO: ideally, BlossomActivationHeight, PostBlossomHalvingInterval, and PostBlossomTargetSpacing should be chosen so that:</p>
<ul>
<li>(BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (<em>height</em> - BlossomActivationHeight) / PostBlossomHalvingInterval) is exactly 1 for some integer <em>height</em>.</li>
<li>MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio · 2<sup>Halving(*height*)</sup>) is an integer for the next few periods.</li>
</ul>
<p>In <a href="#latest-protocol" id="id10" class="footnote_reference">1</a> section 7.8 (Payment of Founders Reward), define:</p>
<ul>
<li>FounderAddressAdjustedHeight(<em>height</em>) :=
<ul>
<li><em>height</em>, if not IsBlossomActivated(<em>height</em>)</li>
<li>BlossomActivationHeight + floor((<em>height</em> - BlossomActivationHeight) / BlossomPoWTargetSpacingRatio), otherwise</li>
</ul>
</li>
</ul>
<p>and in the definition of FounderAddressIndex, replace the use of <em>height</em> with FounderAddressAdjustedHeight(<em>height</em>).</p>
<p>Also define:</p>
<ul>
<li>FoundersRewardLastBlockHeight := max({ <em>height</em> ⦂ N | Halving(<em>height</em>) &lt; 1 })</li>
</ul>
<p>Replace the first note in that section with:</p>
<ul>
<li>No Founders Reward is required to be paid for <em>height</em> &gt; FoundersRewardLastBlockHeight (i.e. after the first halving), or for <em>height</em> = 0 (i.e. the genesis block).</li>
</ul>
<p>and in the second note, replace SlowStartShift + PreBlossomHalvingInterval - 1 with FoundersRewardLastBlockHeight.</p>
</section>
<section id="effect-on-difficulty-adjustment">
<h3>Effect on difficulty adjustment</h3>
<p>The difficulty adjustment parameters PoWAveragingWindow and PoWMedianBlockSpan refer to numbers of blocks, but do <em>not</em> change at Blossom activation. This is because the amount of damping/averaging required is expected to be roughly the same, in terms of the number of blocks, after the change in block target spacing.</p>
<p>The change in the effective value of PoWTargetSpacing will cause the block spacing to adjust to the new target, at the normal rate for a difficulty adjustment. The results of simulations are consistent with this expected behaviour.</p>
<p>Note that the change in AveragingWindowTimespan(height) takes effect immediately when calculating the target difficulty starting from the block at the Blossom activation height, even though the difficulty of the preceding PoWAveragingWindow blocks will have been adjusted using the pre-Blossom target spacing. Therefore it is likely that the difficulty adjustment for the first few blocks after activation will be limited by PoWMaxAdjustDown. This is not anticipated to cause any problem.</p>
<section id="minimum-difficulty-blocks-on-the-test-network">
<h4>Minimum difficulty blocks on the test network</h4>
<p>On the test network from block height 299188 onward, the difficulty adjustment algorithm allows minimum-difficulty blocks, as described in <a href="#zip-0205" id="id11" class="footnote_reference">5</a>, when the block time exceeds a given threshold. This specification changes this threshold to be proportional to the block target spacing.</p>
<p>That is, if the block time of a block at height <em>height</em> ≥ 299188 is at least 6 · PoWTargetSpacing(<em>height</em>) seconds after that of the preceding block, then the block is a minimum-difficulty block, and its target threshold is set to the value of PoWLimit for testnet (see <a href="#latest-protocol" id="id12" class="footnote_reference">1</a> section 5.3).</p>
<p>As before, the <code>nBits</code> field of a minimum-difficulty block is still computed according to the original difficulty adjustment algorithm, and only this field is used for the purpose of computing the MeanTarget values from which subsequent difficulty changes are calculated.</p>
</section>
</section>
<section id="non-consensus-node-behaviour">
<h3>Non-consensus node behaviour</h3>
<section id="end-of-service-halt">
<h4>End-of-Service halt</h4>
<p><cite>zcashd</cite> implements an "End-of-Service halt" behaviour that halts the node at a block height that corresponds approximately to a given time after release. This interval SHOULD be adjusted in releases where the End-of-Service halt time will follow Blossom activation.</p>
</section>
<section id="default-expiry-delta">
<h4>Default expiry delta</h4>
<p>When not overridden by the <cite>-txexpirydelta</cite> option, <cite>zcashd</cite> RPC calls that create transactions use a default value for the number of blocks after which a transaction will expire. The default in recent versions of <cite>zcashd</cite> is 20 blocks, which at the pre-Blossom block target spacing corresponds to roughly 50 minutes.</p>
<p>This default SHOULD change to BlossomPoWTargetSpacingRatio · 20 blocks after Blossom activation, to maintain the approximate expiry time of 50 minutes.</p>
<p>If the <cite>-txexpirydelta</cite> option is set, then the set value SHOULD be used both before and after Blossom activation.</p>
</section>
<section id="fingerprinting-mitigation">
<h4>Fingerprinting mitigation</h4>
<p>A "fingerprinting attack" is a network analysis technique in which nodes are identified across network sessions, for example using information about which blocks they request or send.</p>
<p><code>zcashd</code> inherits from Bitcoin Core the following behaviour, described in a comment in <code>main.cpp</code>, intended as a fingerprinting mitigation:</p>
<pre>// To prevent fingerprinting attacks, only send blocks outside of the active
// chain if they are valid, and no more than a month older (both in time, and in
// best equivalent proof of work) than the best header chain we know about.</code></pre>
<p>We make no assertion about the significance of fingerprinting for Zcash, and (despite the word &quot;prevent&quot; in the above comment) no claim about the effectiveness of this mitigation.</p>
<p>In any case, to estimate the &quot;best equivalent proof of work&quot; of a given block chain (measured in units of time), we take the total work of the chain as defined in<a href="#fn13" class="footnote-ref" id="fnref13"><sup>13</sup></a> section 7.6.5, divide by the work of the block at the active tip, and multiply by the target block spacing of that block.</p>
<p>It is not a requirement of the Zcash protocol that this fingerprinting mitigation is used; however, if it is used, then it SHOULD use the target block spacing at the same block height that is used for the current work estimate.</p>
<h3 id="monitoring-for-quicker--or-slower-than-expected-blocks">Monitoring for quicker- or slower-than-expected blocks</h3>
<p>zcashd previously did this monitoring every 150 seconds; it is now done every 60 seconds.</p>
<h3 id="block-timeout">Block timeout</h3>
<p>The timeout for a requested block is calculated as the target block time, multiplied by 2 + (the number of queued validated headers)/2.</p>
<h3 id="latency-optimization-when-requesting-blocks">Latency optimization when requesting blocks</h3>
<p>When <code>zcashd</code> sees an announced block that chains from headers that it does not already have, it will first ask for the headers, and then the block itself. A latency optimization is performed only if the chain is &quot;nearly synced&quot;:</p>
<pre><code>// First request the headers preceding the announced block. In the normal fully-synced
// best equivalent proof of work) than the best header chain we know about.</pre>
<p>We make no assertion about the significance of fingerprinting for Zcash, and (despite the word "prevent" in the above comment) no claim about the effectiveness of this mitigation.</p>
<p>In any case, to estimate the "best equivalent proof of work" of a given block chain (measured in units of time), we take the total work of the chain as defined in <a href="#latest-protocol" id="id13" class="footnote_reference">1</a> section 7.6.5, divide by the work of the block at the active tip, and multiply by the target block spacing of that block.</p>
<p>It is not a requirement of the Zcash protocol that this fingerprinting mitigation is used; however, if it is used, then it SHOULD use the target block spacing at the same block height that is used for the current work estimate.</p>
</section>
<section id="monitoring-for-quicker-or-slower-than-expected-blocks">
<h4>Monitoring for quicker- or slower-than-expected blocks</h4>
<p><cite>zcashd</cite> previously did this monitoring every 150 seconds; it is now done every 60 seconds.</p>
</section>
<section id="block-timeout">
<h4>Block timeout</h4>
<p>The timeout for a requested block is calculated as the target block time, multiplied by 2 + (the number of queued validated headers)/2.</p>
</section>
<section id="latency-optimization-when-requesting-blocks">
<h4>Latency optimization when requesting blocks</h4>
<p>When <code>zcashd</code> sees an announced block that chains from headers that it does not already have, it will first ask for the headers, and then the block itself. A latency optimization is performed only if the chain is "nearly synced":</p>
<pre>// First request the headers preceding the announced block. In the normal fully-synced
// case where a new block is announced that succeeds the current tip (no reorganization),
// there are no such headers.
// Secondly, and only when we are close to being synced, we request the announced block directly,
// to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
// time the block arrives, the header chain leading up to it is already validated. Not
// doing this will result in the received block being rejected as an orphan in case it is
// not a direct successor.</code></pre>
<p>The heuristic for &quot;nearly synced&quot; is that the timestamp of the block at the active tip is no more than 20 block times before the current &quot;adjusted time&quot;. In <code>zcashd</code> this calculation uses the block target spacing as of the best known header. Around Blossom activation when the block target spacing changes, this could cause the heuristic to be based on the pre-Blossom block target spacing until the node has synced headers past the activation block, but this is not anticipated to cause any problem.</p>
<h3 id="response-to-getblocks-message-when-pruning">Response to getblocks message when pruning</h3>
<p>If pruning is enabled, when <code>zcashd</code> responds to an &quot;getblocks&quot; peer-to-peer message, it will only include blocks that it has on disk, and is likely to still have on disk an hour after responding to the message:</p>
<pre><code>// If pruning, don&#39;t inv blocks unless we have on disk and are likely to still have
// for some reasonable time window (1 hour) that block relay might require.</code></pre>
<p>For each block, when estimating whether it will still be on disk after an hour, we take MIN_BLOCKS_TO_KEEP = 288 blocks, minus approximately the number of blocks expected in one hour at the target block spacing as of that block. Around Blossom activation, this might underestimate the number of blocks in the next hour, but given the value of MIN_BLOCKS_TO_KEEP, this is not anticipated to cause any problem.</p>
<h3 id="estimation-of-fully-synced-chain-height">Estimation of fully synced chain height</h3>
<p><code>zcashd</code> uses the <code>EstimateNetHeight</code> function to estimate the approximate height of the fully synced chain, so that the progress of block download can be displayed to the node operator. This function has been rewritten, simplified, and changed to take account of cases where the time period that needs to be estimated crosses Blossom activation.</p>
<h3 id="other-block-related-constants">Other block-related constants</h3>
<p>The following constants, measured in number of blocks, were reviewed and a decision was made not to change them:</p>
<pre><code>/** The number of blocks within expiry height when a tx is considered to be expiring soon */
// not a direct successor.</pre>
<p>The heuristic for "nearly synced" is that the timestamp of the block at the active tip is no more than 20 block times before the current "adjusted time". In <code>zcashd</code> this calculation uses the block target spacing as of the best known header. Around Blossom activation when the block target spacing changes, this could cause the heuristic to be based on the pre-Blossom block target spacing until the node has synced headers past the activation block, but this is not anticipated to cause any problem.</p>
</section>
<section id="response-to-getblocks-message-when-pruning">
<h4>Response to getblocks message when pruning</h4>
<p>If pruning is enabled, when <code>zcashd</code> responds to an "getblocks" peer-to-peer message, it will only include blocks that it has on disk, and is likely to still have on disk an hour after responding to the message:</p>
<pre>// If pruning, don't inv blocks unless we have on disk and are likely to still have
// for some reasonable time window (1 hour) that block relay might require.</pre>
<p>For each block, when estimating whether it will still be on disk after an hour, we take MIN_BLOCKS_TO_KEEP = 288 blocks, minus approximately the number of blocks expected in one hour at the target block spacing as of that block. Around Blossom activation, this might underestimate the number of blocks in the next hour, but given the value of MIN_BLOCKS_TO_KEEP, this is not anticipated to cause any problem.</p>
</section>
<section id="estimation-of-fully-synced-chain-height">
<h4>Estimation of fully synced chain height</h4>
<p><code>zcashd</code> uses the <code>EstimateNetHeight</code> function to estimate the approximate height of the fully synced chain, so that the progress of block download can be displayed to the node operator. This function has been rewritten, simplified, and changed to take account of cases where the time period that needs to be estimated crosses Blossom activation.</p>
</section>
<section id="other-block-related-constants">
<h4>Other block-related constants</h4>
<p>The following constants, measured in number of blocks, were reviewed and a decision was made not to change them:</p>
<pre>/** The number of blocks within expiry height when a tx is considered to be expiring soon */
TX_EXPIRING_SOON_THRESHOLD = 3
/** Maximum reorg length we will accept before we shut down and alert the user. */
@ -165,32 +193,81 @@ static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16;
static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024;
/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */
static const unsigned int MIN_BLOCKS_TO_KEEP = 288;</code></pre>
<h1 id="deployment">Deployment</h1>
<p>This proposal will be deployed with the Blossom network upgrade.<a href="#fn14" class="footnote-ref" id="fnref14"><sup>14</sup></a></p>
<h1 id="backward-compatibility">Backward compatibility</h1>
<p>This proposal intentionally creates what is known as a &quot;bilateral consensus rule change&quot;. Use of this mechanism requires that all network participants upgrade their software to a compatible version within the upgrade window. Older software will treat post-upgrade blocks as invalid, and will follow any pre-upgrade branch that persists.</p>
<h1 id="reference-implementation">Reference Implementation</h1>
<p><a href="https://github.com/zcash/zcash/pull/4025" class="uri">https://github.com/zcash/zcash/pull/4025</a></p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/protocol/blossom.pdf">Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zips/blob/master/zip-0206.rst">ZIP 206: Deployment of the Blossom Network Upgrade</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p>On Slow and Fast Block Times &lt;<a href="https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/" class="uri">https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/</a>&gt;_<a href="#fnref5" class="footnote-back"></a></p></li>
<li id="fn6"><p><a href="https://github.com/zcash/zips/blob/master/protocol/blossom.pdf">Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref6" class="footnote-back"></a></p></li>
<li id="fn7"><p><a href="https://github.com/zcash/zips/blob/9515d73aac0aea3494f77bcd634e1e4fbd744b97/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-37 (exactly) [Overwinter+Sapling]</a><a href="#fnref7" class="footnote-back"></a></p></li>
<li id="fn8"><p><a href="https://github.com/zcash/zips/blob/master/zip-0206.rst">ZIP 206: Deployment of the Blossom Network Upgrade</a><a href="#fnref8" class="footnote-back"></a></p></li>
<li id="fn9"><p><a href="https://github.com/zcash/zips/blob/master/protocol/blossom.pdf">Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref9" class="footnote-back"></a></p></li>
<li id="fn10"><p><a href="https://github.com/zcash/zips/blob/master/protocol/blossom.pdf">Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref10" class="footnote-back"></a></p></li>
<li id="fn11"><p><a href="https://github.com/zcash/zips/blob/master/zip-0205.rst">ZIP 205: Deployment of the Sapling Network Upgrade</a><a href="#fnref11" class="footnote-back"></a></p></li>
<li id="fn12"><p><a href="https://github.com/zcash/zips/blob/master/protocol/blossom.pdf">Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref12" class="footnote-back"></a></p></li>
<li id="fn13"><p><a href="https://github.com/zcash/zips/blob/master/protocol/blossom.pdf">Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling+Blossom]</a><a href="#fnref13" class="footnote-back"></a></p></li>
<li id="fn14"><p><a href="https://github.com/zcash/zips/blob/master/zip-0206.rst">ZIP 206: Deployment of the Blossom Network Upgrade</a><a href="#fnref14" class="footnote-back"></a></p></li>
</ol>
</section>
static const unsigned int MIN_BLOCKS_TO_KEEP = 288;</pre>
</section>
</section>
</section>
<section id="deployment">
<h2>Deployment</h2>
<p>This proposal will be deployed with the Blossom network upgrade. <a href="#zip-0206" id="id14" class="footnote_reference">6</a></p>
</section>
<section id="backward-compatibility">
<h2>Backward compatibility</h2>
<p>This proposal intentionally creates what is known as a "bilateral consensus rule change". Use of this mechanism requires that all network participants upgrade their software to a compatible version within the upgrade window. Older software will treat post-upgrade blocks as invalid, and will follow any pre-upgrade branch that persists.</p>
</section>
<section id="reference-implementation">
<h2>Reference Implementation</h2>
<p><a href="https://github.com/zcash/zcash/pull/4025">https://github.com/zcash/zcash/pull/4025</a></p>
</section>
<section id="references">
<h2>References</h2>
<table id="latest-protocol" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/blossom.pdf">Zcash Protocol Specification, Version 2019.0.1 or later [Overwinter+Sapling+Blossom]</a></td>
</tr>
</tbody>
</table>
<table id="preblossom-protocol" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://github.com/zcash/zips/blob/9515d73aac0aea3494f77bcd634e1e4fbd744b97/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-37 (exactly) [Overwinter+Sapling]</a></td>
</tr>
</tbody>
</table>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0200" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Mechanism</a></td>
</tr>
</tbody>
</table>
<table id="zip-0205" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0205.rst">ZIP 205: Deployment of the Sapling Network Upgrade</a></td>
</tr>
</tbody>
</table>
<table id="zip-0206" class="footnote">
<tbody>
<tr>
<th>6</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0206.rst">ZIP 206: Deployment of the Blossom Network Upgrade</a></td>
</tr>
</tbody>
</table>
<table id="slowfastblocks" class="footnote">
<tbody>
<tr>
<th>7</th>
<td>On Slow and Fast Block Times &lt;<a href="https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/">https://blog.ethereum.org/2015/09/14/on-slow-and-fast-block-times/</a>&gt;_</td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,50 +1,68 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 209: Prohibit Negative Shielded Value Pool</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 209: Prohibit Negative Shielded Value Pool</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 209
<section>
<pre>ZIP: 209
Title: Prohibit Negative Shielded Value Pool
Owners: Sean Bowe &lt;sean@electriccoin.co&gt;
Status: Final
Category: Consensus
Created: 2019-02-25
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The term &quot;block chain&quot; and &quot;network upgrade&quot; are to be interpreted as defined in<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>.</p>
<p>The &quot;Sprout value pool balance&quot; for a given block chain, as implied by section 4.11 of the Zcash Protocol Specification<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>, is the sum of all <code>vpub_old</code> fields for transactions in the block chain, minus the sum of all <code>vpub_new</code> fields for transactions in the block chain.</p>
<p>The &quot;Sapling value pool balance&quot; for a given block chain, as implied by section 4.12 of Zcash Protocol Specification<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a>, is the negation of the sum of all <code>valueBalance</code> fields for transactions in the block chain.</p>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines how the consensus rules are altered such that blocks which produce negative shielded value pools are prohibited.</p>
<h1 id="motivation">Motivation</h1>
<p>It is possible for nodes to monitor the total value of notes that are shielded to, or unshielded from, each of the Sprout or Sapling value pools. If the total value that is unshielded exceeds the total value that was shielded for a given pool, a balance violation has occurred in the corresponding shielded transaction protocol.</p>
<p>It would be preferable for the network to reject blocks that result in the aforementioned balance violation. However, nodes do not currently react to such an event. Remediation may therefore require chain rollbacks and other disruption.</p>
<h1 id="specification">Specification</h1>
<p>If the &quot;Sprout value pool balance&quot; or &quot;Sapling value pool balance&quot; would become negative in the block chain created as a result of accepting a block, then all nodes MUST reject the block as invalid.</p>
<p>Nodes MAY relay transactions even if one or more of them cannot be mined due to the aforementioned restriction.</p>
<h1 id="deployment">Deployment</h1>
<p>This consensus rule is not deployed as part of a network upgrade as defined in ZIP-200<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a> and there is no mechanism by which the network will synchronize to enforce this rule. Rather, all nodes should begin enforcing this consensus rule upon acceptance of this proposal.</p>
<p>There is a risk that before all nodes on the network begin enforcing this consensus rule that block(s) will be produced that violate it, potentially leading to network fragmentation. This is considered sufficiently unlikely that the benefits of enforcing this consensus rule sooner are overwhelming.</p>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2019.0-beta-37 [Overwinter+Sapling]</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2019.0-beta-37 [Overwinter+Sapling]</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Mechanism</a><a href="#fnref5" class="footnote-back"></a></p></li>
</ol>
</section>
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "SHOULD", "SHOULD NOT", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">1</a></p>
<p>The term "block chain" and "network upgrade" are to be interpreted as defined in <a href="#zip-0200" id="id2" class="footnote_reference">3</a>.</p>
<p>The "Sprout value pool balance" for a given block chain, as implied by section 4.11 of the Zcash Protocol Specification <a href="#protocol" id="id3" class="footnote_reference">2</a>, is the sum of all <code>vpub_old</code> fields for transactions in the block chain, minus the sum of all <code>vpub_new</code> fields for transactions in the block chain.</p>
<p>The "Sapling value pool balance" for a given block chain, as implied by section 4.12 of Zcash Protocol Specification <a href="#protocol" id="id4" class="footnote_reference">2</a>, is the negation of the sum of all <code>valueBalance</code> fields for transactions in the block chain.</p>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal defines how the consensus rules are altered such that blocks which produce negative shielded value pools are prohibited.</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>It is possible for nodes to monitor the total value of notes that are shielded to, or unshielded from, each of the Sprout or Sapling value pools. If the total value that is unshielded exceeds the total value that was shielded for a given pool, a balance violation has occurred in the corresponding shielded transaction protocol.</p>
<p>It would be preferable for the network to reject blocks that result in the aforementioned balance violation. However, nodes do not currently react to such an event. Remediation may therefore require chain rollbacks and other disruption.</p>
</section>
<section id="specification">
<h2>Specification</h2>
<p>If the "Sprout value pool balance" or "Sapling value pool balance" would become negative in the block chain created as a result of accepting a block, then all nodes MUST reject the block as invalid.</p>
<p>Nodes MAY relay transactions even if one or more of them cannot be mined due to the aforementioned restriction.</p>
</section>
<section id="deployment">
<h2>Deployment</h2>
<p>This consensus rule is not deployed as part of a network upgrade as defined in ZIP-200 <a href="#zip-0200" id="id5" class="footnote_reference">3</a> and there is no mechanism by which the network will synchronize to enforce this rule. Rather, all nodes should begin enforcing this consensus rule upon acceptance of this proposal.</p>
<p>There is a risk that before all nodes on the network begin enforcing this consensus rule that block(s) will be produced that violate it, potentially leading to network fragmentation. This is considered sufficiently unlikely that the benefits of enforcing this consensus rule sooner are overwhelming.</p>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="protocol" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2019.0-beta-37 [Overwinter+Sapling]</a></td>
</tr>
</tbody>
</table>
<table id="zip-0200" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Mechanism</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,61 +1,93 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 210: Sapling Anchor Deduplication within Transactions</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 210: Sapling Anchor Deduplication within Transactions</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 210
<section>
<pre>ZIP: 210
Title: Sapling Anchor Deduplication within Transactions
Owners: Jack Grigg &lt;str4d@electriccoin.co&gt;
Status: Draft
Category: Consensus
Created: 2019-03-27
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot; and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The term &quot;network upgrade&quot; in this document is to be interpreted as described in ZIP 200 <a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>.</p>
<p>The term &quot;Sapling&quot; in this document is to be interpreted as described in ZIP 205 <a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>.</p>
<h1 id="abstract">Abstract</h1>
<p>This proposal defines a modification to the transaction format whereby a single Sapling anchor is used for all Sapling spends. This change removes a potential implementation fingerprint, and reduces the size of Sapling transactions within the block chain.</p>
<h1 id="motivation">Motivation</h1>
<p>The Sapling network upgrade<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> introduced new shielded inputs (spends) and outputs. Each spend proves the existence of the note being spent by including the anchor of a Merkle tree that contains the note's commitment, and proving in zero knowledge the existence of a path from the commitment to the anchor (a witness). Valid anchors correspond to the state of the Sapling commitment tree after each block in the chain.</p>
<p>The choice of anchor leaks information about the note being spent, namely that the note was created no later than the anchor's block height. This is an unavoidable outcome of the Zcash design, and the least information it is possible to leak about a note being spent. However, the Sapling v4 transaction format<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a> includes a separate anchor for each Sapling spend, and thus it is possible to leak additional information by using different anchors for different notes. The anchor selection choices could also be used as a fingerprint to identify transactions created by particular wallet implementations, reducing the privacy set.</p>
<p>Modifying the transaction format to have a single Sapling anchor field, instead of one field per Sapling spend, removes the ability (within the new transaction format version) to create transactions with this fingerprint. It also reduces the size of the transaction, costing 32 bytes per transaction instead of 32 bytes per spend.</p>
<h1 id="specification">Specification</h1>
<p>A new transaction format is defined, identical to the Sapling v4 transaction format except for two changes:</p>
<ul>
<li>The <code>anchor</code> field in <code>SpendDescription</code> is removed.</li>
<li>A new field <code>saplingAnchor</code> is placed between <code>vShieldedOutput</code> and <code>vJoinSplit</code>, if and only if <code>vShieldedSpend</code> is not empty.</li>
</ul>
<p>Consensus rules that previously applied to individual <code>anchor</code> entries MUST be applied to <code>saplingAnchor</code>.</p>
<p>TODO: If this is the only ZIP updating the transaction format in a NU, specify the full transaction format here. Otherwise, reference the new transaction format when specified.</p>
<p>Implementations that support older transaction formats MAY copy <code>saplingAnchor</code> into each spend's in-memory representation during parsing to reduce code duplication, and MUST ensure that these per-spend in-memory anchors are all identical prior to serialization.</p>
<h1 id="rationale">Rationale</h1>
<p>Placing the <code>saplingAnchor</code> field after <code>vShieldedOutput</code> means that it can be conditionally included (saving space when there are no Sapling spends), while ensuring that the transaction can still be parsed unambiguously.</p>
<p>Requiring all Sapling spends to use the same anchor removes a possible performance optimisation in certain classes of (particularly light) wallets, where witnesses for older notes are only updated periodically instead of every block. This optimisation is exactly the kind of behaviour that can be used as a fingerprint in the v4 transaction format, and that we are choosing to prevent with this proposal.</p>
<h1 id="security-and-privacy-considerations">Security and Privacy Considerations</h1>
<p>This proposal eliminates a possible avenue for distinguishing transactions based on the client implementation that created them.</p>
<h1 id="reference-implementation">Reference Implementation</h1>
<p>TBD</p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/zip-0205.rst">ZIP 205: Deployment of the Sapling Network Upgrade</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/zcash/zips/blob/master/zip-0205.rst">ZIP 205: Deployment of the Sapling Network Upgrade</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Section 7.1: Encoding of Transactions. Zcash Protocol Specification, Version 2019.0-beta-37 [Overwinter+Sapling]</a><a href="#fnref5" class="footnote-back"></a></p></li>
</ol>
</section>
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST" and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">1</a></p>
<p>The term "network upgrade" in this document is to be interpreted as described in ZIP 200 <a href="#zip-0200" id="id2" class="footnote_reference">2</a>.</p>
<p>The term "Sapling" in this document is to be interpreted as described in ZIP 205 <a href="#zip-0205" id="id3" class="footnote_reference">3</a>.</p>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal defines a modification to the transaction format whereby a single Sapling anchor is used for all Sapling spends. This change removes a potential implementation fingerprint, and reduces the size of Sapling transactions within the block chain.</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>The Sapling network upgrade <a href="#zip-0205" id="id4" class="footnote_reference">3</a> introduced new shielded inputs (spends) and outputs. Each spend proves the existence of the note being spent by including the anchor of a Merkle tree that contains the note's commitment, and proving in zero knowledge the existence of a path from the commitment to the anchor (a witness). Valid anchors correspond to the state of the Sapling commitment tree after each block in the chain.</p>
<p>The choice of anchor leaks information about the note being spent, namely that the note was created no later than the anchor's block height. This is an unavoidable outcome of the Zcash design, and the least information it is possible to leak about a note being spent. However, the Sapling v4 transaction format <a href="#v4-tx" id="id5" class="footnote_reference">4</a> includes a separate anchor for each Sapling spend, and thus it is possible to leak additional information by using different anchors for different notes. The anchor selection choices could also be used as a fingerprint to identify transactions created by particular wallet implementations, reducing the privacy set.</p>
<p>Modifying the transaction format to have a single Sapling anchor field, instead of one field per Sapling spend, removes the ability (within the new transaction format version) to create transactions with this fingerprint. It also reduces the size of the transaction, costing 32 bytes per transaction instead of 32 bytes per spend.</p>
</section>
<section id="specification">
<h2>Specification</h2>
<p>A new transaction format is defined, identical to the Sapling v4 transaction format except for two changes:</p>
<ul>
<li>The <code>anchor</code> field in <code>SpendDescription</code> is removed.</li>
<li>A new field <code>saplingAnchor</code> is placed between <code>vShieldedOutput</code> and <code>vJoinSplit</code>, if and only if <code>vShieldedSpend</code> is not empty.</li>
</ul>
<p>Consensus rules that previously applied to individual <code>anchor</code> entries MUST be applied to <code>saplingAnchor</code>.</p>
<p>TODO: If this is the only ZIP updating the transaction format in a NU, specify the full transaction format here. Otherwise, reference the new transaction format when specified.</p>
<p>Implementations that support older transaction formats MAY copy <code>saplingAnchor</code> into each spend's in-memory representation during parsing to reduce code duplication, and MUST ensure that these per-spend in-memory anchors are all identical prior to serialization.</p>
</section>
<section id="rationale">
<h2>Rationale</h2>
<p>Placing the <code>saplingAnchor</code> field after <code>vShieldedOutput</code> means that it can be conditionally included (saving space when there are no Sapling spends), while ensuring that the transaction can still be parsed unambiguously.</p>
<p>Requiring all Sapling spends to use the same anchor removes a possible performance optimisation in certain classes of (particularly light) wallets, where witnesses for older notes are only updated periodically instead of every block. This optimisation is exactly the kind of behaviour that can be used as a fingerprint in the v4 transaction format, and that we are choosing to prevent with this proposal.</p>
</section>
<section id="security-and-privacy-considerations">
<h2>Security and Privacy Considerations</h2>
<p>This proposal eliminates a possible avenue for distinguishing transactions based on the client implementation that created them.</p>
</section>
<section id="reference-implementation">
<h2>Reference Implementation</h2>
<p>TBD</p>
</section>
<section id="references">
<h2>References</h2>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0200" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0200.rst">ZIP 200: Network Upgrade Activation Mechanism</a></td>
</tr>
</tbody>
</table>
<table id="zip-0205" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0205.rst">ZIP 205: Deployment of the Sapling Network Upgrade</a></td>
</tr>
</tbody>
</table>
<table id="v4-tx" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Section 7.1: Encoding of Transactions. Zcash Protocol Specification, Version 2019.0-beta-37 [Overwinter+Sapling]</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,189 +1,285 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP 308: Sprout to Sapling Migration</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP 308: Sprout to Sapling Migration</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: 308
<section>
<pre>ZIP: 308
Title: Sprout to Sapling Migration
Owners: Daira Hopwood &lt;daira@electriccoin.co&gt;
Eirik Ogilvie-Wigley &lt;eirik@electriccoin.co&gt;
Status: Final
Category: RPC/Wallet
Created: 2018-11-27
License: MIT</code></pre>
<h1 id="terminology">Terminology</h1>
<p>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;SHOULD&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Sprout protocol</dt>
<dd><p>Code-name for the Zcash shielded protocol at launch.</p>
</dd>
<dt>Sapling protocol</dt>
<dd><p>Code-name for the Zcash shielded protocol added by the second Zcash network upgrade, also known as Network Upgrade 1.</p>
</dd>
</dl>
<h1 id="abstract">Abstract</h1>
<p>This proposal describes privacy-preserving procedures to migrate funds from Sprout to Sapling z-addresses; and supporting RPC operations to enable, disable, and monitor the migration process.</p>
<h1 id="motivation">Motivation</h1>
<p>Zcash Sapling<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a> introduces significant efficiency improvements relative to the previous iteration of the Zcash shielded protocol, Sprout. These improvements will pave the way for broad mobile, exchange and vendor adoption of shielded addresses.</p>
<p>Therefore, we anticipate that users will want to migrate all their shielded funds from Sprout to Sapling.</p>
<p>The Zcash consensus rules prohibit direct transfers from Sprout to Sapling z-addresses, unless the amount is revealed by sending it through the &quot;transparent value pool&quot;<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>. The primary motivation for this is to allow detection of any overall inflation of the Zcash monetary base, due to exploitation of possible vulnerabilities in the shielded protocols or their implementation, or a compromise of the Sprout multi-party computation. (It is not necessary for Sprout -&gt; Sapling transfers to go via a t-address.)</p>
<p>Since the exposure of the migrated amount potentially compromises the privacy of users, we wish to define a way to perform the migration that mitigates this privacy leak as far as possible. This can be done by hiding individual migration transactions among those of all users that are doing the migration at around the same time.</p>
<p>The security analysis of migration strategies is quite subtle; the more obvious potential strategies can leak a lot of information.</p>
<h1 id="requirements">Requirements</h1>
<p>Migration is performed &quot;in the background&quot; by a <code>zcashd</code> (or equivalent) node. It does not significantly interfere with concurrent usage of the node, other than possibly increasing the latency of some other shielded operations.</p>
<p>It is possible to enable or disable migration at any time.</p>
<p>All shielded funds in Sprout z-addresses will eventually be transferred to Sapling z-addresses, provided the node is working.</p>
<p>It should take a &quot;reasonable&quot; length of time to complete the transfer; less than a month for amounts up to 1000 ZEC.</p>
<p>The design should mitigate information leakage via timing information and transaction data, including</p>
<ul>
<li>linkage of particular z-addresses or users, and the amounts held;</li>
<li>information about the distribution of amounts of individual notes.</li>
</ul>
<p>The design and implementation is stateless, to the extent practical.</p>
<p>Visibility is provided for the wallet/node user into the progress of the migration.</p>
<p>There is sufficient information available to debug failed transactions that are part of the migration.</p>
<p>The design recovers from failed operations to the extent possible.</p>
<p>The total amount sent by each user is obscured, to the extent practical.</p>
<h1 id="non-requirements">Non-requirements</h1>
<p>There is no requirement or assumption of network layer anonymity. (Users may, but are not expected to, configure Tor.)</p>
<p>The migration procedure does not have to provably leak no information.</p>
<p>There is no need to preserve individual note values (i.e. notes can be consolidated).</p>
<p>Migration txns need only be hidden among themselves, rather than among all kinds of transaction.</p>
<p>A small amount (less than 0.01 ZEC) can be left unmigrated if this helps with privacy.</p>
<p>It is not required to support the case of single wallet being used by multiple users whose funds should be kept distinct.</p>
<h1 id="specification">Specification</h1>
<p>There are two main aspects to a strategy for selecting migration transactions:</p>
<ul>
<li>how many transactions are sent, and when;</li>
<li>the amount sent in each transaction.</li>
</ul>
<h2 id="transaction-schedule">Transaction schedule</h2>
<p>When migration is enabled, a node will send up to 5 transactions for inclusion in each block with height a multiple of 500 (that is, they are sent immediately after seeing a block with height 499, modulo 500). Up to the limit of 5, as many transactions are sent as are needed to migrate the remaining funds (possibly with a remainder less than 0.01 ZEC left unmigrated).</p>
<p>Nodes SHOULD NOT send migration transactions during initial block download, or if the timestamp of the triggering block (with height 499, modulo 500) is more than three hours in the past according to the node's adjusted local clock.</p>
<p>TODO: if we change the target block interval, 500 might need to be changed.</p>
<p>The migration transactions to be sent in a particular batch can take significant time to generate, and this time depends on the speed of the user's computer. If they were generated only after a block is seen at the target height minus 1, then this could leak information. Therefore, for target height N, implementations SHOULD start generating the transactions at around height N-5 (provided that block's timestamp is not more than three hours in the past). Each migration transaction SHOULD specify an anchor at height N-10 for each Sprout JoinSplit description.</p>
<p>Open questions:</p>
<ul>
<li>does this reliably give sufficient time to generate the transactions?</li>
<li>what happens to a batch if the anchor is invalidated -- should it be regenerated, or cancelled?</li>
</ul>
<h3 id="rationale-for-transaction-schedule">Rationale for transaction schedule</h3>
<p>Privacy is increased when the times at which to send transactions are coordinated between nodes. We choose to send a batch of transactions at each coordinated time. Sending multiple transactions in each batch ensures that:</p>
<ul>
<li>less information about balances is leaked;</li>
<li>it is easier to finish in a reasonable length of time.</li>
</ul>
<p>The choice of 500 blocks as the batch interval ensures that each batch occurs at a different time of day, which may help to mitigate problems with the availability of nodes being correlated with the local time-of-day.</p>
<p>Simulation shows that the migration process will typically complete reasonably quickly even if the amount to be migrated is large:</p>
<p>+-----------+--------------------------------------------+ | | Time in days to complete migration | | Amount +-----------------+--------+-----------------+ | | 10th-percentile | median | 90th-percentile | +===========+=================+========+=================+ | 1 ZEC| 1.01 | 1.50 | 2.33 | +-----------+-----------------+--------+-----------------+ | 10 ZEC| 1.65 | 2.46 | 3.45 | +-----------+-----------------+--------+-----------------+ | 100 ZEC| 2.54 | 3.99 | 5.83 | +-----------+-----------------+--------+-----------------+ | 1000 ZEC| 9.86 | 12.52 | 15.54 | +-----------+-----------------+--------+-----------------+ | 10000 ZEC| 89.23 | 97.01 | 105.05 | +-----------+-----------------+--------+-----------------+</p>
<p>The simulation also depends on the amounts sent as specified in the next section. It includes the time spent waiting for the first batch to be sent.</p>
<p>The code used for this simulation is at<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a>.</p>
<h2 id="how-much-to-send-in-each-transaction">How much to send in each transaction</h2>
<p>If the remaining amount to be migrated is less than 0.01 ZEC, end the migration.</p>
<p>Otherwise, the amount to send in each transaction is chosen according to the following distribution:</p>
<ol type="1">
<li>Choose an integer exponent uniformly in the range 6 to 8 inclusive.</li>
<li>Choose an integer mantissa uniformly in the range 1 to 99 inclusive.</li>
<li>Calculate amount := (mantissa * 10<sup>exponent</sup>) zatoshi.</li>
<li>If amount is greater than the amount remaining to send, repeat from step 1.</li>
</ol>
<p>Implementations MAY optimize this procedure by selecting the exponent and mantissa based on the amount remaining to avoid repetition, but the resulting distribution MUST be identical.</p>
<p>The amount chosen <em>includes</em> the 0.0001 ZEC fee for this transaction, i.e. the value of the Sapling output will be 0.0001 ZEC less.</p>
<h3 id="rationale-for-how-much-to-send">Rationale for how much to send</h3>
<p>Suppose that a user has an amount to migrate that is a round number of ZEC. Then, a potential attack would be to find some subset of all the migration transactions that sum to a round number of ZEC, and infer that all of those transactions are from the same user. If amounts sent were a random multiple of 1 zatoshi, then the resulting knapsack problem would be likely to have a unique solution and be practically solvable for the number of transactions involved. The chosen distribution of transaction amounts mitigates this potential vulnerability by ensuring that there will be many solutions for sets of transactions, including &quot;incorrect&quot; solutions (that is, solutions that mix transactions from different users, contrary to the supposed adversary's inference).</p>
<p>Making the chosen amount inclusive of the fee avoids leaving any unmigrated funds at the end, in the case where the original amount to migrate was a multiple of 0.01 ZEC.</p>
<h2 id="other-design-decisions">Other design decisions</h2>
<p>We assume use of the normal wallet note selection algorithm and change handling. Change is sent back to the default address, which is the z-address of the first selected Sprout note. The number of JoinSplits will therefore be the same as for a normal transaction sending the same amount with the same wallet state. Only the <code>vpub_new</code> of the last JoinSplit will be nonzero. There will always be exactly one Sapling Output.</p>
<p>The expiry delta for migration transactions MUST be 450 blocks. Since these transactions are sent when the block height is 499 modulo 500, their expiry height will be 451 blocks later, i.e. <code>nExpiryHeight</code> will be 450 modulo 500.</p>
<p>The fee for each migration transaction MUST be 0.0001 ZEC. This fee is taken from the funds to be migrated.</p>
<p>Some wallets by default add a &quot;developer fee&quot; to each transaction, directed to the developer(s) of the wallet. This is typically implemented by adding the developer address as an explicit output, so if migration transactions are generated internally by <code>zcashd</code>, they will not include the developer fee. We strongly recommend <em>not</em> patching the <code>zcashd</code> code to add the developer fee output to migration transactions, because doing so partitions the anonymity set between users of that wallet and other users.</p>
<p>There MUST NOT be any transparent inputs or outputs, or Sapling Spends, in a migration transaction.</p>
<p>The <code>lock_time</code> field MUST be set to 0 (unused).</p>
<p>When creating Sapling shielded Outputs, the outgoing viewing key <code>ovk</code> SHOULD be chosen in the same way as for a transfer sent from a t-address.</p>
<p>A node SHOULD treat migration transactions in the same way as transactions submitted over the RPC interface.</p>
<h2 id="open-questions">Open questions</h2>
<p>The above strategy has several &quot;magic number&quot; parameters:</p>
<ul>
<li>the interval between batches (500 blocks)</li>
<li>the maximum number of transactions in a batch (5)</li>
<li>the distribution of exponents (uniform integer in 6..8)</li>
<li>the distribution of mantissae (uniform integer in 1..99).</li>
</ul>
<p>These have been chosen by guesswork. Should we change any of them?</p>
<p>In particular, if the amount to migrate is large, then this strategy can result in fairly large amounts (up to 99 ZEC, worth USD ~6700 at time of writing) transferred in each transaction. This leaks the fact that the transaction was sent by a user who has at least that amount.</p>
<p>The strategy does not migrate any remaining fractional amount less than 0.01 ZEC (worth USD ~0.68 at time of writing). Is this reasonable?</p>
<p>In deciding the amount to send in each transaction, the strategy does not take account of the values of individual Sprout notes, only the total amount remaining to migrate. Can a strategy that is sensitive to individual note values improve privacy?</p>
<p>An adversary may attempt to interfere with the view of the block chain seen by a subset of nodes that are performing migrations, in order to cause those nodes to send migration batches at a different time, so that they may be distinguished. Is there anything further we can do to mitigate this vulnerability?</p>
<h2 id="rpc-calls">RPC calls</h2>
<p>Nodes MUST maintain a boolean state variable during their execution, to determine whether migration is enabled. The default when a node starts, is set by a configuration option:</p>
<pre><code>-migration=0/1</code></pre>
<p>The destination z-address can optionally be set by another option:</p>
<pre><code>-migrationdestaddress=&lt;zaddr&gt;</code></pre>
<p>If this option is not present then the migration destination address is the address for Sapling account 0, with the default diversifier<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>.</p>
<p>The state variable can also be set for a running node using the following RPC method:</p>
<pre><code>z_setmigration true/false</code></pre>
<p>It is intentional that the only option associated with the migration is the destination z-address. Other options could potentially distinguish users.</p>
<p>Nodes MUST also support the following RPC call to return the current status of the migration:</p>
<pre><code>z_getmigrationstatus</code></pre>
<p>Returns:</p>
<pre><code>{
&quot;enabled&quot;: true|false,
&quot;destination_address&quot;: &quot;zaddr&quot;,
&quot;unmigrated_amount&quot;: nnn.n,
&quot;unfinalized_migrated_amount&quot;: nnn.n,
&quot;finalized_migrated_amount&quot;: nnn.n,
&quot;finalized_migration_transactions&quot;: nnn,
&quot;time_started&quot;: ttt, // Unix timestamp
&quot;migration_txids&quot;: [txids]
}</code></pre>
<p>The <code>destination_address</code> field MAY be omitted if the <code>-migrationaddress</code> parameter is not set and no default address has yet been generated.</p>
<p>The values of <code>unmigrated_amount</code> and <code>migrated_amount</code> MUST take into account failed transactions, that were not mined within their expiration height.</p>
<p>The values of <code>unfinalized_migrated_amount</code> and <code>finalized_migrated_amount</code> are the total amounts sent to the Sapling destination address in migration transactions, excluding fees.</p>
<p><code>migration_txids</code> is a list of strings representing transaction IDs of all known migration transactions involving this wallet, as lowercase hexadecimal in RPC byte order. A given transaction is defined as a migration transaction iff it has:</p>
<ul>
<li>one or more Sprout JoinSplits with nonzero <code>vpub_new</code> field; and</li>
<li>no Sapling Spends, and;</li>
<li>one or more Sapling Outputs.</li>
</ul>
<p>Note: it is possible that manually created transactions involving this wallet will be recognized as migration transactions and included in <code>migration_txids</code>.</p>
<p>The value of <code>time_started</code> is the earliest Unix timestamp of any known migration transaction involving this wallet; if there is no such transaction, then the field is absent.</p>
<p>A transaction is <code>finalized</code> iff it has at least 10 confirmations. TODO: subject to change, if the recommended number of confirmations changes.</p>
<h1 id="support-in-zcashd">Support in zcashd</h1>
<p>The following PRs implement this specification:</p>
<ul>
<li><a href="https://github.com/zcash/zcash/pull/3848" class="uri">https://github.com/zcash/zcash/pull/3848</a> (TransactionBuilder support)</li>
<li><a href="https://github.com/zcash/zcash/pull/3888" class="uri">https://github.com/zcash/zcash/pull/3888</a> (main RPC)</li>
<li><a href="https://github.com/zcash/zcash/pull/3967" class="uri">https://github.com/zcash/zcash/pull/3967</a> (config options)</li>
<li><a href="https://github.com/zcash/zcash/pull/3973" class="uri">https://github.com/zcash/zcash/pull/3973</a> (getmigrationstatus RPC)</li>
<li><a href="https://github.com/zcash/zcash/pull/3977" class="uri">https://github.com/zcash/zcash/pull/3977</a> (bugfix)</li>
<li><a href="https://github.com/zcash/zcash/pull/3987" class="uri">https://github.com/zcash/zcash/pull/3987</a> (bugfix)</li>
<li><a href="https://github.com/zcash/zcash/pull/3990" class="uri">https://github.com/zcash/zcash/pull/3990</a> (bugfix)</li>
<li><a href="https://github.com/zcash/zcash/pull/3995" class="uri">https://github.com/zcash/zcash/pull/3995</a> (don't migrate in initial block download/after wakeup)</li>
<li><a href="https://github.com/zcash/zcash/pull/3997" class="uri">https://github.com/zcash/zcash/pull/3997</a> (bugfix)</li>
<li><a href="https://github.com/zcash/zcash/pull/4002" class="uri">https://github.com/zcash/zcash/pull/4002</a> (minor RPC improvements)</li>
<li><a href="https://github.com/zcash/zcash/pull/4005" class="uri">https://github.com/zcash/zcash/pull/4005</a> (change expiry for migration transactions)</li>
</ul>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/zip-0205.rst">ZIP 205: Deployment of the Sapling Network Upgrade</a><a href="#fnref2" class="footnote-back"></a></p></li>
<li id="fn3"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-33 [Overwinter+Sapling]; sections 3.4, 4.11 and 4.12</a><a href="#fnref3" class="footnote-back"></a></p></li>
<li id="fn4"><p><a href="https://github.com/daira/zcash-migration">Sprout -&gt; Sapling migration simulation</a><a href="#fnref4" class="footnote-back"></a></p></li>
<li id="fn5"><p><a href="https://github.com/zcash/zips/blob/master/zip-0032.rst">ZIP 32: Shielded Hierarchical Deterministic Wallets</a><a href="#fnref5" class="footnote-back"></a></p></li>
</ol>
</section>
License: MIT</pre>
<section id="terminology">
<h2>Terminology</h2>
<p>The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">2</a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>Sprout protocol</dt>
<dd>Code-name for the Zcash shielded protocol at launch.</dd>
<dt>Sapling protocol</dt>
<dd>Code-name for the Zcash shielded protocol added by the second Zcash network upgrade, also known as Network Upgrade 1.</dd>
</dl>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>This proposal describes privacy-preserving procedures to migrate funds from Sprout to Sapling z-addresses; and supporting RPC operations to enable, disable, and monitor the migration process.</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>Zcash Sapling <a href="#zip-0205" id="id2" class="footnote_reference">4</a> introduces significant efficiency improvements relative to the previous iteration of the Zcash shielded protocol, Sprout. These improvements will pave the way for broad mobile, exchange and vendor adoption of shielded addresses.</p>
<p>Therefore, we anticipate that users will want to migrate all their shielded funds from Sprout to Sapling.</p>
<p>The Zcash consensus rules prohibit direct transfers from Sprout to Sapling z-addresses, unless the amount is revealed by sending it through the "transparent value pool" <a href="#transparent-value-pool" id="id3" class="footnote_reference">1</a>. The primary motivation for this is to allow detection of any overall inflation of the Zcash monetary base, due to exploitation of possible vulnerabilities in the shielded protocols or their implementation, or a compromise of the Sprout multi-party computation. (It is not necessary for Sprout -&gt; Sapling transfers to go via a t-address.)</p>
<p>Since the exposure of the migrated amount potentially compromises the privacy of users, we wish to define a way to perform the migration that mitigates this privacy leak as far as possible. This can be done by hiding individual migration transactions among those of all users that are doing the migration at around the same time.</p>
<p>The security analysis of migration strategies is quite subtle; the more obvious potential strategies can leak a lot of information.</p>
</section>
<section id="requirements">
<h2>Requirements</h2>
<p>Migration is performed "in the background" by a <code>zcashd</code> (or equivalent) node. It does not significantly interfere with concurrent usage of the node, other than possibly increasing the latency of some other shielded operations.</p>
<p>It is possible to enable or disable migration at any time.</p>
<p>All shielded funds in Sprout z-addresses will eventually be transferred to Sapling z-addresses, provided the node is working.</p>
<p>It should take a "reasonable" length of time to complete the transfer; less than a month for amounts up to 1000 ZEC.</p>
<p>The design should mitigate information leakage via timing information and transaction data, including</p>
<ul>
<li>linkage of particular z-addresses or users, and the amounts held;</li>
<li>information about the distribution of amounts of individual notes.</li>
</ul>
<p>The design and implementation is stateless, to the extent practical.</p>
<p>Visibility is provided for the wallet/node user into the progress of the migration.</p>
<p>There is sufficient information available to debug failed transactions that are part of the migration.</p>
<p>The design recovers from failed operations to the extent possible.</p>
<p>The total amount sent by each user is obscured, to the extent practical.</p>
</section>
<section id="non-requirements">
<h2>Non-requirements</h2>
<p>There is no requirement or assumption of network layer anonymity. (Users may, but are not expected to, configure Tor.)</p>
<p>The migration procedure does not have to provably leak no information.</p>
<p>There is no need to preserve individual note values (i.e. notes can be consolidated).</p>
<p>Migration txns need only be hidden among themselves, rather than among all kinds of transaction.</p>
<p>A small amount (less than 0.01 ZEC) can be left unmigrated if this helps with privacy.</p>
<p>It is not required to support the case of single wallet being used by multiple users whose funds should be kept distinct.</p>
</section>
<section id="specification">
<h2>Specification</h2>
<p>There are two main aspects to a strategy for selecting migration transactions:</p>
<ul>
<li>how many transactions are sent, and when;</li>
<li>the amount sent in each transaction.</li>
</ul>
<section id="transaction-schedule">
<h3>Transaction schedule</h3>
<p>When migration is enabled, a node will send up to 5 transactions for inclusion in each block with height a multiple of 500 (that is, they are sent immediately after seeing a block with height 499, modulo 500). Up to the limit of 5, as many transactions are sent as are needed to migrate the remaining funds (possibly with a remainder less than 0.01 ZEC left unmigrated).</p>
<p>Nodes SHOULD NOT send migration transactions during initial block download, or if the timestamp of the triggering block (with height 499, modulo 500) is more than three hours in the past according to the node's adjusted local clock.</p>
<p>TODO: if we change the target block interval, 500 might need to be changed.</p>
<p>The migration transactions to be sent in a particular batch can take significant time to generate, and this time depends on the speed of the user's computer. If they were generated only after a block is seen at the target height minus 1, then this could leak information. Therefore, for target height N, implementations SHOULD start generating the transactions at around height N-5 (provided that block's timestamp is not more than three hours in the past). Each migration transaction SHOULD specify an anchor at height N-10 for each Sprout JoinSplit description.</p>
<p>Open questions:</p>
<ul>
<li>does this reliably give sufficient time to generate the transactions?</li>
<li>what happens to a batch if the anchor is invalidated -- should it be regenerated, or cancelled?</li>
</ul>
<section id="rationale-for-transaction-schedule">
<h4>Rationale for transaction schedule</h4>
<p>Privacy is increased when the times at which to send transactions are coordinated between nodes. We choose to send a batch of transactions at each coordinated time. Sending multiple transactions in each batch ensures that:</p>
<ul>
<li>less information about balances is leaked;</li>
<li>it is easier to finish in a reasonable length of time.</li>
</ul>
<p>The choice of 500 blocks as the batch interval ensures that each batch occurs at a different time of day, which may help to mitigate problems with the availability of nodes being correlated with the local time-of-day.</p>
<p>Simulation shows that the migration process will typically complete reasonably quickly even if the amount to be migrated is large:</p>
<table>
<thead>
<tr>
<th rowspan="2">Amount</th>
<th colspan="3">Time in days to complete migration</th>
</tr>
<tr>
<th>10th-percentile</th>
<th>median</th>
<th>90th-percentile</th>
</tr>
</thead>
<tbody>
<tr>
<td>1 ZEC</td>
<td>1.01</td>
<td>1.50</td>
<td>2.33</td>
</tr>
<tr>
<td>10 ZEC</td>
<td>1.65</td>
<td>2.46</td>
<td>3.45</td>
</tr>
<tr>
<td>100 ZEC</td>
<td>2.54</td>
<td>3.99</td>
<td>5.83</td>
</tr>
<tr>
<td>1000 ZEC</td>
<td>9.86</td>
<td>12.52</td>
<td>15.54</td>
</tr>
<tr>
<td>10000 ZEC</td>
<td>89.23</td>
<td>97.01</td>
<td>105.05</td>
</tr>
</tbody>
</table>
<p>The simulation also depends on the amounts sent as specified in the next section. It includes the time spent waiting for the first batch to be sent.</p>
<p>The code used for this simulation is at <a href="#migration-simulator" id="id4" class="footnote_reference">5</a>.</p>
</section>
</section>
<section id="how-much-to-send-in-each-transaction">
<h3>How much to send in each transaction</h3>
<p>If the remaining amount to be migrated is less than 0.01 ZEC, end the migration.</p>
<p>Otherwise, the amount to send in each transaction is chosen according to the following distribution:</p>
<ol type="1">
<li>Choose an integer exponent uniformly in the range 6 to 8 inclusive.</li>
<li>Choose an integer mantissa uniformly in the range 1 to 99 inclusive.</li>
<li>Calculate amount := (mantissa * 10<sup>exponent</sup>) zatoshi.</li>
<li>If amount is greater than the amount remaining to send, repeat from step 1.</li>
</ol>
<p>Implementations MAY optimize this procedure by selecting the exponent and mantissa based on the amount remaining to avoid repetition, but the resulting distribution MUST be identical.</p>
<p>The amount chosen <em>includes</em> the 0.0001 ZEC fee for this transaction, i.e. the value of the Sapling output will be 0.0001 ZEC less.</p>
<section id="rationale-for-how-much-to-send">
<h4>Rationale for how much to send</h4>
<p>Suppose that a user has an amount to migrate that is a round number of ZEC. Then, a potential attack would be to find some subset of all the migration transactions that sum to a round number of ZEC, and infer that all of those transactions are from the same user. If amounts sent were a random multiple of 1 zatoshi, then the resulting knapsack problem would be likely to have a unique solution and be practically solvable for the number of transactions involved. The chosen distribution of transaction amounts mitigates this potential vulnerability by ensuring that there will be many solutions for sets of transactions, including "incorrect" solutions (that is, solutions that mix transactions from different users, contrary to the supposed adversary's inference).</p>
<p>Making the chosen amount inclusive of the fee avoids leaving any unmigrated funds at the end, in the case where the original amount to migrate was a multiple of 0.01 ZEC.</p>
</section>
</section>
<section id="other-design-decisions">
<h3>Other design decisions</h3>
<p>We assume use of the normal wallet note selection algorithm and change handling. Change is sent back to the default address, which is the z-address of the first selected Sprout note. The number of JoinSplits will therefore be the same as for a normal transaction sending the same amount with the same wallet state. Only the <code>vpub_new</code> of the last JoinSplit will be nonzero. There will always be exactly one Sapling Output.</p>
<p>The expiry delta for migration transactions MUST be 450 blocks. Since these transactions are sent when the block height is 499 modulo 500, their expiry height will be 451 blocks later, i.e. <code>nExpiryHeight</code> will be 450 modulo 500.</p>
<p>The fee for each migration transaction MUST be 0.0001 ZEC. This fee is taken from the funds to be migrated.</p>
<p>Some wallets by default add a "developer fee" to each transaction, directed to the developer(s) of the wallet. This is typically implemented by adding the developer address as an explicit output, so if migration transactions are generated internally by <code>zcashd</code>, they will not include the developer fee. We strongly recommend <em>not</em> patching the <code>zcashd</code> code to add the developer fee output to migration transactions, because doing so partitions the anonymity set between users of that wallet and other users.</p>
<p>There MUST NOT be any transparent inputs or outputs, or Sapling Spends, in a migration transaction.</p>
<p>The <code>lock_time</code> field MUST be set to 0 (unused).</p>
<p>When creating Sapling shielded Outputs, the outgoing viewing key <code>ovk</code> SHOULD be chosen in the same way as for a transfer sent from a t-address.</p>
<p>A node SHOULD treat migration transactions in the same way as transactions submitted over the RPC interface.</p>
</section>
<section id="open-questions">
<h3>Open questions</h3>
<p>The above strategy has several "magic number" parameters:</p>
<ul>
<li>the interval between batches (500 blocks)</li>
<li>the maximum number of transactions in a batch (5)</li>
<li>the distribution of exponents (uniform integer in 6..8)</li>
<li>the distribution of mantissae (uniform integer in 1..99).</li>
</ul>
<p>These have been chosen by guesswork. Should we change any of them?</p>
<p>In particular, if the amount to migrate is large, then this strategy can result in fairly large amounts (up to 99 ZEC, worth USD ~6700 at time of writing) transferred in each transaction. This leaks the fact that the transaction was sent by a user who has at least that amount.</p>
<p>The strategy does not migrate any remaining fractional amount less than 0.01 ZEC (worth USD ~0.68 at time of writing). Is this reasonable?</p>
<p>In deciding the amount to send in each transaction, the strategy does not take account of the values of individual Sprout notes, only the total amount remaining to migrate. Can a strategy that is sensitive to individual note values improve privacy?</p>
<p>An adversary may attempt to interfere with the view of the block chain seen by a subset of nodes that are performing migrations, in order to cause those nodes to send migration batches at a different time, so that they may be distinguished. Is there anything further we can do to mitigate this vulnerability?</p>
</section>
<section id="rpc-calls">
<h3>RPC calls</h3>
<p>Nodes MUST maintain a boolean state variable during their execution, to determine whether migration is enabled. The default when a node starts, is set by a configuration option:</p>
<pre>-migration=0/1</pre>
<p>The destination z-address can optionally be set by another option:</p>
<pre>-migrationdestaddress=&lt;zaddr&gt;</pre>
<p>If this option is not present then the migration destination address is the address for Sapling account 0, with the default diversifier <a href="#zip-0032" id="id5" class="footnote_reference">3</a>.</p>
<p>The state variable can also be set for a running node using the following RPC method:</p>
<pre>z_setmigration true/false</pre>
<p>It is intentional that the only option associated with the migration is the destination z-address. Other options could potentially distinguish users.</p>
<p>Nodes MUST also support the following RPC call to return the current status of the migration:</p>
<pre>z_getmigrationstatus</pre>
<p>Returns:</p>
<pre>{
"enabled": true|false,
"destination_address": "zaddr",
"unmigrated_amount": nnn.n,
"unfinalized_migrated_amount": nnn.n,
"finalized_migrated_amount": nnn.n,
"finalized_migration_transactions": nnn,
"time_started": ttt, // Unix timestamp
"migration_txids": [txids]
}</pre>
<p>The <code>destination_address</code> field MAY be omitted if the <code>-migrationaddress</code> parameter is not set and no default address has yet been generated.</p>
<p>The values of <code>unmigrated_amount</code> and <code>migrated_amount</code> MUST take into account failed transactions, that were not mined within their expiration height.</p>
<p>The values of <code>unfinalized_migrated_amount</code> and <code>finalized_migrated_amount</code> are the total amounts sent to the Sapling destination address in migration transactions, excluding fees.</p>
<p><code>migration_txids</code> is a list of strings representing transaction IDs of all known migration transactions involving this wallet, as lowercase hexadecimal in RPC byte order. A given transaction is defined as a migration transaction iff it has:</p>
<ul>
<li>one or more Sprout JoinSplits with nonzero <code>vpub_new</code> field; and</li>
<li>no Sapling Spends, and;</li>
<li>one or more Sapling Outputs.</li>
</ul>
<p>Note: it is possible that manually created transactions involving this wallet will be recognized as migration transactions and included in <code>migration_txids</code>.</p>
<p>The value of <code>time_started</code> is the earliest Unix timestamp of any known migration transaction involving this wallet; if there is no such transaction, then the field is absent.</p>
<p>A transaction is <code>finalized</code> iff it has at least 10 confirmations. TODO: subject to change, if the recommended number of confirmations changes.</p>
</section>
</section>
<section id="support-in-zcashd">
<h2>Support in zcashd</h2>
<p>The following PRs implement this specification:</p>
<ul>
<li><a href="https://github.com/zcash/zcash/pull/3848">https://github.com/zcash/zcash/pull/3848</a> (TransactionBuilder support)</li>
<li><a href="https://github.com/zcash/zcash/pull/3888">https://github.com/zcash/zcash/pull/3888</a> (main RPC)</li>
<li><a href="https://github.com/zcash/zcash/pull/3967">https://github.com/zcash/zcash/pull/3967</a> (config options)</li>
<li><a href="https://github.com/zcash/zcash/pull/3973">https://github.com/zcash/zcash/pull/3973</a> (getmigrationstatus RPC)</li>
<li><a href="https://github.com/zcash/zcash/pull/3977">https://github.com/zcash/zcash/pull/3977</a> (bugfix)</li>
<li><a href="https://github.com/zcash/zcash/pull/3987">https://github.com/zcash/zcash/pull/3987</a> (bugfix)</li>
<li><a href="https://github.com/zcash/zcash/pull/3990">https://github.com/zcash/zcash/pull/3990</a> (bugfix)</li>
<li><a href="https://github.com/zcash/zcash/pull/3995">https://github.com/zcash/zcash/pull/3995</a> (don't migrate in initial block download/after wakeup)</li>
<li><a href="https://github.com/zcash/zcash/pull/3997">https://github.com/zcash/zcash/pull/3997</a> (bugfix)</li>
<li><a href="https://github.com/zcash/zcash/pull/4002">https://github.com/zcash/zcash/pull/4002</a> (minor RPC improvements)</li>
<li><a href="https://github.com/zcash/zcash/pull/4005">https://github.com/zcash/zcash/pull/4005</a> (change expiry for migration transactions)</li>
</ul>
</section>
<section id="references">
<h2>References</h2>
<table id="transparent-value-pool" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version 2018.0-beta-33 [Overwinter+Sapling]; sections 3.4, 4.11 and 4.12</a></td>
</tr>
</tbody>
</table>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="zip-0032" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0032.rst">ZIP 32: Shielded Hierarchical Deterministic Wallets</a></td>
</tr>
</tbody>
</table>
<table id="zip-0205" class="footnote">
<tbody>
<tr>
<th>4</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-0205.rst">ZIP 205: Deployment of the Sapling Network Upgrade</a></td>
</tr>
</tbody>
</table>
<table id="migration-simulator" class="footnote">
<tbody>
<tr>
<th>5</th>
<td><a href="https://github.com/daira/zcash-migration">Sprout -&gt; Sapling migration simulation</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>

View File

@ -1,19 +1,12 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>ZIP guide: {Something Short and To the Point}</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<title>ZIP guide: {Something Short and To the Point}</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/zip-style.css"><link rel="stylesheet" href="assets/css/style.css"></head>
<body>
<pre><code>ZIP: Unassigned {numbers are assigned by ZIP editors}
<section>
<pre>ZIP: Unassigned {numbers are assigned by ZIP editors}
Title: {Something Short and To the Point}
Owners: First Owner &lt;email&gt;
...
@ -22,60 +15,100 @@ Credits: First Credited &lt;optional email&gt;
Status: Draft
Category: {Consensus | Standards Track | Network | RPC | Wallet | Informational | Process}
Created: yyyy-mm-dd
License: {usually MIT}</code></pre>
<h1 id="dont-panic">Don't Panic</h1>
<p>If this is your first time writing a ZIP, the structure and format may look intimidating. But really, it's just meant to reflect common-sense practice and some technical conventions. Feel free to start with a simple initial draft that gets ideas across, even if it doesn't quite follow this format. The community and ZIP editors will help you figure things out and get it into shape later.</p>
<p>{Delete this section.}</p>
<h1 id="terminology">Terminology</h1>
<p>{Edit this to reflect the key words that are actually used.} The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;SHOULD&quot;, and &quot;MAY&quot; in this document are to be interpreted as described in RFC 2119.<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>{Term to be defined}</dt>
<dd><p>{Definition.}</p>
</dd>
<dt>{Another term}</dt>
<dd><p>{Definition.}</p>
</dd>
</dl>
<h1 id="abstract">Abstract</h1>
<p>{Describe what this proposal does, typically in a few paragraphs.}</p>
<p>{Use links where applicable, e.g.<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>.}</p>
<h1 id="motivation">Motivation</h1>
<p>{Why is this proposal needed?</p>
<p>This is one of the most important sections of the ZIP, and should be detailed and comprehensive. It shouldn't include any of the actual specification --don't put conformance requirements in this section.</p>
<p>Explain the status quo, why the status quo is in need of improvement, and if applicable, the history of how this area has changed. Then describe <em>at a high level</em> why this proposed solution addresses the perceived issues. It is ok if this is somewhat redundant with the abstract, but here you can go into a lot more detail.}</p>
<h1 id="requirements">Requirements</h1>
<p>{Describe design constraints on, or goals for the solution -- typically one paragraph for each constraint or goal. Again, don't actually specify anything here; this section is primarily for use as a consistency check that what is specified meets the requirements.}</p>
<h1 id="non-requirements">Non-requirements</h1>
<p>{This section is entirely optional. If it is present, it describes issues that the proposal is <em>not</em> attempting to address, that someone might otherwise think it does or should.}</p>
<h1 id="specification">Specification</h1>
<p>{This section describes what should change, using precise language and conformance key words. Anything that is <em>required in order to implement the ZIP</em> (or follow its process, in the case of a Process ZIP) should be in this section.</p>
<p>Avoid overspecification! Also avoid underspecification. Specification is hard. Don't be afraid to ask for help.</p>
<p>Unless the specification is particularly simple, you will need to organise it under subheadings.}</p>
<h2 id="example-subheading">Example subheading</h2>
<p>{At least while the ZIP is in Draft, we encourage writing open questions and TODOs.}</p>
<h3 id="open-questions">Open questions</h3>
<ul>
<li>What happens if a full node can't parse the fandangle as a doohicky?</li>
</ul>
<p>TODO: define byte encoding for the Jabberwock.</p>
<p>{Feel free to copy from other ZIPs doing similar things, e.g. defining RPC calls, consensus rules, etc.}</p>
<h2 id="valid-restructuredtext">Valid reStructuredText</h2>
<p>This is optional before publishing a PR, but to check whether a document is valid reStructuredText, first install rst2html5:</p>
<pre><code>sudo apt-get install python-pip
sudo pip install rst2html5</code></pre>
<p>and then run:</p>
<pre><code>rst2html5 -v zip-xxxx.rst &gt;zip-xxxx.html</code></pre>
<p>and view <code>zip-xxxx.html</code> in a web browser.</p>
<h1 id="reference-implementation">Reference implementation</h1>
<p>{This section is entirely optional; if present, it usually gives links to zcashd or zebrad PRs.}</p>
<h1 id="references">References</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a><a href="#fnref1" class="footnote-back"></a></p></li>
<li id="fn2"><p><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version {...} or later [Overwinter+Sapling+Blossom]</a><a href="#fnref2" class="footnote-back"></a></p></li>
</ol>
</section>
License: {usually MIT}</pre>
<section id="don-t-panic">
<h2>Don't Panic</h2>
<p>If this is your first time writing a ZIP, the structure and format may look intimidating. But really, it's just meant to reflect common-sense practice and some technical conventions. Feel free to start with a simple initial draft that gets ideas across, even if it doesn't quite follow this format. The community and ZIP editors will help you figure things out and get it into shape later.</p>
<p>{Delete this section.}</p>
</section>
<section id="terminology">
<h2>Terminology</h2>
<p>{Edit this to reflect the key words that are actually used.} The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119. <a href="#rfc2119" id="id1" class="footnote_reference">1</a></p>
<p>The terms below are to be interpreted as follows:</p>
<dl>
<dt>{Term to be defined}</dt>
<dd>{Definition.}</dd>
<dt>{Another term}</dt>
<dd>{Definition.}</dd>
</dl>
</section>
<section id="abstract">
<h2>Abstract</h2>
<p>{Describe what this proposal does, typically in a few paragraphs.}</p>
<p>{Use links where applicable, e.g. <a href="#protocol" id="id2" class="footnote_reference">2</a>.}</p>
</section>
<section id="motivation">
<h2>Motivation</h2>
<p>{Why is this proposal needed?</p>
<p>This is one of the most important sections of the ZIP, and should be detailed and comprehensive. It shouldn't include any of the actual specification -- don't put conformance requirements in this section.</p>
<p>Explain the status quo, why the status quo is in need of improvement, and if applicable, the history of how this area has changed. Then describe <em>at a high level</em> why this proposed solution addresses the perceived issues. It is ok if this is somewhat redundant with the abstract, but here you can go into a lot more detail.}</p>
</section>
<section id="requirements">
<h2>Requirements</h2>
<p>{Describe design constraints on, or goals for the solution -- typically one paragraph for each constraint or goal. Again, don't actually specify anything here; this section is primarily for use as a consistency check that what is specified meets the requirements.}</p>
</section>
<section id="non-requirements">
<h2>Non-requirements</h2>
<p>{This section is entirely optional. If it is present, it describes issues that the proposal is <em>not</em> attempting to address, that someone might otherwise think it does or should.}</p>
</section>
<section id="specification">
<h2>Specification</h2>
<p>{This section describes what should change, using precise language and conformance key words. Anything that is <em>required in order to implement the ZIP</em> (or follow its process, in the case of a Process ZIP) should be in this section.</p>
<p>Avoid overspecification! Also avoid underspecification. Specification is hard. Don't be afraid to ask for help.</p>
<p>Unless the specification is particularly simple, you will need to organise it under subheadings.}</p>
<section id="example-subheading">
<h3>Example subheading</h3>
<p>{At least while the ZIP is in Draft, we encourage writing open questions and TODOs.}</p>
<section id="open-questions">
<h4>Open questions</h4>
<ul>
<li>What happens if a full node can't parse the fandangle as a doohicky?</li>
</ul>
<p>TODO: define byte encoding for the Jabberwock.</p>
<p>{Feel free to copy from other ZIPs doing similar things, e.g. defining RPC calls, consensus rules, etc.}</p>
</section>
</section>
<section id="valid-restructuredtext">
<h3>Valid reStructuredText</h3>
<p>This is optional before publishing a PR, but to check whether a document is valid reStructuredText, first install rst2html5:</p>
<pre>sudo apt-get install python-pip
sudo pip install rst2html5</pre>
<p>and then run:</p>
<pre>rst2html5 -v zip-xxxx.rst &gt;zip-xxxx.html</pre>
<p>and view <code>zip-xxxx.html</code> in a web browser.</p>
</section>
</section>
<section id="reference-implementation">
<h2>Reference implementation</h2>
<p>{This section is entirely optional; if present, it usually gives links to zcashd or zebrad PRs.}</p>
</section>
<section id="references">
<h2>References</h2>
<table id="rfc2119" class="footnote">
<tbody>
<tr>
<th>1</th>
<td><a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a></td>
</tr>
</tbody>
</table>
<table id="protocol" class="footnote">
<tbody>
<tr>
<th>2</th>
<td><a href="https://github.com/zcash/zips/blob/master/protocol/protocol.pdf">Zcash Protocol Specification, Version {...} or later [Overwinter+Sapling+Blossom]</a></td>
</tr>
</tbody>
</table>
<table id="zip-xxxx" class="footnote">
<tbody>
<tr>
<th>3</th>
<td><a href="https://github.com/zcash/zips/blob/master/zip-xxxx.rst">ZIP xxxx: Title</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
</html>