model more backup provider errors

This commit is contained in:
Florian Dold 2021-05-12 14:16:01 +02:00
parent debc2254fd
commit 4fdcaab632
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
4 changed files with 81 additions and 18 deletions

View File

@ -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[];
}
/**

View File

@ -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.
@ -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[];
}
/**

View File

@ -191,6 +191,7 @@ export async function exportBackup(
terms,
base_url: canonicalizeBaseUrl(bp.baseUrl),
pay_proposal_ids: bp.paymentProposalIds,
uids: bp.uids,
});
});

View File

@ -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))],
});
}
}