Skip to main content

emissary_core/i2np/database/
store.rs

1// Permission is hereby granted, free of charge, to any person obtaining a
2// copy of this software and associated documentation files (the "Software"),
3// to deal in the Software without restriction, including without limitation
4// the rights to use, copy, modify, merge, publish, distribute, sublicense,
5// and/or sell copies of the Software, and to permit persons to whom the
6// Software is furnished to do so, subject to the following conditions:
7//
8// The above copyright notice and this permission notice shall be included in
9// all copies or substantial portions of the Software.
10//
11// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
16// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17// DEALINGS IN THE SOFTWARE.
18
19use crate::{
20    error::parser::DatabaseStoreParseError,
21    i2np::{database::DATABASE_KEY_SIZE, ROUTER_HASH_LEN},
22    primitives::{LeaseSet2, RouterId, RouterInfo, TunnelId},
23    runtime::Runtime,
24};
25
26use bytes::{BufMut, Bytes, BytesMut};
27use nom::{
28    bytes::complete::take,
29    number::complete::{be_u16, be_u32, be_u8},
30    Err, IResult,
31};
32
33use core::{fmt, marker::PhantomData};
34
35/// "No reply" token/tunnel ID.
36const NO_REPLY: u32 = 0u32;
37
38#[derive(Debug, Copy, Clone)]
39enum StoreType {
40    /// Router info.
41    RouterInfo,
42
43    /// Lease set.
44    LeaseSet,
45
46    /// Lease set, type 2.
47    LeaseSet2,
48
49    /// Encrypted lease set.
50    EncryptedLeaseSet,
51
52    /// Meta lease set.
53    MetaLeaseSet,
54}
55
56impl StoreType {
57    /// Try to convert `store_type` into `StoreType`.
58    fn from_u8(store_type: u8) -> Option<Self> {
59        match store_type & 1 {
60            0 => Some(Self::RouterInfo),
61            _ => match (store_type >> 1) & 0x7 {
62                0 => Some(Self::LeaseSet),
63                1 => Some(Self::LeaseSet2),
64                2 => Some(Self::EncryptedLeaseSet),
65                3 => Some(Self::MetaLeaseSet),
66                _ => None,
67            },
68        }
69    }
70
71    /// Serialize [`StoreType`].
72    fn as_u8(&self) -> u8 {
73        match self {
74            Self::RouterInfo => 0u8,
75            Self::LeaseSet => 1u8,
76            Self::LeaseSet2 => 1u8 | (1u8 << 1),
77            Self::EncryptedLeaseSet => 1u8 | (2u8 << 1),
78            Self::MetaLeaseSet => 1u8 | (3u8 << 1),
79        }
80    }
81}
82
83/// Reply type.
84pub enum ReplyType {
85    /// Reply should be sent to tunnel.
86    Tunnel {
87        /// Reply token.
88        reply_token: u32,
89
90        /// ID of the gateway tunnel.
91        tunnel_id: TunnelId,
92
93        /// Router ID of the gateway tunnel.
94        router_id: RouterId,
95    },
96
97    /// Reply should be sent to router.
98    Router {
99        /// Reply token.
100        reply_token: u32,
101
102        /// Router ID of the gateway tunnel.
103        router_id: RouterId,
104    },
105
106    /// No reply required.
107    None,
108}
109
110impl fmt::Debug for ReplyType {
111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112        match self {
113            Self::Tunnel {
114                reply_token,
115                tunnel_id,
116                router_id,
117            } => f
118                .debug_struct("ReplyType::Tunnel")
119                .field("reply_token", &reply_token)
120                .field("router_id", &format_args!("{router_id}"))
121                .field("tunnel_id", &format_args!("{tunnel_id}"))
122                .finish_non_exhaustive(),
123            Self::Router {
124                reply_token,
125                router_id,
126            } => f
127                .debug_struct("ReplyType::Router")
128                .field("reply_token", &reply_token)
129                .field("router_id", &format_args!("{router_id}"))
130                .finish_non_exhaustive(),
131            Self::None => f.debug_struct("ReplyType::None").finish(),
132        }
133    }
134}
135
136impl ReplyType {
137    fn serialized_len(&self) -> usize {
138        match self {
139            Self::Tunnel { .. } | Self::Router { .. } => {
140                // reply token + tunnel id + router hash length
141                4usize + 4usize + ROUTER_HASH_LEN
142            }
143            Self::None => 4usize,
144        }
145    }
146}
147
148/// Payload contained within the `DatabaseStore` message.
149pub enum DatabaseStorePayload {
150    /// Router info.
151    RouterInfo {
152        /// Router info.
153        router_info: RouterInfo,
154    },
155
156    /// Lease set type 2.
157    LeaseSet2 {
158        /// Lease set.
159        lease_set: LeaseSet2,
160    },
161}
162
163impl fmt::Display for DatabaseStorePayload {
164    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165        match self {
166            Self::RouterInfo { router_info } => write!(
167                f,
168                "DatabaseStorePayload::RouterInfo ({})",
169                router_info.identity.id()
170            ),
171            Self::LeaseSet2 { lease_set } => write!(
172                f,
173                "DatabaseStorePayload::LeaseSet2 ({})",
174                lease_set.header.destination.id()
175            ),
176        }
177    }
178}
179
180impl DatabaseStorePayload {
181    #[allow(unused)]
182    fn serialized_len(&self) -> usize {
183        match self {
184            // TODO: calculate actual size
185            Self::RouterInfo { .. } => 2048usize,
186            Self::LeaseSet2 { lease_set } => lease_set.serialized_len(),
187        }
188    }
189}
190
191/// Database store message.
192pub struct DatabaseStore<R: Runtime> {
193    /// Search key.
194    pub key: Bytes,
195
196    /// Payload contained within the `DatabaseStore` message.
197    pub payload: DatabaseStorePayload,
198
199    /// Reply type.
200    pub reply: ReplyType,
201
202    /// Marker for `Runtime`.
203    _runtime: PhantomData<R>,
204}
205
206impl<R: Runtime> fmt::Debug for DatabaseStore<R> {
207    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208        f.debug_struct("DatabaseStore")
209            .field("payload", &format_args!("{}", self.payload))
210            .field("reply", &self.reply)
211            .finish_non_exhaustive()
212    }
213}
214
215impl<R: Runtime> DatabaseStore<R> {
216    /// Attempt to parse [`DatabaseStore`] from `input`.
217    ///
218    /// Returns the parsed message and rest of `input` on success.
219    pub fn parse_frame(input: &[u8]) -> IResult<&[u8], Self, DatabaseStoreParseError> {
220        let (rest, key) = take(DATABASE_KEY_SIZE)(input)?;
221        let (rest, store_type) = be_u8(rest)?;
222        let (rest, reply_token) = be_u32(rest)?;
223        let store_kind = StoreType::from_u8(store_type).ok_or(Err::Error(
224            DatabaseStoreParseError::InvalidStoreType(store_type),
225        ))?;
226
227        let (rest, reply) = match reply_token == NO_REPLY {
228            true => (rest, ReplyType::None),
229            false => {
230                let (rest, gateway_tunnel) = be_u32(rest)?;
231                let (rest, gateway_router) = take(ROUTER_HASH_LEN)(rest)?;
232
233                match gateway_tunnel == NO_REPLY {
234                    true => (
235                        rest,
236                        ReplyType::Router {
237                            reply_token,
238                            router_id: RouterId::from(gateway_router),
239                        },
240                    ),
241                    false => (
242                        rest,
243                        ReplyType::Tunnel {
244                            reply_token,
245                            tunnel_id: TunnelId::from(gateway_tunnel),
246                            router_id: RouterId::from(gateway_router),
247                        },
248                    ),
249                }
250            }
251        };
252
253        match store_kind {
254            StoreType::RouterInfo => {
255                let (rest, size) = be_u16(rest)?;
256                let (rest, data) = take(size)(rest)?;
257
258                let data = R::gzip_decompress(data)
259                    .ok_or(Err::Error(DatabaseStoreParseError::CompressionFailed))?;
260
261                let router_info = RouterInfo::parse(&data)
262                    .map_err(|error| Err::Error(DatabaseStoreParseError::RouterInfo(error)))?;
263
264                Ok((
265                    rest,
266                    Self {
267                        key: Bytes::from(key.to_vec()),
268                        payload: DatabaseStorePayload::RouterInfo { router_info },
269                        reply,
270                        _runtime: Default::default(),
271                    },
272                ))
273            }
274            StoreType::LeaseSet2 => {
275                let (rest, lease_set) = LeaseSet2::parse_frame::<R>(rest).map_err(Err::convert)?;
276
277                Ok((
278                    rest,
279                    Self {
280                        key: Bytes::from(key.to_vec()),
281                        payload: DatabaseStorePayload::LeaseSet2 { lease_set },
282                        reply,
283                        _runtime: Default::default(),
284                    },
285                ))
286            }
287            _ => Err(Err::Error(DatabaseStoreParseError::UnsupportedStoreType(
288                store_type,
289            ))),
290        }
291    }
292
293    /// Attempt to parse `input` into [`DatabaseStore`].
294    pub fn parse(input: &[u8]) -> Result<Self, DatabaseStoreParseError> {
295        Ok(Self::parse_frame(input)?.1)
296    }
297
298    /// Extract raw payload from [`DatabaseStore`] message.
299    fn extraw_raw_data_payload(input: &[u8], router_info: bool) -> Bytes {
300        let (rest, _) = take::<_, _, ()>(DATABASE_KEY_SIZE)(input).expect("to succeed");
301        let (rest, _) = be_u8::<_, ()>(rest).expect("to succeed");
302        let (rest, reply_token) = be_u32::<_, ()>(rest).expect("to succeed");
303
304        let rest = match reply_token == NO_REPLY {
305            true => rest,
306            false => {
307                let (rest, _) = be_u32::<_, ()>(rest).expect("to succeed");
308                let (rest, _) = take::<_, _, ()>(ROUTER_HASH_LEN)(rest).expect("to succeed");
309
310                rest
311            }
312        };
313
314        if router_info {
315            let (rest, size) = be_u16::<_, ()>(rest).expect("to succeed");
316            let (_, data) = take::<_, _, ()>(size)(rest).expect("to succeed");
317
318            BytesMut::from(data).freeze()
319        } else {
320            BytesMut::from(rest).freeze()
321        }
322    }
323
324    /// Extract raw, unserialized [`LeaseSet`] from `input`.
325    ///
326    /// Caller is expected to ensure that `input` is a valid [`DatabaseStore`] that contains
327    /// a valid [`LeaseSet2`].
328    pub fn extract_raw_lease_set(input: &[u8]) -> Bytes {
329        Self::extraw_raw_data_payload(input, false)
330    }
331
332    /// Extract raw, unserialized [`RouterInfo`] from `input`.
333    ///
334    /// Caller is expected to ensure that `input` is a valid [`DatabaseStore`] that contains
335    /// a valid [`RouterInfo`].
336    pub fn extract_raw_router_info(input: &[u8]) -> Bytes {
337        Self::extraw_raw_data_payload(input, true)
338    }
339}
340
341/// Database store kind.
342pub enum DatabaseStoreKind {
343    /// [`RouterInfo`].
344    RouterInfo {
345        /// Serialized [`RouterInfo`].
346        router_info: Bytes,
347    },
348
349    /// [`LeaseSet2`].
350    LeaseSet2 {
351        /// Serialized [`LeaseSet2`].
352        lease_set: Bytes,
353    },
354}
355
356impl DatabaseStoreKind {
357    /// Get serialized length of the payload.
358    fn serialized_len(&self) -> usize {
359        match self {
360            Self::RouterInfo { router_info } => router_info.len(),
361            Self::LeaseSet2 { lease_set } => lease_set.len(),
362        }
363    }
364}
365
366/// [`DatabaseStore`] builder.
367pub struct DatabaseStoreBuilder {
368    /// Store key.
369    key: Bytes,
370
371    /// Database store kind.
372    kind: DatabaseStoreKind,
373
374    /// Reply type, if specified.
375    reply: Option<ReplyType>,
376}
377
378impl DatabaseStoreBuilder {
379    /// Create new [`DatabaseStoreBuilder`].
380    pub fn new(key: Bytes, kind: DatabaseStoreKind) -> Self {
381        Self {
382            key,
383            kind,
384            reply: None,
385        }
386    }
387
388    /// Specify reply type.
389    pub fn with_reply_type(mut self, reply: ReplyType) -> Self {
390        self.reply = Some(reply);
391        self
392    }
393
394    /// Serialize [`DatabaseStore`] into a byte vector.
395    pub fn build(self) -> BytesMut {
396        let reply = self.reply.unwrap_or(ReplyType::None);
397        let mut out = BytesMut::with_capacity(
398            DATABASE_KEY_SIZE
399                .saturating_add(1usize) // store type
400                .saturating_add(reply.serialized_len())
401                .saturating_add(self.kind.serialized_len()),
402        );
403
404        out.put_slice(&self.key);
405
406        match &self.kind {
407            DatabaseStoreKind::RouterInfo { .. } => out.put_u8(StoreType::RouterInfo.as_u8()),
408            DatabaseStoreKind::LeaseSet2 { .. } => out.put_u8(StoreType::LeaseSet2.as_u8()),
409        }
410
411        match reply {
412            ReplyType::None => {
413                out.put_u32(NO_REPLY);
414            }
415            ReplyType::Tunnel {
416                reply_token,
417                tunnel_id,
418                router_id,
419            } => {
420                out.put_u32(reply_token);
421                out.put_u32(*tunnel_id);
422                out.put_slice(&router_id.to_vec());
423            }
424            ReplyType::Router {
425                reply_token,
426                router_id,
427            } => {
428                out.put_u32(reply_token);
429                out.put_u32(NO_REPLY);
430                out.put_slice(&router_id.to_vec());
431            }
432        }
433
434        match self.kind {
435            DatabaseStoreKind::RouterInfo { router_info } => {
436                out.put_u16(router_info.len() as u16);
437                out.put_slice(&router_info);
438            }
439            DatabaseStoreKind::LeaseSet2 { lease_set } => out.put_slice(&lease_set),
440        }
441
442        out
443    }
444}
445
446#[cfg(test)]
447mod tests {
448    use super::*;
449    use crate::runtime::mock::MockRuntime;
450    use rand::RngCore;
451
452    #[test]
453    fn parse_database_store() {
454        let buffer = vec![
455            249, 0, 187, 182, 11, 128, 61, 16, 80, 73, 190, 216, 57, 137, 166, 213, 35, 195, 36,
456            79, 56, 118, 161, 49, 37, 5, 174, 148, 94, 114, 242, 7, 0, 101, 5, 15, 45, 0, 0, 0, 0,
457            249, 0, 187, 182, 11, 128, 61, 16, 80, 73, 190, 216, 57, 137, 166, 213, 35, 195, 36,
458            79, 56, 118, 161, 49, 37, 5, 174, 148, 94, 114, 242, 7, 2, 151, 31, 139, 8, 0, 0, 0, 0,
459            0, 2, 255, 1, 128, 2, 127, 253, 222, 205, 6, 59, 50, 200, 120, 177, 26, 105, 6, 11, 22,
460            247, 62, 125, 94, 166, 157, 159, 205, 26, 68, 197, 126, 246, 167, 208, 34, 44, 152, 53,
461            156, 157, 71, 229, 212, 169, 64, 66, 197, 83, 19, 226, 150, 36, 242, 255, 56, 236, 227,
462            27, 83, 149, 94, 207, 146, 177, 76, 222, 163, 237, 79, 111, 156, 157, 71, 229, 212,
463            169, 64, 66, 197, 83, 19, 226, 150, 36, 242, 255, 56, 236, 227, 27, 83, 149, 94, 207,
464            146, 177, 76, 222, 163, 237, 79, 111, 156, 157, 71, 229, 212, 169, 64, 66, 197, 83, 19,
465            226, 150, 36, 242, 255, 56, 236, 227, 27, 83, 149, 94, 207, 146, 177, 76, 222, 163,
466            237, 79, 111, 156, 157, 71, 229, 212, 169, 64, 66, 197, 83, 19, 226, 150, 36, 242, 255,
467            56, 236, 227, 27, 83, 149, 94, 207, 146, 177, 76, 222, 163, 237, 79, 111, 156, 157, 71,
468            229, 212, 169, 64, 66, 197, 83, 19, 226, 150, 36, 242, 255, 56, 236, 227, 27, 83, 149,
469            94, 207, 146, 177, 76, 222, 163, 237, 79, 111, 156, 157, 71, 229, 212, 169, 64, 66,
470            197, 83, 19, 226, 150, 36, 242, 255, 56, 236, 227, 27, 83, 149, 94, 207, 146, 177, 76,
471            222, 163, 237, 79, 111, 156, 157, 71, 229, 212, 169, 64, 66, 197, 83, 19, 226, 150, 36,
472            242, 255, 56, 236, 227, 27, 83, 149, 94, 207, 146, 177, 76, 222, 163, 237, 79, 111,
473            156, 157, 71, 229, 212, 169, 64, 66, 197, 83, 19, 226, 150, 36, 242, 255, 56, 236, 227,
474            27, 83, 149, 94, 207, 146, 177, 76, 222, 163, 237, 79, 111, 156, 157, 71, 229, 212,
475            169, 64, 66, 197, 83, 19, 226, 150, 36, 242, 255, 56, 236, 227, 27, 83, 149, 94, 207,
476            146, 177, 76, 222, 163, 237, 79, 111, 156, 157, 71, 229, 212, 169, 64, 66, 197, 83, 19,
477            226, 150, 36, 242, 255, 56, 236, 227, 27, 83, 149, 94, 207, 146, 177, 76, 222, 163,
478            237, 79, 111, 193, 118, 156, 13, 187, 24, 148, 135, 201, 57, 162, 146, 109, 209, 194,
479            238, 49, 30, 8, 187, 55, 61, 104, 151, 23, 241, 84, 73, 35, 18, 228, 159, 5, 0, 4, 0,
480            7, 0, 4, 0, 0, 1, 145, 153, 163, 42, 152, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 5, 78, 84, 67,
481            80, 50, 0, 113, 4, 104, 111, 115, 116, 61, 9, 49, 50, 55, 46, 48, 46, 48, 46, 49, 59,
482            1, 105, 61, 24, 77, 117, 115, 99, 83, 117, 67, 90, 106, 105, 57, 108, 72, 113, 102, 73,
483            56, 121, 74, 73, 56, 103, 61, 61, 59, 4, 112, 111, 114, 116, 61, 4, 56, 56, 57, 48, 59,
484            1, 115, 61, 44, 101, 49, 65, 97, 74, 80, 67, 126, 104, 80, 117, 80, 49, 54, 52, 80, 71,
485            105, 71, 107, 97, 105, 52, 50, 119, 80, 55, 110, 89, 70, 117, 111, 56, 121, 74, 115,
486            76, 119, 76, 77, 48, 106, 77, 61, 59, 1, 118, 61, 1, 50, 59, 0, 0, 43, 4, 99, 97, 112,
487            115, 61, 1, 76, 59, 5, 110, 101, 116, 73, 100, 61, 1, 50, 59, 14, 114, 111, 117, 116,
488            101, 114, 46, 118, 101, 114, 115, 105, 111, 110, 61, 6, 48, 46, 57, 46, 54, 50, 59,
489            187, 28, 65, 149, 0, 49, 238, 139, 72, 152, 68, 124, 54, 114, 146, 48, 122, 88, 53, 97,
490            92, 3, 49, 209, 233, 3, 27, 94, 50, 13, 78, 133, 155, 126, 53, 213, 174, 143, 152, 192,
491            84, 122, 104, 147, 39, 185, 101, 38, 20, 216, 147, 187, 19, 47, 233, 162, 56, 58, 45,
492            26, 246, 141, 69, 9, 132, 119, 99, 190, 128, 2, 0, 0,
493        ];
494
495        let _ = DatabaseStore::<MockRuntime>::parse(&buffer).unwrap();
496    }
497
498    #[test]
499    fn parse_leaseset2_store() {
500        let buffer = vec![
501            88, 34, 216, 162, 50, 127, 74, 133, 95, 237, 241, 77, 176, 11, 35, 188, 105, 25, 245,
502            184, 0, 22, 72, 59, 149, 131, 27, 71, 110, 227, 236, 9, 3, 0, 0, 0, 0, 214, 155, 197,
503            98, 170, 161, 183, 41, 58, 103, 216, 196, 180, 218, 194, 93, 131, 248, 109, 234, 196,
504            246, 15, 126, 91, 198, 187, 11, 54, 197, 115, 230, 214, 155, 197, 98, 170, 161, 183,
505            41, 58, 103, 216, 196, 180, 218, 194, 93, 131, 248, 109, 234, 196, 246, 15, 126, 91,
506            198, 187, 11, 54, 197, 115, 230, 214, 155, 197, 98, 170, 161, 183, 41, 58, 103, 216,
507            196, 180, 218, 194, 93, 131, 248, 109, 234, 196, 246, 15, 126, 91, 198, 187, 11, 54,
508            197, 115, 230, 214, 155, 197, 98, 170, 161, 183, 41, 58, 103, 216, 196, 180, 218, 194,
509            93, 131, 248, 109, 234, 196, 246, 15, 126, 91, 198, 187, 11, 54, 197, 115, 230, 214,
510            155, 197, 98, 170, 161, 183, 41, 58, 103, 216, 196, 180, 218, 194, 93, 131, 248, 109,
511            234, 196, 246, 15, 126, 91, 198, 187, 11, 54, 197, 115, 230, 214, 155, 197, 98, 170,
512            161, 183, 41, 58, 103, 216, 196, 180, 218, 194, 93, 131, 248, 109, 234, 196, 246, 15,
513            126, 91, 198, 187, 11, 54, 197, 115, 230, 214, 155, 197, 98, 170, 161, 183, 41, 58,
514            103, 216, 196, 180, 218, 194, 93, 131, 248, 109, 234, 196, 246, 15, 126, 91, 198, 187,
515            11, 54, 197, 115, 230, 214, 155, 197, 98, 170, 161, 183, 41, 58, 103, 216, 196, 180,
516            218, 194, 93, 131, 248, 109, 234, 196, 246, 15, 126, 91, 198, 187, 11, 54, 197, 115,
517            230, 214, 155, 197, 98, 170, 161, 183, 41, 58, 103, 216, 196, 180, 218, 194, 93, 131,
518            248, 109, 234, 196, 246, 15, 126, 91, 198, 187, 11, 54, 197, 115, 230, 214, 155, 197,
519            98, 170, 161, 183, 41, 58, 103, 216, 196, 180, 218, 194, 93, 131, 248, 109, 234, 196,
520            246, 15, 126, 91, 198, 187, 11, 54, 197, 115, 230, 214, 155, 197, 98, 170, 161, 183,
521            41, 58, 103, 216, 196, 180, 218, 194, 93, 131, 248, 109, 234, 196, 246, 15, 126, 91,
522            198, 187, 11, 54, 197, 115, 230, 64, 231, 155, 2, 143, 122, 48, 137, 247, 79, 229, 220,
523            40, 212, 53, 67, 193, 196, 204, 21, 45, 109, 227, 237, 29, 17, 31, 189, 17, 189, 195,
524            40, 5, 0, 4, 0, 7, 0, 0, 102, 216, 119, 64, 2, 88, 0, 0, 0, 0, 2, 0, 4, 0, 32, 103, 57,
525            105, 36, 53, 6, 188, 207, 237, 100, 79, 208, 65, 73, 180, 118, 143, 162, 202, 8, 103,
526            162, 220, 12, 95, 156, 67, 68, 62, 83, 112, 109, 0, 0, 1, 0, 119, 187, 61, 243, 159,
527            159, 198, 178, 65, 81, 148, 19, 78, 105, 92, 175, 190, 170, 136, 62, 19, 45, 23, 246,
528            228, 210, 215, 161, 129, 149, 160, 57, 137, 141, 144, 141, 163, 247, 34, 120, 5, 161,
529            60, 107, 34, 107, 166, 40, 152, 252, 246, 205, 187, 51, 129, 52, 97, 95, 188, 78, 176,
530            198, 254, 4, 19, 197, 215, 74, 73, 55, 135, 16, 43, 68, 159, 141, 78, 234, 63, 118,
531            142, 114, 20, 96, 8, 38, 18, 211, 159, 107, 160, 236, 33, 3, 153, 100, 77, 117, 145,
532            67, 173, 140, 69, 123, 31, 253, 172, 240, 74, 110, 148, 56, 229, 208, 81, 69, 175, 122,
533            89, 252, 43, 29, 193, 100, 232, 33, 150, 48, 105, 230, 76, 125, 114, 135, 88, 222, 21,
534            183, 56, 203, 58, 51, 187, 57, 64, 196, 238, 62, 35, 43, 226, 209, 160, 77, 171, 252,
535            81, 125, 105, 3, 40, 216, 107, 1, 209, 223, 117, 237, 54, 151, 90, 133, 76, 32, 217,
536            167, 214, 86, 42, 226, 222, 126, 45, 133, 138, 28, 77, 37, 28, 200, 74, 3, 240, 188,
537            12, 47, 48, 49, 61, 154, 31, 74, 78, 229, 133, 62, 250, 249, 67, 180, 175, 156, 60,
538            148, 227, 168, 127, 107, 118, 63, 220, 18, 242, 169, 94, 112, 58, 7, 196, 69, 243, 206,
539            205, 89, 54, 174, 162, 106, 223, 195, 152, 90, 155, 98, 223, 122, 21, 248, 181, 118,
540            208, 80, 41, 154, 232, 58, 3, 249, 0, 187, 182, 11, 128, 61, 16, 80, 73, 190, 216, 57,
541            137, 166, 213, 35, 195, 36, 79, 56, 118, 161, 49, 37, 5, 174, 148, 94, 114, 242, 7,
542            240, 177, 138, 122, 102, 216, 121, 152, 249, 0, 187, 182, 11, 128, 61, 16, 80, 73, 190,
543            216, 57, 137, 166, 213, 35, 195, 36, 79, 56, 118, 161, 49, 37, 5, 174, 148, 94, 114,
544            242, 7, 254, 77, 137, 9, 102, 216, 121, 152, 249, 0, 187, 182, 11, 128, 61, 16, 80, 73,
545            190, 216, 57, 137, 166, 213, 35, 195, 36, 79, 56, 118, 161, 49, 37, 5, 174, 148, 94,
546            114, 242, 7, 239, 37, 242, 32, 102, 216, 121, 152, 85, 131, 155, 161, 181, 62, 114,
547            203, 208, 71, 210, 43, 204, 240, 181, 94, 146, 250, 118, 234, 79, 158, 201, 58, 167,
548            187, 35, 177, 69, 215, 241, 60, 154, 198, 121, 194, 199, 142, 61, 196, 142, 139, 85,
549            87, 210, 244, 83, 145, 143, 233, 154, 12, 60, 130, 140, 197, 170, 93, 124, 203, 142,
550            46, 214, 11,
551        ];
552
553        let _ = DatabaseStore::<MockRuntime>::parse(&buffer).unwrap();
554        let raw_lease_set = DatabaseStore::<MockRuntime>::extract_raw_lease_set(&buffer);
555
556        assert!(LeaseSet2::parse::<MockRuntime>(&raw_lease_set).is_ok());
557    }
558
559    #[test]
560    fn serialize_and_parse_store_with_no_reply() {
561        let (leaseset, signing_key) = LeaseSet2::random();
562        let key = {
563            let mut key = vec![0u8; 32];
564            rand::thread_rng().fill_bytes(&mut key);
565
566            Bytes::from(key)
567        };
568
569        let serialized = DatabaseStoreBuilder::new(
570            key.clone(),
571            DatabaseStoreKind::LeaseSet2 {
572                lease_set: Bytes::from(leaseset.clone().serialize(&signing_key)),
573            },
574        )
575        .build();
576
577        let store = DatabaseStore::<MockRuntime>::parse(&serialized).unwrap();
578
579        assert_eq!(store.key, key);
580        assert!(std::matches!(store.reply, ReplyType::None));
581
582        match store.payload {
583            DatabaseStorePayload::LeaseSet2 { lease_set: parsed } => assert!(parsed
584                .leases
585                .iter()
586                .zip(leaseset.leases.iter())
587                .all(|(lease1, lease2)| lease1 == lease2)),
588            _ => panic!("invalid payload"),
589        }
590    }
591
592    #[test]
593    fn serialize_and_parse_store_with_reply() {
594        let (leaseset, signing_key) = LeaseSet2::random();
595        let reply_router = RouterId::random();
596        let key = {
597            let mut key = vec![0u8; 32];
598            rand::thread_rng().fill_bytes(&mut key);
599
600            Bytes::from(key)
601        };
602
603        let serialized = DatabaseStoreBuilder::new(
604            key.clone(),
605            DatabaseStoreKind::LeaseSet2 {
606                lease_set: Bytes::from(leaseset.clone().serialize(&signing_key)),
607            },
608        )
609        .with_reply_type(ReplyType::Tunnel {
610            reply_token: 0x13371338,
611            tunnel_id: TunnelId::from(0x13351336),
612            router_id: reply_router.clone(),
613        })
614        .build();
615
616        let store = DatabaseStore::<MockRuntime>::parse(&serialized).unwrap();
617
618        assert_eq!(store.key, key);
619
620        match store.reply {
621            ReplyType::Tunnel {
622                reply_token,
623                tunnel_id,
624                router_id,
625            } => {
626                assert_eq!(reply_token, 0x13371338);
627                assert_eq!(tunnel_id, TunnelId::from(0x13351336));
628                assert_eq!(router_id, reply_router);
629            }
630            _ => panic!("invalid reply type"),
631        }
632
633        match store.payload {
634            DatabaseStorePayload::LeaseSet2 { lease_set: parsed } => assert!(parsed
635                .leases
636                .iter()
637                .zip(leaseset.leases.iter())
638                .all(|(lease1, lease2)| lease1 == lease2)),
639            _ => panic!("invalid payload"),
640        }
641    }
642}