Merge branch 'master' into develop-master-merge

This commit is contained in:
Ivan Tivonenko
2015-09-15 06:29:26 +03:00
13 changed files with 632 additions and 376 deletions

View File

@@ -1,7 +1,10 @@
machine: machine:
node: node:
version: 0.12.0 version: 0.12.0
<<<<<<< HEAD
test: test:
override: override:
- bin/ci.sh "$CIRCLE_NODE_INDEX" "$CIRCLE_NODE_TOTAL": - bin/ci.sh "$CIRCLE_NODE_INDEX" "$CIRCLE_NODE_TOTAL":
parallel: true parallel: true
=======
>>>>>>> upstream/master

View File

@@ -356,7 +356,7 @@ Amount.prototype._copy = function(value) {
Amount.prototype.compareTo = function(to) { Amount.prototype.compareTo = function(to) {
const toAmount = Amount.from_json(to); const toAmount = Amount.from_json(to);
if (!this.is_comparable(toAmount)) { if (!this.is_comparable(toAmount)) {
return new Amount(); return 0;
} }
return this._value.comparedTo(toAmount._value); return this._value.comparedTo(toAmount._value);
}; };

View File

@@ -20,7 +20,8 @@ function assertValidLegOneOffer(legOneOffer, message) {
function AutobridgeCalculator(currencyGets, currencyPays, function AutobridgeCalculator(currencyGets, currencyPays,
legOneOffers, legTwoOffers, issuerGets, issuerPays) { legOneOffers, legTwoOffers, issuerGets, issuerPays) {
this._currencyGets = currencyGets; this._currencyGets = currencyGets;
this._currencyPays = currencyPays; this._currencyGetsHex = currencyGets.to_hex();
this._currencyPaysHex = currencyPays.to_hex();
this._issuerGets = issuerGets; this._issuerGets = issuerGets;
this._issuerPays = issuerPays; this._issuerPays = issuerPays;
this.legOneOffers = _.cloneDeep(legOneOffers); this.legOneOffers = _.cloneDeep(legOneOffers);
@@ -29,6 +30,8 @@ function AutobridgeCalculator(currencyGets, currencyPays,
this._ownerFundsLeftover = {}; this._ownerFundsLeftover = {};
} }
AutobridgeCalculator.NULL_AMOUNT = Utils.normalizeAmount('0');
/** /**
* Calculates an ordered array of autobridged offers by quality * Calculates an ordered array of autobridged offers by quality
* *
@@ -39,7 +42,7 @@ AutobridgeCalculator.prototype.calculate = function() {
let legOnePointer = 0; let legOnePointer = 0;
let legTwoPointer = 0; let legTwoPointer = 0;
let offersAutobridged = []; const offersAutobridged = [];
this.clearOwnerFundsLeftover(); this.clearOwnerFundsLeftover();
@@ -70,14 +73,17 @@ AutobridgeCalculator.prototype.calculate = function() {
continue; continue;
} }
if (legOneTakerGetsFunded.compareTo(legTwoTakerPaysFunded) > 0) { // using private fields for speed
if (legOneTakerGetsFunded._value.comparedTo(
legTwoTakerPaysFunded._value) > 0) {
autobridgedOffer = this.getAutobridgedOfferWithClampedLegOne( autobridgedOffer = this.getAutobridgedOfferWithClampedLegOne(
legOneOffer, legOneOffer,
legTwoOffer legTwoOffer
); );
legTwoPointer++; legTwoPointer++;
} else if (legTwoTakerPaysFunded.compareTo(legOneTakerGetsFunded) > 0) { } else if (legTwoTakerPaysFunded._value.comparedTo(
legOneTakerGetsFunded._value) > 0) {
autobridgedOffer = this.getAutobridgedOfferWithClampedLegTwo( autobridgedOffer = this.getAutobridgedOfferWithClampedLegTwo(
legOneOffer, legOneOffer,
legTwoOffer legTwoOffer
@@ -210,8 +216,6 @@ AutobridgeCalculator.prototype.clearOwnerFundsLeftover = function() {
*/ */
AutobridgeCalculator.prototype.resetOwnerFundsLeftover = function(account) { AutobridgeCalculator.prototype.resetOwnerFundsLeftover = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
this._ownerFundsLeftover[account] = Utils.normalizeAmount('0'); this._ownerFundsLeftover[account] = Utils.normalizeAmount('0');
return this._ownerFundsLeftover[account]; return this._ownerFundsLeftover[account];
@@ -226,12 +230,10 @@ AutobridgeCalculator.prototype.resetOwnerFundsLeftover = function(account) {
*/ */
AutobridgeCalculator.prototype.getLeftoverOwnerFunds = function(account) { AutobridgeCalculator.prototype.getLeftoverOwnerFunds = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
let amount = this._ownerFundsLeftover[account]; let amount = this._ownerFundsLeftover[account];
if (!amount) { if (!amount) {
amount = Utils.normalizeAmount('0'); amount = AutobridgeCalculator.NULL_AMOUNT.clone();
} }
return amount; return amount;
@@ -248,7 +250,6 @@ AutobridgeCalculator.prototype.getLeftoverOwnerFunds = function(account) {
AutobridgeCalculator.prototype.addLeftoverOwnerFunds = AutobridgeCalculator.prototype.addLeftoverOwnerFunds =
function(account, amount) { function(account, amount) {
assert(UInt160.is_valid(account), 'Account is invalid');
assert(amount instanceof Amount, 'Amount is invalid'); assert(amount instanceof Amount, 'Amount is invalid');
this._ownerFundsLeftover[account] = this.getLeftoverOwnerFunds(account) this._ownerFundsLeftover[account] = this.getLeftoverOwnerFunds(account)
@@ -266,7 +267,6 @@ function(account, amount) {
AutobridgeCalculator.prototype.setLeftoverOwnerFunds = AutobridgeCalculator.prototype.setLeftoverOwnerFunds =
function(account, amount) { function(account, amount) {
assert(UInt160.is_valid(account), 'Account is invalid');
assert(amount instanceof Amount, 'Amount is invalid'); assert(amount instanceof Amount, 'Amount is invalid');
this._ownerFundsLeftover[account] = amount; this._ownerFundsLeftover[account] = amount;
@@ -291,13 +291,13 @@ function(takerGets, takerPays) {
autobridgedOffer.TakerGets = { autobridgedOffer.TakerGets = {
value: takerGets.to_text(), value: takerGets.to_text(),
currency: this._currencyGets.to_hex(), currency: this._currencyGetsHex,
issuer: this._issuerGets issuer: this._issuerGets
}; };
autobridgedOffer.TakerPays = { autobridgedOffer.TakerPays = {
value: takerPays.to_text(), value: takerPays.to_text(),
currency: this._currencyPays.to_hex(), currency: this._currencyPaysHex,
issuer: this._issuerPays issuer: this._issuerPays
}; };
@@ -308,7 +308,8 @@ function(takerGets, takerPays) {
autobridgedOffer.autobridged = true; autobridgedOffer.autobridged = true;
autobridgedOffer.BookDirectory = Utils.convertOfferQualityToHex(quality); autobridgedOffer.BookDirectory = Utils.convertOfferQualityToHexFromText(autobridgedOffer.quality);
autobridgedOffer.qualityHex = autobridgedOffer.BookDirectory;
return autobridgedOffer; return autobridgedOffer;
}; };

View File

@@ -1,28 +1,39 @@
'use strict'; 'use strict';
function normalize(digitArray) { function normalize(digitArray) {
while (digitArray[0] === 0) { let i = 0;
digitArray.shift(); while (digitArray[i] === 0) {
++i;
}
if (i > 0) {
digitArray.splice(0, i);
} }
return digitArray; return digitArray;
} }
function divmod(digitArray, base, divisor) { function divmod(digitArray, base, divisor) {
var remainder = 0; let remainder = 0;
var quotient = []; let temp, divided;
for (var j = 0; j < digitArray.length; j++) { let j = -1;
var temp = remainder * base + parseInt(digitArray[j], 10);
quotient.push(Math.floor(temp / divisor)); const length = digitArray.length;
const quotient = new Array(length);
while (++j < length) {
temp = remainder * base + digitArray[j];
divided = temp / divisor;
quotient[j] = divided << 0;
remainder = temp % divisor; remainder = temp % divisor;
} }
return {quotient: normalize(quotient), remainder: remainder}; return {quotient: normalize(quotient), remainder: remainder};
} }
function convertBase(digitArray, fromBase, toBase) { function convertBase(digitArray, fromBase, toBase) {
var result = []; const result = [];
var dividend = digitArray; let dividend = digitArray, qr;
while (dividend.length > 0) { while (dividend.length > 0) {
var qr = divmod(dividend, fromBase, toBase); qr = divmod(dividend, fromBase, toBase);
result.unshift(qr.remainder); result.unshift(qr.remainder);
dividend = qr.quotient; dividend = qr.quotient;
} }

View File

@@ -22,7 +22,7 @@ var Currency = extend(function() {
this._update(); this._update();
}, UInt160); }, UInt160);
Currency.prototype = extend({}, UInt160.prototype); Currency.prototype = Object.create(extend({}, UInt160.prototype));
Currency.prototype.constructor = Currency; Currency.prototype.constructor = Currency;
Currency.HEX_CURRENCY_BAD = '0000000000000000000000005852500000000000'; Currency.HEX_CURRENCY_BAD = '0000000000000000000000005852500000000000';

View File

@@ -24,10 +24,6 @@ const OrderBookUtils = require('./orderbookutils');
const log = require('./log').internal.sub('orderbook'); const log = require('./log').internal.sub('orderbook');
const IOUValue = require('./iouvalue').IOUValue; const IOUValue = require('./iouvalue').IOUValue;
function assertValidNumber(number, message) {
assert(!_.isNull(number) && !isNaN(number), message);
}
/** /**
* @constructor OrderBook * @constructor OrderBook
* @param {Remote} remote * @param {Remote} remote
@@ -36,11 +32,12 @@ function assertValidNumber(number, message) {
* @param {String} bid currency * @param {String} bid currency
* @param {String} bid issuer * @param {String} bid issuer
* @param {String} orderbook key * @param {String} orderbook key
* @param {Boolean} fire 'model' event after receiving transaction
only once in 10 seconds
*/ */
function OrderBook(remote, function OrderBook(remote,
currencyGets, issuerGets, currencyPays, issuerPays, currencyGets, issuerGets, currencyPays, issuerPays, key) {
key) {
EventEmitter.call(this); EventEmitter.call(this);
const self = this; const self = this;
@@ -61,6 +58,8 @@ function OrderBook(remote,
this._ownerFundsUnadjusted = {}; this._ownerFundsUnadjusted = {};
this._ownerFunds = {}; this._ownerFunds = {};
this._ownerOffersTotal = {}; this._ownerOffersTotal = {};
this._validAccounts = {};
this._validAccountsCount = 0;
// We consider ourselves synced if we have a current // We consider ourselves synced if we have a current
// copy of the offers, we are online and subscribed to updates // copy of the offers, we are online and subscribed to updates
@@ -73,13 +72,44 @@ function OrderBook(remote,
// books that we must keep track of to compute autobridged offers // books that we must keep track of to compute autobridged offers
this._legOneBook = null; this._legOneBook = null;
this._legTwoBook = null; this._legTwoBook = null;
this._gotOffersFromLegOne = false;
this._gotOffersFromLegTwo = false;
this.sortOffers = this._currencyGets.has_interest() ?
_sortOffers.bind(this) : _sortOffersQuick;
this.notifyDirectOffersChanged =
_.debounce(
this.notifyDirectOffersChangedInternal,
OrderBook.NOTIFY_TIMEOUT,
{maxWait: OrderBook.NOTIFY_MAXWAIT});
this._isAutobridgeable = !this._currencyGets.is_native() this._isAutobridgeable = !this._currencyGets.is_native()
&& !this._currencyPays.is_native(); && !this._currencyPays.is_native();
function computeAutobridgedOffersWrapper() { this._autobridgeThrottleTimeMultiplier = 1;
self.computeAutobridgedOffers(); this.createDebouncedOffersWrapper();
self.mergeDirectAndAutobridgedBooks();
function computeAutobridgedOffersWrapperOne() {
self._gotOffersFromLegOne = true;
self.computeAutobridgedOffersThrottled();
}
function computeAutobridgedOffersWrapperTwo() {
self._gotOffersFromLegTwo = true;
self.computeAutobridgedOffersThrottled();
}
function onDisconnect() {
self.resetCache();
self._gotOffersFromLegOne = false;
self._gotOffersFromLegTwo = false;
if (!self._destroyed) {
self._remote.once('disconnect', onDisconnect);
self._remote.once('connect', function() {
self.subscribe();
});
}
} }
if (this._isAutobridgeable) { if (this._isAutobridgeable) {
@@ -89,15 +119,15 @@ function OrderBook(remote,
issuer_pays: issuerPays issuer_pays: issuerPays
}); });
this._legOneBook.on('model', computeAutobridgedOffersWrapper);
this._legTwoBook = remote.createOrderBook({ this._legTwoBook = remote.createOrderBook({
currency_gets: currencyGets, currency_gets: currencyGets,
issuer_gets: issuerGets, issuer_gets: issuerGets,
currency_pays: 'XRP' currency_pays: 'XRP'
}); });
}
this._legTwoBook.on('model', computeAutobridgedOffersWrapper); function updateFundedAmountsWrapper(transaction) {
self.updateFundedAmounts(transaction);
} }
function listenersModified(action, event) { function listenersModified(action, event) {
@@ -107,7 +137,16 @@ function OrderBook(remote,
switch (action) { switch (action) {
case 'add': case 'add':
if (++self._listeners === 1) { if (++self._listeners === 1) {
self._shouldSubscribe = true;
self.subscribe(); self.subscribe();
self._remote.on('transaction', updateFundedAmountsWrapper);
self._remote.once('disconnect', onDisconnect);
if (self._isAutobridgeable) {
self._legOneBook.on('model', computeAutobridgedOffersWrapperOne);
self._legTwoBook.on('model', computeAutobridgedOffersWrapperTwo);
}
} }
break; break;
case 'remove': case 'remove':
@@ -119,10 +158,6 @@ function OrderBook(remote,
} }
} }
function updateFundedAmountsWrapper(transaction) {
self.updateFundedAmounts(transaction);
}
this.on('newListener', function(event) { this.on('newListener', function(event) {
listenersModified('add', event); listenersModified('add', event);
}); });
@@ -131,23 +166,21 @@ function OrderBook(remote,
listenersModified('remove', event); listenersModified('remove', event);
}); });
this._remote.on('transaction', updateFundedAmountsWrapper);
this.on('unsubscribe', function() { this.on('unsubscribe', function() {
self.resetCache(); self.resetCache();
self._remote.removeListener('transaction', updateFundedAmountsWrapper); self._remote.removeListener('transaction', updateFundedAmountsWrapper);
}); self._remote.removeListener('disconnect', onDisconnect);
this._remote.once('prepare_subscribe', function() { self._gotOffersFromLegOne = false;
self.subscribe(); self._gotOffersFromLegTwo = false;
});
this._remote.on('disconnect', function() { if (self._isAutobridgeable) {
self.resetCache(); self._legOneBook.removeListener('model',
self._remote.once('prepare_subscribe', function() { computeAutobridgedOffersWrapperOne);
self.subscribe(); self._legTwoBook.removeListener('model',
}); computeAutobridgedOffersWrapperTwo);
}
}); });
return this; return this;
@@ -165,7 +198,21 @@ OrderBook.EVENTS = [
'offer_changed', 'offer_funds_changed' 'offer_changed', 'offer_funds_changed'
]; ];
OrderBook.DEFAULT_TRANSFER_RATE = 1000000000; OrderBook.DEFAULT_TRANSFER_RATE = Amount.from_json(1000000000);
OrderBook.NOTIFY_TIMEOUT = 100;
OrderBook.NOTIFY_MAXWAIT = 250;
OrderBook.AUTOBRIDGE_CALCULATE_THROTTLE_TIME = 1000;
OrderBook.AUTOBRIDGE_CALCULATE_DEBOUNCE_TIME = 250;
OrderBook.AUTOBRIDGE_CALCULATE_DEBOUNCE_MAXWAIT = 500;
OrderBook.ZERO_NATIVE_AMOUNT = Amount.from_json('0');
OrderBook.ZERO_NORMALIZED_AMOUNT = OrderBookUtils.normalizeAmount('0');
/** /**
* Normalize offers from book_offers and transaction stream * Normalize offers from book_offers and transaction stream
@@ -192,18 +239,20 @@ OrderBook.offerRewrite = function(offer) {
result.Flags = result.Flags || 0; result.Flags = result.Flags || 0;
result.OwnerNode = result.OwnerNode || new Array(16 + 1).join('0'); result.OwnerNode = result.OwnerNode || new Array(16 + 1).join('0');
result.BookNode = result.BookNode || new Array(16 + 1).join('0'); result.BookNode = result.BookNode || new Array(16 + 1).join('0');
result.qualityHex = result.BookDirectory.slice(-16);
return result; return result;
}; };
/** /**
* Initialize orderbook. Get orderbook offers and subscribe to transactions * Initialize orderbook. Get orderbook offers and subscribe to transactions
* @api private
*/ */
OrderBook.prototype.subscribe = function() { OrderBook.prototype.subscribe = function() {
const self = this; const self = this;
if (!this._shouldSubscribe) { if (!this._shouldSubscribe || this._destroyed) {
return; return;
} }
@@ -216,7 +265,7 @@ OrderBook.prototype.subscribe = function() {
self.requestTransferRate(callback); self.requestTransferRate(callback);
}, },
function(callback) { function(callback) {
self.requestOffers(callback); self.requestOffers(callback, true);
}, },
function(callback) { function(callback) {
self.subscribeTransactions(callback); self.subscribeTransactions(callback);
@@ -229,6 +278,7 @@ OrderBook.prototype.subscribe = function() {
/** /**
* Unhook event listeners and prevent ripple-lib from further work on this * Unhook event listeners and prevent ripple-lib from further work on this
* orderbook. There is no more orderbook stream, so "unsubscribe" is nominal * orderbook. There is no more orderbook stream, so "unsubscribe" is nominal
* @api private
*/ */
OrderBook.prototype.unsubscribe = function() { OrderBook.prototype.unsubscribe = function() {
@@ -250,33 +300,75 @@ OrderBook.prototype.unsubscribe = function() {
this.emit('unsubscribe'); this.emit('unsubscribe');
}; };
/**
* After that you can't use this object.
*/
OrderBook.prototype.destroy = function() {
this._destroyed = true;
if (this._subscribed) {
this.unsubscribe();
}
if (this._remote._books.hasOwnProperty(this._key)) {
delete this._remote._books[this._key];
}
if (this._isAutobridgeable) {
this._legOneBook.destroy();
this._legTwoBook.destroy();
}
};
/** /**
* Request orderbook entries from server * Request orderbook entries from server
* *
* @param {Function} callback * @param {Function} callback
*/ */
OrderBook.prototype.requestOffers = function(callback=function() {}) { OrderBook.prototype.requestOffers = function(callback = function() {},
internal = false) {
const self = this; const self = this;
if (!this._remote.isConnected()) {
// do not make request if not online.
// that requests will be queued and
// eventually all of them will fire back
return undefined;
}
if (!this._shouldSubscribe) { if (!this._shouldSubscribe) {
return callback(new Error('Should not request offers')); callback(new Error('Should not request offers'));
return undefined;
} }
if (this._remote.trace) { if (this._remote.trace) {
log.info('requesting offers', this._key); log.info('requesting offers', this._key);
} }
if (this._isAutobridgeable && !internal) {
this._gotOffersFromLegOne = false;
this._gotOffersFromLegTwo = false;
this._legOneBook.requestOffers();
this._legTwoBook.requestOffers();
}
function handleOffers(res) { function handleOffers(res) {
if (self._destroyed) {
return;
}
if (!Array.isArray(res.offers)) { if (!Array.isArray(res.offers)) {
// XXX What now? // XXX What now?
return callback(new Error('Invalid response')); callback(new Error('Invalid response'));
return;
} }
if (self._remote.trace) { if (self._remote.trace) {
log.info('requested offers', self._key, 'offers: ' + res.offers.length); log.info('requested offers', self._key, 'offers: ' + res.offers.length);
} }
self.setOffers(res.offers); self.setOffers(res.offers);
self.notifyDirectOffersChanged(); self.notifyDirectOffersChanged();
@@ -331,8 +423,9 @@ OrderBook.prototype.requestTransferRate = function(callback) {
// When transfer rate is not explicitly set on account, it implies the // When transfer rate is not explicitly set on account, it implies the
// default transfer rate // default transfer rate
self._issuerTransferRate = info.account_data.TransferRate || self._issuerTransferRate =
OrderBook.DEFAULT_TRANSFER_RATE; Amount.from_json(info.account_data.TransferRate ||
OrderBook.DEFAULT_TRANSFER_RATE);
callback(null, self._issuerTransferRate); callback(null, self._issuerTransferRate);
} }
@@ -392,7 +485,7 @@ OrderBook.prototype.subscribeTransactions = function(callback) {
* books, an additional merge step is also performed * books, an additional merge step is also performed
*/ */
OrderBook.prototype.notifyDirectOffersChanged = function() { OrderBook.prototype.notifyDirectOffersChangedInternal = function() {
if (this._isAutobridgeable) { if (this._isAutobridgeable) {
this.mergeDirectAndAutobridgedBooks(); this.mergeDirectAndAutobridgedBooks();
} else { } else {
@@ -409,6 +502,12 @@ OrderBook.prototype.resetCache = function() {
this._ownerOffersTotal = {}; this._ownerOffersTotal = {};
this._offerCounts = {}; this._offerCounts = {};
this._synced = false; this._synced = false;
this._offers = [];
if (this._validAccountsCount > 3000) {
this._validAccounts = {};
this._validAccountsCount = 0;
}
}; };
/** /**
@@ -418,7 +517,6 @@ OrderBook.prototype.resetCache = function() {
*/ */
OrderBook.prototype.hasOwnerFunds = function(account) { OrderBook.prototype.hasOwnerFunds = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
return this._ownerFunds[account] !== undefined; return this._ownerFunds[account] !== undefined;
}; };
@@ -430,7 +528,6 @@ OrderBook.prototype.hasOwnerFunds = function(account) {
*/ */
OrderBook.prototype.setOwnerFunds = function(account, fundedAmount) { OrderBook.prototype.setOwnerFunds = function(account, fundedAmount) {
assert(UInt160.is_valid(account), 'Account is invalid');
assert(!isNaN(fundedAmount), 'Funded amount is invalid'); assert(!isNaN(fundedAmount), 'Funded amount is invalid');
this._ownerFundsUnadjusted[account] = fundedAmount; this._ownerFundsUnadjusted[account] = fundedAmount;
@@ -447,11 +544,16 @@ OrderBook.prototype.setOwnerFunds = function(account, fundedAmount) {
OrderBook.prototype.applyTransferRate = function(balance) { OrderBook.prototype.applyTransferRate = function(balance) {
assert(!isNaN(balance), 'Balance is invalid'); assert(!isNaN(balance), 'Balance is invalid');
assertValidNumber(this._issuerTransferRate, 'Transfer rate is invalid'); assert(this._issuerTransferRate.is_valid(), 'Transfer rate is invalid');
const adjustedBalance = (new IOUValue(balance)) const adjustedBalance = (new IOUValue(balance))
.divide(new IOUValue(this._issuerTransferRate)) .divide(new IOUValue(this._issuerTransferRate))
.multiply(new IOUValue(OrderBook.DEFAULT_TRANSFER_RATE)).toString(); .multiply(new IOUValue(OrderBook.DEFAULT_TRANSFER_RATE)).toString();
const adjustedBalance = OrderBookUtils.normalizeAmount(balance)
.divide(this._issuerTransferRate)
.multiply(OrderBook.DEFAULT_TRANSFER_RATE)
.to_json()
.value;
return adjustedBalance; return adjustedBalance;
}; };
@@ -464,7 +566,6 @@ OrderBook.prototype.applyTransferRate = function(balance) {
*/ */
OrderBook.prototype.getOwnerFunds = function(account) { OrderBook.prototype.getOwnerFunds = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
if (this.hasOwnerFunds(account)) { if (this.hasOwnerFunds(account)) {
if (this._currencyGets.is_native()) { if (this._currencyGets.is_native()) {
return Amount.from_json(this._ownerFunds[account]); return Amount.from_json(this._ownerFunds[account]);
@@ -481,7 +582,6 @@ OrderBook.prototype.getOwnerFunds = function(account) {
*/ */
OrderBook.prototype.getUnadjustedOwnerFunds = function(account) { OrderBook.prototype.getUnadjustedOwnerFunds = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
return this._ownerFundsUnadjusted[account]; return this._ownerFundsUnadjusted[account];
}; };
@@ -492,7 +592,6 @@ OrderBook.prototype.getUnadjustedOwnerFunds = function(account) {
*/ */
OrderBook.prototype.deleteOwnerFunds = function(account) { OrderBook.prototype.deleteOwnerFunds = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
this._ownerFunds[account] = undefined; this._ownerFunds[account] = undefined;
}; };
@@ -504,7 +603,6 @@ OrderBook.prototype.deleteOwnerFunds = function(account) {
*/ */
OrderBook.prototype.getOwnerOfferCount = function(account) { OrderBook.prototype.getOwnerOfferCount = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
return this._offerCounts[account] || 0; return this._offerCounts[account] || 0;
}; };
@@ -516,7 +614,6 @@ OrderBook.prototype.getOwnerOfferCount = function(account) {
*/ */
OrderBook.prototype.incrementOwnerOfferCount = function(account) { OrderBook.prototype.incrementOwnerOfferCount = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
const result = (this._offerCounts[account] || 0) + 1; const result = (this._offerCounts[account] || 0) + 1;
this._offerCounts[account] = result; this._offerCounts[account] = result;
return result; return result;
@@ -531,7 +628,6 @@ OrderBook.prototype.incrementOwnerOfferCount = function(account) {
*/ */
OrderBook.prototype.decrementOwnerOfferCount = function(account) { OrderBook.prototype.decrementOwnerOfferCount = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
const result = (this._offerCounts[account] || 1) - 1; const result = (this._offerCounts[account] || 1) - 1;
this._offerCounts[account] = result; this._offerCounts[account] = result;
@@ -552,8 +648,6 @@ OrderBook.prototype.decrementOwnerOfferCount = function(account) {
*/ */
OrderBook.prototype.addOwnerOfferTotal = function(account, amount) { OrderBook.prototype.addOwnerOfferTotal = function(account, amount) {
assert(UInt160.is_valid(account), 'Account is invalid');
const previousAmount = this.getOwnerOfferTotal(account); const previousAmount = this.getOwnerOfferTotal(account);
const currentAmount = previousAmount.add(Amount.from_json(amount)); const currentAmount = previousAmount.add(Amount.from_json(amount));
@@ -572,14 +666,12 @@ OrderBook.prototype.addOwnerOfferTotal = function(account, amount) {
*/ */
OrderBook.prototype.subtractOwnerOfferTotal = function(account, amount) { OrderBook.prototype.subtractOwnerOfferTotal = function(account, amount) {
assert(UInt160.is_valid(account), 'Account is invalid');
const previousAmount = this.getOwnerOfferTotal(account); const previousAmount = this.getOwnerOfferTotal(account);
const newAmount = previousAmount.subtract(Amount.from_json(amount)); const newAmount = previousAmount.subtract(Amount.from_json(amount));
this._ownerOffersTotal[account] = newAmount; this._ownerOffersTotal[account] = newAmount;
assert(!newAmount.is_negative(), 'Offer total cannot be negative'); assert(!newAmount.is_negative(), 'Offer total cannot be negative');
return newAmount; return newAmount;
}; };
@@ -591,15 +683,14 @@ OrderBook.prototype.subtractOwnerOfferTotal = function(account, amount) {
*/ */
OrderBook.prototype.getOwnerOfferTotal = function(account) { OrderBook.prototype.getOwnerOfferTotal = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
const amount = this._ownerOffersTotal[account]; const amount = this._ownerOffersTotal[account];
if (amount) { if (amount) {
return amount; return amount;
} }
if (this._currencyGets.is_native()) { if (this._currencyGets.is_native()) {
return Amount.from_json('0'); return OrderBook.ZERO_NATIVE_AMOUNT.clone();
} }
return OrderBookUtils.normalizeAmount('0'); return OrderBook.ZERO_NORMALIZED_AMOUNT.clone();
}; };
/** /**
@@ -610,11 +701,10 @@ OrderBook.prototype.getOwnerOfferTotal = function(account) {
*/ */
OrderBook.prototype.resetOwnerOfferTotal = function(account) { OrderBook.prototype.resetOwnerOfferTotal = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid');
if (this._currencyGets.is_native()) { if (this._currencyGets.is_native()) {
this._ownerOffersTotal[account] = Amount.from_json('0'); this._ownerOffersTotal[account] = OrderBook.ZERO_NATIVE_AMOUNT.clone();
} else { } else {
this._ownerOffersTotal[account] = OrderBookUtils.normalizeAmount('0'); this._ownerOffersTotal[account] = OrderBook.ZERO_NORMALIZED_AMOUNT.clone();
} }
}; };
@@ -632,17 +722,18 @@ OrderBook.prototype.resetOwnerOfferTotal = function(account) {
OrderBook.prototype.setOfferFundedAmount = function(offer) { OrderBook.prototype.setOfferFundedAmount = function(offer) {
assert.strictEqual(typeof offer, 'object', 'Offer is invalid'); assert.strictEqual(typeof offer, 'object', 'Offer is invalid');
const takerGets = Amount.from_json(offer.TakerGets);
const fundedAmount = this.getOwnerFunds(offer.Account); const fundedAmount = this.getOwnerFunds(offer.Account);
const previousOfferSum = this.getOwnerOfferTotal(offer.Account); const previousOfferSum = this.getOwnerOfferTotal(offer.Account);
const currentOfferSum = previousOfferSum.add( const currentOfferSum = previousOfferSum.add(takerGets);
Amount.from_json(offer.TakerGets));
offer.owner_funds = this.getUnadjustedOwnerFunds(offer.Account); offer.owner_funds = this.getUnadjustedOwnerFunds(offer.Account);
offer.is_fully_funded = fundedAmount.compareTo(currentOfferSum) >= 0; offer.is_fully_funded = fundedAmount.is_comparable(currentOfferSum) &&
fundedAmount.compareTo(currentOfferSum) >= 0;
if (offer.is_fully_funded) { if (offer.is_fully_funded) {
offer.taker_gets_funded = Amount.from_json(offer.TakerGets).to_text(); offer.taker_gets_funded = takerGets.to_text();
offer.taker_pays_funded = Amount.from_json(offer.TakerPays).to_text(); offer.taker_pays_funded = Amount.from_json(offer.TakerPays).to_text();
} else if (previousOfferSum.compareTo(fundedAmount) < 0) { } else if (previousOfferSum.compareTo(fundedAmount) < 0) {
offer.taker_gets_funded = fundedAmount.subtract(previousOfferSum).to_text(); offer.taker_gets_funded = fundedAmount.subtract(previousOfferSum).to_text();
@@ -698,7 +789,11 @@ OrderBook.prototype.parseAccountBalanceFromNode = function(node) {
} }
assert(!isNaN(result.balance), 'node has an invalid balance'); assert(!isNaN(result.balance), 'node has an invalid balance');
assert(UInt160.is_valid(result.account), 'node has an invalid account'); if (this._validAccounts[result.Account] === undefined) {
assert(UInt160.is_valid(result.account), 'node has an invalid account');
this._validAccounts[result.Account] = true;
this._validAccountsCount++;
}
return result; return result;
}; };
@@ -786,6 +881,7 @@ OrderBook.prototype.updateFundedAmounts = function(transaction) {
}); });
}; };
/** /**
* Update offers' funded amount with their owner's funds * Update offers' funded amount with their owner's funds
* *
@@ -793,10 +889,15 @@ OrderBook.prototype.updateFundedAmounts = function(transaction) {
*/ */
OrderBook.prototype.updateOwnerOffersFundedAmount = function(account) { OrderBook.prototype.updateOwnerOffersFundedAmount = function(account) {
assert(UInt160.is_valid(account), 'Account is invalid'); // assert(UInt160.is_valid(account), 'Account is invalid');
const self = this; const self = this;
if (!this.hasOwnerFunds(account)) {
// We are only updating owner funds that are already cached
return;
}
if (this._remote.trace) { if (this._remote.trace) {
const ownerFunds = this.getOwnerFunds(account); const ownerFunds = this.getOwnerFunds(account);
log.info('updating offer funds', this._key, account, log.info('updating offer funds', this._key, account,
@@ -848,7 +949,7 @@ OrderBook.prototype.updateOwnerOffersFundedAmount = function(account) {
OrderBook.prototype.notify = function(transaction) { OrderBook.prototype.notify = function(transaction) {
const self = this; const self = this;
if (!(this._subscribed && this._synced)) { if (!(this._subscribed && this._synced) || this._destroyed) {
return; return;
} }
@@ -884,6 +985,12 @@ OrderBook.prototype.notify = function(transaction) {
function handleNode(node) { function handleNode(node) {
switch (node.nodeType) { switch (node.nodeType) {
case 'DeletedNode': case 'DeletedNode':
if (self._validAccounts[node.fields.Account] === undefined) {
assert(UInt160.is_valid(node.fields.Account),
'node has an invalid account');
self._validAccounts[node.fields.Account] = true;
self._validAccountsCount++;
}
self.deleteOffer(node, isOfferCancel); self.deleteOffer(node, isOfferCancel);
// We don't want to count an OfferCancel as a trade // We don't want to count an OfferCancel as a trade
@@ -894,6 +1001,12 @@ OrderBook.prototype.notify = function(transaction) {
break; break;
case 'ModifiedNode': case 'ModifiedNode':
if (self._validAccounts[node.fields.Account] === undefined) {
assert(UInt160.is_valid(node.fields.Account),
'node has an invalid account');
self._validAccounts[node.fields.Account] = true;
self._validAccountsCount++;
}
self.modifyOffer(node); self.modifyOffer(node);
takerGetsTotal = takerGetsTotal takerGetsTotal = takerGetsTotal
@@ -906,6 +1019,12 @@ OrderBook.prototype.notify = function(transaction) {
break; break;
case 'CreatedNode': case 'CreatedNode':
if (self._validAccounts[node.fields.Account] === undefined) {
assert(UInt160.is_valid(node.fields.Account),
'node has an invalid account');
self._validAccounts[node.fields.Account] = true;
self._validAccountsCount++;
}
// rippled does not set owner_funds if the order maker is the issuer // rippled does not set owner_funds if the order maker is the issuer
// because the value would be infinite // because the value would be infinite
const fundedAmount = transactionOwnerFunds !== undefined ? const fundedAmount = transactionOwnerFunds !== undefined ?
@@ -919,7 +1038,9 @@ OrderBook.prototype.notify = function(transaction) {
_.each(affectedNodes, handleNode); _.each(affectedNodes, handleNode);
this.emit('transaction', transaction); this.emit('transaction', transaction);
this.notifyDirectOffersChanged(); this.notifyDirectOffersChanged();
if (!takerGetsTotal.is_zero()) { if (!takerGetsTotal.is_zero()) {
this.emit('trade', takerPaysTotal, takerGetsTotal); this.emit('trade', takerPaysTotal, takerGetsTotal);
} }
@@ -951,17 +1072,27 @@ OrderBook.prototype.insertOffer = function(node) {
const originalLength = this._offers.length; const originalLength = this._offers.length;
for (let i = 0; i < originalLength; i++) { if (!this._currencyGets.has_interest()) {
const quality = OrderBookUtils.getOfferQuality(offer, this._currencyGets); // use fast path
const existingOfferQuality = OrderBookUtils.getOfferQuality( for (let i = 0; i < originalLength; i++) {
this._offers[i], if (offer.qualityHex <= this._offers[i].qualityHex) {
this._currencyGets this._offers.splice(i, 0, offer);
); break;
}
}
} else {
for (let i = 0; i < originalLength; i++) {
const quality = OrderBookUtils.getOfferQuality(offer, this._currencyGets);
const existingOfferQuality = OrderBookUtils.getOfferQuality(
this._offers[i],
this._currencyGets
);
if (quality.compareTo(existingOfferQuality) <= 0) { if (quality.compareTo(existingOfferQuality) <= 0) {
this._offers.splice(i, 0, offer); this._offers.splice(i, 0, offer);
break; break;
}
} }
} }
@@ -1067,28 +1198,33 @@ OrderBook.prototype.deleteOffer = function(node, isOfferCancel) {
OrderBook.prototype.setOffers = function(offers) { OrderBook.prototype.setOffers = function(offers) {
assert(Array.isArray(offers), 'Offers is not an array'); assert(Array.isArray(offers), 'Offers is not an array');
const self = this;
this.resetCache(); this.resetCache();
const newOffers = _.map(offers, function(rawOffer) { let i = -1, offer;
const offer = OrderBook.offerRewrite(rawOffer); const l = offers.length;
if (offer.hasOwnProperty('owner_funds')) { while (++i < l) {
offer = OrderBook.offerRewrite(offers[i]);
if (this._validAccounts[offer.Account] === undefined) {
assert(UInt160.is_valid(offer.Account), 'Account is invalid');
this._validAccounts[offer.Account] = true;
this._validAccountsCount++;
}
if (offer.owner_funds !== undefined) {
// The first offer of each owner from book_offers contains owner balance // The first offer of each owner from book_offers contains owner balance
// of offer's output // of offer's output
self.setOwnerFunds(offer.Account, offer.owner_funds); this.setOwnerFunds(offer.Account, offer.owner_funds);
} }
self.incrementOwnerOfferCount(offer.Account); this.incrementOwnerOfferCount(offer.Account);
self.setOfferFundedAmount(offer); this.setOfferFundedAmount(offer);
self.addOwnerOfferTotal(offer.Account, offer.TakerGets); this.addOwnerOfferTotal(offer.Account, offer.TakerGets);
offers[i] = offer;
}
return offer; this._offers = offers;
});
this._offers = newOffers;
this._synced = true; this._synced = true;
}; };
@@ -1191,6 +1327,14 @@ OrderBook.prototype.computeAutobridgedOffers = function() {
assert(!this._currencyGets.is_native() && !this._currencyPays.is_native(), assert(!this._currencyGets.is_native() && !this._currencyPays.is_native(),
'Autobridging is only for IOU:IOU orderbooks'); 'Autobridging is only for IOU:IOU orderbooks');
if (this._destroyed) {
return;
}
if (!this._gotOffersFromLegOne || !this._gotOffersFromLegTwo) {
return;
}
const autobridgeCalculator = new AutobridgeCalculator( const autobridgeCalculator = new AutobridgeCalculator(
this._currencyGets, this._currencyGets,
this._currencyPays, this._currencyPays,
@@ -1203,6 +1347,44 @@ OrderBook.prototype.computeAutobridgedOffers = function() {
this._offersAutobridged = autobridgeCalculator.calculate(); this._offersAutobridged = autobridgeCalculator.calculate();
}; };
OrderBook.prototype.computeAutobridgedOffersWrapper = function() {
var startTime = Date.now();
this.computeAutobridgedOffers();
this.mergeDirectAndAutobridgedBooks();
var lasted = (Date.now() - startTime);
const newMult =
((lasted * 2 / OrderBook.AUTOBRIDGE_CALCULATE_THROTTLE_TIME) << 0) + 1;
if (newMult !== this._autobridgeThrottleTimeMultiplier) {
this._autobridgeThrottleTimeMultiplier = newMult;
this.createDebouncedOffersWrapper();
}
}
OrderBook.prototype.createDebouncedOffersWrapper = function() {
const m = this._autobridgeThrottleTimeMultiplier;
this.computeAutobridgedOffersThrottled =
_.debounce(
_.throttle(
this.computeAutobridgedOffersWrapper,
OrderBook.AUTOBRIDGE_CALCULATE_THROTTLE_TIME * m,
{leading: true, trailing: true}),
OrderBook.AUTOBRIDGE_CALCULATE_DEBOUNCE_TIME,
{maxWait: OrderBook.AUTOBRIDGE_CALCULATE_DEBOUNCE_MAXWAIT});
}
function _sortOffers(a, b) {
const aQuality = OrderBookUtils.getOfferQuality(a, this._currencyGets);
const bQuality = OrderBookUtils.getOfferQuality(b, this._currencyGets);
return aQuality._value.comparedTo(bQuality._value);
}
function _sortOffersQuick(a, b) {
return a.qualityHex.localeCompare(b.qualityHex);
}
/** /**
* Merge direct and autobridged offers into a combined orderbook * Merge direct and autobridged offers into a combined orderbook
* *
@@ -1210,22 +1392,24 @@ OrderBook.prototype.computeAutobridgedOffers = function() {
*/ */
OrderBook.prototype.mergeDirectAndAutobridgedBooks = function() { OrderBook.prototype.mergeDirectAndAutobridgedBooks = function() {
const self = this;
if (this._destroyed) {
return;
}
if (_.isEmpty(this._offers) && _.isEmpty(this._offersAutobridged)) { if (_.isEmpty(this._offers) && _.isEmpty(this._offersAutobridged)) {
// still emit empty offers list to indicate that load is completed if (this._synced && this._gotOffersFromLegOne &&
this.emit('model', []); this._gotOffersFromLegTwo) {
// emit empty model to indicate to listeners that we've got offers,
// just there was no one
this.emit('model', []);
}
return; return;
} }
this._mergedOffers = this._offers this._mergedOffers = this._offers
.concat(this._offersAutobridged) .concat(this._offersAutobridged)
.sort(function(a, b) { .sort(this.sortOffers);
const aQuality = OrderBookUtils.getOfferQuality(a, self._currencyGets);
const bQuality = OrderBookUtils.getOfferQuality(b, self._currencyGets);
return aQuality.compareTo(bQuality);
});
this.emit('model', this._mergedOffers); this.emit('model', this._mergedOffers);
}; };

View File

@@ -19,7 +19,7 @@ const Seed = extend(function() {
}, UInt); }, UInt);
Seed.width = 16; Seed.width = 16;
Seed.prototype = extend({}, UInt.prototype); Seed.prototype = Object.create(extend({}, UInt.prototype));
Seed.prototype.constructor = Seed; Seed.prototype.constructor = Seed;
// value = NaN on error. // value = NaN on error.

View File

@@ -13,7 +13,7 @@ var UInt128 = extend(function() {
}, UInt); }, UInt);
UInt128.width = 16; UInt128.width = 16;
UInt128.prototype = extend({}, UInt.prototype); UInt128.prototype = Object.create(extend({}, UInt.prototype));
UInt128.prototype.constructor = UInt128; UInt128.prototype.constructor = UInt128;
var HEX_ZERO = UInt128.HEX_ZERO = '00000000000000000000000000000000'; var HEX_ZERO = UInt128.HEX_ZERO = '00000000000000000000000000000000';

View File

@@ -17,7 +17,7 @@ var UInt160 = extend(function() {
}, UInt); }, UInt);
UInt160.width = 20; UInt160.width = 20;
UInt160.prototype = extend({}, UInt.prototype); UInt160.prototype = Object.create(extend({}, UInt.prototype));
UInt160.prototype.constructor = UInt160; UInt160.prototype.constructor = UInt160;
var HEX_ZERO = UInt160.HEX_ZERO = '0000000000000000000000000000000000000000'; var HEX_ZERO = UInt160.HEX_ZERO = '0000000000000000000000000000000000000000';

View File

@@ -13,7 +13,7 @@ var UInt256 = extend(function() {
}, UInt); }, UInt);
UInt256.width = 32; UInt256.width = 32;
UInt256.prototype = extend({}, UInt.prototype); UInt256.prototype = Object.create(extend({}, UInt.prototype));
UInt256.prototype.constructor = UInt256; UInt256.prototype.constructor = UInt256;
var HEX_ZERO = UInt256.HEX_ZERO = '00000000000000000000000000000000' + var HEX_ZERO = UInt256.HEX_ZERO = '00000000000000000000000000000000' +

View File

@@ -5,6 +5,9 @@
const _ = require('lodash'); const _ = require('lodash');
const addresses = require('./addresses'); const addresses = require('./addresses');
const Meta = require('ripple-lib').Meta; const Meta = require('ripple-lib').Meta;
const Amount = require('ripple-lib').Amount;
const SerializedObject = require('ripple-lib').SerializedObject;
const Types = require('ripple-lib').types;
module.exports.FIAT_BALANCE = '10'; module.exports.FIAT_BALANCE = '10';
module.exports.NATIVE_BALANCE = '55'; module.exports.NATIVE_BALANCE = '55';
@@ -809,6 +812,8 @@ module.exports.transactionWithInvalidAccountRoot = function(options) {
}; };
}; };
const IOU_SUFFIX = '/000/rrrrrrrrrrrrrrrrrrrrrhoLvTp';
module.exports.transactionWithCreatedOffer = function(options) { module.exports.transactionWithCreatedOffer = function(options) {
options = options || {}; options = options || {};
_.defaults(options, { _.defaults(options, {
@@ -816,7 +821,16 @@ module.exports.transactionWithCreatedOffer = function(options) {
amount: '1.9951' amount: '1.9951'
}); });
const meta = new Meta({ const takerGets = Amount.from_json(options.amount + IOU_SUFFIX);
const takerPays = Amount.from_json(module.exports.TAKER_PAYS + IOU_SUFFIX);
const quality = takerPays.divide(takerGets);
const so = new SerializedObject();
Types.Quality.serialize(so, quality);
const BookDirectory = so.to_hex();
var meta = new Meta({
AffectedNodes: [ AffectedNodes: [
{ {
CreatedNode: { CreatedNode: {
@@ -824,7 +838,7 @@ module.exports.transactionWithCreatedOffer = function(options) {
LedgerIndex: 'AF3C702057C9C47DB9E809FD8C76CD22521012C5CC7AE95D914EC9E226F1D7E5', LedgerIndex: 'AF3C702057C9C47DB9E809FD8C76CD22521012C5CC7AE95D914EC9E226F1D7E5',
NewFields: { NewFields: {
Account: options.account, Account: options.account,
BookDirectory: '7B73A610A009249B0CC0D4311E8BA7927B5A34D86634581C5F211CEE1E0697A0', BookDirectory: BookDirectory,
Flags: 131072, Flags: 131072,
Sequence: 1404, Sequence: 1404,
TakerGets: { TakerGets: {

View File

@@ -1,19 +1,30 @@
/*eslint-disable max-len */ /* eslint-disable max-len */
'use strict'; 'use strict';
var _ = require('lodash'); const _ = require('lodash');
var assert = require('assert-diff'); const assert = require('assert-diff');
var Remote = require('ripple-lib').Remote; const Remote = require('ripple-lib').Remote;
var Currency = require('ripple-lib').Currency; const Currency = require('ripple-lib').Currency;
var addresses = require('./fixtures/addresses'); const Amount = require('ripple-lib').Amount;
var fixtures = require('./fixtures/orderbook'); const addresses = require('./fixtures/addresses');
const fixtures = require('./fixtures/orderbook');
describe('OrderBook Autobridging', function() { describe('OrderBook Autobridging', function() {
this.timeout(0); this.timeout(0);
function createRemote() {
const remote = new Remote();
remote.isConnected = function() {
return true;
};
return remote;
}
it('Initialize IOU/IOU', function() { it('Initialize IOU/IOU', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
@@ -27,23 +38,24 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers', function() { it('Compute autobridged offers', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1));
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 1); assert.strictEqual(book._offersAutobridged.length, 1);
@@ -58,25 +70,26 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - leg one partially funded', function() { it('Compute autobridged offers - leg one partially funded', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1));
legOneOffers[0].owner_funds = '2105863129'; legOneOffers[0].owner_funds = '2105863129';
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 1); assert.strictEqual(book._offersAutobridged.length, 1);
@@ -88,25 +101,26 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - leg two partially funded', function() { it('Compute autobridged offers - leg two partially funded', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1));
legTwoOffers[0].owner_funds = '10'; legTwoOffers[0].owner_funds = '10';
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 1); assert.strictEqual(book._offersAutobridged.length, 1);
@@ -118,25 +132,26 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - leg two transfer rate', function() { it('Compute autobridged offers - leg two transfer rate', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1002000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1002000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1));
legTwoOffers[0].owner_funds = '10'; legTwoOffers[0].owner_funds = '10';
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '9.980039920159681'); assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '9.980039920159681');
@@ -146,19 +161,19 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - taker funds < leg two in', function() { it('Compute autobridged offers - taker funds < leg two in', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1));
legOneOffers[0].owner_funds = '33461561812'; legOneOffers[0].owner_funds = '33461561812';
@@ -169,6 +184,7 @@ describe('OrderBook Autobridging', function() {
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 1); assert.strictEqual(book._offersAutobridged.length, 1);
@@ -180,19 +196,19 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - leg one partially funded - owners equal', function() { it('Compute autobridged offers - leg one partially funded - owners equal', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1));
legOneOffers[0].owner_funds = '2105863129'; legOneOffers[0].owner_funds = '2105863129';
@@ -201,6 +217,7 @@ describe('OrderBook Autobridging', function() {
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 1); assert.strictEqual(book._offersAutobridged.length, 1);
@@ -212,19 +229,19 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - leg one partially funded - owners equal - leg two in > leg one out', function() { it('Compute autobridged offers - leg one partially funded - owners equal - leg two in > leg one out', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1));
legOneOffers[0].owner_funds = '2105863129'; legOneOffers[0].owner_funds = '2105863129';
@@ -236,6 +253,7 @@ describe('OrderBook Autobridging', function() {
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 1); assert.strictEqual(book._offersAutobridged.length, 1);
@@ -247,23 +265,24 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - leg one consumes leg two fully', function() { it('Compute autobridged offers - leg one consumes leg two fully', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 2)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 2));
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 2); assert.strictEqual(book._offersAutobridged.length, 2);
@@ -280,19 +299,19 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - leg two consumes first leg one offer fully', function() { it('Compute autobridged offers - leg two consumes first leg one offer fully', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 2)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 2));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 1));
legTwoOffers[0].TakerGets.value = '170.7639524223001'; legTwoOffers[0].TakerGets.value = '170.7639524223001';
legTwoOffers[0].TakerPays = '49439476610'; legTwoOffers[0].TakerPays = '49439476610';
@@ -301,6 +320,7 @@ describe('OrderBook Autobridging', function() {
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 2); assert.strictEqual(book._offersAutobridged.length, 2);
@@ -317,19 +337,19 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - owners equal', function() { it('Compute autobridged offers - owners equal', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1002000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1002000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 2)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 2));
legOneOffers[0].owner_funds = '2105863129'; legOneOffers[0].owner_funds = '2105863129';
legTwoOffers[1].owner_funds = '19.32660005780981'; legTwoOffers[1].owner_funds = '19.32660005780981';
@@ -339,6 +359,7 @@ describe('OrderBook Autobridging', function() {
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 2); assert.strictEqual(book._offersAutobridged.length, 2);
@@ -355,19 +376,19 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - owners equal - leg one overfunded', function() { it('Compute autobridged offers - owners equal - leg one overfunded', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1002000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1002000000);
var legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1)); const legOneOffers = _.cloneDeep(fixtures.LEG_ONE_OFFERS.slice(0, 1));
var legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 2)); const legTwoOffers = _.cloneDeep(fixtures.LEG_TWO_OFFERS.slice(0, 2));
legOneOffers[0].owner_funds = '41461561812'; legOneOffers[0].owner_funds = '41461561812';
@@ -378,6 +399,7 @@ describe('OrderBook Autobridging', function() {
book._legOneBook.setOffers(legOneOffers); book._legOneBook.setOffers(legOneOffers);
book._legTwoBook.setOffers(legTwoOffers); book._legTwoBook.setOffers(legTwoOffers);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 2); assert.strictEqual(book._offersAutobridged.length, 2);
@@ -394,20 +416,21 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - TakerPays < Quality * TakerGets', function() { it('Compute autobridged offers - TakerPays < Quality * TakerGets', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook.setOffers([ book._legOneBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: '75', TakerGets: '75',
TakerPays: { TakerPays: {
value: '50', value: '50',
@@ -422,6 +445,7 @@ describe('OrderBook Autobridging', function() {
book._legTwoBook.setOffers([ book._legTwoBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '90', value: '90',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -433,6 +457,7 @@ describe('OrderBook Autobridging', function() {
} }
]); ]);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 1); assert.strictEqual(book._offersAutobridged.length, 1);
@@ -444,20 +469,21 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - update funded amount', function() { it('Compute autobridged offers - update funded amount', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook.setOffers([ book._legOneBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: '100', TakerGets: '100',
TakerPays: { TakerPays: {
value: '100', value: '100',
@@ -469,6 +495,7 @@ describe('OrderBook Autobridging', function() {
}, },
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: '50', TakerGets: '50',
TakerPays: { TakerPays: {
value: '100', value: '100',
@@ -482,6 +509,7 @@ describe('OrderBook Autobridging', function() {
book._legTwoBook.setOffers([ book._legTwoBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '90', value: '90',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -493,6 +521,7 @@ describe('OrderBook Autobridging', function() {
}, },
{ {
Account: addresses.OTHER_ACCOUNT, Account: addresses.OTHER_ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '30', value: '30',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -504,6 +533,7 @@ describe('OrderBook Autobridging', function() {
} }
]); ]);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 3); assert.strictEqual(book._offersAutobridged.length, 3);
@@ -525,20 +555,21 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - update funded amount - owners equal', function() { it('Compute autobridged offers - update funded amount - owners equal', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook.setOffers([ book._legOneBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: '100', TakerGets: '100',
TakerPays: { TakerPays: {
value: '100', value: '100',
@@ -550,6 +581,7 @@ describe('OrderBook Autobridging', function() {
}, },
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: '20', TakerGets: '20',
TakerPays: { TakerPays: {
value: '100', value: '100',
@@ -563,6 +595,7 @@ describe('OrderBook Autobridging', function() {
book._legTwoBook.setOffers([ book._legTwoBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '90', value: '90',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -574,6 +607,7 @@ describe('OrderBook Autobridging', function() {
}, },
{ {
Account: addresses.OTHER_ACCOUNT, Account: addresses.OTHER_ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '30', value: '30',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -585,6 +619,7 @@ describe('OrderBook Autobridging', function() {
} }
]); ]);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 3); assert.strictEqual(book._offersAutobridged.length, 3);
@@ -606,20 +641,21 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - update funded amount - first two owners equal', function() { it('Compute autobridged offers - update funded amount - first two owners equal', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook.setOffers([ book._legOneBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: '100', TakerGets: '100',
TakerPays: { TakerPays: {
value: '100', value: '100',
@@ -631,6 +667,7 @@ describe('OrderBook Autobridging', function() {
}, },
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: '100', TakerGets: '100',
TakerPays: { TakerPays: {
value: '200', value: '200',
@@ -644,6 +681,7 @@ describe('OrderBook Autobridging', function() {
book._legTwoBook.setOffers([ book._legTwoBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '90', value: '90',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -655,6 +693,7 @@ describe('OrderBook Autobridging', function() {
}, },
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '30', value: '30',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -665,6 +704,7 @@ describe('OrderBook Autobridging', function() {
}, },
{ {
Account: addresses.OTHER_ACCOUNT, Account: addresses.OTHER_ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '20', value: '20',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -676,6 +716,7 @@ describe('OrderBook Autobridging', function() {
} }
]); ]);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 4); assert.strictEqual(book._offersAutobridged.length, 4);
@@ -702,20 +743,21 @@ describe('OrderBook Autobridging', function() {
}); });
it('Compute autobridged offers - unfunded offer - owners equal', function() { it('Compute autobridged offers - unfunded offer - owners equal', function() {
var book = new Remote().createOrderBook({ const book = createRemote().createOrderBook({
currency_gets: 'EUR', currency_gets: 'EUR',
issuer_gets: addresses.ISSUER, issuer_gets: addresses.ISSUER,
currency_pays: 'USD', currency_pays: 'USD',
issuer_pays: addresses.ISSUER issuer_pays: addresses.ISSUER
}); });
book._issuerTransferRate = 1000000000; book._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook._issuerTransferRate = 1000000000; book._legOneBook._issuerTransferRate = Amount.from_json(1000000000);
book._legTwoBook._issuerTransferRate = 1000000000; book._legTwoBook._issuerTransferRate = Amount.from_json(1000000000);
book._legOneBook.setOffers([ book._legOneBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: '75', TakerGets: '75',
TakerPays: { TakerPays: {
value: '75', value: '75',
@@ -730,6 +772,7 @@ describe('OrderBook Autobridging', function() {
book._legTwoBook.setOffers([ book._legTwoBook.setOffers([
{ {
Account: addresses.ACCOUNT, Account: addresses.ACCOUNT,
BookDirectory: '3B95C29205977C2136BBC70F21895F8C8F471C8522BF446E570463F9CDB31517',
TakerGets: { TakerGets: {
value: '90', value: '90',
issuer: addresses.ISSUER, issuer: addresses.ISSUER,
@@ -741,6 +784,7 @@ describe('OrderBook Autobridging', function() {
} }
]); ]);
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
book.computeAutobridgedOffers(); book.computeAutobridgedOffers();
assert.strictEqual(book._offersAutobridged.length, 1); assert.strictEqual(book._offersAutobridged.length, 1);

File diff suppressed because it is too large Load Diff