tree_index/
lib.rs

1#![forbid(unsafe_code, missing_debug_implementations, missing_docs)]
2#![cfg_attr(test, deny(warnings))]
3
4//! ## Example
5//! ```rust
6//! extern crate sparse_bitfield as bitfield;
7//! extern crate tree_index;
8//!
9//! use tree_index::TreeIndex;
10//! use self::bitfield::{Bitfield, Change};
11//!
12//! let bitfield = Bitfield::new(1024);
13//! let mut tree = TreeIndex::new(bitfield);
14//! assert_eq!(tree.set(0), Change::Changed);
15//! assert_eq!(tree.set(0), Change::Unchanged);
16//! assert_eq!(tree.get(0), true);
17//! assert_eq!(tree.get(1), false);
18//! ```
19
20extern crate flat_tree as flat;
21extern crate sparse_bitfield as bitfield;
22
23mod proof;
24mod verification;
25
26pub use self::bitfield::{Bitfield, Change};
27pub use self::proof::Proof;
28pub use self::verification::Verification;
29
30use std::{cmp, convert};
31
32/// Index a tree structure or something.
33#[derive(Debug)]
34pub struct TreeIndex {
35  bitfield: Bitfield,
36}
37
38impl TreeIndex {
39  /// Create a new TreeIndex by passing it a sparse_bitfield instance.
40  #[inline]
41  pub fn new(bitfield: Bitfield) -> Self {
42    TreeIndex { bitfield }
43  }
44
45  /// Get a bit from the bitfield.
46  #[inline]
47  pub fn get(&mut self, index: u64) -> bool {
48    self.bitfield.get(index as usize)
49  }
50
51  /// Set an index on the tree to `true`, and also all of the parents to the
52  /// index. Walks the flat-tree upward, until it finds the upper most node.
53  #[inline]
54  pub fn set(&mut self, mut index: u64) -> Change {
55    if self.bitfield.set(index as usize, true).is_unchanged() {
56      return Change::Unchanged;
57    }
58
59    while self.bitfield.get(flat::sibling(index) as usize) {
60      index = flat::parent(index);
61      if self.bitfield.set(index as usize, true).is_unchanged() {
62        break;
63      }
64    }
65    Change::Changed
66  }
67
68  /// Prove a method.
69  #[inline]
70  pub fn proof<'a>(
71    &'a mut self,
72    index: u64,
73    include_hash: bool,
74    nodes: &'a mut impl convert::AsMut<Vec<u64>>,
75    remote_tree: &mut Self,
76  ) -> Option<Proof> {
77    let digest = 0;
78    self.proof_with_digest(index, digest, include_hash, nodes, remote_tree)
79  }
80
81  /// Determine which Nodes prove the correctness for the Node at `index`.
82  ///
83  /// The passed buffer is filled with nodes that are verified by the same
84  /// index. This is done so allocations can happen at the top level, and a
85  /// buffer (pool) can be used to prevent extra allocations.
86  // - opts.hash: always push index to nodes.
87  // - nodes: proven nodes.
88  // - opts.digest: not sure what digest does.
89  pub fn proof_with_digest<'a>(
90    &'a mut self,
91    index: u64,
92    mut digest: u64,
93    include_hash: bool,
94    nodes: &'a mut impl convert::AsMut<Vec<u64>>,
95    remote_tree: &mut Self,
96  ) -> Option<Proof> {
97    let nodes = nodes.as_mut();
98
99    if !self.get(index) {
100      return None;
101    }
102
103    // Always return hash - no matter what the digest says.
104    // NOTE: this feels like a mild hack.
105    if include_hash {
106      nodes.push(index);
107    }
108
109    if digest == 1 {
110      let verified_by = 0;
111      return Some(Proof::new(index, verified_by, nodes));
112    }
113
114    let mut roots = vec![]; // TODO: reuse from a buffer pool.
115    let mut next = index;
116    let mut sibling;
117    let has_root = digest & 1;
118    digest >>= 1;
119
120    while digest > 0 {
121      if digest == 1 && has_root != 0 {
122        if self.get(next) {
123          remote_tree.set(next);
124        }
125
126        let next_sibling = flat::sibling(next);
127        if next_sibling < next {
128          next = next_sibling
129        }
130
131        flat::full_roots(flat::right_span(next) + 2, &mut roots);
132
133        for root in &roots {
134          if self.get(*root) {
135            remote_tree.set(*root);
136          }
137        }
138        break;
139      }
140
141      sibling = flat::sibling(next);
142      if !is_even(digest) && self.get(sibling) {
143        remote_tree.set(sibling);
144      }
145
146      next = flat::parent(next);
147      digest >>= 1;
148    }
149
150    next = index;
151
152    while !remote_tree.get(next) {
153      sibling = flat::sibling(next);
154
155      if !self.get(sibling) {
156        let verified_by = self.verified_by(next).node;
157        let mut roots = vec![];
158        flat::full_roots(verified_by, &mut roots);
159        for root in roots {
160          if root != next && !remote_tree.get(root) {
161            nodes.push(root);
162          }
163        }
164        return Some(Proof::new(index, verified_by, nodes));
165      } else if !remote_tree.get(sibling) {
166        nodes.push(sibling);
167      }
168
169      next = flat::parent(next);
170    }
171
172    let verified_by = 0;
173    Some(Proof::new(index, verified_by, nodes))
174  }
175
176  /// Create a digest for data at index.
177  #[inline]
178  pub fn digest(&mut self, index: u64) -> u64 {
179    if self.get(index) {
180      return 1;
181    }
182
183    let mut digest = 0;
184    let mut next = flat::sibling(index);
185    let max = cmp::max(next + 2, self.bitfield.len() as u64); // TODO(from mafintosh/hypercore): make this less hacky
186
187    let mut bit = 2;
188    let mut parent = flat::parent(next);
189
190    while (flat::right_span(next) < max) || flat::left_span(parent) > 0 {
191      if self.get(next) {
192        digest |= bit;
193      }
194
195      if self.get(parent) {
196        digest |= 2 * bit + 1;
197        if digest + 1 == 4 * bit {
198          return 1;
199        }
200        return digest;
201      }
202
203      next = flat::sibling(parent);
204      parent = flat::parent(next);
205      bit *= 2;
206    }
207    digest
208  }
209
210  /// Get the position of the highest entry in the tree. Aka max.
211  ///
212  /// NOTE: should we rename this to `.len()` ?
213  /// ## Examples
214  /// ```txt
215  ///        3
216  ///    1       5
217  ///  0   2   4   6
218  /// ```
219  ///
220  /// ```rust
221  /// extern crate tree_index as tree;
222  /// use tree::{Change, TreeIndex, Verification};
223  ///
224  /// let mut tree = TreeIndex::default();
225  /// for i in (0..8).step_by(2) {
226  ///   tree.set(i);
227  /// }
228  /// assert_eq!(tree.blocks(), 4);
229  /// tree = TreeIndex::default();
230  /// tree.set(1);
231  /// tree.set(5);
232  /// assert_eq!(tree.blocks(), 4);
233  /// tree = TreeIndex::default();
234  /// tree.set(3);
235  /// assert_eq!(tree.blocks(), 4);
236  /// ```
237  #[inline]
238  pub fn blocks(&mut self) -> u64 {
239    let mut top = 0;
240    let mut next = 0;
241    let max = self.bitfield.len() as u64;
242
243    while flat::right_span(next) < max {
244      next = flat::parent(next);
245      if self.get(next) {
246        top = next;
247      }
248    }
249
250    if self.get(top) {
251      self.verified_by(top).node / 2
252    } else {
253      0
254    }
255  }
256
257  /// Get all root nodes.
258  ///
259  /// TODO: don't make this allocate, but fill a vector instead.
260  #[inline]
261  pub fn roots(&mut self, roots: &mut Vec<u64>) {
262    flat::full_roots(2 * self.blocks(), roots)
263  }
264
265  /// Find the node that verified the node that's passed.
266  ///
267  /// This is different from the Javascript implementation in that it doesn't
268  /// push the `top` value into an array, but returns it instead through the
269  /// `Verification` type.
270  #[inline]
271  pub fn verified_by(&mut self, index: u64) -> Verification {
272    let has_index = self.get(index);
273    if !has_index {
274      return Verification { node: 0, top: 0 };
275    }
276
277    // Find root of current tree.
278    let mut depth = flat::depth(index);
279    let mut top = index;
280    let mut parent = flat::parent(top);
281    depth += 1;
282    while self.get(parent) && self.get(flat::sibling(top)) {
283      top = parent;
284      parent = flat::parent(top);
285      depth += 1;
286    }
287
288    // Expand right down.
289    //
290    // NOTE: this is probably a candidate to move to `flat-tree`.
291    depth -= 1;
292    while depth != 0 {
293      top =
294        flat::left_child(flat::index(depth, flat::offset(top) + 1)).unwrap();
295      depth -= 1;
296
297      while !self.get(top) && depth > 0 {
298        top = flat::left_child(top).unwrap();
299        depth -= 1;
300      }
301    }
302
303    let node = if self.get(top) { top + 2 } else { top };
304
305    Verification { node, top }
306  }
307
308  /// Get a reference to underlying bitfield
309  pub fn as_bitfield(&self) -> &Bitfield {
310    &self.bitfield
311  }
312}
313
314/// Create a TreeIndex with an empty sparse_bitfield instance with a page size
315/// of `1024`.
316impl Default for TreeIndex {
317  #[inline]
318  fn default() -> Self {
319    TreeIndex {
320      bitfield: Bitfield::new(1024),
321    }
322  }
323}
324
325/// Check if a value is even.
326#[inline]
327fn is_even(n: u64) -> bool {
328  match n & 1 {
329    0 => true,
330    1 => false,
331    _ => panic!(format!(
332      "Bitshift failure. Received bit {}. Expected 1 or 0",
333      n
334    )),
335  }
336}