1use std::{iter, marker, ops::Range, u64};
16
17use croaring::Bitmap;
18
19use crate::core::hash::{Hash, ZERO_HASH};
20use crate::core::merkle_proof::MerkleProof;
21use crate::core::pmmr::{Backend, ReadonlyPMMR};
22use crate::core::BlockHeader;
23use crate::ser::{PMMRIndexHashable, PMMRable};
24
25pub trait ReadablePMMR {
27 type Item;
29
30 fn get_hash(&self, pos: u64) -> Option<Hash>;
34
35 fn get_data(&self, pos: u64) -> Option<Self::Item>;
37
38 fn get_from_file(&self, pos: u64) -> Option<Hash>;
40
41 fn get_peak_from_file(&self, pos: u64) -> Option<Hash>;
45
46 fn get_data_from_file(&self, pos: u64) -> Option<Self::Item>;
48
49 fn unpruned_size(&self) -> u64;
51
52 fn leaf_pos_iter(&self) -> Box<dyn Iterator<Item = u64> + '_>;
54
55 fn leaf_idx_iter(&self, from_idx: u64) -> Box<dyn Iterator<Item = u64> + '_>;
57
58 fn n_unpruned_leaves(&self) -> u64;
60
61 fn n_unpruned_leaves_to_index(&self, to_index: u64) -> u64;
63
64 fn is_empty(&self) -> bool {
66 self.unpruned_size() == 0
67 }
68
69 fn bag_the_rhs(&self, peak_pos0: u64) -> Option<Hash> {
74 let size = self.unpruned_size();
75 let rhs = peaks(size)
76 .into_iter()
77 .filter(|&x| x > peak_pos0)
78 .filter_map(|x| self.get_from_file(x));
79
80 let mut res = None;
81 for peak in rhs.rev() {
82 res = match res {
83 None => Some(peak),
84 Some(rhash) => Some((peak, rhash).hash_with_index(size)),
85 }
86 }
87 res
88 }
89
90 fn peaks(&self) -> Vec<Hash> {
92 peaks(self.unpruned_size())
93 .into_iter()
94 .filter_map(move |pi0| self.get_peak_from_file(pi0))
95 .collect()
96 }
97
98 fn peak_path(&self, peak_pos0: u64) -> Vec<Hash> {
100 let rhs = self.bag_the_rhs(peak_pos0);
101 let mut res = peaks(self.unpruned_size())
102 .into_iter()
103 .filter(|&x| x < peak_pos0)
104 .filter_map(|x| self.get_peak_from_file(x))
105 .collect::<Vec<_>>();
106 if let Some(rhs) = rhs {
107 res.push(rhs);
108 }
109 res.reverse();
110
111 res
112 }
113
114 fn root(&self) -> Result<Hash, String> {
117 if self.is_empty() {
118 return Ok(ZERO_HASH);
119 }
120 let mut res = None;
121 let peaks = self.peaks();
122 let mmr_size = self.unpruned_size();
123 for peak in peaks.into_iter().rev() {
124 res = match res {
125 None => Some(peak),
126 Some(rhash) => Some((peak, rhash).hash_with_index(mmr_size)),
127 }
128 }
129 res.ok_or_else(|| "no root, invalid tree".to_owned())
130 }
131
132 fn merkle_proof(&self, pos0: u64) -> Result<MerkleProof, String> {
134 let size = self.unpruned_size();
135 debug!("merkle_proof {}, size {}", pos0, size);
136
137 if !is_leaf(pos0) {
139 return Err(format!("not a leaf at pos {}", pos0));
140 }
141
142 self.get_hash(pos0)
144 .ok_or_else(|| format!("no element at pos {}", pos0))?;
145
146 let family_branch = family_branch(pos0, size);
147
148 let mut path = family_branch
149 .iter()
150 .filter_map(|x| self.get_from_file(x.1))
151 .collect::<Vec<_>>();
152
153 let peak_pos = match family_branch.last() {
154 Some(&(x, _)) => x,
155 None => pos0,
156 };
157
158 path.append(&mut self.peak_path(peak_pos));
159
160 Ok(MerkleProof {
161 mmr_size: size,
162 path,
163 })
164 }
165}
166
167pub struct PMMR<'a, T, B>
174where
175 T: PMMRable,
176 B: Backend<T>,
177{
178 pub size: u64,
180 backend: &'a mut B,
181 _marker: marker::PhantomData<T>,
183}
184
185impl<'a, T, B> PMMR<'a, T, B>
186where
187 T: PMMRable,
188 B: 'a + Backend<T>,
189{
190 pub fn new(backend: &'a mut B) -> PMMR<'_, T, B> {
192 PMMR {
193 backend,
194 size: 0,
195 _marker: marker::PhantomData,
196 }
197 }
198
199 pub fn at(backend: &'a mut B, size: u64) -> PMMR<'_, T, B> {
202 PMMR {
203 backend,
204 size,
205 _marker: marker::PhantomData,
206 }
207 }
208
209 pub fn readonly_pmmr(&self) -> ReadonlyPMMR<'_, T, B> {
211 ReadonlyPMMR::at(&self.backend, self.size)
212 }
213
214 pub fn push(&mut self, leaf: &T) -> Result<u64, String> {
217 let leaf_pos = self.size;
218 let mut current_hash = leaf.hash_with_index(leaf_pos);
219
220 let mut hashes = vec![current_hash];
221 let mut pos = leaf_pos;
222
223 let (peak_map, height) = peak_map_height(pos);
224 if height != 0 {
225 return Err(format!("bad mmr size {}", pos));
226 }
227 let mut peak = 1;
229 while (peak_map & peak) != 0 {
230 let left_sibling = pos + 1 - 2 * peak;
231 let left_hash = self
232 .backend
233 .get_peak_from_file(left_sibling)
234 .ok_or("missing left sibling in tree, should not have been pruned")?;
235 peak *= 2;
236 pos += 1;
237 current_hash = (left_hash, current_hash).hash_with_index(pos);
238 hashes.push(current_hash);
239 }
240
241 self.backend.append(leaf, &hashes)?;
243 self.size = pos + 1;
244 Ok(leaf_pos)
245 }
246
247 pub fn push_pruned_subtree(&mut self, hash: Hash, pos0: u64) -> Result<(), String> {
249 self.backend.append_pruned_subtree(hash, pos0)?;
251 self.size = pos0 + 1;
252
253 let mut pos = pos0;
254 let mut current_hash = hash;
255
256 let (peak_map, _) = peak_map_height(pos);
257
258 let mut peak = 1;
260 while (peak_map & peak) != 0 {
261 let (parent, sibling) = family(pos);
262 peak *= 2;
263 if sibling > pos {
264 continue;
266 }
267 let left_hash = self
268 .backend
269 .get_hash(sibling)
270 .ok_or("missing left sibling in tree, should not have been pruned")?;
271 pos = parent;
272 current_hash = (left_hash, current_hash).hash_with_index(parent);
273 self.backend.append_hash(current_hash)?;
274 }
275
276 self.size = crate::core::pmmr::round_up_to_leaf_pos(pos);
278 Ok(())
279 }
280
281 pub fn reset_prune_list(&mut self) {
283 self.backend.reset_prune_list();
284 }
285
286 pub fn remove_from_leaf_set(&mut self, pos0: u64) {
288 self.backend.remove_from_leaf_set(pos0);
289 }
290
291 pub fn snapshot(&mut self, header: &BlockHeader) -> Result<(), String> {
295 self.backend.snapshot(header)?;
296 Ok(())
297 }
298
299 pub fn rewind(&mut self, position: u64, rewind_rm_pos: &Bitmap) -> Result<(), String> {
304 let leaf_pos = round_up_to_leaf_pos(position);
308 self.backend.rewind(leaf_pos, rewind_rm_pos)?;
309 self.size = leaf_pos;
310 Ok(())
311 }
312
313 pub fn prune(&mut self, pos0: u64) -> Result<bool, String> {
318 if !is_leaf(pos0) {
319 return Err(format!("Node at {} is not a leaf, can't prune.", pos0));
320 }
321
322 if self.backend.get_hash(pos0).is_none() {
323 return Ok(false);
324 }
325
326 self.backend.remove(pos0)?;
327 Ok(true)
328 }
329
330 pub fn validate(&self) -> Result<(), String> {
332 for n in 0..self.size {
334 let height = bintree_postorder_height(n);
335 if height > 0 {
336 if let Some(hash) = self.get_hash(n) {
337 let left_pos = n - (1 << height);
338 let right_pos = n - 1;
339 if let Some(left_child_hs) = self.get_from_file(left_pos) {
341 if let Some(right_child_hs) = self.get_from_file(right_pos) {
342 if (left_child_hs, right_child_hs).hash_with_index(n) != hash {
344 return Err(format!(
345 "Invalid MMR, hash of parent at {} does \
346 not match children.",
347 n + 1
348 ));
349 }
350 }
351 }
352 }
353 }
354 }
355 Ok(())
356 }
357
358 pub fn dump(&self, short: bool) {
361 let sz = self.unpruned_size();
362 if sz > 2000 && !short {
363 return;
364 }
365 let start = if short { sz / 8 } else { 0 };
366 for n in start..(sz / 8 + 1) {
367 let mut idx = "".to_owned();
368 let mut hashes = "".to_owned();
369 for m in (n * 8)..(n + 1) * 8 {
370 if m >= sz {
371 break;
372 }
373 idx.push_str(&format!("{:>8} ", m));
374 let ohs = self.get_hash(m);
375 match ohs {
376 Some(hs) => hashes.push_str(&format!("{} ", hs)),
377 None => hashes.push_str(&format!("{:>8} ", "??")),
378 }
379 }
380 debug!("{}", idx);
381 debug!("{}", hashes);
382 }
383 }
384
385 pub fn dump_stats(&self) {
387 debug!("pmmr: unpruned - {}", self.unpruned_size());
388 self.backend.dump_stats();
389 }
390
391 pub fn dump_from_file(&self, short: bool) {
395 let sz = self.unpruned_size();
396 if sz > 2000 && !short {
397 return;
398 }
399 let start = if short { sz / 8 } else { 0 };
400 for n in start..(sz / 8 + 1) {
401 let mut idx = "".to_owned();
402 let mut hashes = "".to_owned();
403 for m in (n * 8)..(n + 1) * 8 {
404 if m >= sz {
405 break;
406 }
407 idx.push_str(&format!("{:>8} ", m + 1));
408 let ohs = self.get_from_file(m);
409 match ohs {
410 Some(hs) => hashes.push_str(&format!("{} ", hs)),
411 None => hashes.push_str(&format!("{:>8} ", " .")),
412 }
413 }
414 debug!("{}", idx);
415 debug!("{}", hashes);
416 }
417 }
418}
419
420impl<'a, T, B> ReadablePMMR for PMMR<'a, T, B>
421where
422 T: PMMRable,
423 B: 'a + Backend<T>,
424{
425 type Item = T::E;
426
427 fn get_hash(&self, pos0: u64) -> Option<Hash> {
428 if pos0 >= self.size {
429 None
430 } else if is_leaf(pos0) {
431 self.backend.get_hash(pos0)
433 } else {
434 self.backend.get_from_file(pos0)
436 }
437 }
438
439 fn get_data(&self, pos0: u64) -> Option<Self::Item> {
440 if pos0 >= self.size {
441 None
443 } else if is_leaf(pos0) {
444 self.backend.get_data(pos0)
446 } else {
447 None
449 }
450 }
451
452 fn get_from_file(&self, pos0: u64) -> Option<Hash> {
453 if pos0 >= self.size {
454 None
455 } else {
456 self.backend.get_from_file(pos0)
457 }
458 }
459
460 fn get_peak_from_file(&self, pos0: u64) -> Option<Hash> {
461 if pos0 >= self.size {
462 None
463 } else {
464 self.backend.get_peak_from_file(pos0)
465 }
466 }
467
468 fn get_data_from_file(&self, pos0: u64) -> Option<Self::Item> {
469 if pos0 >= self.size {
470 None
471 } else {
472 self.backend.get_data_from_file(pos0)
473 }
474 }
475
476 fn unpruned_size(&self) -> u64 {
477 self.size
478 }
479
480 fn leaf_pos_iter(&self) -> Box<dyn Iterator<Item = u64> + '_> {
481 self.backend.leaf_pos_iter()
482 }
483
484 fn leaf_idx_iter(&self, from_idx: u64) -> Box<dyn Iterator<Item = u64> + '_> {
485 self.backend.leaf_idx_iter(from_idx)
486 }
487
488 fn n_unpruned_leaves(&self) -> u64 {
489 self.backend.n_unpruned_leaves()
490 }
491
492 fn n_unpruned_leaves_to_index(&self, to_index: u64) -> u64 {
493 self.backend.n_unpruned_leaves_to_index(to_index)
494 }
495}
496
497const ALL_ONES: u64 = u64::MAX;
499
500pub fn peak_map_height(mut size: u64) -> (u64, u64) {
512 if size == 0 {
513 return (0, 0);
515 }
516 let mut peak_size = ALL_ONES >> size.leading_zeros();
517 let mut peak_map = 0;
518 while peak_size != 0 {
519 peak_map <<= 1;
520 if size >= peak_size {
521 size -= peak_size;
522 peak_map |= 1;
523 }
524 peak_size >>= 1;
525 }
526 (peak_map, size)
527}
528
529pub fn peak_sizes_height(mut size: u64) -> (Vec<u64>, u64) {
536 if size == 0 {
537 return (vec![], 0);
539 }
540 let mut peak_size = ALL_ONES >> size.leading_zeros();
541 let mut peak_sizes = vec![];
542 while peak_size != 0 {
543 if size >= peak_size {
544 peak_sizes.push(peak_size);
545 size -= peak_size;
546 }
547 peak_size >>= 1;
548 }
549 (peak_sizes, size)
550}
551
552pub fn peaks(size: u64) -> Vec<u64> {
558 let (peak_sizes, height) = peak_sizes_height(size);
559 if height == 0 {
560 peak_sizes
561 .iter()
562 .scan(0, |acc, &x| {
563 *acc += &x;
564 Some(*acc)
565 })
566 .map(|x| x - 1) .collect()
568 } else {
569 vec![]
570 }
571}
572pub fn n_leaves(size: u64) -> u64 {
574 let (peak_map, height) = peak_map_height(size);
575 if height == 0 {
576 peak_map
577 } else {
578 peak_map + 1
579 }
580}
581
582pub fn round_up_to_leaf_pos(pos0: u64) -> u64 {
584 let (insert_idx, height) = peak_map_height(pos0);
585 let leaf_idx = if height == 0 {
586 insert_idx
587 } else {
588 insert_idx + 1
589 };
590 return insertion_to_pmmr_index(leaf_idx);
591}
592
593pub fn insertion_to_pmmr_index(nleaf0: u64) -> u64 {
595 2 * nleaf0 - nleaf0.count_ones() as u64
596}
597
598pub fn pmmr_leaf_to_insertion_index(pos0: u64) -> Option<u64> {
600 let (insert_idx, height) = peak_map_height(pos0);
601 if height == 0 {
602 Some(insert_idx)
603 } else {
604 None
605 }
606}
607
608pub fn bintree_postorder_height(pos0: u64) -> u64 {
611 peak_map_height(pos0).1
612}
613
614pub fn is_leaf(pos0: u64) -> bool {
619 bintree_postorder_height(pos0) == 0
620}
621
622pub fn family(pos0: u64) -> (u64, u64) {
625 let (peak_map, height) = peak_map_height(pos0);
626 let peak = 1 << height;
627 if (peak_map & peak) != 0 {
628 (pos0 + 1, pos0 + 1 - 2 * peak)
629 } else {
630 (pos0 + 2 * peak, pos0 + 2 * peak - 1)
631 }
632}
633
634pub fn is_left_sibling(pos0: u64) -> bool {
636 let (peak_map, height) = peak_map_height(pos0);
637 let peak = 1 << height;
638 (peak_map & peak) == 0
639}
640
641pub fn family_branch(pos0: u64, size: u64) -> Vec<(u64, u64)> {
645 let (peak_map, height) = peak_map_height(pos0);
648 let mut peak = 1 << height;
649 let mut branch = vec![];
650 let mut current = pos0;
651 let mut sibling;
652 while current + 1 < size {
653 if (peak_map & peak) != 0 {
654 current += 1;
655 sibling = current - 2 * peak;
656 } else {
657 current += 2 * peak;
658 sibling = current - 1;
659 };
660 if current >= size {
661 break;
662 }
663 branch.push((current, sibling));
664 peak <<= 1;
665 }
666 branch
667}
668
669pub fn bintree_rightmost(pos0: u64) -> u64 {
671 pos0 - bintree_postorder_height(pos0)
672}
673
674pub fn bintree_leftmost(pos0: u64) -> u64 {
676 let height = bintree_postorder_height(pos0);
677 pos0 + 2 - (2 << height)
678}
679
680pub fn bintree_leaf_pos_iter(pos0: u64) -> Box<dyn Iterator<Item = u64>> {
682 let leaf_start = pmmr_leaf_to_insertion_index(bintree_leftmost(pos0));
683 let leaf_end = pmmr_leaf_to_insertion_index(bintree_rightmost(pos0));
684 let leaf_start = match leaf_start {
685 Some(l) => l,
686 None => return Box::new(iter::empty::<u64>()),
687 };
688 let leaf_end = match leaf_end {
689 Some(l) => l,
690 None => return Box::new(iter::empty::<u64>()),
691 };
692 Box::new((leaf_start..=leaf_end).map(|n| insertion_to_pmmr_index(n)))
693}
694
695pub fn bintree_pos_iter(pos0: u64) -> impl Iterator<Item = u64> {
697 let leaf_start = bintree_leftmost(pos0);
698 (leaf_start..=pos0).into_iter()
699}
700
701pub fn bintree_range(pos0: u64) -> Range<u64> {
703 let height = bintree_postorder_height(pos0);
704 let leftmost = pos0 + 2 - (2 << height);
705 leftmost..(pos0 + 1)
706}