zebra_state/service/finalized_state/disk_format/
shielded.rs
1use bincode::Options;
9
10use zebra_chain::{
11 block::Height,
12 orchard, sapling, sprout,
13 subtree::{NoteCommitmentSubtreeData, NoteCommitmentSubtreeIndex},
14};
15
16use crate::service::finalized_state::disk_format::{FromDisk, IntoDisk};
17
18use super::block::HEIGHT_DISK_BYTES;
19
20impl IntoDisk for sprout::Nullifier {
21 type Bytes = [u8; 32];
22
23 fn as_bytes(&self) -> Self::Bytes {
24 *self.0
25 }
26}
27
28impl IntoDisk for sapling::Nullifier {
29 type Bytes = [u8; 32];
30
31 fn as_bytes(&self) -> Self::Bytes {
32 *self.0
33 }
34}
35
36impl IntoDisk for orchard::Nullifier {
37 type Bytes = [u8; 32];
38
39 fn as_bytes(&self) -> Self::Bytes {
40 let nullifier: orchard::Nullifier = *self;
41 nullifier.into()
42 }
43}
44
45impl IntoDisk for sprout::tree::Root {
46 type Bytes = [u8; 32];
47
48 fn as_bytes(&self) -> Self::Bytes {
49 self.into()
50 }
51}
52
53impl FromDisk for sprout::tree::Root {
54 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
55 let array: [u8; 32] = bytes.as_ref().try_into().unwrap();
56 array.into()
57 }
58}
59
60impl IntoDisk for sapling::tree::Root {
61 type Bytes = [u8; 32];
62
63 fn as_bytes(&self) -> Self::Bytes {
64 self.into()
65 }
66}
67
68impl FromDisk for sapling::tree::Root {
69 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
70 let array: [u8; 32] = bytes.as_ref().try_into().unwrap();
71 array.try_into().expect("finalized data must be valid")
72 }
73}
74
75impl IntoDisk for orchard::tree::Root {
76 type Bytes = [u8; 32];
77
78 fn as_bytes(&self) -> Self::Bytes {
79 self.into()
80 }
81}
82
83impl FromDisk for orchard::tree::Root {
84 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
85 let array: [u8; 32] = bytes.as_ref().try_into().unwrap();
86 array.try_into().expect("finalized data must be valid")
87 }
88}
89
90impl IntoDisk for NoteCommitmentSubtreeIndex {
91 type Bytes = [u8; 2];
92
93 fn as_bytes(&self) -> Self::Bytes {
94 self.0.to_be_bytes()
95 }
96}
97
98impl FromDisk for NoteCommitmentSubtreeIndex {
99 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
100 let array: [u8; 2] = bytes.as_ref().try_into().unwrap();
101 Self(u16::from_be_bytes(array))
102 }
103}
104
105impl IntoDisk for sprout::tree::NoteCommitmentTree {
113 type Bytes = Vec<u8>;
114
115 fn as_bytes(&self) -> Self::Bytes {
116 bincode::DefaultOptions::new()
117 .serialize(self)
118 .expect("serialization to vec doesn't fail")
119 }
120}
121
122impl FromDisk for sprout::tree::NoteCommitmentTree {
123 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
124 bincode::DefaultOptions::new()
125 .deserialize(bytes.as_ref())
126 .expect("deserialization format should match the serialization format used by IntoDisk")
127 }
128}
129impl IntoDisk for sapling::tree::NoteCommitmentTree {
130 type Bytes = Vec<u8>;
131
132 fn as_bytes(&self) -> Self::Bytes {
133 bincode::DefaultOptions::new()
134 .serialize(self)
135 .expect("serialization to vec doesn't fail")
136 }
137}
138
139impl FromDisk for sapling::tree::NoteCommitmentTree {
140 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
141 bincode::DefaultOptions::new()
142 .deserialize(bytes.as_ref())
143 .expect("deserialization format should match the serialization format used by IntoDisk")
144 }
145}
146
147impl IntoDisk for orchard::tree::NoteCommitmentTree {
148 type Bytes = Vec<u8>;
149
150 fn as_bytes(&self) -> Self::Bytes {
151 bincode::DefaultOptions::new()
152 .serialize(self)
153 .expect("serialization to vec doesn't fail")
154 }
155}
156
157impl FromDisk for orchard::tree::NoteCommitmentTree {
158 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
159 bincode::DefaultOptions::new()
160 .deserialize(bytes.as_ref())
161 .expect("deserialization format should match the serialization format used by IntoDisk")
162 }
163}
164
165impl IntoDisk for sapling::tree::Node {
166 type Bytes = Vec<u8>;
167
168 fn as_bytes(&self) -> Self::Bytes {
169 self.as_ref().to_vec()
170 }
171}
172
173impl IntoDisk for orchard::tree::Node {
174 type Bytes = Vec<u8>;
175
176 fn as_bytes(&self) -> Self::Bytes {
177 self.to_repr().to_vec()
178 }
179}
180
181impl<Root: IntoDisk<Bytes = Vec<u8>>> IntoDisk for NoteCommitmentSubtreeData<Root> {
182 type Bytes = Vec<u8>;
183
184 fn as_bytes(&self) -> Self::Bytes {
185 [self.end_height.as_bytes().to_vec(), self.root.as_bytes()].concat()
186 }
187}
188
189impl FromDisk for sapling::tree::Node {
190 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
191 Self::try_from(bytes.as_ref()).expect("trusted data should deserialize successfully")
192 }
193}
194
195impl FromDisk for orchard::tree::Node {
196 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
197 Self::try_from(bytes.as_ref()).expect("trusted data should deserialize successfully")
198 }
199}
200
201impl<Node: FromDisk> FromDisk for NoteCommitmentSubtreeData<Node> {
202 fn from_bytes(disk_bytes: impl AsRef<[u8]>) -> Self {
203 let (height_bytes, node_bytes) = disk_bytes.as_ref().split_at(HEIGHT_DISK_BYTES);
204 Self::new(
205 Height::from_bytes(height_bytes),
206 Node::from_bytes(node_bytes),
207 )
208 }
209}