Update documentation.

This commit is contained in:
Romain Ruetschi
2016-11-20 23:11:43 +01:00
committed by Romain Ruetschi
parent 2593789b0a
commit 28d7824b8c
9 changed files with 209 additions and 132 deletions

View File

@ -47,7 +47,7 @@
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-0' class='srclink' href='../src/merkle/src/lib.rs.html#2-17' title='goto source code'>[src]</a></span></h1>
</span><a id='src-0' class='srclink' href='../src/merkle/src/lib.rs.html#1-18' title='goto source code'>[src]</a></span></h1>
<div class='docblock'><p><em>merkle</em> implements a Merkle Tree in Rust.</p>
</div><h2 id='structs' class='section-header'><a href="#structs">Structs</a></h2>
<table>

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../merkle/struct.Proof.html">
</head>
<body>
<p>Redirecting to <a href="../../merkle/struct.Proof.html">../../merkle/struct.Proof.html</a>...</p>
<script>location.replace("../../merkle/struct.Proof.html" + location.search + location.hash);</script>
</body>
</html>

View File

@ -47,31 +47,30 @@
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-10' class='srclink' href='../src/merkle/src/merkletree.rs.html#14-26' title='goto source code'>[src]</a></span></h1>
</span><a id='src-10' class='srclink' href='../src/merkle/src/merkletree.rs.html#12-24' title='goto source code'>[src]</a></span></h1>
<pre class='rust struct'>pub struct MerkleTree&lt;D,&nbsp;T&gt; {
pub digest: D,
pub tree: Tree&lt;T&gt;,
pub height: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a>,
pub count: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a>,
// some fields omitted
}</pre><div class='docblock'><p>A Merkle tree is a binary tree, with values of type <code>T</code> at the leafs,
and where every node holds the hash of the concatenation of the hashes of
its children nodes.</p>
</div><h2 class='fields'>Fields</h2><span id='structfield.digest' class='structfield'><code>digest: D</code>
</span><span class='stab '></span><div class='docblock'><p>The hashing function used by this Merkle tree</p>
</div><span id='structfield.tree' class='structfield'><code>tree: Tree&lt;T&gt;</code>
</span><span class='stab '></span><div class='docblock'><p>The inner binary tree</p>
</div><span id='structfield.height' class='structfield'><code>height: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a></code>
</span><span class='stab '></span><div class='docblock'><p>The height of the tree</p>
</div><span id='structfield.count' class='structfield'><code>count: <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a></code>
</span><span class='stab '></span><div class='docblock'><p>The number of leaf nodes in the tree</p>
</div><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl&lt;D,&nbsp;T&gt; <a class='struct' href='../merkle/struct.MerkleTree.html' title='merkle::MerkleTree'>MerkleTree</a>&lt;D,&nbsp;T&gt; <span class='where'>where D: Digest + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a>, T: <a class='trait' href='https://doc.rust-lang.org/nightly/core/convert/trait.Into.html' title='core::convert::Into'>Into</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt; + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a></span></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-17' class='srclink' href='../src/merkle/src/merkletree.rs.html#28-109' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.from_vec' class='method'><code>fn <a href='#method.from_vec' class='fnname'>from_vec</a>(digest: D, values: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;T&gt;) -&gt; Self</code></h4>
<div class='docblock'><p>Constructs a Merkle Tree from a vector of data blocks</p>
</div><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl&lt;D,&nbsp;T&gt; <a class='struct' href='../merkle/struct.MerkleTree.html' title='merkle::MerkleTree'>MerkleTree</a>&lt;D,&nbsp;T&gt; <span class='where'>where D: Digest + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a>, T: <a class='trait' href='https://doc.rust-lang.org/nightly/core/convert/trait.Into.html' title='core::convert::Into'>Into</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt; + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a></span></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-17' class='srclink' href='../src/merkle/src/merkletree.rs.html#26-124' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.from_vec_unsafe' class='method'><code>fn <a href='#method.from_vec_unsafe' class='fnname'>from_vec_unsafe</a>(digest: D, values: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;T&gt;) -&gt; Self</code></h4>
<div class='docblock'><p>Constructs a Merkle Tree from a vector of data blocks.
WARNING: Panics if <code>values</code> is empty!</p>
</div><h4 id='method.from_vec' class='method'><code>fn <a href='#method.from_vec' class='fnname'>from_vec</a>(digest: D, values: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;T&gt;) -&gt; <a class='enum' href='https://doc.rust-lang.org/nightly/core/option/enum.Option.html' title='core::option::Option'>Option</a>&lt;Self&gt;</code></h4>
<div class='docblock'><p>Constructs a Merkle Tree from a vector of data blocks.
Returns None if <code>values</code> is empty.</p>
</div><h4 id='method.digest' class='method'><code>fn <a href='#method.digest' class='fnname'>digest</a>(&amp;self) -&gt; &amp;D</code></h4>
<div class='docblock'><p>Returns the hash function used in this Merkle tree</p>
</div><h4 id='method.root_hash' class='method'><code>fn <a href='#method.root_hash' class='fnname'>root_hash</a>(&amp;self) -&gt; &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code></h4>
<div class='docblock'><p>Returns the tree&#39;s root hash</p>
<div class='docblock'><p>Returns the root hash of Merkle tree</p>
</div><h4 id='method.height' class='method'><code>fn <a href='#method.height' class='fnname'>height</a>(&amp;self) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a></code></h4>
<div class='docblock'><p>Returns the height of Merkle tree</p>
</div><h4 id='method.count' class='method'><code>fn <a href='#method.count' class='fnname'>count</a>(&amp;self) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.usize.html'>usize</a></code></h4>
<div class='docblock'><p>Returns the number of leaves in the Merkle tree</p>
</div><h4 id='method.gen_proof' class='method'><code>fn <a href='#method.gen_proof' class='fnname'>gen_proof</a>(&amp;self, value: &amp;T) -&gt; <a class='enum' href='https://doc.rust-lang.org/nightly/core/option/enum.Option.html' title='core::option::Option'>Option</a>&lt;<a class='struct' href='../merkle/struct.Proof.html' title='merkle::Proof'>Proof</a>&lt;D,&nbsp;T&gt;&gt;</code></h4>
<div class='docblock'><p>Generate an inclusion proof for the given value.
<code>None</code> is returned if the given value is not found in the tree.</p>
Returns <code>None</code> if the given value is not found in the tree.</p>
</div></div></section>
<section id='search' class="content hidden"></section>

