aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-05-12 14:16:01 +0200
committerFlorian Dold <florian@dold.me>2021-05-12 14:16:01 +0200
commit4fdcaab6325289fd8525fc9e63c8c86b07131376 (patch)
tree5d14c2b32792d572d23bcc0fbcaaff71751029ec
parentdebc2254fdf1cf748a846e429e32c2e92d557080 (diff)
model more backup provider errors
-rw-r--r--packages/taler-util/src/backupTypes.ts5
-rw-r--r--packages/taler-wallet-core/src/db.ts39
-rw-r--r--packages/taler-wallet-core/src/operations/backup/export.ts1
-rw-r--r--packages/taler-wallet-core/src/operations/backup/index.ts54
4 files changed, 81 insertions, 18 deletions
diff --git a/packages/taler-util/src/backupTypes.ts b/packages/taler-util/src/backupTypes.ts
index 13ff75190..1980bfb4e 100644
--- a/packages/taler-util/src/backupTypes.ts
+++ b/packages/taler-util/src/backupTypes.ts
@@ -304,6 +304,11 @@ export class BackupBackupProvider {
* Proposal IDs for payments to this provider.
*/
pay_proposal_ids: string[];
+
+ /**
+ * UIDs for adding this backup provider.
+ */
+ uids: OperationUid[];
}
/**
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index 22cbd16cc..946e71e10 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -13,7 +13,22 @@ import {
IDBKeyPath,
} from "@gnu-taler/idb-bridge";
import { Logger } from "./util/logging";
-import { AmountJson, AmountString, Auditor, CoinDepositPermission, ContractTerms, Duration, ExchangeSignKeyJson, InternationalizedString, MerchantInfo, Product, RefreshReason, ReserveTransaction, TalerErrorDetails, Timestamp } from "@gnu-taler/taler-util";
+import {
+ AmountJson,
+ AmountString,
+ Auditor,
+ CoinDepositPermission,
+ ContractTerms,
+ Duration,
+ ExchangeSignKeyJson,
+ InternationalizedString,
+ MerchantInfo,
+ Product,
+ RefreshReason,
+ ReserveTransaction,
+ TalerErrorDetails,
+ Timestamp,
+} from "@gnu-taler/taler-util";
import { RetryInfo } from "./util/retries.js";
import { PayCoinSelection } from "./util/coinSelection.js";
@@ -170,7 +185,6 @@ export function deleteTalerDatabase(idbFactory: IDBFactory): void {
Database.deleteDatabase(idbFactory, TALER_DB_NAME);
}
-
export enum ReserveRecordStatus {
/**
* Reserve must be registered with the bank.
@@ -1269,14 +1283,12 @@ export interface WalletContractData {
maxDepositFee: AmountJson;
}
-
export enum AbortStatus {
None = "none",
AbortRefund = "abort-refund",
AbortFinished = "abort-finished",
}
-
/**
* Record that stores status information about one purchase, starting from when
* the customer accepts a proposal. Includes refund status if applicable.
@@ -1316,7 +1328,7 @@ export interface PurchaseRecord {
/**
* Pending removals from pay coin selection.
- *
+ *
* Used when a the pay coin selection needs to be changed
* because a coin became known as double-spent or invalid,
* but a new coin selection can't immediately be done, as
@@ -1548,6 +1560,12 @@ export enum BackupProviderStatus {
Ready = "ready",
}
+export interface BackupProviderTerms {
+ supportedProtocolVersion: string;
+ annualFee: AmountString;
+ storageLimitInMegabytes: number;
+}
+
export interface BackupProviderRecord {
baseUrl: string;
@@ -1556,11 +1574,7 @@ export interface BackupProviderRecord {
* Might be unavailable in the DB in certain situations
* (such as loading a recovery document).
*/
- terms?: {
- supportedProtocolVersion: string;
- annualFee: AmountString;
- storageLimitInMegabytes: number;
- };
+ terms?: BackupProviderTerms;
active: boolean;
@@ -1601,6 +1615,11 @@ export interface BackupProviderRecord {
* Last error that occurred, if any.
*/
lastError: TalerErrorDetails | undefined;
+
+ /**
+ * UIDs for the operation that added the backup provider.
+ */
+ uids: string[];
}
/**
diff --git a/packages/taler-wallet-core/src/operations/backup/export.ts b/packages/taler-wallet-core/src/operations/backup/export.ts
index 4ccaf8f42..70d249ab8 100644
--- a/packages/taler-wallet-core/src/operations/backup/export.ts
+++ b/packages/taler-wallet-core/src/operations/backup/export.ts
@@ -191,6 +191,7 @@ export async function exportBackup(
terms,
base_url: canonicalizeBaseUrl(bp.baseUrl),
pay_proposal_ids: bp.paymentProposalIds,
+ uids: bp.uids,
});
});
diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts
index b4c1a6c92..110e76596 100644
--- a/packages/taler-wallet-core/src/operations/backup/index.ts
+++ b/packages/taler-wallet-core/src/operations/backup/index.ts
@@ -31,8 +31,12 @@ import {
codecForAmountString,
WalletBackupContentV1,
} from "@gnu-taler/taler-util";
-import { TransactionHandle } from "../../util/query";
-import { BackupProviderRecord, ConfigRecord, Stores } from "../../db.js";
+import {
+ BackupProviderRecord,
+ BackupProviderTerms,
+ ConfigRecord,
+ Stores,
+} from "../../db.js";
import { checkDbInvariant, checkLogicInvariant } from "../../util/invariants";
import {
bytesToString,
@@ -40,13 +44,13 @@ import {
eddsaGetPublic,
EddsaKeyPair,
encodeCrock,
+ getRandomBytes,
hash,
rsaBlind,
stringToBytes,
} from "../../crypto/talerCrypto";
import { canonicalizeBaseUrl, canonicalJson, j2s } from "@gnu-taler/taler-util";
import {
- durationAdd,
durationFromSpec,
getTimestampNow,
Timestamp,
@@ -495,6 +499,7 @@ export async function addBackupProvider(
baseUrl: canonUrl,
lastError: undefined,
retryInfo: initRetryInfo(false),
+ uids: [encodeCrock(getRandomBytes(32))],
});
}
@@ -513,14 +518,39 @@ export async function restoreFromRecoverySecret(): Promise<void> {}
export interface ProviderInfo {
active: boolean;
syncProviderBaseUrl: string;
+ terms?: BackupProviderTerms;
+ /**
+ * Last communication issue with the provider.
+ */
lastError?: TalerErrorDetails;
- lastRemoteClock?: number;
- lastBackupTimestamp?: Timestamp;
+ lastSuccessfulBackupTimestamp?: Timestamp;
+ lastAttemptedBackupTimestamp?: Timestamp;
paymentProposalIds: string[];
+ backupProblem?: BackupProblem;
paymentStatus: ProviderPaymentStatus;
}
+export type BackupProblem =
+ | BackupUnreadableProblem
+ | BackupConflictingDeviceProblem;
+
+export interface BackupUnreadableProblem {
+ type: "backup-unreadable";
+}
+
+export interface BackupUnreadableProblem {
+ type: "backup-unreadable";
+}
+
+export interface BackupConflictingDeviceProblem {
+ type: "backup-conflicting-device";
+ otherDeviceId: string;
+ myDeviceId: string;
+ backupTimestamp: Timestamp;
+}
+
export type ProviderPaymentStatus =
+ | ProviderPaymentTermsChanged
| ProviderPaymentPaid
| ProviderPaymentInsufficientBalance
| ProviderPaymentUnpaid
@@ -529,7 +559,6 @@ export type ProviderPaymentStatus =
export interface BackupInfo {
walletRootPub: string;
deviceId: string;
- lastLocalClock: number;
providers: ProviderInfo[];
}
@@ -550,6 +579,7 @@ export enum ProviderPaymentType {
Pending = "pending",
InsufficientBalance = "insufficient-balance",
Paid = "paid",
+ TermsChanged = "terms-changed",
}
export interface ProviderPaymentUnpaid {
@@ -569,6 +599,13 @@ export interface ProviderPaymentPaid {
paidUntil: Timestamp;
}
+export interface ProviderPaymentTermsChanged {
+ type: ProviderPaymentType.TermsChanged;
+ paidUntil: Timestamp;
+ oldTerms: BackupProviderTerms;
+ newTerms: BackupProviderTerms;
+}
+
async function getProviderPaymentInfo(
ws: InternalWalletState,
provider: BackupProviderRecord,
@@ -623,15 +660,15 @@ export async function getBackupInfo(
providers.push({
active: x.active,
syncProviderBaseUrl: x.baseUrl,
- lastBackupTimestamp: x.lastBackupTimestamp,
+ lastSuccessfulBackupTimestamp: x.lastBackupTimestamp,
paymentProposalIds: x.paymentProposalIds,
lastError: x.lastError,
paymentStatus: await getProviderPaymentInfo(ws, x),
+ terms: x.terms,
});
}
return {
deviceId: backupConfig.deviceId,
- lastLocalClock: backupConfig.clocks[backupConfig.deviceId],
walletRootPub: backupConfig.walletRootPub,
providers,
};
@@ -686,6 +723,7 @@ async function backupRecoveryTheirs(
paymentProposalIds: [],
retryInfo: initRetryInfo(false),
lastError: undefined,
+ uids: [encodeCrock(getRandomBytes(32))],
});
}
}