From f4b92578b0dd08ccd0b7a31b9da318ba661ae3ec Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 21 Oct 2022 12:14:06 -0300 Subject: fix: support for empty denom_selection when recoverying from backup --- .../src/operations/backup/import.ts | 187 +++++++++++---------- .../src/operations/backup/index.ts | 3 +- 2 files changed, 98 insertions(+), 92 deletions(-) (limited to 'packages/taler-wallet-core/src/operations/backup') diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts index 995ae1091..6ec541edc 100644 --- a/packages/taler-wallet-core/src/operations/backup/import.ts +++ b/packages/taler-wallet-core/src/operations/backup/import.ts @@ -175,20 +175,16 @@ async function recoverPayCoinSelection( async function getDenomSelStateFromBackup( tx: GetReadOnlyAccess<{ denominations: typeof WalletStoresV1.denominations }>, + currency: string, exchangeBaseUrl: string, sel: BackupDenomSel, ): Promise { - const d0 = await tx.denominations.get([ - exchangeBaseUrl, - sel[0].denom_pub_hash, - ]); - checkBackupInvariant(!!d0); const selectedDenoms: { denomPubHash: string; count: number; }[] = []; - let totalCoinValue = Amounts.getZero(d0.currency); - let totalWithdrawCost = Amounts.getZero(d0.currency); + let totalCoinValue = Amounts.getZero(currency); + let totalWithdrawCost = Amounts.getZero(currency); for (const s of sel) { const d = await tx.denominations.get([exchangeBaseUrl, s.denom_pub_hash]); checkBackupInvariant(!!d); @@ -486,91 +482,94 @@ export async function importBackup( }); } } + } - for (const backupWg of backupBlob.withdrawal_groups) { - const reservePub = cryptoComp.reservePrivToPub[backupWg.reserve_priv]; - checkLogicInvariant(!!reservePub); - const ts = makeTombstoneId(TombstoneTag.DeleteReserve, reservePub); - if (tombstoneSet.has(ts)) { - continue; - } - const existingWg = await tx.withdrawalGroups.get( - backupWg.withdrawal_group_id, - ); - if (existingWg) { - continue; - } - let wgInfo: WgInfo; - switch (backupWg.info.type) { - case BackupWgType.BankIntegrated: - wgInfo = { - withdrawalType: WithdrawalRecordType.BankIntegrated, - bankInfo: { - exchangePaytoUri: backupWg.info.exchange_payto_uri, - talerWithdrawUri: backupWg.info.taler_withdraw_uri, - confirmUrl: backupWg.info.confirm_url, - timestampBankConfirmed: - backupWg.info.timestamp_bank_confirmed, - timestampReserveInfoPosted: - backupWg.info.timestamp_reserve_info_posted, - }, - }; - break; - case BackupWgType.BankManual: - wgInfo = { - withdrawalType: WithdrawalRecordType.BankManual, - }; - break; - case BackupWgType.PeerPullCredit: - wgInfo = { - withdrawalType: WithdrawalRecordType.PeerPullCredit, - contractTerms: backupWg.info.contract_terms, - contractPriv: backupWg.info.contract_priv, - }; - break; - case BackupWgType.PeerPushCredit: - wgInfo = { - withdrawalType: WithdrawalRecordType.PeerPushCredit, - contractTerms: backupWg.info.contract_terms, - }; - break; - case BackupWgType.Recoup: - wgInfo = { - withdrawalType: WithdrawalRecordType.Recoup, - }; - break; - default: - assertUnreachable(backupWg.info); - } - await tx.withdrawalGroups.put({ - withdrawalGroupId: backupWg.withdrawal_group_id, - exchangeBaseUrl: backupWg.exchange_base_url, - instructedAmount: Amounts.parseOrThrow(backupWg.instructed_amount), - secretSeed: backupWg.secret_seed, - denomsSel: await getDenomSelStateFromBackup( - tx, - backupWg.exchange_base_url, - backupWg.selected_denoms, - ), - denomSelUid: backupWg.selected_denoms_uid, - rawWithdrawalAmount: Amounts.parseOrThrow( - backupWg.raw_withdrawal_amount, - ), - effectiveWithdrawalAmount: Amounts.parseOrThrow( - backupWg.effective_withdrawal_amount, - ), - reservePriv: backupWg.reserve_priv, - reservePub, - status: backupWg.timestamp_finish - ? WithdrawalGroupStatus.Finished - : WithdrawalGroupStatus.QueryingStatus, // FIXME! - timestampStart: backupWg.timestamp_created, - wgInfo, - restrictAge: backupWg.restrict_age, - senderWire: undefined, // FIXME! - timestampFinish: backupWg.timestamp_finish, - }); + for (const backupWg of backupBlob.withdrawal_groups) { + const reservePub = cryptoComp.reservePrivToPub[backupWg.reserve_priv]; + checkLogicInvariant(!!reservePub); + const ts = makeTombstoneId(TombstoneTag.DeleteReserve, reservePub); + if (tombstoneSet.has(ts)) { + continue; + } + const existingWg = await tx.withdrawalGroups.get( + backupWg.withdrawal_group_id, + ); + if (existingWg) { + continue; + } + let wgInfo: WgInfo; + switch (backupWg.info.type) { + case BackupWgType.BankIntegrated: + wgInfo = { + withdrawalType: WithdrawalRecordType.BankIntegrated, + bankInfo: { + exchangePaytoUri: backupWg.info.exchange_payto_uri, + talerWithdrawUri: backupWg.info.taler_withdraw_uri, + confirmUrl: backupWg.info.confirm_url, + timestampBankConfirmed: backupWg.info.timestamp_bank_confirmed, + timestampReserveInfoPosted: + backupWg.info.timestamp_reserve_info_posted, + }, + }; + break; + case BackupWgType.BankManual: + wgInfo = { + withdrawalType: WithdrawalRecordType.BankManual, + }; + break; + case BackupWgType.PeerPullCredit: + wgInfo = { + withdrawalType: WithdrawalRecordType.PeerPullCredit, + contractTerms: backupWg.info.contract_terms, + contractPriv: backupWg.info.contract_priv, + }; + break; + case BackupWgType.PeerPushCredit: + wgInfo = { + withdrawalType: WithdrawalRecordType.PeerPushCredit, + contractTerms: backupWg.info.contract_terms, + }; + break; + case BackupWgType.Recoup: + wgInfo = { + withdrawalType: WithdrawalRecordType.Recoup, + }; + break; + default: + assertUnreachable(backupWg.info); } + const instructedAmount = Amounts.parseOrThrow( + backupWg.instructed_amount, + ); + await tx.withdrawalGroups.put({ + withdrawalGroupId: backupWg.withdrawal_group_id, + exchangeBaseUrl: backupWg.exchange_base_url, + instructedAmount, + secretSeed: backupWg.secret_seed, + denomsSel: await getDenomSelStateFromBackup( + tx, + instructedAmount.currency, + backupWg.exchange_base_url, + backupWg.selected_denoms, + ), + denomSelUid: backupWg.selected_denoms_uid, + rawWithdrawalAmount: Amounts.parseOrThrow( + backupWg.raw_withdrawal_amount, + ), + effectiveWithdrawalAmount: Amounts.parseOrThrow( + backupWg.effective_withdrawal_amount, + ), + reservePriv: backupWg.reserve_priv, + reservePub, + status: backupWg.timestamp_finish + ? WithdrawalGroupStatus.Finished + : WithdrawalGroupStatus.QueryingStatus, // FIXME! + timestampStart: backupWg.timestamp_created, + wgInfo, + restrictAge: backupWg.restrict_age, + senderWire: undefined, // FIXME! + timestampFinish: backupWg.timestamp_finish, + }); } for (const backupPurchase of backupBlob.purchases) { @@ -745,9 +744,13 @@ export async function importBackup( for (const oldCoin of backupRefreshGroup.old_coins) { const c = await tx.coins.get(oldCoin.coin_pub); checkBackupInvariant(!!c); + const d = await tx.denominations.get(c.denomPubHash); + checkBackupInvariant(!!d); + if (oldCoin.refresh_session) { const denomSel = await getDenomSelStateFromBackup( tx, + d.currency, c.exchangeBaseUrl, oldCoin.refresh_session.new_denoms, ); @@ -800,8 +803,10 @@ export async function importBackup( } const existingTip = await tx.tips.get(backupTip.wallet_tip_id); if (!existingTip) { + const tipAmountRaw = Amounts.parseOrThrow(backupTip.tip_amount_raw); const denomsSel = await getDenomSelStateFromBackup( tx, + tipAmountRaw.currency, backupTip.exchange_base_url, backupTip.selected_denoms, ); @@ -815,7 +820,7 @@ export async function importBackup( pickedUpTimestamp: backupTip.timestamp_finished, secretSeed: backupTip.secret_seed, tipAmountEffective: denomsSel.totalCoinValue, - tipAmountRaw: Amounts.parseOrThrow(backupTip.tip_amount_raw), + tipAmountRaw, tipExpiration: backupTip.timestamp_expiration, walletTipId: backupTip.wallet_tip_id, denomSelUid: backupTip.selected_denoms_uid, diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts index 8e5e69097..080adf1cd 100644 --- a/packages/taler-wallet-core/src/operations/backup/index.ts +++ b/packages/taler-wallet-core/src/operations/backup/index.ts @@ -846,6 +846,7 @@ export async function getBackupRecovery( .filter((x) => x.state.tag !== BackupProviderStateTag.Provisional) .map((x) => { return { + name: x.name, url: x.baseUrl, }; }), @@ -881,7 +882,7 @@ async function backupRecoveryTheirs( if (!existingProv) { await tx.backupProviders.put({ baseUrl: prov.url, - name: "not-defined", + name: prov.name, paymentProposalIds: [], state: { tag: BackupProviderStateTag.Ready, -- cgit v1.2.3