aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-04-27 04:06:48 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-04-27 04:06:48 +0200
commitce97b1076b7e4a53b84d3fd34bf2047580ddeb22 (patch)
treebe365d6cf69b9c6a9b7841869727e57c1a152ad3
parent82b5754e157a1a3b22afe48c8366c76525eb91e3 (diff)
fix signature checks, add wire fee
-rw-r--r--src/cryptoWorker.ts4
-rw-r--r--src/emscriptif.ts4
-rw-r--r--src/types.ts19
-rw-r--r--src/wallet.ts36
4 files changed, 55 insertions, 8 deletions
diff --git a/src/cryptoWorker.ts b/src/cryptoWorker.ts
index 4275d659b..55c08d4b5 100644
--- a/src/cryptoWorker.ts
+++ b/src/cryptoWorker.ts
@@ -113,8 +113,8 @@ namespace RpcFunctions {
export function isValidWireFee(type: string, wf: WireFee, masterPub: string): boolean {
let p = new native.MasterWireFeePS({
h_wire_method: native.ByteArray.fromStringWithNull(type).hash(),
- start_date: native.AbsoluteTimeNbo.fromStamp(wf.startStamp),
- end_date: native.AbsoluteTimeNbo.fromStamp(wf.endStamp),
+ start_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.startStamp),
+ end_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.endStamp),
wire_fee: (new native.Amount(wf.wireFee)).toNbo(),
closing_fee: (new native.Amount(wf.closingFee)).toNbo(),
});
diff --git a/src/emscriptif.ts b/src/emscriptif.ts
index 3f23476aa..347ee54a0 100644
--- a/src/emscriptif.ts
+++ b/src/emscriptif.ts
@@ -1038,11 +1038,11 @@ export class AbsoluteTimeNbo extends PackedArenaObject {
return x;
}
- static fromStamp(stamp: number): AbsoluteTimeNbo {
+ static fromStampSeconds(stamp: number): AbsoluteTimeNbo {
let x = new AbsoluteTimeNbo();
x.alloc();
// XXX: This only works up to 54 bit numbers.
- set64(x.nativePtr, stamp);
+ set64(x.nativePtr, stamp * 1000000);
return x;
}
diff --git a/src/types.ts b/src/types.ts
index c6111bd09..5d53f8db0 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -526,10 +526,10 @@ export class Contract {
fulfillment_url: string;
@Checkable.Number
- wire_fee_amortization: number;
+ wire_fee_amortization?: number;
@Checkable.Value(AmountJson)
- max_wire_fee: AmountJson;
+ max_wire_fee?: AmountJson;
@Checkable.Any
extra: any;
@@ -661,6 +661,21 @@ export namespace Amounts {
}
}
+ export function divide(a: AmountJson, n: number): AmountJson {
+ if (n == 0) {
+ throw Error(`Division by 0`);
+ }
+ if (n == 1) {
+ return {value: a.value, fraction: a.fraction, currency: a.currency};
+ }
+ let r = a.value % n;
+ return {
+ currency: a.currency,
+ value: Math.floor(a.value / n),
+ fraction: Math.floor(((r * fractionalBase) + a.fraction) / n),
+ }
+ }
+
export function isNonZero(a: AmountJson) {
return a.value > 0 || a.fraction > 0;
}
diff --git a/src/wallet.ts b/src/wallet.ts
index 8b220ec4f..982801f43 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -601,7 +601,11 @@ export class Wallet {
* but only if the sum the coins' remaining value exceeds the payment amount.
*/
private async getCoinsForPayment(paymentAmount: AmountJson,
+ wireMethod: string,
+ wireFeeTime: number,
depositFeeLimit: AmountJson,
+ wireFeeLimit: AmountJson,
+ wireFeeAmortization: number,
allowedExchanges: ExchangeHandle[],
allowedAuditors: Auditor[]): Promise<CoinSelectionResult> {
@@ -610,7 +614,6 @@ export class Wallet {
for (let exchange of exchanges) {
let isOkay: boolean = false;
-
// is the exchange explicitly allowed?
for (let allowedExchange of allowedExchanges) {
if (allowedExchange.master_pub == exchange.masterPublicKey) {
@@ -677,6 +680,27 @@ export class Wallet {
cds.push({coin, denom});
}
+ let fees = await this.q().get(Stores.exchangeWireFees, exchange.baseUrl);
+ if (!fees) {
+ console.error("no fees found for exchange", exchange);
+ continue;
+ }
+
+ let wireFee: AmountJson|undefined = undefined;
+ for (let fee of (fees.feesForType[wireMethod] || [])) {
+ if (fee.startStamp >= wireFeeTime && fee.endStamp <= wireFeeTime) {
+ wireFee = fee.wireFee;
+ break;
+ }
+ }
+
+ if (wireFee) {
+ let amortizedWireFee = Amounts.divide(wireFee, wireFeeAmortization);
+ if (Amounts.cmp(wireFeeLimit, amortizedWireFee) < 0) {
+ paymentAmount = Amounts.add(amortizedWireFee, paymentAmount).amount;
+ }
+ }
+
let res = selectCoins(cds, paymentAmount, depositFeeLimit);
if (res) {
return {
@@ -766,7 +790,11 @@ export class Wallet {
}
let res = await this.getCoinsForPayment(offer.contract.amount,
+ offer.contract.wire_method,
+ getTalerStampSec(offer.contract.timestamp) || 0,
offer.contract.max_fee,
+ offer.contract.max_wire_fee || Amounts.getZero(offer.contract.amount.currency),
+ offer.contract.wire_fee_amortization || 1,
offer.contract.exchanges,
offer.contract.auditors);
@@ -802,7 +830,11 @@ export class Wallet {
// If not already payed, check if we could pay for it.
let res = await this.getCoinsForPayment(offer.contract.amount,
+ offer.contract.wire_method,
+ getTalerStampSec(offer.contract.timestamp) || 0,
offer.contract.max_fee,
+ offer.contract.max_wire_fee || Amounts.getZero(offer.contract.amount.currency),
+ offer.contract.wire_fee_amortization || 1,
offer.contract.exchanges,
offer.contract.auditors);
@@ -1427,7 +1459,7 @@ export class Wallet {
let valid: boolean = await this.cryptoApi.isValidWireFee(detail.type, wf, exchangeInfo.masterPublicKey);
if (!valid) {
console.error("fee signature invalid", fee);
- continue;
+ throw Error("fee signature invalid");
}
fees.push(wf);
}