engine/snapshot/migration/
mod.rs

1// Copyright 2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4mod error;
5mod v2;
6mod v3;
7
8use std::{
9    fs::{File, OpenOptions},
10    io::{Read, Write},
11    path::Path,
12};
13
14use crypto::{
15    ciphers::{chacha::XChaCha20Poly1305, traits::Aead},
16    hashes::{blake2b, Digest},
17    keys::{age, x25519},
18};
19
20// These dependencies must not change between versions,
21// otherwise migration will work differently.
22pub use self::error::Error;
23use crate::snapshot::{compress, decompress};
24use zeroize::Zeroizing;
25
26pub enum Version<'a> {
27    V2 {
28        path: &'a Path,
29        key: &'a [u8; 32],
30        aad: &'a [u8],
31    },
32    V3 {
33        path: &'a Path,
34        password: &'a [u8],
35    },
36}
37
38impl<'a> Version<'a> {
39    pub fn v2(path: &'a Path, key: &'a [u8; 32], aad: &'a [u8]) -> Self {
40        Self::V2 { path, key, aad }
41    }
42
43    pub fn v3(path: &'a Path, password: &'a [u8]) -> Self {
44        Self::V3 { path, password }
45    }
46}
47
48/// Magic bytes (bytes 0-4 in a snapshot file) aka PARTI
49const MAGIC: [u8; 5] = [0x50, 0x41, 0x52, 0x54, 0x49];
50
51#[inline]
52fn guard<E>(cond: bool, err: E) -> Result<(), E> {
53    if cond {
54        Ok(())
55    } else {
56        Err(err)
57    }
58}
59
60fn migrate_from_v2_to_v3(
61    v2_path: &Path,
62    v2_key: &[u8; 32],
63    v2_aad: &[u8],
64    v3_path: &Path,
65    v3_pwd: &[u8],
66) -> Result<(), Error> {
67    let v = v2::read_snapshot(v2_path, v2_key, v2_aad)?;
68    v3::write_snapshot(&v[..], v3_path, v3_pwd)
69}
70
71pub fn migrate(prev: Version, next: Version) -> Result<(), Error> {
72    match (prev, next) {
73        (
74            Version::V2 {
75                path: v2_path,
76                key: v2_key,
77                aad: v2_aad,
78            },
79            Version::V3 {
80                path: v3_path,
81                password: v3_pwd,
82            },
83        ) => migrate_from_v2_to_v3(v2_path, v2_key, v2_aad, v3_path, v3_pwd),
84        _ => Err(Error::BadMigrationVersion),
85    }
86}