Skip to content

Commit

Permalink
chore(mint-client): migrate old recovery state by just deleting it
Browse files Browse the repository at this point in the history
  • Loading branch information
dpc committed Sep 30, 2024
1 parent 904ae4d commit 2f91b3a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 10 deletions.
6 changes: 3 additions & 3 deletions modules/fedimint-mint-client/src/backup/recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl RecoveryFromHistory for MintRecovery {
.get_value(&RecoveryStateKey)
.await
.and_then(|(state, common)| {
if let MintRecoveryState::V0(state) = state {
if let MintRecoveryState::V1(state) = state {
Some((state, common))
} else {
warn!(target: LOG_CLIENT_RECOVERY, "Found unknown version recovery state. Ignoring");
Expand All @@ -112,7 +112,7 @@ impl RecoveryFromHistory for MintRecovery {
) {
dbtx.insert_entry(
&RecoveryStateKey,
&(MintRecoveryState::V0(self.state.clone()), common.clone()),
&(MintRecoveryState::V1(self.state.clone()), common.clone()),
)
.await;
}
Expand Down Expand Up @@ -266,7 +266,7 @@ impl From<CompressedBlindedMessage> for BlindedMessage {

#[derive(Debug, Clone, Decodable, Encodable)]
pub enum MintRecoveryState {
V0(MintRecoveryStateV0),
V1(MintRecoveryStateV0),
#[encodable_default]
Default {
variant: u64,
Expand Down
12 changes: 12 additions & 0 deletions modules/fedimint-mint-client/src/client_db.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use fedimint_client::module::init::recovery::RecoveryFromHistoryCommon;
use fedimint_core::core::OperationId;
use fedimint_core::db::{DatabaseTransaction, IDatabaseTransactionOpsCoreTyped as _};
use fedimint_core::encoding::{Decodable, Encodable};
use fedimint_core::{impl_db_lookup, impl_db_record, Amount};
use fedimint_mint_common::Nonce;
Expand Down Expand Up @@ -98,3 +99,14 @@ impl_db_lookup!(
key = CancelledOOBSpendKey,
query_prefix = CancelledOOBSpendKeyPrefix,
);

pub async fn migrate_to_v1(
dbtx: &mut DatabaseTransaction<'_>,
) -> anyhow::Result<Option<(Vec<(Vec<u8>, OperationId)>, Vec<(Vec<u8>, OperationId)>)>> {
// between v0 and v1, we changed the format of `MintRecoveryState`, and instead
// of migrating it, we can just delete it, so the recovery will just start
// again, ignoring any existing state from before the migration
dbtx.remove_entry(&RecoveryStateKey).await;

Ok(None)
}
14 changes: 12 additions & 2 deletions modules/fedimint-mint-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ use async_stream::{stream, try_stream};
use backup::recovery::MintRecovery;
use base64::Engine as _;
use bitcoin_hashes::{sha256, sha256t, Hash, HashEngine as BitcoinHashEngine};
use client_db::{DbKeyPrefix, NoteKeyPrefix, RecoveryFinalizedKey};
use client_db::{migrate_to_v1, DbKeyPrefix, NoteKeyPrefix, RecoveryFinalizedKey};
use fedimint_client::db::ClientMigrationFn;
use fedimint_client::module::init::{
ClientModuleInit, ClientModuleInitArgs, ClientModuleRecoverArgs,
};
Expand Down Expand Up @@ -509,7 +510,7 @@ pub struct MintClientInit;

impl ModuleInit for MintClientInit {
type Common = MintCommonInit;
const DATABASE_VERSION: DatabaseVersion = DatabaseVersion(0);
const DATABASE_VERSION: DatabaseVersion = DatabaseVersion(1);

async fn dump_database(
&self,
Expand Down Expand Up @@ -595,6 +596,15 @@ impl ClientModuleInit for MintClientInit {
args.recover_from_history::<MintRecovery>(self, snapshot)
.await
}

fn get_database_migrations(&self) -> BTreeMap<DatabaseVersion, ClientMigrationFn> {
let mut migrations: BTreeMap<DatabaseVersion, ClientMigrationFn> = BTreeMap::new();
migrations.insert(DatabaseVersion(0), |dbtx, _, _| {
Box::pin(migrate_to_v1(dbtx))
});

migrations
}
}

/// The `MintClientModule` is responsible for handling e-cash minting
Expand Down
11 changes: 6 additions & 5 deletions modules/fedimint-mint-tests/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,8 @@ mod fedimint_migration_tests {
use fedimint_mint_client::backup::{EcashBackup, EcashBackupV0};
use fedimint_mint_client::client_db::{
CancelledOOBSpendKey, CancelledOOBSpendKeyPrefix, NextECashNoteIndexKey,
NextECashNoteIndexKeyPrefix, NoteKey, NoteKeyPrefix, RecoveryStateKey,
NextECashNoteIndexKeyPrefix, NoteKey, NoteKeyPrefix, RecoveryFinalizedKey,
RecoveryStateKey,
};
use fedimint_mint_client::output::NoteIssuanceRequest;
use fedimint_mint_client::{MintClientInit, MintClientModule, NoteIndex, SpendableNote};
Expand Down Expand Up @@ -522,7 +523,7 @@ mod fedimint_migration_tests {

let backup = create_ecash_backup_v0(spendable_note, secret.clone());

let mint_recovery_state = MintRecoveryState::V0(MintRecoveryStateV0::from_backup(
let mint_recovery_state = MintRecoveryState::V1(MintRecoveryStateV0::from_backup(
backup,
10,
tbs_pks,
Expand Down Expand Up @@ -711,13 +712,13 @@ mod fedimint_migration_tests {
fedimint_mint_client::client_db::DbKeyPrefix::RecoveryState => {
let restore_state = dbtx.get_value(&RecoveryStateKey).await;
ensure!(
restore_state.is_some(),
"validate_migrations was not able to read any RecoveryState"
restore_state.is_none(),
"validate_migrations expect the restore state to get deleted"
);
info!("Validated RecoveryState");
}
fedimint_mint_client::client_db::DbKeyPrefix::RecoveryFinalized => {
let recovery_finalized = dbtx.get_value(&RecoveryStateKey).await;
let recovery_finalized = dbtx.get_value(&RecoveryFinalizedKey).await;
ensure!(
recovery_finalized.is_some(),
"validate_migrations was not able to read any RecoveryFinalized"
Expand Down

0 comments on commit 2f91b3a

Please sign in to comment.