1use std::collections::HashMap;
2
3use crate::{Entry, EntryKind, EntryLink, Error, Version};
4
5pub struct Tree<V: Version> {
17 stored: HashMap<u32, Entry<V>>,
18
19 generated: Vec<Entry<V>>,
21
22 stored_count: u32,
24
25 root: EntryLink,
26}
27
28impl<V: Version> Tree<V> {
29 pub fn resolve_link(&self, link: EntryLink) -> Result<IndexedNode<V>, Error> {
31 match link {
32 EntryLink::Generated(index) => self.generated.get(index as usize),
33 EntryLink::Stored(index) => self.stored.get(&index),
34 }
35 .map(|node| IndexedNode { node, link })
36 .ok_or(Error::ExpectedInMemory(link))
37 }
38
39 fn push(&mut self, data: Entry<V>) -> EntryLink {
40 let idx = self.stored_count;
41 self.stored_count += 1;
42 self.stored.insert(idx, data);
43 EntryLink::Stored(idx)
44 }
45
46 fn push_generated(&mut self, data: Entry<V>) -> EntryLink {
47 self.generated.push(data);
48 EntryLink::Generated(self.generated.len() as u32 - 1)
49 }
50
51 #[cfg(test)]
54 pub fn populate(loaded: Vec<Entry<V>>, root: EntryLink) -> Self {
55 let mut result = Tree::invalid();
56 result.stored_count = loaded.len() as u32;
57 for (idx, item) in loaded.into_iter().enumerate() {
58 result.stored.insert(idx as u32, item);
59 }
60 result.root = root;
61
62 result
63 }
64
65 fn invalid() -> Self {
67 Tree {
68 root: EntryLink::Generated(0),
69 generated: Default::default(),
70 stored: Default::default(),
71 stored_count: 0,
72 }
73 }
74
75 pub fn new(length: u32, peaks: Vec<(u32, Entry<V>)>, extra: Vec<(u32, Entry<V>)>) -> Self {
87 assert!(!peaks.is_empty());
88
89 let mut result = Tree::invalid();
90
91 result.stored_count = length;
92
93 let mut root = EntryLink::Stored(peaks[0].0);
94 for (gen, (idx, node)) in peaks.into_iter().enumerate() {
95 result.stored.insert(idx, node);
96 if gen != 0 {
97 let next_generated = combine_nodes(
98 result
99 .resolve_link(root)
100 .expect("Inserted before, cannot fail; qed"),
101 result
102 .resolve_link(EntryLink::Stored(idx))
103 .expect("Inserted before, cannot fail; qed"),
104 );
105 root = result.push_generated(next_generated);
106 }
107 }
108
109 for (idx, node) in extra {
110 result.stored.insert(idx, node);
111 }
112
113 result.root = root;
114
115 result
116 }
117
118 fn get_peaks(&self, root: EntryLink, target: &mut Vec<EntryLink>) -> Result<(), Error> {
119 let (left_child_link, right_child_link) = {
120 let root = self.resolve_link(root)?;
121 if root.node.complete() {
122 target.push(root.link);
123 return Ok(());
124 }
125 (root.left()?, root.right()?)
126 };
127
128 self.get_peaks(left_child_link, target)?;
129 self.get_peaks(right_child_link, target)?;
130 Ok(())
131 }
132
133 pub fn append_leaf(&mut self, new_leaf: V::NodeData) -> Result<Vec<EntryLink>, Error> {
139 let root = self.root;
140 let new_leaf_link = self.push(Entry::new_leaf(new_leaf));
141 let mut appended = vec![new_leaf_link];
142
143 let mut peaks = Vec::new();
144 self.get_peaks(root, &mut peaks)?;
145
146 let mut merge_stack = vec![new_leaf_link];
147
148 while let Some(next_peak) = peaks.pop() {
152 let next_merge = merge_stack
153 .pop()
154 .expect("there should be at least one, initial or re-pushed");
155
156 if let Some(stored) = {
157 let peak = self.resolve_link(next_peak)?;
158 let m = self.resolve_link(next_merge)?;
159 if peak.node.leaf_count() == m.node.leaf_count() {
160 Some(combine_nodes(peak, m))
161 } else {
162 None
163 }
164 } {
165 let link = self.push(stored);
166 merge_stack.push(link);
167 appended.push(link);
168 continue;
169 } else {
170 merge_stack.push(next_merge);
171 merge_stack.push(next_peak);
172 }
173 }
174
175 let mut new_root = merge_stack
176 .pop()
177 .expect("Loop above cannot reduce the merge_stack");
178 while let Some(next_child) = merge_stack.pop() {
181 new_root = self.push_generated(combine_nodes(
182 self.resolve_link(new_root)?,
183 self.resolve_link(next_child)?,
184 ))
185 }
186
187 self.root = new_root;
188
189 Ok(appended)
190 }
191
192 #[cfg(test)]
193 fn for_children<F: Fn(EntryLink, EntryLink)>(&self, node: EntryLink, f: F) {
194 let (left, right) = {
195 let link = self
196 .resolve_link(node)
197 .expect("Failed to resolve link in test");
198 (
199 link.left().expect("Failed to find node in test"),
200 link.right().expect("Failed to find node in test"),
201 )
202 };
203 f(left, right);
204 }
205
206 fn pop(&mut self) {
207 self.stored.remove(&(self.stored_count - 1));
208 self.stored_count -= 1;
209 }
210
211 pub fn truncate_leaf(&mut self) -> Result<u32, Error> {
216 let root = {
217 let (leaves, root_left_child) = {
218 let n = self.resolve_link(self.root)?;
219 (n.node.leaf_count(), n.node.left()?)
220 };
221 if leaves & 1 != 0 {
222 self.pop();
223 self.root = root_left_child;
224 return Ok(1);
225 } else {
226 self.resolve_link(self.root)?
227 }
228 };
229
230 let mut peaks = vec![root.left()?];
231 let mut subtree_root_link = root.right()?;
232 let mut truncated = 1;
233
234 loop {
235 let left_link = self.resolve_link(subtree_root_link)?.node;
236 if let EntryKind::Node(left, right) = left_link.kind {
237 peaks.push(left);
238 subtree_root_link = right;
239 truncated += 1;
240 } else {
241 if root.node.complete() {
242 truncated += 1;
243 }
244 break;
245 }
246 }
247
248 let mut new_root = *peaks.first().expect("At lest 1 elements in peaks");
249
250 for next_peak in peaks.into_iter().skip(1) {
251 new_root = self.push_generated(combine_nodes(
252 self.resolve_link(new_root)?,
253 self.resolve_link(next_peak)?,
254 ));
255 }
256
257 for _ in 0..truncated {
258 self.pop();
259 }
260
261 self.root = new_root;
262
263 Ok(truncated)
264 }
265
266 pub fn len(&self) -> u32 {
268 self.stored_count
269 }
270
271 pub fn root(&self) -> EntryLink {
273 self.root
274 }
275
276 pub fn root_node(&self) -> Result<IndexedNode<V>, Error> {
278 self.resolve_link(self.root)
279 }
280
281 pub fn is_empty(&self) -> bool {
283 self.stored_count == 0
284 }
285}
286
287#[derive(Debug)]
289pub struct IndexedNode<'a, V: Version> {
290 node: &'a Entry<V>,
291 link: EntryLink,
292}
293
294impl<V: Version> IndexedNode<'_, V> {
295 fn left(&self) -> Result<EntryLink, Error> {
296 self.node.left().map_err(|e| e.augment(self.link))
297 }
298
299 fn right(&self) -> Result<EntryLink, Error> {
300 self.node.right().map_err(|e| e.augment(self.link))
301 }
302
303 pub fn node(&self) -> &Entry<V> {
305 self.node
306 }
307
308 pub fn data(&self) -> &V::NodeData {
310 &self.node.data
311 }
312
313 pub fn link(&self) -> EntryLink {
315 self.link
316 }
317}
318
319fn combine_nodes<'a, V: Version>(left: IndexedNode<'a, V>, right: IndexedNode<'a, V>) -> Entry<V> {
320 Entry {
321 kind: EntryKind::Node(left.link, right.link),
322 data: V::combine(&left.node.data, &right.node.data),
323 }
324}
325
326#[cfg(test)]
327mod tests {
328 use super::{Entry, EntryKind, EntryLink, Tree};
329 use crate::{node_data, NodeData, Version, V2};
330
331 use assert_matches::assert_matches;
332 use proptest::prelude::*;
333
334 fn leaf(height: u32) -> node_data::V2 {
335 node_data::V2 {
336 v1: NodeData {
337 consensus_branch_id: 1,
338 subtree_commitment: [0u8; 32],
339 start_time: 0,
340 end_time: 0,
341 start_target: 0,
342 end_target: 0,
343 start_sapling_root: [0u8; 32],
344 end_sapling_root: [0u8; 32],
345 subtree_total_work: 0.into(),
346 start_height: height as u64,
347 end_height: height as u64,
348 sapling_tx: 7,
349 },
350 start_orchard_root: [0u8; 32],
351 end_orchard_root: [0u8; 32],
352 orchard_tx: 42,
353 }
354 }
355
356 fn initial() -> Tree<V2> {
357 let node1 = Entry::new_leaf(leaf(1));
358 let node2 = Entry::new_leaf(leaf(2));
359
360 let node3 = Entry {
361 data: V2::combine(&node1.data, &node2.data),
362 kind: EntryKind::Leaf,
363 };
364
365 Tree::populate(vec![node1, node2, node3], EntryLink::Stored(2))
366 }
367
368 fn generated(length: u32) -> Tree<V2> {
370 assert!(length >= 3);
371 let mut tree = initial();
372 for i in 2..length {
373 tree.append_leaf(leaf(i + 1)).expect("Failed to append");
374 }
375
376 tree
377 }
378
379 #[test]
380 fn discrete_append() {
381 let mut tree = initial();
382
383 let appended = tree.append_leaf(leaf(3)).expect("Failed to append");
385 let new_root = tree.root_node().expect("Failed to resolve root").node;
386
387 assert_eq!(new_root.data.v1.end_height, 3);
401 assert_eq!(appended.len(), 1);
402
403 let appended = tree.append_leaf(leaf(4)).expect("Failed to append");
405
406 let new_root = tree.root_node().expect("Failed to resolve root").node;
407
408 assert_eq!(new_root.data.v1.end_height, 4);
425 assert_eq!(appended.len(), 3);
426 assert_matches!(tree.root(), EntryLink::Stored(6));
427
428 let appended = tree.append_leaf(leaf(5)).expect("Failed to append");
431 let new_root = tree.root_node().expect("Failed to resolve root").node;
432
433 assert_eq!(new_root.data.v1.end_height, 5);
452 assert_eq!(appended.len(), 1);
453 assert_matches!(tree.root(), EntryLink::Generated(_));
454 tree.for_children(tree.root(), |l, r| {
455 assert_matches!(l, EntryLink::Stored(6));
456 assert_matches!(r, EntryLink::Stored(7));
457 });
458
459 let appended = tree.append_leaf(leaf(6)).expect("Failed to append");
461 let new_root = tree.root_node().expect("Failed to resolve root").node;
462
463 assert_eq!(new_root.data.v1.end_height, 6);
484 assert_eq!(appended.len(), 2);
485 assert_matches!(tree.root(), EntryLink::Generated(_));
486 tree.for_children(tree.root(), |l, r| {
487 assert_matches!(l, EntryLink::Stored(6));
488 assert_matches!(r, EntryLink::Stored(9));
489 });
490
491 let appended = tree.append_leaf(leaf(7)).expect("Failed to append");
494 let new_root = tree.root_node().expect("Failed to resolve root").node;
495
496 assert_eq!(new_root.data.v1.end_height, 7);
519 assert_eq!(appended.len(), 1);
520 assert_matches!(tree.root(), EntryLink::Generated(_));
521 tree.for_children(tree.root(), |l, r| {
522 assert_matches!(l, EntryLink::Generated(_));
523 tree.for_children(l, |l, r| {
524 assert_matches!((l, r), (EntryLink::Stored(6), EntryLink::Stored(9)))
525 });
526 assert_matches!(r, EntryLink::Stored(10));
527 });
528 }
529
530 #[test]
531 fn truncate_simple() {
532 let mut tree = generated(9);
533 let total_truncated = tree.truncate_leaf().expect("Failed to truncate");
534
535 assert_matches!(tree.root(), EntryLink::Stored(14));
560 assert_eq!(total_truncated, 1);
561 assert_eq!(tree.len(), 15);
562 }
563
564 #[test]
565 fn truncate_generated() {
566 let mut tree = generated(10);
567 let deleted = tree.truncate_leaf().expect("Failed to truncate");
568
569 assert_matches!(tree.root(), EntryLink::Generated(_));
595
596 tree.for_children(tree.root(), |left, right| {
597 assert_matches!(
598 (left, right),
599 (EntryLink::Stored(14), EntryLink::Stored(15))
600 )
601 });
602
603 assert_eq!(deleted, 2);
605 assert_eq!(tree.len(), 16);
606 }
607
608 #[test]
609 fn tree_len() {
610 let mut tree = initial();
611
612 assert_eq!(tree.len(), 3);
613
614 for i in 0..2 {
615 tree.append_leaf(leaf(i + 3)).expect("Failed to append");
616 }
617 assert_eq!(tree.len(), 7);
618
619 tree.truncate_leaf().expect("Failed to truncate");
620
621 assert_eq!(tree.len(), 4);
622 }
623
624 #[test]
625 fn tree_len_long() {
626 let mut tree = initial();
627
628 assert_eq!(tree.len(), 3);
629
630 for i in 0..4094 {
631 tree.append_leaf(leaf(i + 3)).expect("Failed to append");
632 }
633 assert_eq!(tree.len(), 8191); for _ in 0..2049 {
636 tree.truncate_leaf().expect("Failed to truncate");
637 }
638
639 assert_eq!(tree.len(), 4083); }
641
642 proptest! {
643 #[test]
644 fn prop_there_and_back(number in 0u32..=1024) {
645 let mut tree = initial();
646 for i in 0..number {
647 tree.append_leaf(leaf(i+3)).expect("Failed to append");
648 }
649 for _ in 0..number {
650 tree.truncate_leaf().expect("Failed to truncate");
651 }
652
653 assert_matches!(tree.root(), EntryLink::Stored(2));
654 }
655
656 #[test]
657 fn prop_leaf_count(number in 3u32..=1024) {
658 let mut tree = initial();
659 for i in 1..(number-1) {
660 tree.append_leaf(leaf(i+2)).expect("Failed to append");
661 }
662
663 assert_eq!(tree.root_node().expect("no root").node.leaf_count(), number as u64);
664 }
665
666 #[test]
667 fn prop_parity(number in 3u32..=2048) {
668 let mut tree = initial();
669 for i in 1..(number-1) {
670 tree.append_leaf(leaf(i+2)).expect("Failed to append");
671 }
672
673 if number & (number - 1) == 0 {
674 assert_matches!(tree.root(), EntryLink::Stored(_));
675 } else {
676 assert_matches!(tree.root(), EntryLink::Generated(_));
677 }
678 }
679
680 #[test]
681 fn prop_parity_with_truncate(
682 add_and_delete in (0u32..=2048).prop_flat_map(
683 |add| (Just(add), 0..=add)
684 )
685 ) {
686 let (add, delete) = add_and_delete;
687 let mut tree = initial();
690 for i in 0..add {
691 tree.append_leaf(leaf(i+3)).expect("Failed to append");
692 }
693 for _ in 0..delete {
694 tree.truncate_leaf().expect("Failed to truncate");
695 }
696
697 let total = add - delete + 2;
698
699 if total & (total - 1) == 0 {
700 assert_matches!(tree.root(), EntryLink::Stored(_));
701 } else {
702 assert_matches!(tree.root(), EntryLink::Generated(_));
703 }
704 }
705
706 #[test]
707 fn prop_stored_length(
708 add_and_delete in (0u32..=2048).prop_flat_map(
709 |add| (Just(add), 0..=add)
710 )
711 ) {
712 let (add, delete) = add_and_delete;
713 let mut tree = initial();
714 for i in 0..add {
715 tree.append_leaf(leaf(i+3)).expect("Failed to append");
716 }
717 for _ in 0..delete {
718 tree.truncate_leaf().expect("Failed to truncate");
719 }
720
721 let total = add - delete + 2;
722
723 assert!(total * total > tree.len())
724 }
725 }
726}