1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
// Copyright 2019 Stichting Organism // Copyright 2019 The Grin Developers // Copyright 2019 The Tari Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! Gene: Over the Mountains //! - MMR //! - Dynamic Accumulator //! //! # Merkle Mountain Ranges //! //! ## Introduction //! //! The Merkle mountain range was invented by Peter Todd more about them can be read at //! [Open Timestamps](https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md) //! and the [Grin project](https://github.com/mimblewimble/grin/blob/master/doc/mmr.md). //! //! A Merkle mountain range(MMR) is a binary tree where each parent is the concatenated hash of its two //! children. The leaves at the bottom of the MMR is the hashes of the data. The MMR allows easy to add and proof //! of existence inside of the tree. MMR always tries to have the largest possible single binary tree, so in effect //! it is possible to have more than one binary tree. Every time you have to get the merkle root (the single merkle //! proof of the whole MMR) you have the bag the peaks of the individual trees, or mountain peaks. //! //! Lets take an example of how to construct one. Say you have the following MMR already made: //! ```plaintext //! /\ //! / \ //! /\ /\ /\ //! /\/\/\/\ /\/\ /\ //! ``` //! From this we can see we have 3 trees or mountains. We have constructed the largest possible tree's we can. //! If we want to calculate the merkle root we simply concatenate and then hash the three peaks. //! //! Lets continue the example, by adding a single object. Our MMR now looks as follows //! ```plaintext //! /\ //! / \ //! /\ /\ /\ //! /\/\/\/\ /\/\ /\ / //! ``` //! We now have 4 mountains. Calculating the root means hashing the concatenation of the (now) four peaks. //! //! Lets continue thw example, by adding a single object. Our MMR now looks as follows //! ```plaintext //! /\ //! / \ //! / \ //! / \ //! /\ /\ //! / \ / \ //! /\ /\ /\ /\ //! /\/\/\/\/\/\/\/\ //! ``` //! Now we only have a single binary tree, and the root is now the hash of the single peak's hash. This //! process continues as you add more objects to the MMR. //! ```plaintext //! /\ //! / \ //! / \ //! / \ //! / \ //! / \ //! / \ //! /\ \ //! /\ \ /\ //! / \ \ / \ //! /\ \ \ /\ \ //! / \ \ \ / \ \ //! /\ /\ /\ \ /\ /\ /\ //! /\/\/\/\/\/\/\ /\/\/\/\/\/\ //! ``` //! Due to the unique way the MMR is constructed we can easily represent the MMR as a linear list of the nodes. Lets //! take the following MMR and number the nodes in the order we create them. //! ```plaintext //! 6 //! / \ //! / \ //! 2 5 //! / \ / \ //! 0 1 3 4 //! ``` //! Looking above at the example of when you create the nodes, you will see the MMR nodes will have been created in the //! order as they are named. This means we can easily represent them as a list: //! Height: 0 | 0 | 1 | 0 | 0 | 1 | 2 //! Node: 0 | 1 | 2 | 3 | 4 | 5 | 6 //! //! Because of the list nature of the MMR we can easily navigate around the MMR using the following formulas: //! //! Jump to right sibling : $$ n + 2^{H+1} - 1 $$ //! Jump to left sibling : $$ n - 2^{H+1} - 1 $$ //! peak of binary tree : $$ 2^{ H+1 } - 2 $$ //! left down : $$ n - 2^H $$ //! right down: $$ n-1 $$ //! //! ## Node numbering //! //! There can be some confusion about how nodes are numbered in an MMR. The following conventions are used in this //! crate: //! //! * _All_ indices are numbered starting from zero. //! * MMR nodes refer to all the nodes in the Merkle Mountain Range and are ordered in the canonical mmr ordering //! described above. //! * Leaf nodes are numbered counting from zero and increment by one each time a leaf is added. //! //! To illustrate, consider this MMR: //! //! //! ```plaintext //! 14 //! / \ //! / \ //! 6 13 21 <-- MMR indices //! / \ / \ / \ //! / \ / \ / \ //! 2 5 9 12 17 21 //! / \ / \ / \ / \ / \ / \ //! 0 1 3 4 7 8 10 11 15 16 18 19 22 //! ---------------------------------- //! 0 1 2 3 4 5 6 7 8 9 10 11 12 <-- Leaf node indices //! ---------------------------------- //! ``` #[cfg(target_pointer_width = "32")] pub type Bitmap = croaring::Bitmap; #[cfg(target_pointer_width = "64")] pub type Bitmap = croaring::Bitmap; // pub type Bitmap = croaring::TreeMap; use thiserror::Error; /// Represents an error in proof creation, verification, or parsing. #[derive(Error, Clone, Debug, Eq, PartialEq)] pub enum GeneError { /// This error occurs when we receive a proof that's outdated and cannot be auto-updated. #[error("Item proof is outdated and must be re-created against the new state")] OutdatedProof, /// This error occurs when the merkle proof is too short or too long, or does not lead to a node /// to which it should. #[error("Merkle proof is invalid")] InvalidProof, /// Merkle proof root hash does not match when attempting to verify. #[error("Merkle proof is invalid")] RootMismatch, /// You tried to construct or verify a Merkle proof using a non-leaf node as the inclusion candidate #[error("Merkle proof is invalid")] NonLeafNode, /// There was no hash in the merkle tree backend with the given position #[error("Merkle proof is invalid")] HashNotFound(usize), /// The list of peak hashes provided in the proof has an error #[error("Merkle proof is invalid")] IncorrectPeakMap, /// Unexpected #[error("Merkle proof is invalid")] Unexpected, /// A problem has been encountered with the backend #[error("Backend Error: {}", _0)] BackendError(String), /// The Merkle tree is not internally consistent. A parent hash isn't equal to the hash of its children #[error("Merkle is not internally consistent")] InvalidMerkleTree, /// The next position was not a leaf node as expected #[error("Merkle Tree Malformed")] CorruptDataStructure, /// The tree has reached its maximum size #[error("Tree has reached its maximum size")] MaximumSizeReached, /// A request was out of range #[error("A request was out of range")] OutOfRange, /// Conflicting or invalid configuration parameters provided. #[error("Invalid configuration parameters ")] InvalidConfig, } /// A vector-based backend for [Gene] mod storage; pub use storage::{ Storage, StorageExt }; /// Hiker pub mod algos; /// An immutable, append-only Merkle Mountain range (MMR) data structure mod mmr; pub use mmr::MerkleMountainRange; /// A data structure for proving a hash inclusion in an MMR mod merkle_proof; pub use merkle_proof::MerkleProof; /// An append-only Merkle Mountain range (MMR) data structure that allows deletion of existing leaf nodes. mod mutable_mmr; pub use mutable_mmr::MutableMmr; /// A function for snapshotting and pruning a Merkle Mountain Range pub mod pruned_hashset; pub mod pruned_mmr; /// A data structure that maintains a list of diffs on an MMR, enabling you to rewind to a previous state mod change_tracker; pub use change_tracker::{ MerkleChangeTracker, MerkleCheckPoint, MerkleChangeTrackerConfig }; mod mutable_mmr_leaf_nodes; /// A data structure for storing all the data required to restore the state of an MMR. pub use mutable_mmr_leaf_nodes::MutableMmrLeafNodes; // /// Dynamic Accumulator // mod pollard; #[cfg(test)] mod test_gene; // /// Generic trait to ensure PMMR elements can be hashed with an index // pub trait PMMRIndexHashable { // /// Hash with a given index // fn hash_with_index(&self, index: u64) -> Hash; // } // impl<T: DefaultHashable> PMMRIndexHashable for T { // fn hash_with_index(&self, index: u64) -> Hash { // (index, self).hash() // } // }