consider auditors when selecting exchange for payment

This commit is contained in:
Florian Dold 2017-04-26 14:11:35 +02:00
parent a787cf2f6c
commit 3c563c78d4
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
2 changed files with 56 additions and 11 deletions

View File

@ -216,9 +216,22 @@ export class Denomination {
} }
export interface Auditor {
// official name
name: string;
// Auditor's public key
auditor_pub: string;
// Base URL of the auditor
url: string;
}
export interface ExchangeRecord { export interface ExchangeRecord {
baseUrl: string; baseUrl: string;
masterPublicKey: string; masterPublicKey: string;
auditors: Auditor[];
/** /**
* Timestamp for last update. * Timestamp for last update.

View File

@ -38,6 +38,7 @@ import {
ReserveCreationInfo, ReserveCreationInfo,
ReserveRecord, ReserveRecord,
CurrencyRecord, CurrencyRecord,
Auditor,
AuditorRecord, AuditorRecord,
WalletBalance, WalletBalance,
WalletBalanceEntry, WalletBalanceEntry,
@ -557,17 +558,45 @@ export class Wallet {
*/ */
private async getCoinsForPayment(paymentAmount: AmountJson, private async getCoinsForPayment(paymentAmount: AmountJson,
depositFeeLimit: AmountJson, depositFeeLimit: AmountJson,
allowedExchanges: ExchangeHandle[]): Promise<CoinSelectionResult> { allowedExchanges: ExchangeHandle[],
allowedAuditors: Auditor[]): Promise<CoinSelectionResult> {
for (let exchangeHandle of allowedExchanges) { let exchanges = await this.q().iter(Stores.exchanges).toArray();
let exchange = await this.q().get(Stores.exchanges, exchangeHandle.url);
if (!exchange) { for (let exchange of exchanges) {
console.error("db inconsistent"); let isOkay: boolean = false;
// is the exchange explicitly allowed?
for (let allowedExchange of allowedExchanges) {
if (allowedExchange.master_pub == exchange.masterPublicKey) {
isOkay = true;
break;
}
}
// is the exchange allowed because of one of its auditors?
if (!isOkay) {
for (let allowedAuditor of allowedAuditors) {
for (let auditor of exchange.auditors) {
if (auditor.auditor_pub == allowedAuditor.auditor_pub) {
isOkay = true;
break;
}
}
if (isOkay) {
break;
}
}
}
if (!isOkay) {
continue; continue;
} }
let coins: CoinRecord[] = await this.q() let coins: CoinRecord[] = await this.q()
.iterIndex(Stores.coins.exchangeBaseUrlIndex, .iterIndex(Stores.coins.exchangeBaseUrlIndex,
exchangeHandle.url) exchange.baseUrl)
.toArray(); .toArray();
if (!coins || coins.length == 0) { if (!coins || coins.length == 0) {
continue; continue;
@ -576,7 +605,7 @@ export class Wallet {
// coins have the same currency // coins have the same currency
let firstDenom = await this.q().get(Stores.denominations, let firstDenom = await this.q().get(Stores.denominations,
[ [
exchangeHandle.url, exchange.baseUrl,
coins[0].denomPub coins[0].denomPub
]); ]);
if (!firstDenom) { if (!firstDenom) {
@ -587,7 +616,7 @@ export class Wallet {
for (let i = 0; i < coins.length; i++) { for (let i = 0; i < coins.length; i++) {
let coin = coins[i]; let coin = coins[i];
let denom = await this.q().get(Stores.denominations, let denom = await this.q().get(Stores.denominations,
[exchangeHandle.url, coin.denomPub]); [exchange.baseUrl, coin.denomPub]);
if (!denom) { if (!denom) {
throw Error("db inconsistent"); throw Error("db inconsistent");
} }
@ -607,7 +636,7 @@ export class Wallet {
let res = selectCoins(cds, paymentAmount, depositFeeLimit); let res = selectCoins(cds, paymentAmount, depositFeeLimit);
if (res) { if (res) {
return { return {
exchangeUrl: exchangeHandle.url, exchangeUrl: exchange.baseUrl,
cds: res, cds: res,
} }
} }
@ -694,7 +723,8 @@ export class Wallet {
let res = await this.getCoinsForPayment(offer.contract.amount, let res = await this.getCoinsForPayment(offer.contract.amount,
offer.contract.max_fee, offer.contract.max_fee,
offer.contract.exchanges); offer.contract.exchanges,
offer.contract.auditors);
console.log("max_fee", offer.contract.max_fee); console.log("max_fee", offer.contract.max_fee);
console.log("coin selection result", res); console.log("coin selection result", res);
@ -729,7 +759,8 @@ export class Wallet {
// If not already payed, check if we could pay for it. // If not already payed, check if we could pay for it.
let res = await this.getCoinsForPayment(offer.contract.amount, let res = await this.getCoinsForPayment(offer.contract.amount,
offer.contract.max_fee, offer.contract.max_fee,
offer.contract.exchanges); offer.contract.exchanges,
offer.contract.auditors);
if (!res) { if (!res) {
console.log("not confirming payment, insufficient coins"); console.log("not confirming payment, insufficient coins");
@ -1273,6 +1304,7 @@ export class Wallet {
baseUrl, baseUrl,
lastUpdateTime: updateTimeSec, lastUpdateTime: updateTimeSec,
masterPublicKey: exchangeKeysJson.master_public_key, masterPublicKey: exchangeKeysJson.master_public_key,
auditors: exchangeKeysJson.auditors,
}; };
console.log("making fresh exchange"); console.log("making fresh exchange");
} else { } else {