View File

@ -47,22 +47,18 @@
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-50' class='srclink' href='../src/merkle/src/proof.rs.html#9-14' title='goto source code'>[src]</a></span></h1>
</span><a id='src-60' class='srclink' href='../src/merkle/src/proof.rs.html#11-16' title='goto source code'>[src]</a></span></h1>
<pre class='rust struct'>pub struct Proof&lt;D,&nbsp;T&gt; {
pub digest: D,
pub root_hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;,
pub block: ProofBlock,
pub value: T,
// some fields omitted
}</pre><div class='docblock'><p>An inclusion proof represent the fact that a <code>value</code> is a member
of a <code>MerkleTree</code> with root hash <code>root_hash</code>, and hash function <code>digest</code>.</p>
</div><h2 class='fields'>Fields</h2><span id='structfield.digest' class='structfield'><code>digest: D</code>
</span><span class='stab '></span><span id='structfield.root_hash' class='structfield'><code>root_hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;</code>
</span><span class='stab '></span><span id='structfield.block' class='structfield'><code>block: ProofBlock</code>
</span><span class='stab '></span><span id='structfield.value' class='structfield'><code>value: T</code>
</span><span class='stab '></span><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl&lt;D,&nbsp;T&gt; <a class='struct' href='../merkle/struct.Proof.html' title='merkle::Proof'>Proof</a>&lt;D,&nbsp;T&gt; <span class='where'>where D: Digest + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a>, T: <a class='trait' href='https://doc.rust-lang.org/nightly/core/convert/trait.Into.html' title='core::convert::Into'>Into</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt; + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a></span></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-57' class='srclink' href='../src/merkle/src/proof.rs.html#16-51' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.validate' class='method'><code>fn <a href='#method.validate' class='fnname'>validate</a>(&amp;self, root_hash: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.bool.html'>bool</a></code></h4>
<h4 id='method.validate_block' class='method'><code>fn <a href='#method.validate_block' class='fnname'>validate_block</a>(&amp;self, block: &amp;ProofBlock, digest: &amp;mut D) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.bool.html'>bool</a></code></h4>
</div></section>
</div><h2 id='methods'>Methods</h2><h3 class='impl'><span class='in-band'><code>impl&lt;D,&nbsp;T&gt; <a class='struct' href='../merkle/struct.Proof.html' title='merkle::Proof'>Proof</a>&lt;D,&nbsp;T&gt; <span class='where'>where D: Digest + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a>, T: <a class='trait' href='https://doc.rust-lang.org/nightly/core/convert/trait.Into.html' title='core::convert::Into'>Into</a>&lt;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;&gt; + <a class='trait' href='https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html' title='core::clone::Clone'>Clone</a></span></code></span><span class='out-of-band'><div class='ghost'></div><a id='src-67' class='srclink' href='../src/merkle/src/proof.rs.html#18-70' title='goto source code'>[src]</a></span></h3>
<div class='impl-items'><h4 id='method.new' class='method'><code>fn <a href='#method.new' class='fnname'>new</a>(digest: D, root_hash: <a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;, lemma: Lemma) -&gt; Self</code></h4>
<div class='docblock'><p>Constructs a new <code>Proof</code></p>
</div><h4 id='method.validate' class='method'><code>fn <a href='#method.validate' class='fnname'>validate</a>(&amp;self, root_hash: &amp;<a class='struct' href='https://doc.rust-lang.org/nightly/collections/vec/struct.Vec.html' title='collections::vec::Vec'>Vec</a>&lt;<a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.u8.html'>u8</a>&gt;) -&gt; <a class='primitive' href='https://doc.rust-lang.org/nightly/std/primitive.bool.html'>bool</a></code></h4>
<div class='docblock'><p>Checks whether this inclusion proof is well-formed,
and whether its root hash matches the given <code>root_hash</code>.</p>
</div></div></section>
<section id='search' class="content hidden"></section>
<section class="footer"></section>

View File

@ -1,3 +1,3 @@
var searchIndex = {};
searchIndex["merkle"] = {"doc":"*merkle* implements a Merkle Tree in Rust.","items":[[3,"MerkleTree","merkle","A Merkle tree is a binary tree, with values of type `T` at the leafs,\nand where every node holds the hash of the concatenation of the hashes of\nits children nodes.",null,null],[12,"digest","","The hashing function used by this Merkle tree",0,null],[12,"tree","","The inner binary tree",0,null],[12,"height","","The height of the tree",0,null],[12,"count","","The number of leaf nodes in the tree",0,null],[3,"Proof","","An inclusion proof represent the fact that a `value` is a member\nof a `MerkleTree` with root hash `root_hash`, and hash function `digest`.",null,null],[12,"digest","","",1,null],[12,"root_hash","","",1,null],[12,"block","","",1,null],[12,"value","","",1,null],[11,"from_vec","","Constructs a Merkle Tree from a vector of data blocks",0,{"inputs":[{"name":"d"},{"name":"vec"}],"output":{"name":"self"}}],[11,"root_hash","","Returns the tree&#39;s root hash",0,null],[11,"gen_proof","","Generate an inclusion proof for the given value.\n`None` is returned if the given value is not found in the tree.",0,null],[11,"validate","","",1,null],[11,"validate_block","","",1,null]],"paths":[[3,"MerkleTree"],[3,"Proof"]]};
searchIndex["merkle"] = {"doc":"*merkle* implements a Merkle Tree in Rust.","items":[[3,"MerkleTree","merkle","A Merkle tree is a binary tree, with values of type `T` at the leafs,\nand where every node holds the hash of the concatenation of the hashes of\nits children nodes.",null,null],[3,"Proof","","An inclusion proof represent the fact that a `value` is a member\nof a `MerkleTree` with root hash `root_hash`, and hash function `digest`.",null,null],[11,"from_vec_unsafe","","Constructs a Merkle Tree from a vector of data blocks.\nWARNING: Panics if `values` is empty!",0,{"inputs":[{"name":"d"},{"name":"vec"}],"output":{"name":"self"}}],[11,"from_vec","","Constructs a Merkle Tree from a vector of data blocks.\nReturns None if `values` is empty.",0,{"inputs":[{"name":"d"},{"name":"vec"}],"output":{"name":"option"}}],[11,"digest","","Returns the hash function used in this Merkle tree",0,null],[11,"root_hash","","Returns the root hash of Merkle tree",0,null],[11,"height","","Returns the height of Merkle tree",0,null],[11,"count","","Returns the number of leaves in the Merkle tree",0,null],[11,"gen_proof","","Generate an inclusion proof for the given value.\nReturns `None` if the given value is not found in the tree.",0,null],[11,"new","","Constructs a new `Proof`",1,{"inputs":[{"name":"d"},{"name":"vec"},{"name":"lemma"}],"output":{"name":"self"}}],[11,"validate","","Checks whether this inclusion proof is well-formed,\nand whether its root hash matches the given `root_hash`.",1,null]],"paths":[[3,"MerkleTree"],[3,"Proof"]]};
initSearch(searchIndex);

View File

@ -60,7 +60,9 @@
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
</pre><pre class='rust '>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>warn</span>(<span class='ident'>missing_docs</span>)]</span>
<span class='doccomment'>//! *merkle* implements a Merkle Tree in Rust.</span>

