From e319e99ef9657f68c82e7b37dd928c126d865ecb Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 7 Jan 2021 15:01:23 +0100 Subject: restore denom selection on import --- .../taler-wallet-core/src/operations/backup.ts | 53 ++++++++++++++++++---- packages/taler-wallet-core/src/operations/state.ts | 4 ++ 2 files changed, 47 insertions(+), 10 deletions(-) (limited to 'packages/taler-wallet-core/src/operations') diff --git a/packages/taler-wallet-core/src/operations/backup.ts b/packages/taler-wallet-core/src/operations/backup.ts index b82e63ff2..4f736c3df 100644 --- a/packages/taler-wallet-core/src/operations/backup.ts +++ b/packages/taler-wallet-core/src/operations/backup.ts @@ -588,10 +588,6 @@ export async function exportBackup( ); } -export interface BackupRequest { - backupBlob: any; -} - export async function encryptBackup( config: WalletBackupConfState, blob: WalletBackupContentV1, @@ -621,7 +617,7 @@ interface BackupCryptoPrecomputedData { /** * Compute cryptographic values for a backup blob. - * + * * FIXME: Take data that we already know from the DB. * FIXME: Move computations into crypto worker. */ @@ -650,7 +646,7 @@ async function computeBackupCryptoData( cryptoData.coinPrivToCompletedCoin[backupCoin.coin_priv] = { coinEvHash: encodeCrock(hash(blindedCoin)), coinPub, - } + }; } cryptoData.denomPubToHash[backupDenom.denom_pub] = encodeCrock( hash(decodeCrock(backupDenom.denom_pub)), @@ -777,16 +773,35 @@ async function recoverPayCoinSelection( }; } -function getDenomSelStateFromBackup( +async function getDenomSelStateFromBackup( tx: TransactionHandle, + exchangeBaseUrl: string, sel: BackupDenomSel, ): Promise { - throw Error("not implemented"); + const d0 = await tx.get(Stores.denominations, [exchangeBaseUrl, sel[0].denom_pub_hash]); + checkBackupInvariant(!!d0); + const selectedDenoms: { + denomPubHash: string; + count: number; + }[] = []; + let totalCoinValue = Amounts.getZero(d0.value.currency); + let totalWithdrawCost = Amounts.getZero(d0.value.currency); + for (const s of sel) { + const d = await tx.get(Stores.denominations, [exchangeBaseUrl, s.denom_pub_hash]); + checkBackupInvariant(!!d); + totalCoinValue = Amounts.add(totalCoinValue, d.value).amount; + totalWithdrawCost = Amounts.add(totalWithdrawCost, d.value, d.feeWithdraw).amount; + } + return { + selectedDenoms, + totalCoinValue, + totalWithdrawCost, + } } export async function importBackup( ws: InternalWalletState, - backupRequest: BackupRequest, + backupBlobArg: any, cryptoComp: BackupCryptoPrecomputedData, ): Promise { await provideBackupState(ws); @@ -807,7 +822,7 @@ export async function importBackup( ], async (tx) => { // FIXME: validate schema! - const backupBlob = backupRequest.backupBlob as WalletBackupContentV1; + const backupBlob = backupBlobArg as WalletBackupContentV1; // FIXME: validate version @@ -993,6 +1008,7 @@ export async function importBackup( reserveStatus: ReserveRecordStatus.QUERYING_STATUS, initialDenomSel: await getDenomSelStateFromBackup( tx, + backupExchange.base_url, backupReserve.initial_selected_denoms, ), }); @@ -1006,6 +1022,7 @@ export async function importBackup( await tx.put(Stores.withdrawalGroups, { denomsSel: await getDenomSelStateFromBackup( tx, + backupExchange.base_url, backupWg.selected_denoms, ), exchangeBaseUrl: backupExchange.base_url, @@ -1300,9 +1317,12 @@ export async function importBackup( | undefined )[] = []; for (const oldCoin of backupRefreshGroup.old_coins) { + const c = await tx.get(Stores.coins, oldCoin.coin_pub); + checkBackupInvariant(!!c); if (oldCoin.refresh_session) { const denomSel = await getDenomSelStateFromBackup( tx, + c.exchangeBaseUrl, oldCoin.refresh_session.new_denoms, ); refreshSessionPerCoin.push({ @@ -1346,6 +1366,7 @@ export async function importBackup( if (!existingTip) { const denomsSel = await getDenomSelStateFromBackup( tx, + backupTip.exchange_base_url, backupTip.selected_denoms, ); await tx.put(Stores.tips, { @@ -1530,6 +1551,18 @@ export interface BackupInfo { providers: ProviderInfo[]; } +export async function importBackupPlain( + ws: InternalWalletState, + blob: any, +): Promise { + // FIXME: parse + const backup: WalletBackupContentV1 = blob; + + const cryptoData = await computeBackupCryptoData(ws.cryptoApi, backup); + + await importBackup(ws, blob, cryptoData); +} + /** * Get information about the current state of wallet backups. */ diff --git a/packages/taler-wallet-core/src/operations/state.ts b/packages/taler-wallet-core/src/operations/state.ts index 11695f6d0..1733f13bb 100644 --- a/packages/taler-wallet-core/src/operations/state.ts +++ b/packages/taler-wallet-core/src/operations/state.ts @@ -55,6 +55,10 @@ export class InternalWalletState { private resourceLocks: Set = new Set(); constructor( + // FIXME: Make this a getter and make + // the actual value nullable. + // Check if we are in a DB migration / garbage collection + // and throw an error in that case. public db: Database, public http: HttpRequestLibrary, cryptoWorkerFactory: CryptoWorkerFactory, -- cgit v1.2.3