zebra_chain/sapling/tree/
legacy.rs1use incrementalmerkletree::{frontier::Frontier, Position};
15use serde::Serialize;
16
17use super::{serde_helpers, NoteCommitmentTree, Root, MERKLE_DEPTH};
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct Node(#[serde(with = "serde_helpers::Node")] pub sapling_crypto::Node);
22
23impl From<sapling_crypto::Node> for Node {
24 fn from(n: sapling_crypto::Node) -> Self {
25 Node(n)
26 }
27}
28
29impl From<Node> for sapling_crypto::Node {
30 fn from(n: Node) -> Self {
31 n.0
32 }
33}
34
35#[derive(Debug, Serialize, Deserialize)]
37#[serde(rename = "NoteCommitmentTree")]
38#[allow(missing_docs)]
39pub struct LegacyNoteCommitmentTree {
40 pub inner: LegacyFrontier<Node, MERKLE_DEPTH>,
41 cached_root: std::sync::RwLock<Option<Root>>,
42}
43
44impl From<NoteCommitmentTree> for LegacyNoteCommitmentTree {
45 fn from(nct: NoteCommitmentTree) -> Self {
46 LegacyNoteCommitmentTree {
47 inner: nct.inner.into(),
48 cached_root: nct.cached_root,
49 }
50 }
51}
52
53impl From<LegacyNoteCommitmentTree> for NoteCommitmentTree {
54 fn from(nct: LegacyNoteCommitmentTree) -> Self {
55 NoteCommitmentTree {
56 inner: nct.inner.into(),
57 cached_root: nct.cached_root,
58 }
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
63#[serde(rename = "Frontier")]
64#[allow(missing_docs)]
65pub struct LegacyFrontier<H, const DEPTH: u8> {
66 pub frontier: Option<LegacyNonEmptyFrontier<H>>,
67}
68
69impl From<LegacyFrontier<Node, MERKLE_DEPTH>> for Frontier<sapling_crypto::Node, MERKLE_DEPTH> {
70 fn from(legacy_frontier: LegacyFrontier<Node, MERKLE_DEPTH>) -> Self {
71 if let Some(legacy_frontier_data) = legacy_frontier.frontier {
72 let mut ommers = legacy_frontier_data
73 .ommers
74 .into_iter()
75 .map(|o| o.0)
76 .collect::<Vec<_>>();
77 let position = Position::from(
78 u64::try_from(legacy_frontier_data.position.0)
79 .expect("old `usize` always fits in `u64`"),
80 );
81 let leaf = match legacy_frontier_data.leaf {
82 LegacyLeaf::Left(a) => a.0,
83 LegacyLeaf::Right(a, b) => {
84 ommers.insert(0, a.0);
85 b.0
86 }
87 };
88 Frontier::from_parts(
89 position,
90 leaf,
91 ommers,
92 )
93 .expect("We should be able to construct a frontier from parts given legacy frontier is not empty")
94 } else {
95 Frontier::empty()
96 }
97 }
98}
99
100impl From<Frontier<sapling_crypto::Node, MERKLE_DEPTH>> for LegacyFrontier<Node, MERKLE_DEPTH> {
101 fn from(frontier: Frontier<sapling_crypto::Node, MERKLE_DEPTH>) -> Self {
102 if let Some(frontier_data) = frontier.value() {
103 let leaf_from_frontier = Node(*frontier_data.leaf());
104 let mut leaf = LegacyLeaf::Left(leaf_from_frontier.clone());
105 let mut ommers = frontier_data
106 .ommers()
107 .iter()
108 .map(|o| Node(*o))
109 .collect::<Vec<_>>();
110 let position = usize::try_from(u64::from(frontier_data.position()))
111 .expect("new position should fit in a `usize`");
112 if frontier_data.position().is_right_child() {
113 let left = ommers.remove(0);
114 leaf = LegacyLeaf::Right(left, leaf_from_frontier);
115 }
116 LegacyFrontier {
117 frontier: Some(LegacyNonEmptyFrontier {
118 position: LegacyPosition(position),
119 leaf,
120 ommers: ommers.to_vec(),
121 }),
122 }
123 } else {
124 LegacyFrontier { frontier: None }
125 }
126 }
127}
128
129#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
130#[serde(rename = "NonEmptyFrontier")]
131#[allow(missing_docs)]
132pub struct LegacyNonEmptyFrontier<H> {
133 pub position: LegacyPosition,
134 pub leaf: LegacyLeaf<H>,
135 pub ommers: Vec<H>,
136}
137
138#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
140#[serde(rename = "Leaf")]
141#[allow(missing_docs)]
142pub enum LegacyLeaf<A> {
143 Left(A),
144 Right(A, A),
145}
146
147#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
148#[repr(transparent)]
149#[allow(missing_docs)]
150pub struct LegacyPosition(pub usize);