ZIP 207: remove example implementation and add links to zcashd PRs.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2020-11-10 14:55:48 +00:00
parent ef94502ba3
commit 03e57714c1
2 changed files with 8 additions and 329 deletions

View File

@ -208,167 +208,6 @@ License: MIT</pre>
</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>
</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</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">&amp;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</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">&lt;</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">&lt;</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">&lt;</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">&amp;</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">&lt;=</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">&lt;=</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">&gt;=</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">&gt;=</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">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">addressIndex</span> <span class="o">&lt;</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">&amp;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">CScript</span><span class="p">,</span> <span class="n">CAmount</span><span class="o">&gt;&gt;</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">&amp;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">CScript</span><span class="p">,</span> <span class="n">CAmount</span><span class="o">&gt;&gt;</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">&lt;</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">&gt;=</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">&amp;&amp;</span>
<span class="n">nHeight</span> <span class="o">&lt;</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">&amp;</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">-&gt;</span><span class="n">first</span> <span class="o">&amp;&amp;</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">-&gt;</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">&quot;%s: funding stream missing&quot;</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">&quot;cb-funding-stream-missing&quot;</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&#39; Reward script, until the last Founders&#39;</span>
<span class="c1">// Reward block is reached, with exception of the genesis block.</span>
<span class="c1">// The last Founders&#39; 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">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">nHeight</span> <span class="o">&lt;=</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">&amp;</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">&quot;%s: founders reward missing&quot;</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">&quot;cb-no-founders-reward&quot;</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 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>
@ -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>
</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>
<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 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">

View File

@ -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]_
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
==========
@ -391,7 +225,9 @@ pre-upgrade consensus branch that persists.
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