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}