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 {
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(),
});

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}