mirror of https://github.com/zcash/zips.git
ZIP 207: remove example implementation and add links to zcashd PRs.
Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
parent
ef94502ba3
commit
03e57714c1
167
zip-0207.html
167
zip-0207.html
|
@ -208,167 +208,6 @@ License: MIT</pre>
|
||||||
</ul>
|
</ul>
|
||||||
<p>For the funding stream definitions to be activated at Canopy, see ZIP 214. <a id="id21" class="footnote_reference" href="#zip-0214">14</a> Funding stream definitions can be added, changed, or deleted in ZIPs associated with subsequent network upgrades, subject to the ZIP process. <a id="id22" class="footnote_reference" href="#zip-0000">9</a></p>
|
<p>For the funding stream definitions to be activated at Canopy, see ZIP 214. <a id="id21" class="footnote_reference" href="#zip-0214">14</a> Funding stream definitions can be added, changed, or deleted in ZIPs associated with subsequent network upgrades, subject to the ZIP process. <a id="id22" class="footnote_reference" href="#zip-0000">9</a></p>
|
||||||
</section>
|
</section>
|
||||||
<section id="example-implementation"><h3><span class="section-heading">Example implementation</span><span class="section-anchor"> <a rel="bookmark" href="#example-implementation"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h3>
|
|
||||||
<pre data-language="cpp"><span class="k">struct</span> <span class="n">FundingPeriod</span> <span class="p">{</span>
|
|
||||||
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">addresses</span><span class="p">,</span>
|
|
||||||
<span class="kt">uint64_t</span> <span class="n">valueNumerator</span><span class="p">,</span>
|
|
||||||
<span class="kt">uint64_t</span> <span class="n">valueDenominator</span><span class="p">,</span>
|
|
||||||
<span class="kt">int</span> <span class="n">startHeight</span><span class="p">,</span>
|
|
||||||
<span class="kt">int</span> <span class="n">endHeight</span><span class="p">,</span>
|
|
||||||
<span class="p">};</span>
|
|
||||||
|
|
||||||
<span class="k">enum</span> <span class="n">FundingStream</span> <span class="p">{</span>
|
|
||||||
<span class="n">FS_ECC</span><span class="p">,</span>
|
|
||||||
<span class="n">FS_ZF</span><span class="p">,</span>
|
|
||||||
<span class="n">FS_MG</span><span class="p">,</span>
|
|
||||||
<span class="n">MAX_FUNDING_STREAMS</span><span class="p">,</span>
|
|
||||||
<span class="p">};</span>
|
|
||||||
|
|
||||||
<span class="k">const</span> <span class="k">auto</span> <span class="n">FIRST_FUNDING_STREAM</span> <span class="o">=</span> <span class="n">FS_ECC</span><span class="p">;</span>
|
|
||||||
|
|
||||||
<span class="k">struct</span> <span class="n">Params</span> <span class="p">{</span>
|
|
||||||
<span class="p">...</span>
|
|
||||||
<span class="kt">int</span> <span class="n">nFundingPeriodLength</span><span class="p">;</span>
|
|
||||||
<span class="n">FundingPeriod</span> <span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">MAX_FUNDING_STREAMS</span><span class="p">];</span>
|
|
||||||
<span class="p">...</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
|
|
||||||
<span class="kt">void</span> <span class="n">AddZIP207FundingStream</span><span class="p">(</span>
|
|
||||||
<span class="n">Consensus</span><span class="o">::</span><span class="n">Params</span><span class="o">&</span> <span class="n">params</span><span class="p">,</span>
|
|
||||||
<span class="n">Consensus</span><span class="o">::</span><span class="n">FundingStream</span> <span class="n">idx</span><span class="p">,</span>
|
|
||||||
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">addresses</span><span class="p">,</span>
|
|
||||||
<span class="kt">uint64_t</span> <span class="n">valueNumerator</span><span class="p">,</span>
|
|
||||||
<span class="kt">uint64_t</span> <span class="n">valueDenominator</span><span class="p">,</span>
|
|
||||||
<span class="kt">int</span> <span class="n">startHeight</span><span class="p">,</span>
|
|
||||||
<span class="kt">int</span> <span class="n">endHeight</span><span class="p">)</span>
|
|
||||||
<span class="p">{</span>
|
|
||||||
<span class="n">assert</span><span class="p">(</span><span class="n">valueNumerator</span> <span class="o"><</span> <span class="n">valueDenominator</span><span class="p">);</span>
|
|
||||||
<span class="n">assert</span><span class="p">(</span><span class="n">valueNumerator</span> <span class="o"><</span> <span class="n">INT64_MAX</span> <span class="o">/</span> <span class="n">MAX_MONEY</span><span class="p">);</span>
|
|
||||||
<span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">addresses</span> <span class="o">=</span> <span class="n">addresses</span><span class="p">;</span>
|
|
||||||
<span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">valueNumerator</span> <span class="o">=</span> <span class="n">valueNumerator</span><span class="p">;</span>
|
|
||||||
<span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">valueDenominator</span> <span class="o">=</span> <span class="n">valueDenominator</span><span class="p">;</span>
|
|
||||||
<span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">startHeight</span> <span class="o">=</span> <span class="n">startHeight</span><span class="p">;</span>
|
|
||||||
<span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">endHeight</span> <span class="o">=</span> <span class="n">endHeight</span><span class="p">;</span>
|
|
||||||
<span class="n">assert</span><span class="p">(</span><span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">startHeight</span> <span class="o"><</span> <span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">endHeight</span><span class="p">);</span>
|
|
||||||
<span class="p">};</span>
|
|
||||||
|
|
||||||
<span class="n">CMainParams</span><span class="p">()</span> <span class="p">{</span>
|
|
||||||
<span class="p">...</span>
|
|
||||||
|
|
||||||
<span class="n">consensus</span><span class="p">.</span><span class="n">nFundingPeriodLength</span> <span class="o">=</span> <span class="n">consensus</span><span class="p">.</span><span class="n">nSubsidyPostBlossomHalvingInterval</span> <span class="o">/</span> <span class="mi">48</span><span class="p">;</span>
|
|
||||||
|
|
||||||
<span class="kt">int</span> <span class="n">devFundStartHeight</span> <span class="o">=</span> <span class="n">HeightForHalving</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
||||||
<span class="kt">int</span> <span class="n">devFundEndHeight</span> <span class="o">=</span> <span class="n">HeightForHalving</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
|
|
||||||
<span class="n">AddZIP207FundingStream</span><span class="p">(</span><span class="n">consensus</span><span class="p">,</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">FS_ECC</span><span class="p">,</span> <span class="n">FS_ECC_ADDRESSES</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="n">devFundStartHeight</span><span class="p">,</span> <span class="n">devFundEndHeight</span><span class="p">);</span>
|
|
||||||
<span class="n">AddZIP207FundingStream</span><span class="p">(</span><span class="n">consensus</span><span class="p">,</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">FS_ZF</span><span class="p">,</span> <span class="n">FS_ZF_ADDRESSES</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="n">devFundStartHeight</span><span class="p">,</span> <span class="n">devFundEndHeight</span><span class="p">);</span>
|
|
||||||
<span class="n">AddZIP207FundingStream</span><span class="p">(</span><span class="n">consensus</span><span class="p">,</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">FS_MG</span><span class="p">,</span> <span class="n">FS_MG_ADDRESSES</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="n">devFundStartHeight</span><span class="p">,</span> <span class="n">devFundEndHeight</span><span class="p">);</span>
|
|
||||||
|
|
||||||
<span class="p">...</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
|
|
||||||
<span class="n">CScript</span> <span class="n">FundingStreamRecipientAddress</span><span class="p">(</span>
|
|
||||||
<span class="kt">int</span> <span class="n">nHeight</span><span class="p">,</span>
|
|
||||||
<span class="k">const</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">Params</span><span class="o">&</span> <span class="n">params</span><span class="p">,</span>
|
|
||||||
<span class="n">Consensus</span><span class="o">::</span><span class="n">FundingStream</span> <span class="n">idx</span><span class="p">)</span>
|
|
||||||
<span class="p">{</span>
|
|
||||||
<span class="n">assert</span><span class="p">(</span><span class="n">nHeight</span> <span class="o"><=</span> <span class="n">INT_MAX</span> <span class="o">-</span> <span class="n">params</span><span class="p">.</span><span class="n">nSubsidyPostBlossomHalvingInterval</span><span class="p">);</span>
|
|
||||||
<span class="n">assert</span><span class="p">(</span><span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">startHeight</span> <span class="o"><=</span> <span class="n">INT_MAX</span> <span class="o">-</span> <span class="n">params</span><span class="p">.</span><span class="n">nSubsidyPostBlossomHalvingInterval</span><span class="p">);</span>
|
|
||||||
|
|
||||||
<span class="kt">int</span> <span class="n">curPeriodNumerator</span> <span class="o">=</span> <span class="n">nHeight</span> <span class="o">+</span> <span class="n">params</span><span class="p">.</span><span class="n">nSubsidyPostBlossomHalvingInterval</span> <span class="o">-</span> <span class="n">HeightForHalving</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
||||||
<span class="kt">int</span> <span class="n">startPeriodNumerator</span> <span class="o">=</span> <span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">startHeight</span> <span class="o">+</span> <span class="n">params</span><span class="p">.</span><span class="n">nSubsidyPostBlossomHalvingInterval</span>
|
|
||||||
<span class="o">-</span> <span class="n">HeightForHalving</span><span class="p">(</span><span class="n">params</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
||||||
|
|
||||||
<span class="c1">// Integer division is floor division for nonnegative integers in C++</span>
|
|
||||||
<span class="n">assert</span><span class="p">(</span><span class="n">curPeriodNumerator</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">);</span>
|
|
||||||
<span class="n">assert</span><span class="p">(</span><span class="n">startPeriodNumerator</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">);</span>
|
|
||||||
<span class="k">auto</span> <span class="n">curPeriod</span> <span class="o">=</span> <span class="n">curPeriodNumerator</span> <span class="o">/</span> <span class="n">params</span><span class="p">.</span><span class="n">nFundingPeriodLength</span><span class="p">;</span>
|
|
||||||
<span class="k">auto</span> <span class="n">startPeriod</span> <span class="o">=</span> <span class="n">startPeriodNumerator</span> <span class="o">/</span> <span class="n">params</span><span class="p">.</span><span class="n">nFundingPeriodLength</span><span class="p">;</span>
|
|
||||||
<span class="k">auto</span> <span class="n">addressIndex</span> <span class="o">=</span> <span class="n">curPeriod</span> <span class="o">-</span> <span class="n">startPeriod</span><span class="p">;</span>
|
|
||||||
|
|
||||||
<span class="k">auto</span> <span class="n">addresses</span> <span class="o">=</span> <span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">addresses</span><span class="p">;</span>
|
|
||||||
<span class="n">assert</span><span class="p">(</span><span class="n">addressIndex</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">&&</span> <span class="n">addressIndex</span> <span class="o"><</span> <span class="n">addresses</span><span class="p">.</span><span class="n">size</span><span class="p">());</span>
|
|
||||||
<span class="k">return</span> <span class="n">addresses</span><span class="p">[</span><span class="n">addressIndex</span><span class="p">];</span>
|
|
||||||
<span class="p">};</span>
|
|
||||||
|
|
||||||
<span class="n">CAmount</span> <span class="nf">FundingStreamValue</span><span class="p">(</span>
|
|
||||||
<span class="kt">int</span> <span class="n">nHeight</span><span class="p">,</span>
|
|
||||||
<span class="k">const</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">Params</span><span class="o">&</span> <span class="n">params</span><span class="p">,</span>
|
|
||||||
<span class="n">Consensus</span><span class="o">::</span><span class="n">FundingStream</span> <span class="n">idx</span><span class="p">)</span>
|
|
||||||
<span class="p">{</span>
|
|
||||||
<span class="c1">// Integer division is floor division for nonnegative integers in C++</span>
|
|
||||||
<span class="k">return</span> <span class="n">CAmount</span><span class="p">((</span>
|
|
||||||
<span class="n">GetBlockSubsidy</span><span class="p">(</span><span class="n">nHeight</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span> <span class="o">*</span> <span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">valueNumerator</span>
|
|
||||||
<span class="p">)</span> <span class="o">/</span> <span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">valueDenominator</span><span class="p">);</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
|
|
||||||
<span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">CScript</span><span class="p">,</span> <span class="n">CAmount</span><span class="o">>></span> <span class="n">GetActiveFundingStreams</span><span class="p">(</span>
|
|
||||||
<span class="kt">int</span> <span class="n">nHeight</span><span class="p">,</span>
|
|
||||||
<span class="k">const</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">Params</span><span class="o">&</span> <span class="n">params</span><span class="p">)</span>
|
|
||||||
<span class="p">{</span>
|
|
||||||
<span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">CScript</span><span class="p">,</span> <span class="n">CAmount</span><span class="o">>></span> <span class="n">requiredStreams</span><span class="p">;</span>
|
|
||||||
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">idx</span> <span class="o">=</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">FIRST_FUNDING_STREAM</span><span class="p">;</span> <span class="n">idx</span> <span class="o"><</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">MAX_FUNDING_STREAMS</span><span class="p">;</span> <span class="n">idx</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
|
||||||
<span class="c1">// Funding period is [startHeight, endHeight)</span>
|
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="n">nHeight</span> <span class="o">>=</span> <span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">startHeight</span> <span class="o">&&</span>
|
|
||||||
<span class="n">nHeight</span> <span class="o"><</span> <span class="n">params</span><span class="p">.</span><span class="n">vFundingPeriods</span><span class="p">[</span><span class="n">idx</span><span class="p">].</span><span class="n">endHeight</span><span class="p">)</span>
|
|
||||||
<span class="p">{</span>
|
|
||||||
<span class="n">requiredStreams</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">make_pair</span><span class="p">(</span>
|
|
||||||
<span class="n">FundingStreamRecipientAddress</span><span class="p">(</span><span class="n">nHeight</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">idx</span><span class="p">),</span>
|
|
||||||
<span class="n">FundingStreamValue</span><span class="p">(</span><span class="n">nHeight</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">idx</span><span class="p">));</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="k">return</span> <span class="n">requiredStreams</span><span class="p">;</span>
|
|
||||||
<span class="p">};</span>
|
|
||||||
|
|
||||||
<span class="kt">bool</span> <span class="nf">ContextualCheckBlock</span><span class="p">(...)</span>
|
|
||||||
<span class="p">{</span>
|
|
||||||
<span class="p">...</span>
|
|
||||||
|
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="n">NetworkUpgradeActive</span><span class="p">(</span><span class="n">nHeight</span><span class="p">,</span> <span class="n">consensusParams</span><span class="p">,</span> <span class="n">Consensus</span><span class="o">::</span><span class="n">UPGRADE_CANOPY</span><span class="p">))</span> <span class="p">{</span>
|
|
||||||
<span class="c1">// Coinbase transaction must include outputs corresponding to the consensus</span>
|
|
||||||
<span class="c1">// funding streams active at the current block height.</span>
|
|
||||||
<span class="k">auto</span> <span class="n">requiredStreams</span> <span class="o">=</span> <span class="n">GetActiveFundingStreams</span><span class="p">(</span><span class="n">nHeight</span><span class="p">,</span> <span class="n">consensusParams</span><span class="p">);</span>
|
|
||||||
|
|
||||||
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">CTxOut</span><span class="o">&</span> <span class="nl">output</span> <span class="p">:</span> <span class="n">block</span><span class="p">.</span><span class="n">vtx</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">vout</span><span class="p">)</span> <span class="p">{</span>
|
|
||||||
<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">requiredStreams</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span> <span class="n">it</span> <span class="o">!=</span> <span class="n">requiredStreams</span><span class="p">.</span><span class="n">end</span><span class="p">();</span> <span class="o">++</span><span class="n">it</span><span class="p">)</span> <span class="p">{</span>
|
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="n">output</span><span class="p">.</span><span class="n">scriptPubKey</span> <span class="o">==</span> <span class="n">it</span><span class="o">-></span><span class="n">first</span> <span class="o">&&</span> <span class="n">output</span><span class="p">.</span><span class="n">nValue</span> <span class="o">==</span> <span class="n">it</span><span class="o">-></span><span class="n">second</span><span class="p">)</span> <span class="p">{</span>
|
|
||||||
<span class="n">requiredStreams</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">it</span><span class="p">);</span>
|
|
||||||
<span class="k">break</span><span class="p">;</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
|
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">requiredStreams</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
|
|
||||||
<span class="k">return</span> <span class="n">state</span><span class="p">.</span><span class="n">DoS</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="n">error</span><span class="p">(</span><span class="s">"%s: funding stream missing"</span><span class="p">,</span> <span class="n">__func__</span><span class="p">),</span>
|
|
||||||
<span class="n">REJECT_INVALID</span><span class="p">,</span> <span class="s">"cb-funding-stream-missing"</span><span class="p">);</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
||||||
<span class="c1">// Coinbase transaction must include an output sending 20% of</span>
|
|
||||||
<span class="c1">// the block subsidy to a Founders' Reward script, until the last Founders'</span>
|
|
||||||
<span class="c1">// Reward block is reached, with exception of the genesis block.</span>
|
|
||||||
<span class="c1">// The last Founders' Reward block is defined as the block just before the</span>
|
|
||||||
<span class="c1">// first subsidy halving block.</span>
|
|
||||||
<span class="k">if</span> <span class="p">((</span><span class="n">nHeight</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="o">&&</span> <span class="p">(</span><span class="n">nHeight</span> <span class="o"><=</span> <span class="n">consensusParams</span><span class="p">.</span><span class="n">GetLastFoundersRewardBlockHeight</span><span class="p">()))</span> <span class="p">{</span>
|
|
||||||
<span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
|
|
||||||
|
|
||||||
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">CTxOut</span><span class="o">&</span> <span class="nl">output</span> <span class="p">:</span> <span class="n">block</span><span class="p">.</span><span class="n">vtx</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">vout</span><span class="p">)</span> <span class="p">{</span>
|
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="n">output</span><span class="p">.</span><span class="n">scriptPubKey</span> <span class="o">==</span> <span class="n">Params</span><span class="p">().</span><span class="n">GetFoundersRewardScriptAtHeight</span><span class="p">(</span><span class="n">nHeight</span><span class="p">))</span> <span class="p">{</span>
|
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="n">output</span><span class="p">.</span><span class="n">nValue</span> <span class="o">==</span> <span class="p">(</span><span class="n">GetBlockSubsidy</span><span class="p">(</span><span class="n">nHeight</span><span class="p">,</span> <span class="n">consensusParams</span><span class="p">)</span> <span class="o">/</span> <span class="mi">5</span><span class="p">))</span> <span class="p">{</span>
|
|
||||||
<span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
|
|
||||||
<span class="k">break</span><span class="p">;</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
|
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">found</span><span class="p">)</span> <span class="p">{</span>
|
|
||||||
<span class="k">return</span> <span class="n">state</span><span class="p">.</span><span class="n">DoS</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="n">error</span><span class="p">(</span><span class="s">"%s: founders reward missing"</span><span class="p">,</span> <span class="n">__func__</span><span class="p">),</span>
|
|
||||||
<span class="n">REJECT_INVALID</span><span class="p">,</span> <span class="s">"cb-no-founders-reward"</span><span class="p">);</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
<span class="p">}</span>
|
|
||||||
|
|
||||||
<span class="p">...</span>
|
|
||||||
<span class="p">}</span></pre>
|
|
||||||
</section>
|
|
||||||
</section>
|
</section>
|
||||||
<section id="deployment"><h2><span class="section-heading">Deployment</span><span class="section-anchor"> <a rel="bookmark" href="#deployment"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
<section id="deployment"><h2><span class="section-heading">Deployment</span><span class="section-anchor"> <a rel="bookmark" href="#deployment"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||||||
<p>This proposal is intended to be deployed with Canopy. <a id="id23" class="footnote_reference" href="#zip-0251">15</a></p>
|
<p>This proposal is intended to be deployed with Canopy. <a id="id23" class="footnote_reference" href="#zip-0251">15</a></p>
|
||||||
|
@ -377,7 +216,11 @@ License: MIT</pre>
|
||||||
<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 consensus branch that persists.</p>
|
<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 consensus branch that persists.</p>
|
||||||
</section>
|
</section>
|
||||||
<section id="reference-implementation"><h2><span class="section-heading">Reference Implementation</span><span class="section-anchor"> <a rel="bookmark" href="#reference-implementation"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
<section id="reference-implementation"><h2><span class="section-heading">Reference Implementation</span><span class="section-anchor"> <a rel="bookmark" href="#reference-implementation"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||||||
<p>TBC</p>
|
<ul>
|
||||||
|
<li><a href="https://github.com/zcash/zcash/pull/4560">https://github.com/zcash/zcash/pull/4560</a></li>
|
||||||
|
<li><a href="https://github.com/zcash/zcash/pull/4675">https://github.com/zcash/zcash/pull/4675</a></li>
|
||||||
|
<li><a href="https://github.com/zcash/zcash/pull/4830">https://github.com/zcash/zcash/pull/4830</a></li>
|
||||||
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
<section id="references"><h2><span class="section-heading">References</span><span class="section-anchor"> <a rel="bookmark" href="#references"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
<section id="references"><h2><span class="section-heading">References</span><span class="section-anchor"> <a rel="bookmark" href="#references"><img width="24" height="24" src="assets/images/section-anchor.png" alt=""></a></span></h2>
|
||||||
<table id="rfc2119" class="footnote">
|
<table id="rfc2119" class="footnote">
|
||||||
|
|
170
zip-0207.rst
170
zip-0207.rst
|
@ -206,172 +206,6 @@ Funding stream definitions can be added, changed, or deleted in ZIPs associated
|
||||||
with subsequent network upgrades, subject to the ZIP process. [#zip-0000]_
|
with subsequent network upgrades, subject to the ZIP process. [#zip-0000]_
|
||||||
|
|
||||||
|
|
||||||
Example implementation
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
.. code:: cpp
|
|
||||||
|
|
||||||
struct FundingPeriod {
|
|
||||||
std::vector<std::string> addresses,
|
|
||||||
uint64_t valueNumerator,
|
|
||||||
uint64_t valueDenominator,
|
|
||||||
int startHeight,
|
|
||||||
int endHeight,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum FundingStream {
|
|
||||||
FS_ECC,
|
|
||||||
FS_ZF,
|
|
||||||
FS_MG,
|
|
||||||
MAX_FUNDING_STREAMS,
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto FIRST_FUNDING_STREAM = FS_ECC;
|
|
||||||
|
|
||||||
struct Params {
|
|
||||||
...
|
|
||||||
int nFundingPeriodLength;
|
|
||||||
FundingPeriod vFundingPeriods[MAX_FUNDING_STREAMS];
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddZIP207FundingStream(
|
|
||||||
Consensus::Params& params,
|
|
||||||
Consensus::FundingStream idx,
|
|
||||||
std::vector<std::string> addresses,
|
|
||||||
uint64_t valueNumerator,
|
|
||||||
uint64_t valueDenominator,
|
|
||||||
int startHeight,
|
|
||||||
int endHeight)
|
|
||||||
{
|
|
||||||
assert(valueNumerator < valueDenominator);
|
|
||||||
assert(valueNumerator < INT64_MAX / MAX_MONEY);
|
|
||||||
params.vFundingPeriods[idx].addresses = addresses;
|
|
||||||
params.vFundingPeriods[idx].valueNumerator = valueNumerator;
|
|
||||||
params.vFundingPeriods[idx].valueDenominator = valueDenominator;
|
|
||||||
params.vFundingPeriods[idx].startHeight = startHeight;
|
|
||||||
params.vFundingPeriods[idx].endHeight = endHeight;
|
|
||||||
assert(params.vFundingPeriods[idx].startHeight < params.vFundingPeriods[idx].endHeight);
|
|
||||||
};
|
|
||||||
|
|
||||||
CMainParams() {
|
|
||||||
...
|
|
||||||
|
|
||||||
consensus.nFundingPeriodLength = consensus.nSubsidyPostBlossomHalvingInterval / 48;
|
|
||||||
|
|
||||||
int devFundStartHeight = HeightForHalving(params, 1);
|
|
||||||
int devFundEndHeight = HeightForHalving(params, 2);
|
|
||||||
AddZIP207FundingStream(consensus, Consensus::FS_ECC, FS_ECC_ADDRESSES, 7, 100, devFundStartHeight, devFundEndHeight);
|
|
||||||
AddZIP207FundingStream(consensus, Consensus::FS_ZF, FS_ZF_ADDRESSES, 5, 100, devFundStartHeight, devFundEndHeight);
|
|
||||||
AddZIP207FundingStream(consensus, Consensus::FS_MG, FS_MG_ADDRESSES, 8, 100, devFundStartHeight, devFundEndHeight);
|
|
||||||
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
CScript FundingStreamRecipientAddress(
|
|
||||||
int nHeight,
|
|
||||||
const Consensus::Params& params,
|
|
||||||
Consensus::FundingStream idx)
|
|
||||||
{
|
|
||||||
assert(nHeight <= INT_MAX - params.nSubsidyPostBlossomHalvingInterval);
|
|
||||||
assert(params.vFundingPeriods[idx].startHeight <= INT_MAX - params.nSubsidyPostBlossomHalvingInterval);
|
|
||||||
|
|
||||||
int curPeriodNumerator = nHeight + params.nSubsidyPostBlossomHalvingInterval - HeightForHalving(params, 1);
|
|
||||||
int startPeriodNumerator = params.vFundingPeriods[idx].startHeight + params.nSubsidyPostBlossomHalvingInterval
|
|
||||||
- HeightForHalving(params, 1);
|
|
||||||
|
|
||||||
// Integer division is floor division for nonnegative integers in C++
|
|
||||||
assert(curPeriodNumerator >= 0);
|
|
||||||
assert(startPeriodNumerator >= 0);
|
|
||||||
auto curPeriod = curPeriodNumerator / params.nFundingPeriodLength;
|
|
||||||
auto startPeriod = startPeriodNumerator / params.nFundingPeriodLength;
|
|
||||||
auto addressIndex = curPeriod - startPeriod;
|
|
||||||
|
|
||||||
auto addresses = params.vFundingPeriods[idx].addresses;
|
|
||||||
assert(addressIndex >= 0 && addressIndex < addresses.size());
|
|
||||||
return addresses[addressIndex];
|
|
||||||
};
|
|
||||||
|
|
||||||
CAmount FundingStreamValue(
|
|
||||||
int nHeight,
|
|
||||||
const Consensus::Params& params,
|
|
||||||
Consensus::FundingStream idx)
|
|
||||||
{
|
|
||||||
// Integer division is floor division for nonnegative integers in C++
|
|
||||||
return CAmount((
|
|
||||||
GetBlockSubsidy(nHeight, params) * params.vFundingPeriods[idx].valueNumerator
|
|
||||||
) / params.vFundingPeriods[idx].valueDenominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::set<std::pair<CScript, CAmount>> GetActiveFundingStreams(
|
|
||||||
int nHeight,
|
|
||||||
const Consensus::Params& params)
|
|
||||||
{
|
|
||||||
std::set<std::pair<CScript, CAmount>> requiredStreams;
|
|
||||||
for (int idx = Consensus::FIRST_FUNDING_STREAM; idx < Consensus::MAX_FUNDING_STREAMS; idx++) {
|
|
||||||
// Funding period is [startHeight, endHeight)
|
|
||||||
if (nHeight >= params.vFundingPeriods[idx].startHeight &&
|
|
||||||
nHeight < params.vFundingPeriods[idx].endHeight)
|
|
||||||
{
|
|
||||||
requiredStreams.insert(std::make_pair(
|
|
||||||
FundingStreamRecipientAddress(nHeight, params, idx),
|
|
||||||
FundingStreamValue(nHeight, params, idx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return requiredStreams;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool ContextualCheckBlock(...)
|
|
||||||
{
|
|
||||||
...
|
|
||||||
|
|
||||||
if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_CANOPY)) {
|
|
||||||
// Coinbase transaction must include outputs corresponding to the consensus
|
|
||||||
// funding streams active at the current block height.
|
|
||||||
auto requiredStreams = GetActiveFundingStreams(nHeight, consensusParams);
|
|
||||||
|
|
||||||
for (const CTxOut& output : block.vtx[0].vout) {
|
|
||||||
for (auto it = requiredStreams.begin(); it != requiredStreams.end(); ++it) {
|
|
||||||
if (output.scriptPubKey == it->first && output.nValue == it->second) {
|
|
||||||
requiredStreams.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!requiredStreams.empty()) {
|
|
||||||
return state.DoS(100, error("%s: funding stream missing", __func__),
|
|
||||||
REJECT_INVALID, "cb-funding-stream-missing");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Coinbase transaction must include an output sending 20% of
|
|
||||||
// the block subsidy to a Founders' Reward script, until the last Founders'
|
|
||||||
// Reward block is reached, with exception of the genesis block.
|
|
||||||
// The last Founders' Reward block is defined as the block just before the
|
|
||||||
// first subsidy halving block.
|
|
||||||
if ((nHeight > 0) && (nHeight <= consensusParams.GetLastFoundersRewardBlockHeight())) {
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (const CTxOut& output : block.vtx[0].vout) {
|
|
||||||
if (output.scriptPubKey == Params().GetFoundersRewardScriptAtHeight(nHeight)) {
|
|
||||||
if (output.nValue == (GetBlockSubsidy(nHeight, consensusParams) / 5)) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
return state.DoS(100, error("%s: founders reward missing", __func__),
|
|
||||||
REJECT_INVALID, "cb-no-founders-reward");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Deployment
|
Deployment
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
@ -391,7 +225,9 @@ pre-upgrade consensus branch that persists.
|
||||||
Reference Implementation
|
Reference Implementation
|
||||||
========================
|
========================
|
||||||
|
|
||||||
TBC
|
* https://github.com/zcash/zcash/pull/4560
|
||||||
|
* https://github.com/zcash/zcash/pull/4675
|
||||||
|
* https://github.com/zcash/zcash/pull/4830
|
||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
|
|
Loading…
Reference in New Issue