fix signature checks, add wire fee

This commit is contained in:
Florian Dold 2017-04-27 04:06:48 +02:00
parent 82b5754e15
commit ce97b1076b
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
4 changed files with 55 additions and 8 deletions

View File

@ -113,8 +113,8 @@ namespace RpcFunctions {
export function isValidWireFee(type: string, wf: WireFee, masterPub: string): boolean { export function isValidWireFee(type: string, wf: WireFee, masterPub: string): boolean {
let p = new native.MasterWireFeePS({ let p = new native.MasterWireFeePS({
h_wire_method: native.ByteArray.fromStringWithNull(type).hash(), h_wire_method: native.ByteArray.fromStringWithNull(type).hash(),
start_date: native.AbsoluteTimeNbo.fromStamp(wf.startStamp), start_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.startStamp),
end_date: native.AbsoluteTimeNbo.fromStamp(wf.endStamp), end_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.endStamp),
wire_fee: (new native.Amount(wf.wireFee)).toNbo(), wire_fee: (new native.Amount(wf.wireFee)).toNbo(),
closing_fee: (new native.Amount(wf.closingFee)).toNbo(), closing_fee: (new native.Amount(wf.closingFee)).toNbo(),
}); });

View File

@ -1038,11 +1038,11 @@ export class AbsoluteTimeNbo extends PackedArenaObject {
return x; return x;
} }
static fromStamp(stamp: number): AbsoluteTimeNbo { static fromStampSeconds(stamp: number): AbsoluteTimeNbo {
let x = new AbsoluteTimeNbo(); let x = new AbsoluteTimeNbo();
x.alloc(); x.alloc();
// XXX: This only works up to 54 bit numbers. // XXX: This only works up to 54 bit numbers.
set64(x.nativePtr, stamp); set64(x.nativePtr, stamp * 1000000);
return x; return x;
} }

View File

@ -526,10 +526,10 @@ export class Contract {
fulfillment_url: string; fulfillment_url: string;
@Checkable.Number @Checkable.Number
wire_fee_amortization: number; wire_fee_amortization?: number;
@Checkable.Value(AmountJson) @Checkable.Value(AmountJson)
max_wire_fee: AmountJson; max_wire_fee?: AmountJson;
@Checkable.Any @Checkable.Any
extra: 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) { export function isNonZero(a: AmountJson) {
return a.value > 0 || a.fraction > 0; return a.value > 0 || a.fraction > 0;
} }

View File

@ -601,7 +601,11 @@ export class Wallet {
* 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 async getCoinsForPayment(paymentAmount: AmountJson, private async getCoinsForPayment(paymentAmount: AmountJson,
wireMethod: string,
wireFeeTime: number,
depositFeeLimit: AmountJson, depositFeeLimit: AmountJson,
wireFeeLimit: AmountJson,
wireFeeAmortization: number,
allowedExchanges: ExchangeHandle[], allowedExchanges: ExchangeHandle[],
allowedAuditors: Auditor[]): Promise<CoinSelectionResult> { allowedAuditors: Auditor[]): Promise<CoinSelectionResult> {
@ -610,7 +614,6 @@ export class Wallet {
for (let exchange of exchanges) { for (let exchange of exchanges) {
let isOkay: boolean = false; let isOkay: boolean = false;
// is the exchange explicitly allowed? // is the exchange explicitly allowed?
for (let allowedExchange of allowedExchanges) { for (let allowedExchange of allowedExchanges) {
if (allowedExchange.master_pub == exchange.masterPublicKey) { if (allowedExchange.master_pub == exchange.masterPublicKey) {
@ -677,6 +680,27 @@ export class Wallet {
cds.push({coin, denom}); 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); let res = selectCoins(cds, paymentAmount, depositFeeLimit);
if (res) { if (res) {
return { return {
@ -766,7 +790,11 @@ export class Wallet {
} }
let res = await this.getCoinsForPayment(offer.contract.amount, let res = await this.getCoinsForPayment(offer.contract.amount,
offer.contract.wire_method,
getTalerStampSec(offer.contract.timestamp) || 0,
offer.contract.max_fee, 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.exchanges,
offer.contract.auditors); offer.contract.auditors);
@ -802,7 +830,11 @@ 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.wire_method,
getTalerStampSec(offer.contract.timestamp) || 0,
offer.contract.max_fee, 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.exchanges,
offer.contract.auditors); offer.contract.auditors);
@ -1427,7 +1459,7 @@ export class Wallet {
let valid: boolean = await this.cryptoApi.isValidWireFee(detail.type, wf, exchangeInfo.masterPublicKey); let valid: boolean = await this.cryptoApi.isValidWireFee(detail.type, wf, exchangeInfo.masterPublicKey);
if (!valid) { if (!valid) {
console.error("fee signature invalid", fee); console.error("fee signature invalid", fee);
continue; throw Error("fee signature invalid");
} }
fees.push(wf); fees.push(wf);
} }