zebra_state/service/finalized_state/disk_format/
shielded.rs1use bincode::Options;
9
10use zebra_chain::{
11 block::Height,
12 ironwood, 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 ironwood::Nullifier {
46 type Bytes = [u8; 32];
47
48 fn as_bytes(&self) -> Self::Bytes {
49 (*self).into()
52 }
53}
54
55impl IntoDisk for sprout::tree::Root {
56 type Bytes = [u8; 32];
57
58 fn as_bytes(&self) -> Self::Bytes {
59 self.into()
60 }
61}
62
63impl FromDisk for sprout::tree::Root {
64 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
65 let array: [u8; 32] = bytes.as_ref().try_into().unwrap();
66 array.into()
67 }
68}
69
70impl IntoDisk for sapling::tree::Root {
71 type Bytes = [u8; 32];
72
73 fn as_bytes(&self) -> Self::Bytes {
74 self.into()
75 }
76}
77
78impl FromDisk for sapling::tree::Root {
79 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
80 let array: [u8; 32] = bytes.as_ref().try_into().unwrap();
81 array.try_into().expect("finalized data must be valid")
82 }
83}
84
85impl IntoDisk for orchard::tree::Root {
86 type Bytes = [u8; 32];
87
88 fn as_bytes(&self) -> Self::Bytes {
89 self.into()
90 }
91}
92
93impl FromDisk for orchard::tree::Root {
94 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
95 let array: [u8; 32] = bytes.as_ref().try_into().unwrap();
96 array.try_into().expect("finalized data must be valid")
97 }
98}
99
100impl IntoDisk for NoteCommitmentSubtreeIndex {
101 type Bytes = [u8; 2];
102
103 fn as_bytes(&self) -> Self::Bytes {
104 self.0.to_be_bytes()
105 }
106}
107
108impl FromDisk for NoteCommitmentSubtreeIndex {
109 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
110 let array: [u8; 2] = bytes.as_ref().try_into().unwrap();
111 Self(u16::from_be_bytes(array))
112 }
113}
114
115impl IntoDisk for sprout::tree::NoteCommitmentTree {
123 type Bytes = Vec<u8>;
124
125 fn as_bytes(&self) -> Self::Bytes {
126 bincode::DefaultOptions::new()
127 .serialize(self)
128 .expect("serialization to vec doesn't fail")
129 }
130}
131
132impl FromDisk for sprout::tree::NoteCommitmentTree {
133 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
134 bincode::DefaultOptions::new()
135 .deserialize(bytes.as_ref())
136 .expect("deserialization format should match the serialization format used by IntoDisk")
137 }
138}
139impl IntoDisk for sapling::tree::NoteCommitmentTree {
140 type Bytes = Vec<u8>;
141
142 fn as_bytes(&self) -> Self::Bytes {
143 bincode::DefaultOptions::new()
144 .serialize(self)
145 .expect("serialization to vec doesn't fail")
146 }
147}
148
149impl FromDisk for sapling::tree::NoteCommitmentTree {
150 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
151 bincode::DefaultOptions::new()
152 .deserialize(bytes.as_ref())
153 .expect("deserialization format should match the serialization format used by IntoDisk")
154 }
155}
156
157impl IntoDisk for orchard::tree::NoteCommitmentTree {
158 type Bytes = Vec<u8>;
159
160 fn as_bytes(&self) -> Self::Bytes {
161 bincode::DefaultOptions::new()
162 .serialize(self)
163 .expect("serialization to vec doesn't fail")
164 }
165}
166
167impl FromDisk for orchard::tree::NoteCommitmentTree {
168 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
169 bincode::DefaultOptions::new()
170 .deserialize(bytes.as_ref())
171 .expect("deserialization format should match the serialization format used by IntoDisk")
172 }
173}
174
175impl IntoDisk for sapling_crypto::Node {
176 type Bytes = Vec<u8>;
177
178 fn as_bytes(&self) -> Self::Bytes {
179 self.to_bytes().to_vec()
180 }
181}
182
183impl IntoDisk for orchard::tree::Node {
184 type Bytes = Vec<u8>;
185
186 fn as_bytes(&self) -> Self::Bytes {
187 self.to_repr().to_vec()
188 }
189}
190
191impl<Root: IntoDisk<Bytes = Vec<u8>>> IntoDisk for NoteCommitmentSubtreeData<Root> {
192 type Bytes = Vec<u8>;
193
194 fn as_bytes(&self) -> Self::Bytes {
195 [self.end_height.as_bytes().to_vec(), self.root.as_bytes()].concat()
196 }
197}
198
199impl FromDisk for sapling_crypto::Node {
200 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
201 Self::from_bytes(
202 bytes
203 .as_ref()
204 .try_into()
205 .expect("trusted data should be 32 bytes"),
206 )
207 .expect("trusted data should deserialize successfully")
208 }
209}
210
211impl FromDisk for orchard::tree::Node {
212 fn from_bytes(bytes: impl AsRef<[u8]>) -> Self {
213 Self::try_from(bytes.as_ref()).expect("trusted data should deserialize successfully")
214 }
215}
216
217impl<Node: FromDisk> FromDisk for NoteCommitmentSubtreeData<Node> {
218 fn from_bytes(disk_bytes: impl AsRef<[u8]>) -> Self {
219 let (height_bytes, node_bytes) = disk_bytes.as_ref().split_at(HEIGHT_DISK_BYTES);
220 Self::new(
221 Height::from_bytes(height_bytes),
222 Node::from_bytes(node_bytes),
223 )
224 }
225}