1use crate::hash_tree::HashTree;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize))]
6#[cfg_attr(
7 feature = "serde",
8 serde(bound(serialize = "Storage: serde_bytes::Serialize"))
9)]
10pub struct Certificate<Storage: AsRef<[u8]>> {
11 pub tree: HashTree<Storage>,
13
14 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
16 pub signature: Storage,
17
18 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
20 pub delegation: Option<Delegation<Storage>>,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize))]
26#[cfg_attr(
27 feature = "serde",
28 serde(bound(serialize = "Storage: serde_bytes::Serialize"))
29)]
30pub struct Delegation<Storage: AsRef<[u8]>> {
31 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
32 pub subnet_id: Storage,
33
34 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
35 pub certificate: Storage,
36}
37
38#[cfg(feature = "serde")]
39mod serde_impl {
40 use super::{Certificate, Delegation};
41 use crate::{hash_tree::HashTreeNode, serde_impl::*};
42
43 use std::{borrow::Cow, fmt, marker::PhantomData};
44
45 use serde::{
46 de::{self, MapAccess, SeqAccess, Visitor},
47 Deserialize, Deserializer,
48 };
49
50 #[derive(Deserialize)]
51 #[serde(field_identifier, rename_all = "snake_case")]
52 enum CertificateField {
53 Tree,
54 Signature,
55 Delegation,
56 }
57 struct CertificateVisitor<S>(PhantomData<S>);
58
59 impl<'de, S: Storage> Visitor<'de> for CertificateVisitor<S>
60 where
61 Delegation<S::Value<'de>>: Deserialize<'de>,
62 HashTreeNode<S::Value<'de>>: Deserialize<'de>,
63 {
64 type Value = Certificate<S::Value<'de>>;
65
66 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
67 formatter.write_str("struct Delegation")
68 }
69
70 fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
71 where
72 V: SeqAccess<'de>,
73 {
74 let tree = seq
75 .next_element()?
76 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
77 let signature = S::convert(
78 seq.next_element()?
79 .ok_or_else(|| de::Error::invalid_length(1, &self))?,
80 );
81 let delegation = seq.next_element()?;
82
83 Ok(Certificate {
84 tree,
85 signature,
86 delegation,
87 })
88 }
89
90 fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
91 where
92 V: MapAccess<'de>,
93 {
94 let mut tree = None;
95 let mut signature = None;
96 let mut delegation = None;
97 while let Some(key) = map.next_key()? {
98 match key {
99 CertificateField::Tree => {
100 if tree.is_some() {
101 return Err(de::Error::duplicate_field("tree"));
102 }
103 tree = Some(map.next_value()?);
104 }
105 CertificateField::Signature => {
106 if signature.is_some() {
107 return Err(de::Error::duplicate_field("signature"));
108 }
109 signature = Some(map.next_value()?);
110 }
111 CertificateField::Delegation => {
112 if delegation.is_some() {
113 return Err(de::Error::duplicate_field("signature"));
114 }
115 delegation = Some(map.next_value()?);
116 }
117 }
118 }
119 let tree = tree.ok_or_else(|| de::Error::missing_field("tree"))?;
120 let signature =
121 S::convert(signature.ok_or_else(|| de::Error::missing_field("signature"))?);
122 Ok(Certificate {
123 tree,
124 signature,
125 delegation,
126 })
127 }
128 }
129
130 fn deserialize_certificate<'de, S: Storage, D>(
131 deserializer: D,
132 ) -> Result<Certificate<S::Value<'de>>, D::Error>
133 where
134 Delegation<S::Value<'de>>: Deserialize<'de>,
135 HashTreeNode<S::Value<'de>>: Deserialize<'de>,
136 D: Deserializer<'de>,
137 {
138 const FIELDS: &[&str] = &["tree", "signature", "delegation"];
139 deserializer.deserialize_struct("Certificate", FIELDS, CertificateVisitor::<S>(PhantomData))
140 }
141
142 impl<'de> Deserialize<'de> for Certificate<Vec<u8>> {
143 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
144 where
145 D: Deserializer<'de>,
146 {
147 deserialize_certificate::<VecStorage, _>(deserializer)
148 }
149 }
150
151 impl<'de> Deserialize<'de> for Certificate<&'de [u8]> {
152 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
153 where
154 D: Deserializer<'de>,
155 {
156 deserialize_certificate::<SliceStorage, _>(deserializer)
157 }
158 }
159
160 impl<'de> Deserialize<'de> for Certificate<Cow<'de, [u8]>> {
161 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
162 where
163 D: Deserializer<'de>,
164 {
165 deserialize_certificate::<CowStorage, _>(deserializer)
166 }
167 }
168
169 #[derive(Deserialize)]
170 #[serde(field_identifier, rename_all = "snake_case")]
171 enum DelegationField {
172 SubnetId,
173 Certificate,
174 }
175 struct DelegationVisitor<S>(PhantomData<S>);
176
177 impl<'de, S: Storage> Visitor<'de> for DelegationVisitor<S> {
178 type Value = Delegation<S::Value<'de>>;
179
180 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
181 formatter.write_str("struct Delegation")
182 }
183
184 fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
185 where
186 V: SeqAccess<'de>,
187 {
188 let subnet_id = S::convert(
189 seq.next_element()?
190 .ok_or_else(|| de::Error::invalid_length(0, &self))?,
191 );
192 let certificate = S::convert(
193 seq.next_element()?
194 .ok_or_else(|| de::Error::invalid_length(1, &self))?,
195 );
196 Ok(Delegation {
197 subnet_id,
198 certificate,
199 })
200 }
201
202 fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
203 where
204 V: MapAccess<'de>,
205 {
206 let mut subnet_id = None;
207 let mut certificate = None;
208 while let Some(key) = map.next_key()? {
209 match key {
210 DelegationField::SubnetId => {
211 if subnet_id.is_some() {
212 return Err(de::Error::duplicate_field("subnet_id"));
213 }
214 subnet_id = Some(map.next_value()?);
215 }
216 DelegationField::Certificate => {
217 if certificate.is_some() {
218 return Err(de::Error::duplicate_field("certificate"));
219 }
220 certificate = Some(map.next_value()?);
221 }
222 }
223 }
224 let subnet_id =
225 S::convert(subnet_id.ok_or_else(|| de::Error::missing_field("subnet_id"))?);
226 let certificate =
227 S::convert(certificate.ok_or_else(|| de::Error::missing_field("certificate"))?);
228 Ok(Delegation {
229 subnet_id,
230 certificate,
231 })
232 }
233 }
234
235 fn deserialize_delegation<'de, S: Storage, D>(
236 deserializer: D,
237 ) -> Result<Delegation<S::Value<'de>>, D::Error>
238 where
239 D: Deserializer<'de>,
240 {
241 const FIELDS: &[&str] = &["subnet_id", "certificate"];
242 deserializer.deserialize_struct("Delegation", FIELDS, DelegationVisitor::<S>(PhantomData))
243 }
244
245 impl<'de> Deserialize<'de> for Delegation<Vec<u8>> {
246 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
247 where
248 D: Deserializer<'de>,
249 {
250 deserialize_delegation::<VecStorage, _>(deserializer)
251 }
252 }
253
254 impl<'de> Deserialize<'de> for Delegation<&'de [u8]> {
255 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
256 where
257 D: Deserializer<'de>,
258 {
259 deserialize_delegation::<SliceStorage, _>(deserializer)
260 }
261 }
262
263 impl<'de> Deserialize<'de> for Delegation<Cow<'de, [u8]>> {
264 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
265 where
266 D: Deserializer<'de>,
267 {
268 deserialize_delegation::<CowStorage, _>(deserializer)
269 }
270 }
271}
272
273#[cfg(test)]
274#[cfg(feature = "serde")]
275mod tests {
276 use super::*;
277 use crate::hash_tree::{empty, fork, label, leaf};
278
279 fn create_tree() -> HashTree<Vec<u8>> {
280 fork(
281 fork(
282 label(
283 "a",
284 fork(
285 fork(label("x", leaf(*b"hello")), empty()),
286 label("y", leaf(*b"world")),
287 ),
288 ),
289 label("b", leaf(*b"good")),
290 ),
291 fork(label("c", empty()), label("d", leaf(*b"morning"))),
292 )
293 }
294
295 #[test]
296 fn serialize_to_cbor() {
297 let tree = create_tree();
298 let signature = vec![1, 2, 3, 4, 5, 6];
299
300 let certificate = Certificate {
301 tree,
302 signature,
303 delegation: None,
304 };
305
306 let cbor_bytes =
307 serde_cbor::to_vec(&certificate).expect("Failed to encode certificate to cbor");
308 let cbor_hex = hex::encode(cbor_bytes);
309
310 assert_eq!(cbor_hex, "a264747265658301830183024161830183018302417882034568656c6c6f810083024179820345776f726c6483024162820344676f6f648301830241638100830241648203476d6f726e696e67697369676e617475726546010203040506");
311 }
312
313 #[test]
314 fn serialize_to_cbor_with_delegation() {
315 let tree = create_tree();
316 let signature = vec![1, 2, 3, 4, 5, 6];
317 let delegation = Delegation {
318 subnet_id: vec![7, 8, 9, 10, 11, 12],
319 certificate: vec![13, 14, 15, 16, 17, 18],
320 };
321
322 let certificate = Certificate {
323 tree,
324 signature,
325 delegation: Some(delegation),
326 };
327
328 let cbor_bytes =
329 serde_cbor::to_vec(&certificate).expect("Failed to encode certificate to cbor");
330 let cbor_hex = hex::encode(cbor_bytes);
331
332 assert_eq!(cbor_hex, "a364747265658301830183024161830183018302417882034568656c6c6f810083024179820345776f726c6483024162820344676f6f648301830241638100830241648203476d6f726e696e67697369676e6174757265460102030405066a64656c65676174696f6ea2697375626e65745f6964460708090a0b0c6b6365727469666963617465460d0e0f101112");
333 }
334}