diff --git a/crates/cashu-sdk/src/mint/localstore/mod.rs b/crates/cashu-sdk/src/mint/localstore/mod.rs index f95d0c10..94ff2281 100644 --- a/crates/cashu-sdk/src/mint/localstore/mod.rs +++ b/crates/cashu-sdk/src/mint/localstore/mod.rs @@ -3,6 +3,7 @@ pub mod memory; pub mod redb_store; use std::collections::HashMap; +use std::num::ParseIntError; use async_trait::async_trait; use cashu::nuts::nut02::mint::KeySet; @@ -37,6 +38,8 @@ pub enum Error { #[cfg(all(not(target_arch = "wasm32"), feature = "redb"))] #[error("`{0}`")] Serde(#[from] serde_json::Error), + #[error("`{0}`")] + ParseInt(#[from] ParseIntError), #[error("Unknown Mint Info")] UnknownMintInfo, #[error("`{0}`")] diff --git a/crates/cashu-sdk/src/mint/localstore/redb_store.rs b/crates/cashu-sdk/src/mint/localstore/redb_store.rs index 666a4849..dae9ea38 100644 --- a/crates/cashu-sdk/src/mint/localstore/redb_store.rs +++ b/crates/cashu-sdk/src/mint/localstore/redb_store.rs @@ -25,6 +25,8 @@ const CONFIG_TABLE: TableDefinition<&str, &str> = TableDefinition::new("config") // Key is hex blinded_message B_ value is blinded_signature const BLINDED_SIGNATURES: TableDefinition<&[u8], &str> = TableDefinition::new("blinded_signatures"); +const DATABASE_VERSION: u64 = 0; + #[derive(Debug, Clone)] pub struct RedbLocalStore { db: Arc>, @@ -35,18 +37,35 @@ impl RedbLocalStore { let db = Database::create(path)?; let write_txn = db.begin_write()?; + // Check database version { - let _ = write_txn.open_table(ACTIVE_KEYSETS_TABLE)?; - let _ = write_txn.open_table(KEYSETS_TABLE)?; - let _ = write_txn.open_table(MINT_QUOTES_TABLE)?; - let _ = write_txn.open_table(MELT_QUOTES_TABLE)?; - let _ = write_txn.open_table(PENDING_PROOFS_TABLE)?; - let _ = write_txn.open_table(SPENT_PROOFS_TABLE)?; let _ = write_txn.open_table(CONFIG_TABLE)?; - let _ = write_txn.open_table(BLINDED_SIGNATURES)?; - } - write_txn.commit()?; + let mut table = write_txn.open_table(CONFIG_TABLE)?; + let db_version = table.get("db_version")?; + let db_version = db_version.map(|v| v.value().to_owned()); + + if let Some(db_version) = db_version { + let current_file_version = u64::from_str(&db_version)?; + if current_file_version.ne(&DATABASE_VERSION) { + // Database needs to be upgraded + todo!() + } + } else { + // Open all tables to init a new db + let _ = write_txn.open_table(ACTIVE_KEYSETS_TABLE)?; + let _ = write_txn.open_table(KEYSETS_TABLE)?; + let _ = write_txn.open_table(MINT_QUOTES_TABLE)?; + let _ = write_txn.open_table(MELT_QUOTES_TABLE)?; + let _ = write_txn.open_table(PENDING_PROOFS_TABLE)?; + let _ = write_txn.open_table(SPENT_PROOFS_TABLE)?; + let _ = write_txn.open_table(BLINDED_SIGNATURES)?; + + table.insert("db_version", "0")?; + }; + } + + write_txn.commit()?; Ok(Self { db: Arc::new(Mutex::new(db)), }) diff --git a/crates/cashu-sdk/src/wallet/localstore/mod.rs b/crates/cashu-sdk/src/wallet/localstore/mod.rs index c477e7c8..898ed04f 100644 --- a/crates/cashu-sdk/src/wallet/localstore/mod.rs +++ b/crates/cashu-sdk/src/wallet/localstore/mod.rs @@ -4,6 +4,7 @@ mod memory; mod redb_store; use std::collections::HashMap; +use std::num::ParseIntError; use async_trait::async_trait; use cashu::nuts::{Id, KeySetInfo, Keys, MintInfo, Proofs}; @@ -37,6 +38,8 @@ pub enum Error { #[cfg(all(not(target_arch = "wasm32"), feature = "redb"))] #[error("`{0}`")] Serde(#[from] serde_json::Error), + #[error("`{0}`")] + ParseInt(#[from] ParseIntError), } #[async_trait] diff --git a/crates/cashu-sdk/src/wallet/localstore/redb_store.rs b/crates/cashu-sdk/src/wallet/localstore/redb_store.rs index d1fd4b67..f7daee32 100644 --- a/crates/cashu-sdk/src/wallet/localstore/redb_store.rs +++ b/crates/cashu-sdk/src/wallet/localstore/redb_store.rs @@ -20,9 +20,12 @@ const MINT_KEYS_TABLE: TableDefinition<&str, &str> = TableDefinition::new("mint_ const PROOFS_TABLE: MultimapTableDefinition<&str, &str> = MultimapTableDefinition::new("proofs"); const PENDING_PROOFS_TABLE: MultimapTableDefinition<&str, &str> = MultimapTableDefinition::new("pending_proofs"); +const CONFIG_TABLE: TableDefinition<&str, &str> = TableDefinition::new("config"); #[cfg(feature = "nut13")] const KEYSET_COUNTER: TableDefinition<&str, u64> = TableDefinition::new("keyset_counter"); +const DATABASE_VERSION: u64 = 0; + #[derive(Debug, Clone)] pub struct RedbLocalStore { db: Arc>, @@ -33,15 +36,35 @@ impl RedbLocalStore { let db = Database::create(path)?; let write_txn = db.begin_write()?; + + // Check database version { - let _ = write_txn.open_table(MINTS_TABLE)?; - let _ = write_txn.open_multimap_table(MINT_KEYSETS_TABLE)?; - let _ = write_txn.open_table(MINT_QUOTES_TABLE)?; - let _ = write_txn.open_table(MELT_QUOTES_TABLE)?; - let _ = write_txn.open_table(MINT_KEYS_TABLE)?; - let _ = write_txn.open_multimap_table(PROOFS_TABLE)?; - #[cfg(feature = "nut13")] - let _ = write_txn.open_table(KEYSET_COUNTER)?; + let _ = write_txn.open_table(CONFIG_TABLE)?; + let mut table = write_txn.open_table(CONFIG_TABLE)?; + + let db_version = table.get("db_version")?; + let db_version = db_version.map(|v| v.value().to_owned()); + + if let Some(db_version) = db_version { + let current_file_version = u64::from_str(&db_version)?; + if current_file_version.ne(&DATABASE_VERSION) { + // Database needs to be upgraded + todo!() + } + #[cfg(feature = "nut13")] + let _ = write_txn.open_table(KEYSET_COUNTER)?; + } else { + // Open all tables to init a new db + let _ = write_txn.open_table(MINTS_TABLE)?; + let _ = write_txn.open_multimap_table(MINT_KEYSETS_TABLE)?; + let _ = write_txn.open_table(MINT_QUOTES_TABLE)?; + let _ = write_txn.open_table(MELT_QUOTES_TABLE)?; + let _ = write_txn.open_table(MINT_KEYS_TABLE)?; + let _ = write_txn.open_multimap_table(PROOFS_TABLE)?; + #[cfg(feature = "nut13")] + let _ = write_txn.open_table(KEYSET_COUNTER)?; + table.insert("db_version", "0")?; + }; } write_txn.commit()?; diff --git a/crates/cashu-sdk/src/wallet/mod.rs b/crates/cashu-sdk/src/wallet/mod.rs index 38fb0ec9..780bb8d9 100644 --- a/crates/cashu-sdk/src/wallet/mod.rs +++ b/crates/cashu-sdk/src/wallet/mod.rs @@ -1,5 +1,6 @@ //! Cashu Wallet use std::collections::{HashMap, HashSet}; +use std::num::ParseIntError; use std::str::FromStr; use std::sync::Arc; @@ -60,6 +61,8 @@ pub enum Error { #[error("Unknown Key")] UnknownKey, #[error("`{0}`")] + ParseInt(#[from] ParseIntError), + #[error("`{0}`")] Custom(String), }