penumbra_sdk_tct/internal/frontier/
leaf.rs

1use crate::prelude::*;
2
3/// The frontier (rightmost) leaf in a frontier of a tree.
4///
5/// Insertion into a leaf always fails, causing the tree above it to insert a new leaf to contain
6/// the inserted item.
7#[derive(Clone, Copy, Derivative, Serialize, Deserialize)]
8#[derivative(Debug = "transparent")]
9pub struct Leaf<Item> {
10    item: Item,
11}
12
13impl<Item: GetHash> GetHash for Leaf<Item> {
14    #[inline]
15    fn hash(&self) -> Hash {
16        self.item.hash()
17    }
18
19    #[inline]
20    fn cached_hash(&self) -> Option<Hash> {
21        self.item.cached_hash()
22    }
23}
24
25impl<Item: Height> Height for Leaf<Item> {
26    type Height = Item::Height;
27}
28
29impl<Item: Focus> Frontier for Leaf<Item> {
30    type Item = Item;
31
32    #[inline]
33    fn new(item: Self::Item) -> Self {
34        Self { item }
35    }
36
37    #[inline]
38    fn update<T>(&mut self, f: impl FnOnce(&mut Self::Item) -> T) -> Option<T> {
39        Some(f(&mut self.item))
40    }
41
42    #[inline]
43    fn focus(&self) -> Option<&Self::Item> {
44        Some(&self.item)
45    }
46
47    #[inline]
48    /// Insertion into a leaf always fails, causing the tree above it to insert a new leaf to
49    /// contain the inserted item.
50    fn insert_owned(self, item: Self::Item) -> Result<Self, Full<Self>> {
51        Err(Full {
52            item,
53            complete: self.finalize_owned(),
54        })
55    }
56
57    #[inline]
58    fn is_full(&self) -> bool {
59        true
60    }
61}
62
63impl<Item: Focus> Focus for Leaf<Item> {
64    type Complete = complete::Leaf<<Item as Focus>::Complete>;
65
66    #[inline]
67    fn finalize_owned(self) -> Insert<Self::Complete> {
68        self.item.finalize_owned().map(complete::Leaf::new)
69    }
70}
71
72impl<Item: Witness> Witness for Leaf<Item> {
73    #[inline]
74    fn witness(&self, index: impl Into<u64>) -> Option<(AuthPath<Self>, Hash)> {
75        self.item.witness(index)
76    }
77}
78
79impl<Item: GetPosition> GetPosition for Leaf<Item> {
80    #[inline]
81    fn position(&self) -> Option<u64> {
82        self.item.position()
83    }
84}
85
86impl<Item: GetHash + Forget> Forget for Leaf<Item> {
87    #[inline]
88    fn forget(&mut self, forgotten: Option<Forgotten>, index: impl Into<u64>) -> bool {
89        self.item.forget(forgotten, index)
90    }
91}
92
93impl<'tree, Item: GetPosition + Height + structure::Any<'tree>> structure::Any<'tree>
94    for Leaf<Item>
95{
96    fn kind(&self) -> Kind {
97        self.item.kind()
98    }
99
100    fn forgotten(&self) -> Forgotten {
101        self.item.forgotten()
102    }
103
104    fn children(&'tree self) -> Vec<HashOrNode<'tree>> {
105        self.item.children()
106    }
107}
108
109impl<Item: OutOfOrder> OutOfOrder for Leaf<Item> {
110    fn uninitialized(position: Option<u64>, forgotten: Forgotten) -> Self {
111        Self {
112            item: Item::uninitialized(position, forgotten),
113        }
114    }
115
116    fn uninitialized_out_of_order_insert_commitment(
117        &mut self,
118        index: u64,
119        commitment: StateCommitment,
120    ) {
121        self.item
122            .uninitialized_out_of_order_insert_commitment(index, commitment)
123    }
124}
125
126impl<Item: UncheckedSetHash> UncheckedSetHash for Leaf<Item> {
127    fn unchecked_set_hash(&mut self, index: u64, height: u8, hash: Hash) {
128        self.item.unchecked_set_hash(index, height, hash)
129    }
130
131    fn finish_initialize(&mut self) {
132        self.item.finish_initialize()
133    }
134}