Skip to main content

fedimint_core/
backup.rs

1//! Federation-stored client backups
2//!
3//! Federations can store client-encrypted backups to help
4//! clients recover from a snapshot, instead of a blank slate.
5use std::time::SystemTime;
6
7use fedimint_core::encoding::{
8    Decodable, DecodeError, Encodable, decode_field_from_finite_reader,
9    decode_legacy_system_time_from_finite_reader, encode_legacy_system_time, with_decoding_context,
10};
11use fedimint_core::module::registry::ModuleDecoderRegistry;
12use fedimint_core::{impl_db_lookup, impl_db_record};
13use serde::{Deserialize, Serialize};
14
15use crate::db::DbKeyPrefix;
16
17/// Key used to store user's ecash backups
18#[derive(Debug, Clone, Copy, Encodable, Decodable, Serialize)]
19pub struct ClientBackupKey(pub secp256k1::PublicKey);
20
21#[derive(Debug, Encodable, Decodable)]
22pub struct ClientBackupKeyPrefix;
23
24impl_db_record!(
25    key = ClientBackupKey,
26    value = ClientBackupSnapshot,
27    db_prefix = DbKeyPrefix::ClientBackup,
28);
29impl_db_lookup!(key = ClientBackupKey, query_prefix = ClientBackupKeyPrefix);
30
31/// User's backup, received at certain time, containing encrypted payload
32#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
33pub struct ClientBackupSnapshot {
34    pub timestamp: SystemTime,
35    #[serde(with = "fedimint_core::hex::serde")]
36    pub data: Vec<u8>,
37}
38
39impl Encodable for ClientBackupSnapshot {
40    fn consensus_encode<W: std::io::Write>(&self, writer: &mut W) -> Result<(), std::io::Error> {
41        encode_legacy_system_time(&self.timestamp, writer)?;
42        self.data.consensus_encode(writer)
43    }
44}
45
46impl Decodable for ClientBackupSnapshot {
47    fn consensus_decode_partial_from_finite_reader<D: std::io::Read>(
48        decoder: &mut D,
49        modules: &ModuleDecoderRegistry,
50    ) -> Result<Self, DecodeError> {
51        Ok(Self {
52            timestamp: with_decoding_context(
53                decode_legacy_system_time_from_finite_reader(decoder, modules),
54                "Decoding named block field: ClientBackupSnapshot{ ... timestamp ... }",
55            )?,
56            data: decode_field_from_finite_reader(
57                decoder,
58                modules,
59                "Decoding named block field: ClientBackupSnapshot{ ... data ... }",
60            )?,
61        })
62    }
63}
64
65/// Statistics about backups stored in the federation
66#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Default)]
67pub struct BackupStatistics {
68    pub num_backups: usize,
69    pub total_size: usize,
70    pub refreshed_1d: usize,
71    pub refreshed_1w: usize,
72    pub refreshed_1m: usize,
73    pub refreshed_3m: usize,
74}