aboutsummaryrefslogtreecommitdiff
path: root/lib/wallet
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2016-05-24 01:18:23 +0200
committerFlorian Dold <florian.dold@gmail.com>2016-05-24 01:18:23 +0200
commit50fb0f2beb5e5a2ac6a08b694fbec9e4300fe734 (patch)
treec3921d7b1463aa8997f73e81a936d1097e01e531 /lib/wallet
parentcb7e04c041af3a0fc3c7222c6828caf06758a26a (diff)
retry operations from db / after failure
Diffstat (limited to 'lib/wallet')
-rw-r--r--lib/wallet/types.ts3
-rw-r--r--lib/wallet/wallet.ts57
2 files changed, 55 insertions, 5 deletions
diff --git a/lib/wallet/types.ts b/lib/wallet/types.ts
index 5045a5b9a..d3c1c781a 100644
--- a/lib/wallet/types.ts
+++ b/lib/wallet/types.ts
@@ -119,6 +119,9 @@ export interface ReserveCreationInfo {
}
+/**
+ * A coin that isn't yet signed by an exchange.
+ */
export interface PreCoin {
coinPub: string;
coinPriv: string;
diff --git a/lib/wallet/wallet.ts b/lib/wallet/wallet.ts
index 4d79392d0..bae7873f1 100644
--- a/lib/wallet/wallet.ts
+++ b/lib/wallet/wallet.ts
@@ -261,6 +261,11 @@ function getTalerStampSec(stamp: string) {
}
+function setTimeout(f, t) {
+ return chrome.extension.getBackgroundPage().setTimeout(f, t);
+}
+
+
function isWithdrawableDenom(d: Denomination) {
const now_sec = (new Date).getTime() / 1000;
const stamp_withdraw_sec = getTalerStampSec(d.stamp_expire_withdraw);
@@ -343,6 +348,31 @@ export class Wallet {
this.badge = badge;
this.notifier = notifier;
this.cryptoApi = new CryptoApi();
+
+ this.resumePendingFromDb();
+ }
+
+
+ /**
+ * Resume various pending operations that are pending
+ * by looking at the database.
+ */
+ private resumePendingFromDb(): void {
+ console.log("resuming pending operations from db");
+
+ Query(this.db)
+ .iter("reserves")
+ .reduce((reserve: any) => {
+ console.log("resuming reserve", reserve.reserve_pub);
+ this.processReserve(reserve);
+ });
+
+ Query(this.db)
+ .iter("precoins")
+ .reduce((preCoin: any) => {
+ console.log("resuming precoin");
+ this.processPreCoin(preCoin);
+ });
}
@@ -578,7 +608,8 @@ export class Wallet {
* First fetch information requred to withdraw from the reserve,
* then deplete the reserve, withdrawing coins until it is empty.
*/
- private processReserve(reserveRecord) {
+ private processReserve(reserveRecord): void {
+ let retryDelayMs = 100;
this.updateExchangeFromUrl(reserveRecord.exchange_base_url)
.then((exchange) =>
this.updateReserve(reserveRecord.reserve_pub, exchange)
@@ -597,6 +628,23 @@ export class Wallet {
.catch((e) => {
console.error("Failed to deplete reserve");
console.error(e);
+ setTimeout(() => this.processReserve(reserveRecord), retryDelayMs);
+ // exponential backoff truncated at one minute
+ retryDelayMs = Math.min(retryDelayMs * 2, 1000 * 60);
+ });
+ }
+
+
+ private processPreCoin(preCoin): void {
+ let retryDelayMs = 100;
+ this.withdrawExecute(preCoin)
+ .then((c) => this.storeCoin(c))
+ .catch((e) => {
+ console.error("Failed to withdraw coin from precoin");
+ console.error(e);
+ setTimeout(() => this.processPreCoin(preCoin), retryDelayMs);
+ // exponential backoff truncated at one minute
+ retryDelayMs = Math.min(retryDelayMs * 2, 1000 * 60);
});
}
@@ -735,7 +783,7 @@ export class Wallet {
/**
- * Withdraw one coins of the given denomination from the given reserve.
+ * Withdraw one coin of the given denomination from the given reserve.
*/
private withdraw(denom: Denomination, reserve: Reserve): Promise<void> {
console.log("creating pre coin at", new Date());
@@ -745,8 +793,7 @@ export class Wallet {
return Query(this.db)
.put("precoins", preCoin)
.finish()
- .then(() => this.withdrawExecute(preCoin))
- .then((c) => this.storeCoin(c));
+ .then(() => this.processPreCoin(preCoin));
});
}
@@ -963,4 +1010,4 @@ export class Wallet {
}
});
}
-}
+} \ No newline at end of file