fix signature checks, add wire fee
This commit is contained in:
parent
82b5754e15
commit
ce97b1076b
@ -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(),
|
||||||
});
|
});
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
src/types.ts
19
src/types.ts
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user