even more async

This commit is contained in:
Florian Dold 2016-09-28 19:09:10 +02:00
parent b4815b2b06
commit db9b98b2a9

View File

@ -333,9 +333,9 @@ export class Wallet {
* Get exchanges and associated coins that are still spendable, * Get exchanges and associated coins that are still spendable,
* but only if the sum the coins' remaining value exceeds the payment amount. * but only if the sum the coins' remaining value exceeds the payment amount.
*/ */
private getPossibleExchangeCoins(paymentAmount: AmountJson, private async getPossibleExchangeCoins(paymentAmount: AmountJson,
depositFeeLimit: AmountJson, depositFeeLimit: AmountJson,
allowedExchanges: ExchangeHandle[]): Promise<ExchangeCoins> { allowedExchanges: ExchangeHandle[]): Promise<ExchangeCoins> {
// Mapping from exchange base URL to list of coins together with their // Mapping from exchange base URL to list of coins together with their
// denomination // denomination
let m: ExchangeCoins = {}; let m: ExchangeCoins = {};
@ -389,54 +389,54 @@ export class Wallet {
]; ];
}); });
return Promise.all(ps).then(() => { await Promise.all(ps);
let ret: ExchangeCoins = {};
if (Object.keys(m).length == 0) { let ret: ExchangeCoins = {};
console.log("not suitable exchanges found");
}
console.dir(m); if (Object.keys(m).length == 0) {
console.log("not suitable exchanges found");
}
// We try to find the first exchange where we have console.dir(m);
// enough coins to cover the paymentAmount with fees
// under depositFeeLimit
nextExchange: // We try to find the first exchange where we have
for (let key in m) { // enough coins to cover the paymentAmount with fees
let coins = m[key]; // under depositFeeLimit
// Sort by ascending deposit fee
coins.sort((o1, o2) => Amounts.cmp(o1.denom.fee_deposit, nextExchange:
o2.denom.fee_deposit)); for (let key in m) {
let maxFee = Amounts.copy(depositFeeLimit); let coins = m[key];
let minAmount = Amounts.copy(paymentAmount); // Sort by ascending deposit fee
let accFee = Amounts.copy(coins[0].denom.fee_deposit); coins.sort((o1, o2) => Amounts.cmp(o1.denom.fee_deposit,
let accAmount = Amounts.getZero(coins[0].coin.currentAmount.currency); o2.denom.fee_deposit));
let usableCoins: CoinWithDenom[] = []; let maxFee = Amounts.copy(depositFeeLimit);
nextCoin: let minAmount = Amounts.copy(paymentAmount);
for (let i = 0; i < coins.length; i++) { let accFee = Amounts.copy(coins[0].denom.fee_deposit);
let coinAmount = Amounts.copy(coins[i].coin.currentAmount); let accAmount = Amounts.getZero(coins[0].coin.currentAmount.currency);
let coinFee = coins[i].denom.fee_deposit; let usableCoins: CoinWithDenom[] = [];
if (Amounts.cmp(coinAmount, coinFee) <= 0) { nextCoin:
continue nextCoin; for (let i = 0; i < coins.length; i++) {
} let coinAmount = Amounts.copy(coins[i].coin.currentAmount);
accFee = Amounts.add(accFee, coinFee).amount; let coinFee = coins[i].denom.fee_deposit;
accAmount = Amounts.add(accAmount, coinAmount).amount; if (Amounts.cmp(coinAmount, coinFee) <= 0) {
if (Amounts.cmp(accFee, maxFee) >= 0) { continue nextCoin;
// FIXME: if the fees are too high, we have
// to cover them ourselves ....
console.log("too much fees");
continue nextExchange;
}
usableCoins.push(coins[i]);
if (Amounts.cmp(accAmount, minAmount) >= 0) {
ret[key] = usableCoins;
continue nextExchange;
}
} }
} accFee = Amounts.add(accFee, coinFee).amount;
return ret; accAmount = Amounts.add(accAmount, coinAmount).amount;
}); if (Amounts.cmp(accFee, maxFee) >= 0) {
// FIXME: if the fees are too high, we have
// to cover them ourselves ....
console.log("too much fees");
continue nextExchange;
}
usableCoins.push(coins[i]);
if (Amounts.cmp(accAmount, minAmount) >= 0) {
ret[key] = usableCoins;
continue nextExchange;
}
}
}
return ret;
} }
@ -691,14 +691,12 @@ export class Wallet {
return; return;
} }
r.confirmed = true; r.confirmed = true;
return Query(this.db) await Query(this.db)
.put("reserves", r) .put("reserves", r)
.put("history", historyEntry) .put("history", historyEntry)
.finish() .finish();
.then(() => {
// Do this in the background this.processReserve(r);
this.processReserve(r);
});
} }
@ -757,17 +755,14 @@ export class Wallet {
/** /**
* Withdraw one coin 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> { private async withdraw(denom: Denomination, reserve: Reserve): Promise<void> {
console.log("creating pre coin at", new Date()); console.log("creating pre coin at", new Date());
return this.cryptoApi let preCoin = await this.cryptoApi
.createPreCoin(denom, reserve) .createPreCoin(denom, reserve);
.then((preCoin) => { await Query(this.db)
return Query(this.db) .put("precoins", preCoin)
.put("precoins", preCoin) .finish();
.finish() await this.processPreCoin(preCoin);
.then(() => this.processPreCoin(preCoin));
});
} }
@ -791,37 +786,34 @@ export class Wallet {
*/ */
private async updateReserve(reservePub: string, private async updateReserve(reservePub: string,
exchange: IExchangeInfo): Promise<Reserve> { exchange: IExchangeInfo): Promise<Reserve> {
return Query(this.db) let reserve = await Query(this.db)
.get("reserves", reservePub) .get("reserves", reservePub);
.then((reserve) => { let reqUrl = URI("reserve/status").absoluteTo(exchange.baseUrl);
let reqUrl = URI("reserve/status").absoluteTo(exchange.baseUrl); reqUrl.query({'reserve_pub': reservePub});
reqUrl.query({'reserve_pub': reservePub}); let resp = await this.http.get(reqUrl);
return this.http.get(reqUrl).then(resp => { if (resp.status != 200) {
if (resp.status != 200) { throw Error();
throw Error(); }
} let reserveInfo = JSON.parse(resp.responseText);
let reserveInfo = JSON.parse(resp.responseText); if (!reserveInfo) {
if (!reserveInfo) { throw Error();
throw Error(); }
} let oldAmount = reserve.current_amount;
let oldAmount = reserve.current_amount; let newAmount = reserveInfo.balance;
let newAmount = reserveInfo.balance; reserve.current_amount = reserveInfo.balance;
reserve.current_amount = reserveInfo.balance; let historyEntry = {
let historyEntry = { type: "reserve-update",
type: "reserve-update", timestamp: (new Date).getTime(),
timestamp: (new Date).getTime(), detail: {
detail: { reservePub,
reservePub, oldAmount,
oldAmount, newAmount
newAmount }
} };
}; await Query(this.db)
return Query(this.db) .put("reserves", reserve)
.put("reserves", reserve) .finish();
.finish() return reserve;
.then(() => reserve);
});
});
} }
@ -950,16 +942,15 @@ export class Wallet {
} }
private updateExchangeInfo(exchangeInfo: IExchangeInfo, private async updateExchangeInfo(exchangeInfo: IExchangeInfo,
newKeys: KeysJson): Promise<IExchangeInfo> { newKeys: KeysJson): Promise<IExchangeInfo> {
if (exchangeInfo.masterPublicKey != newKeys.master_public_key) { if (exchangeInfo.masterPublicKey != newKeys.master_public_key) {
throw Error("public keys do not match"); throw Error("public keys do not match");
} }
exchangeInfo.active_denoms = []; exchangeInfo.active_denoms = [];
let ps = newKeys.denoms.map((newDenom) => { let denomsToCheck = newKeys.denoms.filter((newDenom) => {
// did we find the new denom in the list of all (old) denoms? // did we find the new denom in the list of all (old) denoms?
let found = false; let found = false;
for (let oldDenom of exchangeInfo.all_denoms) { for (let oldDenom of exchangeInfo.all_denoms) {
@ -983,28 +974,29 @@ export class Wallet {
if (found) { if (found) {
exchangeInfo.active_denoms.push(newDenom); exchangeInfo.active_denoms.push(newDenom);
// No need to check signatures // No need to check signatures
return Promise.resolve(); return false;
} }
return true;
return this.cryptoApi
.isValidDenom(newDenom, exchangeInfo.masterPublicKey)
.then((valid) => {
if (!valid) {
console.error("invalid denomination",
newDenom,
"with key",
exchangeInfo.masterPublicKey);
// FIXME: report to auditors
}
return this.cryptoApi.hashRsaPub(newDenom.denom_pub);
})
.then((h) => {
exchangeInfo.active_denoms.push(newDenom);
exchangeInfo.all_denoms.push(newDenom);
});
}); });
return Promise.all(ps).then(() => exchangeInfo); let ps = denomsToCheck.map(async(denom) => {
let valid = await this.cryptoApi
.isValidDenom(denom,
exchangeInfo.masterPublicKey);
if (!valid) {
console.error("invalid denomination",
denom,
"with key",
exchangeInfo.masterPublicKey);
// FIXME: report to auditors
}
exchangeInfo.active_denoms.push(denom);
exchangeInfo.all_denoms.push(denom);
});
await Promise.all(ps);
return exchangeInfo;
} }