even more async
This commit is contained in:
parent
b4815b2b06
commit
db9b98b2a9
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user