View File

@ -152,46 +152,65 @@
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
</pre><pre class='rust '>
<span class='kw'>use</span> <span class='ident'>crypto</span>::<span class='ident'>digest</span>::<span class='ident'>Digest</span>;
<span class='kw'>use</span> <span class='ident'>tree</span>::{ <span class='ident'>Tree</span> };
<span class='kw'>use</span> <span class='ident'>merkledigest</span>::{ <span class='ident'>MerkleDigest</span> };
<span class='kw'>use</span> <span class='ident'>tree</span>::<span class='ident'>Tree</span>;
<span class='kw'>use</span> <span class='ident'>merkledigest</span>::<span class='ident'>MerkleDigest</span>;
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>proof</span>::{
<span class='ident'>Proof</span>,
<span class='ident'>ProofBlock</span>
};
<span class='kw'>use</span> <span class='ident'>proof</span>::{ <span class='ident'>Proof</span>, <span class='ident'>Lemma</span> };
<span class='doccomment'>/// A Merkle tree is a binary tree, with values of type `T` at the leafs,</span>
<span class='doccomment'>/// and where every node holds the hash of the concatenation of the hashes of</span>
<span class='doccomment'>/// its children nodes.</span>
<span class='kw'>pub</span> <span class='kw'>struct</span> <span class='ident'>MerkleTree</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='doccomment'>/// The hashing function used by this Merkle tree</span>
<span class='kw'>pub</span> <span class='ident'>digest</span>: <span class='ident'>D</span>,
<span class='ident'>digest</span>: <span class='ident'>D</span>,
<span class='doccomment'>/// The inner binary tree</span>
<span class='kw'>pub</span> <span class='ident'>tree</span>: <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>,
<span class='doccomment'>/// The root of the inner binary tree</span>
<span class='ident'>root</span>: <span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>,
<span class='doccomment'>/// The height of the tree</span>
<span class='kw'>pub</span> <span class='ident'>height</span>: <span class='ident'>usize</span>,
<span class='ident'>height</span>: <span class='ident'>usize</span>,
<span class='doccomment'>/// The number of leaf nodes in the tree</span>
<span class='kw'>pub</span> <span class='ident'>count</span>: <span class='ident'>usize</span>
<span class='ident'>count</span>: <span class='ident'>usize</span>
}
<span class='kw'>impl</span> <span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='ident'>MerkleTree</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='kw'>where</span> <span class='ident'>D</span>: <span class='ident'>Digest</span> <span class='op'>+</span> <span class='ident'>Clone</span>, <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span> {
<span class='doccomment'>/// Constructs a Merkle Tree from a vector of data blocks</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>from_vec</span>(<span class='kw-2'>mut</span> <span class='ident'>digest</span>: <span class='ident'>D</span>, <span class='ident'>values</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='self'>Self</span> {
<span class='doccomment'>/// Constructs a Merkle Tree from a vector of data blocks. </span>
<span class='doccomment'>/// WARNING: Panics if `values` is empty!</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>from_vec_unsafe</span>(<span class='ident'>digest</span>: <span class='ident'>D</span>, <span class='ident'>values</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='self'>Self</span> {
<span class='self'>Self</span>::<span class='ident'>from_vec</span>(<span class='ident'>digest</span>, <span class='ident'>values</span>).<span class='ident'>unwrap</span>()
}
<span class='doccomment'>/// Constructs a Merkle Tree from a vector of data blocks. </span>
<span class='doccomment'>/// Returns None if `values` is empty.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>from_vec</span>(<span class='kw-2'>mut</span> <span class='ident'>digest</span>: <span class='ident'>D</span>, <span class='ident'>values</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='self'>Self</span><span class='op'>&gt;</span> {
<span class='kw'>if</span> <span class='ident'>values</span>.<span class='ident'>is_empty</span>() {
<span class='macro'>panic</span><span class='macro'>!</span>(<span class='string'>&quot;Cannot build a Merkle tree from an empty vector.&quot;</span>);
<span class='kw'>return</span> <span class='prelude-val'>None</span>
}
<span class='kw'>let</span> <span class='ident'>count</span> <span class='op'>=</span> <span class='ident'>values</span>.<span class='ident'>len</span>();
<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>height</span> <span class='op'>=</span> <span class='number'>0</span>;
<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>cur</span> <span class='op'>=</span> <span class='ident'>Vec</span>::<span class='ident'>with_capacity</span>(<span class='ident'>count</span>);
<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>cur</span> <span class='op'>=</span> <span class='ident'>Vec</span>::<span class='ident'>with_capacity</span>(<span class='ident'>count</span>);
<span class='kw'>for</span> <span class='ident'>v</span> <span class='kw'>in</span> <span class='ident'>values</span>.<span class='ident'>into_iter</span>() {
<span class='kw'>let</span> <span class='ident'>leaf</span> <span class='op'>=</span> <span class='ident'>Tree</span>::<span class='ident'>make_leaf</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>digest</span>, <span class='ident'>v</span>);
@ -209,8 +228,8 @@
<span class='kw'>let</span> <span class='ident'>right</span> <span class='op'>=</span> <span class='ident'>cur</span>.<span class='ident'>remove</span>(<span class='number'>0</span>);
<span class='kw'>let</span> <span class='ident'>combined_hash</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>combine_hashes</span>(
<span class='ident'>left</span>.<span class='ident'>get_hash</span>(),
<span class='ident'>right</span>.<span class='ident'>get_hash</span>()
<span class='ident'>left</span>.<span class='ident'>hash</span>(),
<span class='ident'>right</span>.<span class='ident'>hash</span>()
);
<span class='kw'>let</span> <span class='ident'>node</span> <span class='op'>=</span> <span class='ident'>Tree</span>::<span class='ident'>Node</span> {
@ -230,34 +249,45 @@
<span class='macro'>assert</span><span class='macro'>!</span>(<span class='ident'>cur</span>.<span class='ident'>len</span>() <span class='op'>==</span> <span class='number'>1</span>);
<span class='kw'>let</span> <span class='ident'>tree</span> <span class='op'>=</span> <span class='ident'>cur</span>.<span class='ident'>remove</span>(<span class='number'>0</span>);
<span class='kw'>let</span> <span class='ident'>root</span> <span class='op'>=</span> <span class='ident'>cur</span>.<span class='ident'>remove</span>(<span class='number'>0</span>);
<span class='ident'>MerkleTree</span> {
<span class='prelude-val'>Some</span>(<span class='ident'>MerkleTree</span> {
<span class='ident'>digest</span>: <span class='ident'>digest</span>,
<span class='ident'>tree</span>: <span class='ident'>tree</span>,
<span class='ident'>root</span>: <span class='ident'>root</span>,
<span class='ident'>height</span>: <span class='ident'>height</span>,
<span class='ident'>count</span>: <span class='ident'>count</span>
}
})
}
<span class='doccomment'>/// Returns the tree&#39;s root hash</span>
<span class='doccomment'>/// Returns the hash function used in this Merkle tree</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>digest</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='ident'>D</span> {
<span class='kw-2'>&amp;</span><span class='self'>self</span>.<span class='ident'>digest</span>
}
<span class='doccomment'>/// Returns the root hash of Merkle tree</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>root_hash</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='self'>self</span>.<span class='ident'>tree</span>.<span class='ident'>get_hash</span>()
<span class='self'>self</span>.<span class='ident'>root</span>.<span class='ident'>hash</span>()
}
<span class='doccomment'>/// Returns the height of Merkle tree</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>height</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='ident'>usize</span> {
<span class='self'>self</span>.<span class='ident'>height</span>
}
<span class='doccomment'>/// Returns the number of leaves in the Merkle tree</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>count</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='ident'>usize</span> {
<span class='self'>self</span>.<span class='ident'>count</span>
}
<span class='doccomment'>/// Generate an inclusion proof for the given value.</span>
<span class='doccomment'>/// `None` is returned if the given value is not found in the tree.</span>
<span class='doccomment'>/// Returns `None` if the given value is not found in the tree.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>gen_proof</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>, <span class='ident'>value</span>: <span class='kw-2'>&amp;</span><span class='ident'>T</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Proof</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;&gt;</span> {
<span class='kw'>let</span> <span class='kw-2'>mut</span> <span class='ident'>digest</span> <span class='op'>=</span> <span class='self'>self</span>.<span class='ident'>digest</span>.<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>hash</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>hash_bytes</span>(<span class='kw-2'>&amp;</span><span class='ident'>value</span>.<span class='ident'>clone</span>().<span class='ident'>into</span>());
<span class='kw'>let</span> <span class='ident'>root_hash</span> <span class='op'>=</span> <span class='self'>self</span>.<span class='ident'>root_hash</span>().<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>node_hash</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>hash_bytes</span>(<span class='kw-2'>&amp;</span><span class='ident'>value</span>.<span class='ident'>clone</span>().<span class='ident'>into</span>());
<span class='ident'>ProofBlock</span>::<span class='ident'>new</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>.<span class='ident'>tree</span>, <span class='kw-2'>&amp;</span><span class='ident'>hash</span>).<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>block</span><span class='op'>|</span>
<span class='ident'>Proof</span> {
<span class='ident'>digest</span>: <span class='ident'>digest</span>,
<span class='ident'>root_hash</span>: <span class='self'>self</span>.<span class='ident'>root_hash</span>().<span class='ident'>clone</span>(),
<span class='ident'>block</span>: <span class='ident'>block</span>,
<span class='ident'>value</span>: <span class='ident'>value</span>.<span class='ident'>clone</span>()
}
<span class='ident'>Lemma</span>::<span class='ident'>new</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>.<span class='ident'>root</span>, <span class='kw-2'>&amp;</span><span class='ident'>node_hash</span>).<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>lemma</span><span class='op'>|</span>
<span class='ident'>Proof</span>::<span class='ident'>new</span>(<span class='ident'>digest</span>, <span class='ident'>root_hash</span>, <span class='ident'>lemma</span>)
)
}

