1use std::collections::BTreeSet;
2
3use bitcoin::hex::DisplayHex as _;
4use fedimint_core::db::{
5 DatabaseTransaction, IDatabaseTransactionOpsCore as _, MODULE_GLOBAL_PREFIX,
6};
7use fedimint_core::encoding::{Decodable, Encodable};
8use fedimint_core::impl_db_record;
9use futures::StreamExt as _;
10use strum::{EnumIter, IntoEnumIterator as _};
11
12#[repr(u8)]
13#[derive(Clone, EnumIter, Debug)]
14pub enum DbKeyPrefix {
15 AcceptedItem = 0x01,
16 AcceptedTransaction = 0x02,
17 SignedSessionOutcome = 0x04,
18 AlephUnits = 0x05,
19 ApiAnnouncements = 0x06,
21 ServerInfo = 0x07,
22 GuardianMetadata = 0x08,
23
24 DatabaseVersion = fedimint_core::db::DbKeyPrefix::DatabaseVersion as u8,
25 ClientBackup = fedimint_core::db::DbKeyPrefix::ClientBackup as u8,
26 Module = MODULE_GLOBAL_PREFIX,
27}
28
29pub(crate) async fn verify_server_db_integrity_dbtx(dbtx: &mut DatabaseTransaction<'_>) {
30 let prefixes: BTreeSet<u8> = DbKeyPrefix::iter().map(|prefix| prefix as u8).collect();
31
32 let mut records = dbtx.raw_find_by_prefix(&[]).await.expect("DB fail");
33 while let Some((k, v)) = records.next().await {
34 if k[0] == DbKeyPrefix::Module as u8 {
36 break;
37 }
38
39 assert!(
40 prefixes.contains(&k[0]),
41 "Unexpected server db record found: {}: {}",
42 k.as_hex(),
43 v.as_hex()
44 );
45 }
46}
47
48impl std::fmt::Display for DbKeyPrefix {
49 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
50 write!(f, "{self:?}")
51 }
52}
53
54#[derive(Clone, Debug, Encodable, Decodable)]
55pub struct ServerInfoKey;
56
57#[derive(Clone, Debug, Encodable, Decodable)]
58pub struct ServerInfo {
59 pub init_version: String,
61 pub last_version: String,
63}
64
65impl_db_record!(
66 key = ServerInfoKey,
67 value = ServerInfo,
68 db_prefix = DbKeyPrefix::ServerInfo,
69 notify_on_modify = false,
70);