merklemountainrange/lib.rs
1// Copyright 2019 The Tari Project
2//
3// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
4// following conditions are met:
5//
6// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
7// disclaimer.
8//
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
10// following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
13// products derived from this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
21// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
23//! The Merkle mountain range was invented by Peter Todd more about them can be read at:
24//! https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md
25//! https://github.com/mimblewimble/grin/blob/master/doc/mmr.md
26//!
27//! A Merkle mountain range(MMR) is a binary tree where each parent is the concatenated hash of its two
28//! children. The leaves at the bottom of the MMR is the hashes of the data. The MMR allows easy to add and proof
29//! of existence inside of the tree. MMR always tries to have the largest possible single binary tree, so in effect
30//! it is possible to have more than one binary tree. Every time you have to get the merkle root (the single merkle
31//! proof of the whole MMR) you have the bag the peaks of the individual trees, or mountain peaks.
32//!
33//! Lets take an example of how to construct one. Say you have the following MMR already made:
34//! '''
35//! /\
36//! / \
37//! /\ /\ /\
38//! /\/\/\/\ /\/\ /\
39//! '''
40//! From this we can see we have 3 trees or mountains. We have constructed the largest possible tree's we can.
41//! If we want to calculate the merkle route we will bag each of the mountains in the following way
42//! '''
43//! /\
44//! /\ \
45//! / \ \
46//! /\ \ \
47//! / \ \ \
48//! /\ /\ /\ \
49//! /\/\/\/\/\/\/\
50//! '''
51//! Lets continue the example, by adding a single object. Our MMR now looks as follows
52//! '''
53//! /\
54//! / \
55//! /\ /\ /\
56//! /\/\/\/\ /\/\ /\ /
57//! '''
58//! We now have 4 mountains. Lets bag and calculate the merkle root again
59//! '''
60//! /\
61//! /\ \
62//! /\ \ \
63//! / \ \ \
64//! /\ \ \ \
65//! / \ \ \ \
66//! /\ /\ /\ \ \
67//! /\/\/\/\/\/\/\ \
68//! '''
69//! Lets continue thw example, by adding a single object. Our MMR now looks as follows
70//! '''
71//! /\
72//! / \
73//! / \
74//! / \
75//! /\ /\
76//! / \ / \
77//! /\ /\ /\ /\
78//! /\/\/\/\/\/\/\/\
79//! '''
80//! Now we only have a single binary tree, we dont have to bag the mountains to calculate the merkle root. This
81//! process continues as you add more objects to the MMR.
82//! '''
83//! /\
84//! / \
85//! / \
86//! / \
87//! / \
88//! / \
89//! / \
90//! /\ \
91//! /\ \ /\
92//! / \ \ / \
93//! /\ \ \ /\ \
94//! / \ \ \ / \ \
95//! /\ /\ /\ \ /\ /\ /\
96//! /\/\/\/\/\/\/\ /\/\/\/\/\/\
97//! '''
98//! Due to the unique way the MMR is constructed we can easily represent the MMR as a list of the nodes, as when
99//! adding nodes you only append. Lets take the following MMR and number the nodes in the order we create them.
100//! '''
101//! 7
102//! / \
103//! / \
104//! 3 6
105//! / \ / \
106//! 1 2 4 5
107//! '''
108//! Looking above at the example of when you create the nodes, you will see the nodes will have been created in the
109//! order as they are named. This means we can easily represent them as a list:
110//! Height: 0 | 0 | 1 | 0 | 0 | 1 | 2
111//! Node: 1 | 2 | 3 | 4 | 5 | 6 | 7
112//!
113//! Because of the list nature of the MMR we can easily navigate around the MMR using the following formulas:
114//! Jump to sibling : 2^(H+1) -1
115//! find peak : 2^(H+1) -2 where < total elements
116//! left down : 2^H
117//! right down: -1
118//! Note that the formulas are for direct indexes in the array, meaning the nodes count from 0 and not 1 as in
119//! the examples above. H - Height
120//! I - Index
121//!
122//! Pruning the MMR means flagging a node as pruned and only removing it if its sibling has been removed.
123//! We do this as we require the sibling to prove the hash of the node. Taking the above example, let's prune leaf 1.
124//! '''
125//! /\
126//! / \
127//! / \
128//! / \
129//! / \
130//! / \
131//! / \
132//! /\ \
133//! /\ \ /\
134//! / \ \ / \
135//! /\ \ \ /\ \
136//! / \ \ \ / \ \
137//! /\ /\ /\ \ /\ /\ /\
138//! /\/\/\/\/\/\/\ /\/\/\/\/\/\
139//! '''
140//! Node 1 has now only been marked as pruned but we cannot remove it as of yet because we still require it to
141//! prove node 2. When we prune node 2, the MMR looks as follows
142//! '''
143//! /\
144//! / \
145//! / \
146//! / \
147//! / \
148//! / \
149//! / \
150//! /\ \
151//! /\ \ /\
152//! / \ \ / \
153//! /\ \ \ /\ \
154//! / \ \ \ / \ \
155//! /\ /\ /\ \ /\ /\ /\
156//! /\/\/\/\/\/\ /\/\/\/\/\/\
157//! '''
158//! Although we have not removed node 1 and node 2 from the MMR, we cannot yet remove node 3 as we require node 3
159//! for the proof of node 6. Let's prune 4 and 5.
160//! '''
161//! /\
162//! / \
163//! / \
164//! / \
165//! / \
166//! / \
167//! / \
168//! /\ \
169//! /\ \ /\
170//! / \ \ / \
171//! /\ \ \ /\ \
172//! / \ \ \ / \ \
173//! /\ /\ \ /\ /\ /\
174//! /\/\/\/\/\ /\/\/\/\/\/\
175//! '''
176//! Now we removed 3 from the MMR
177
178pub mod error;
179pub mod merklemountainrange;
180pub mod merklenode;
181pub mod mmr {
182 pub use crate::merklemountainrange::*;
183}