View File

@ -172,130 +172,190 @@
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
</pre><pre class='rust '>
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>marker</span>::<span class='ident'>PhantomData</span>;
<span class='kw'>use</span> <span class='ident'>crypto</span>::<span class='ident'>digest</span>::<span class='ident'>Digest</span>;
<span class='kw'>use</span> <span class='ident'>merkledigest</span>::{ <span class='ident'>MerkleDigest</span> };
<span class='kw'>use</span> <span class='ident'>tree</span>::{ <span class='ident'>Tree</span> };
<span class='kw'>use</span> <span class='ident'>tree</span>::<span class='ident'>Tree</span>;
<span class='kw'>use</span> <span class='ident'>merkledigest</span>::<span class='ident'>MerkleDigest</span>;
<span class='doccomment'>/// An inclusion proof represent the fact that a `value` is a member</span>
<span class='doccomment'>/// of a `MerkleTree` with root hash `root_hash`, and hash function `digest`.</span>
<span class='kw'>pub</span> <span class='kw'>struct</span> <span class='ident'>Proof</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='kw'>pub</span> <span class='ident'>digest</span>: <span class='ident'>D</span>,
<span class='kw'>pub</span> <span class='ident'>root_hash</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>,
<span class='kw'>pub</span> <span class='ident'>block</span>: <span class='ident'>ProofBlock</span>,
<span class='kw'>pub</span> <span class='ident'>value</span>: <span class='ident'>T</span>
<span class='ident'>digest</span>: <span class='ident'>D</span>,
<span class='ident'>root_hash</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>,
<span class='ident'>lemma</span>: <span class='ident'>Lemma</span>,
<span class='ident'>_value_marker</span>: <span class='ident'>PhantomData</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>
}
<span class='kw'>impl</span> <span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='ident'>Proof</span><span class='op'>&lt;</span><span class='ident'>D</span>, <span class='ident'>T</span><span class='op'>&gt;</span> <span class='kw'>where</span> <span class='ident'>D</span>: <span class='ident'>Digest</span> <span class='op'>+</span> <span class='ident'>Clone</span>, <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span> {
<span class='doccomment'>/// Constructs a new `Proof`</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>new</span>(<span class='ident'>digest</span>: <span class='ident'>D</span>, <span class='ident'>root_hash</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>lemma</span>: <span class='ident'>Lemma</span>) <span class='op'>-&gt;</span> <span class='self'>Self</span> {
<span class='ident'>Proof</span> {
<span class='ident'>digest</span>: <span class='ident'>digest</span>,
<span class='ident'>root_hash</span>: <span class='ident'>root_hash</span>,
<span class='ident'>lemma</span>: <span class='ident'>lemma</span>,
<span class='ident'>_value_marker</span>: <span class='ident'>PhantomData</span>
}
}
<span class='doccomment'>/// Checks whether this inclusion proof is well-formed,</span>
<span class='doccomment'>/// and whether its root hash matches the given `root_hash`.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>validate</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>, <span class='ident'>root_hash</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='ident'>bool</span> {
<span class='kw'>if</span> <span class='self'>self</span>.<span class='ident'>root_hash</span> <span class='op'>!=</span> <span class='op'>*</span><span class='ident'>root_hash</span> <span class='op'>||</span> <span class='self'>self</span>.<span class='ident'>block</span>.<span class='ident'>node_hash</span> <span class='op'>!=</span> <span class='op'>*</span><span class='ident'>root_hash</span> {
<span class='kw'>if</span> <span class='self'>self</span>.<span class='ident'>root_hash</span> <span class='op'>!=</span> <span class='op'>*</span><span class='ident'>root_hash</span> <span class='op'>||</span> <span class='self'>self</span>.<span class='ident'>lemma</span>.<span class='ident'>node_hash</span> <span class='op'>!=</span> <span class='op'>*</span><span class='ident'>root_hash</span> {
<span class='kw'>return</span> <span class='bool-val'>false</span>
}
<span class='self'>self</span>.<span class='ident'>validate_block</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>.<span class='ident'>block</span>, <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>.<span class='ident'>digest</span>.<span class='ident'>clone</span>())
<span class='self'>self</span>.<span class='ident'>validate_lemma</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>.<span class='ident'>lemma</span>, <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>.<span class='ident'>digest</span>.<span class='ident'>clone</span>())
}
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>validate_block</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>, <span class='ident'>block</span>: <span class='kw-2'>&amp;</span><span class='ident'>ProofBlock</span>, <span class='ident'>digest</span>: <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>D</span>) <span class='op'>-&gt;</span> <span class='ident'>bool</span> {
<span class='kw'>match</span> <span class='ident'>block</span>.<span class='ident'>sub_proof</span> {
<span class='kw'>fn</span> <span class='ident'>validate_lemma</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>, <span class='ident'>lemma</span>: <span class='kw-2'>&amp;</span><span class='ident'>Lemma</span>, <span class='ident'>digest</span>: <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>D</span>) <span class='op'>-&gt;</span> <span class='ident'>bool</span> {
<span class='kw'>match</span> <span class='ident'>lemma</span>.<span class='ident'>sub_lemma</span> {
<span class='prelude-val'>None</span> <span class='op'>=&gt;</span>
<span class='ident'>block</span>.<span class='ident'>sibling_hash</span> <span class='op'>==</span> <span class='ident'>Positioned</span>::<span class='ident'>Nowhere</span>,
<span class='ident'>lemma</span>.<span class='ident'>sibling_hash</span>.<span class='ident'>is_none</span>(),
<span class='prelude-val'>Some</span>(<span class='kw-2'>ref</span> <span class='ident'>sub</span>) <span class='op'>=&gt;</span>
<span class='kw'>match</span> <span class='ident'>block</span>.<span class='ident'>sibling_hash</span> {
<span class='ident'>Positioned</span>::<span class='ident'>Nowhere</span> <span class='op'>=&gt;</span>
<span class='kw'>match</span> <span class='ident'>lemma</span>.<span class='ident'>sibling_hash</span> {
<span class='prelude-val'>None</span> <span class='op'>=&gt;</span>
<span class='bool-val'>false</span>,
<span class='ident'>Positioned</span>::<span class='ident'>Left</span>(<span class='kw-2'>ref</span> <span class='ident'>hash</span>) <span class='op'>=&gt;</span> {
<span class='kw'>let</span> <span class='ident'>hashes_match</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>combine_hashes</span>(<span class='kw-2'>&amp;</span><span class='ident'>hash</span>, <span class='kw-2'>&amp;</span><span class='ident'>sub</span>.<span class='ident'>node_hash</span>) <span class='op'>==</span> <span class='ident'>block</span>.<span class='ident'>node_hash</span>;
<span class='ident'>hashes_match</span> <span class='op'>&amp;&amp;</span> <span class='self'>self</span>.<span class='ident'>validate_block</span>(<span class='ident'>sub</span>, <span class='ident'>digest</span>)
<span class='prelude-val'>Some</span>(<span class='ident'>Positioned</span>::<span class='ident'>Left</span>(<span class='kw-2'>ref</span> <span class='ident'>hash</span>)) <span class='op'>=&gt;</span> {
<span class='kw'>let</span> <span class='ident'>hashes_match</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>combine_hashes</span>(<span class='kw-2'>&amp;</span><span class='ident'>hash</span>, <span class='kw-2'>&amp;</span><span class='ident'>sub</span>.<span class='ident'>node_hash</span>) <span class='op'>==</span> <span class='ident'>lemma</span>.<span class='ident'>node_hash</span>;
<span class='ident'>hashes_match</span> <span class='op'>&amp;&amp;</span> <span class='self'>self</span>.<span class='ident'>validate_lemma</span>(<span class='ident'>sub</span>, <span class='ident'>digest</span>)
}
<span class='ident'>Positioned</span>::<span class='ident'>Right</span>(<span class='kw-2'>ref</span> <span class='ident'>hash</span>) <span class='op'>=&gt;</span> {
<span class='kw'>let</span> <span class='ident'>hashes_match</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>combine_hashes</span>(<span class='kw-2'>&amp;</span><span class='ident'>sub</span>.<span class='ident'>node_hash</span>, <span class='kw-2'>&amp;</span><span class='ident'>hash</span>) <span class='op'>==</span> <span class='ident'>block</span>.<span class='ident'>node_hash</span>;
<span class='ident'>hashes_match</span> <span class='op'>&amp;&amp;</span> <span class='self'>self</span>.<span class='ident'>validate_block</span>(<span class='ident'>sub</span>, <span class='ident'>digest</span>)
<span class='prelude-val'>Some</span>(<span class='ident'>Positioned</span>::<span class='ident'>Right</span>(<span class='kw-2'>ref</span> <span class='ident'>hash</span>)) <span class='op'>=&gt;</span> {
<span class='kw'>let</span> <span class='ident'>hashes_match</span> <span class='op'>=</span> <span class='ident'>digest</span>.<span class='ident'>combine_hashes</span>(<span class='kw-2'>&amp;</span><span class='ident'>sub</span>.<span class='ident'>node_hash</span>, <span class='kw-2'>&amp;</span><span class='ident'>hash</span>) <span class='op'>==</span> <span class='ident'>lemma</span>.<span class='ident'>node_hash</span>;
<span class='ident'>hashes_match</span> <span class='op'>&amp;&amp;</span> <span class='self'>self</span>.<span class='ident'>validate_lemma</span>(<span class='ident'>sub</span>, <span class='ident'>digest</span>)
}
}
}
}
<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>lemma_mut</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>Lemma</span> {
<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>.<span class='ident'>lemma</span>
}
}
<span class='doccomment'>/// A `ProofBlock` is a linked-list holding the hash of the node, the hash of its sibling node,</span>
<span class='doccomment'>/// and the rest of the inclusion proof.</span>
<span class='kw'>pub</span> <span class='kw'>struct</span> <span class='ident'>ProofBlock</span> {
<span class='kw'>pub</span> <span class='ident'>node_hash</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>,
<span class='kw'>pub</span> <span class='ident'>sibling_hash</span>: <span class='ident'>Positioned</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span>,
<span class='kw'>pub</span> <span class='ident'>sub_proof</span>: <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Box</span><span class='op'>&lt;</span><span class='ident'>ProofBlock</span><span class='op'>&gt;&gt;</span>
<span class='doccomment'>/// A `Lemma` holds the hash of a node, the hash of its sibling node,</span>
<span class='doccomment'>/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`</span>
<span class='doccomment'>/// must be equal to this `node_hash`.</span>
<span class='kw'>pub</span> <span class='kw'>struct</span> <span class='ident'>Lemma</span> {
<span class='ident'>node_hash</span>: <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>,
<span class='ident'>sibling_hash</span>: <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Positioned</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span><span class='op'>&gt;</span>,
<span class='ident'>sub_lemma</span>: <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Box</span><span class='op'>&lt;</span><span class='ident'>Lemma</span><span class='op'>&gt;&gt;</span>
}
<span class='kw'>impl</span> <span class='ident'>ProofBlock</span> {
<span class='kw'>impl</span> <span class='ident'>Lemma</span> {
<span class='doccomment'>/// Attempt to generate a proof that the hash `needle` is a member of the given `tree`.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>new</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>(<span class='ident'>tree</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>ProofBlock</span><span class='op'>&gt;</span>
<span class='kw'>where</span> <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span>
{
<span class='doccomment'>/// Attempts to generate a proof that the a value with hash `needle` is a member of the given `tree`.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>new</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>(<span class='ident'>tree</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Lemma</span><span class='op'>&gt;</span> <span class='kw'>where</span> <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span> {
<span class='kw'>match</span> <span class='op'>*</span><span class='ident'>tree</span> {
<span class='ident'>Tree</span>::<span class='ident'>Leaf</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, .. } <span class='op'>=&gt;</span>
<span class='ident'>ProofBlock</span>::<span class='ident'>new_leaf_proof</span>(<span class='ident'>hash</span>, <span class='ident'>needle</span>),
<span class='ident'>Lemma</span>::<span class='ident'>new_leaf_proof</span>(<span class='ident'>hash</span>, <span class='ident'>needle</span>),
<span class='ident'>Tree</span>::<span class='ident'>Node</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, <span class='kw-2'>ref</span> <span class='ident'>left</span>, <span class='kw-2'>ref</span> <span class='ident'>right</span> } <span class='op'>=&gt;</span>
<span class='ident'>ProofBlock</span>::<span class='ident'>new_tree_proof</span>(<span class='ident'>hash</span>, <span class='ident'>needle</span>, <span class='ident'>left</span>, <span class='ident'>right</span>)
<span class='ident'>Lemma</span>::<span class='ident'>new_tree_proof</span>(<span class='ident'>hash</span>, <span class='ident'>needle</span>, <span class='ident'>left</span>, <span class='ident'>right</span>)
}
}
<span class='kw'>fn</span> <span class='ident'>new_leaf_proof</span>(<span class='ident'>hash</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>ProofBlock</span><span class='op'>&gt;</span> {
<span class='kw'>fn</span> <span class='ident'>new_leaf_proof</span>(<span class='ident'>hash</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Lemma</span><span class='op'>&gt;</span> {
<span class='kw'>if</span> <span class='op'>*</span><span class='ident'>hash</span> <span class='op'>==</span> <span class='op'>*</span><span class='ident'>needle</span> {
<span class='prelude-val'>Some</span>(<span class='ident'>ProofBlock</span> {
<span class='prelude-val'>Some</span>(<span class='ident'>Lemma</span> {
<span class='ident'>node_hash</span>: <span class='ident'>hash</span>.<span class='ident'>clone</span>(),
<span class='ident'>sibling_hash</span>: <span class='ident'>Positioned</span>::<span class='ident'>Nowhere</span>,
<span class='ident'>sub_proof</span>: <span class='prelude-val'>None</span>
<span class='ident'>sibling_hash</span>: <span class='prelude-val'>None</span>,
<span class='ident'>sub_lemma</span>: <span class='prelude-val'>None</span>
})
} <span class='kw'>else</span> {
<span class='prelude-val'>None</span>
}
}
<span class='kw'>fn</span> <span class='ident'>new_tree_proof</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>(<span class='ident'>hash</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>left</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>, <span class='ident'>right</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>ProofBlock</span><span class='op'>&gt;</span>
<span class='kw'>fn</span> <span class='ident'>new_tree_proof</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>(<span class='ident'>hash</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>needle</span>: <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span>, <span class='ident'>left</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>, <span class='ident'>right</span>: <span class='kw-2'>&amp;</span><span class='ident'>Tree</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span>) <span class='op'>-&gt;</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Lemma</span><span class='op'>&gt;</span>
<span class='kw'>where</span> <span class='ident'>T</span>: <span class='ident'>Into</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span> <span class='op'>+</span> <span class='ident'>Clone</span>
{
<span class='ident'>ProofBlock</span>::<span class='ident'>new</span>(<span class='ident'>left</span>, <span class='ident'>needle</span>)
.<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>block</span><span class='op'>|</span> {
<span class='kw'>let</span> <span class='ident'>right_hash</span> <span class='op'>=</span> <span class='ident'>right</span>.<span class='ident'>get_hash</span>().<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>sub_proof</span> <span class='op'>=</span> <span class='ident'>Positioned</span>::<span class='ident'>Right</span>(<span class='ident'>right_hash</span>);
(<span class='ident'>block</span>, <span class='ident'>sub_proof</span>)
<span class='ident'>Lemma</span>::<span class='ident'>new</span>(<span class='ident'>left</span>, <span class='ident'>needle</span>)
.<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>lemma</span><span class='op'>|</span> {
<span class='kw'>let</span> <span class='ident'>right_hash</span> <span class='op'>=</span> <span class='ident'>right</span>.<span class='ident'>hash</span>().<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>sub_lemma</span> <span class='op'>=</span> <span class='prelude-val'>Some</span>(<span class='ident'>Positioned</span>::<span class='ident'>Right</span>(<span class='ident'>right_hash</span>));
(<span class='ident'>lemma</span>, <span class='ident'>sub_lemma</span>)
})
.<span class='ident'>or_else</span>(<span class='op'>||</span> {
<span class='kw'>let</span> <span class='ident'>sub_proof</span> <span class='op'>=</span> <span class='ident'>ProofBlock</span>::<span class='ident'>new</span>(<span class='ident'>right</span>, <span class='ident'>needle</span>);
<span class='ident'>sub_proof</span>.<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>block</span><span class='op'>|</span> {
<span class='kw'>let</span> <span class='ident'>left_hash</span> <span class='op'>=</span> <span class='ident'>left</span>.<span class='ident'>get_hash</span>().<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>sub_proof</span> <span class='op'>=</span> <span class='ident'>Positioned</span>::<span class='ident'>Left</span>(<span class='ident'>left_hash</span>);
(<span class='ident'>block</span>, <span class='ident'>sub_proof</span>)
<span class='kw'>let</span> <span class='ident'>sub_lemma</span> <span class='op'>=</span> <span class='ident'>Lemma</span>::<span class='ident'>new</span>(<span class='ident'>right</span>, <span class='ident'>needle</span>);
<span class='ident'>sub_lemma</span>.<span class='ident'>map</span>(<span class='op'>|</span><span class='ident'>lemma</span><span class='op'>|</span> {
<span class='kw'>let</span> <span class='ident'>left_hash</span> <span class='op'>=</span> <span class='ident'>left</span>.<span class='ident'>hash</span>().<span class='ident'>clone</span>();
<span class='kw'>let</span> <span class='ident'>sub_lemma</span> <span class='op'>=</span> <span class='prelude-val'>Some</span>(<span class='ident'>Positioned</span>::<span class='ident'>Left</span>(<span class='ident'>left_hash</span>));
(<span class='ident'>lemma</span>, <span class='ident'>sub_lemma</span>)
})
})
.<span class='ident'>map</span>(<span class='op'>|</span>(<span class='ident'>sub_proof</span>, <span class='ident'>sibling_hash</span>)<span class='op'>|</span> {
<span class='ident'>ProofBlock</span> {
.<span class='ident'>map</span>(<span class='op'>|</span>(<span class='ident'>sub_lemma</span>, <span class='ident'>sibling_hash</span>)<span class='op'>|</span> {
<span class='ident'>Lemma</span> {
<span class='ident'>node_hash</span>: <span class='ident'>hash</span>.<span class='ident'>clone</span>(),
<span class='ident'>sibling_hash</span>: <span class='ident'>sibling_hash</span>,
<span class='ident'>sub_proof</span>: <span class='prelude-val'>Some</span>(<span class='ident'>Box</span>::<span class='ident'>new</span>(<span class='ident'>sub_proof</span>))
<span class='ident'>sub_lemma</span>: <span class='prelude-val'>Some</span>(<span class='ident'>Box</span>::<span class='ident'>new</span>(<span class='ident'>sub_lemma</span>))
}
})
}
<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>node_hash_mut</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>.<span class='ident'>node_hash</span>
}
<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>sibling_hash_mut</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Positioned</span><span class='op'>&lt;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;&gt;</span><span class='op'>&gt;</span> {
<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>.<span class='ident'>sibling_hash</span>
}
<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>sub_lemma_mut</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='prelude-ty'>Option</span><span class='op'>&lt;</span><span class='ident'>Box</span><span class='op'>&lt;</span><span class='ident'>Lemma</span><span class='op'>&gt;&gt;</span> {
<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='self'>self</span>.<span class='ident'>sub_lemma</span>
}
}
<span class='doccomment'>/// Tags a value so that we know from in branch (if any) it was found.</span>
<span class='doccomment'>/// Tags a value so that we know from which branch of a `Tree` (if any) it was found.</span>
<span class='attribute'>#[<span class='ident'>derive</span>(<span class='ident'>PartialEq</span>)]</span>
<span class='kw'>pub</span> <span class='kw'>enum</span> <span class='ident'>Positioned</span><span class='op'>&lt;</span><span class='ident'>T</span><span class='op'>&gt;</span> {
<span class='doccomment'>/// No value was found</span>
<span class='ident'>Nowhere</span>,
<span class='doccomment'>/// The value was found in the left branch</span>
<span class='ident'>Left</span>(<span class='ident'>T</span>),

View File

@ -99,7 +99,7 @@
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>proof</span>::{
<span class='ident'>Proof</span>,
<span class='ident'>ProofBlock</span>,
<span class='ident'>Lemma</span>,
<span class='ident'>Positioned</span>
};
@ -134,7 +134,7 @@
}
<span class='doccomment'>/// Returns a hash from the tree.</span>
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>get_hash</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>hash</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>) <span class='op'>-&gt;</span> <span class='kw-2'>&amp;</span><span class='ident'>Vec</span><span class='op'>&lt;</span><span class='ident'>u8</span><span class='op'>&gt;</span> {
<span class='kw'>match</span> <span class='op'>*</span><span class='self'>self</span> {
<span class='ident'>Tree</span>::<span class='ident'>Leaf</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, .. } <span class='op'>=&gt;</span> <span class='ident'>hash</span>,
<span class='ident'>Tree</span>::<span class='ident'>Node</span> { <span class='kw-2'>ref</span> <span class='ident'>hash</span>, .. } <span class='op'>=&gt;</span> <span class='ident'>hash</span>