mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-16 02:25:47 +00:00
Compare commits
12 Commits
0.13.0-rc7
...
0.12.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61afca2337 | ||
|
|
47251bd38b | ||
|
|
e641a347db | ||
|
|
3e17d91edf | ||
|
|
d0ebed9822 | ||
|
|
a3775f18ba | ||
|
|
f282585c3f | ||
|
|
ae5ff31c96 | ||
|
|
0bdd37090e | ||
|
|
c745faaaf0 | ||
|
|
0c62fa2112 | ||
|
|
806547dd15 |
12
HISTORY.md
12
HISTORY.md
@@ -1,3 +1,15 @@
|
|||||||
|
##0.12.9
|
||||||
|
|
||||||
|
+ [OrderBook performance optimizations](https://github.com/ripple/ripple-lib/commit/3e17d91edf36745f6b6c09b0ad88971b7775f6ab)
|
||||||
|
|
||||||
|
##0.12.7 and 0.12.8
|
||||||
|
|
||||||
|
+ [Improve performance of orderbook](https://github.com/ripple/ripple-lib/commit/c745faaaf0956ca98448a754b4fe97fb50574fc7)
|
||||||
|
|
||||||
|
+ [Remove Firefox warning about prototype overwrite](https://github.com/ripple/ripple-lib/commit/0c62fa21123b220b066871e1c41a3b4fe6f51885)
|
||||||
|
|
||||||
|
+ [Fix compare bug in Amount class](https://github.com/ripple/ripple-lib/commit/806547dd154e1b0bf252e8a74ad3ac6aa8a97660)
|
||||||
|
|
||||||
##0.12.6
|
##0.12.6
|
||||||
|
|
||||||
+ [Fix webpack require failure due to "./" notation](https://github.com/ripple/ripple-lib/commit/8d9746d7b10be203ee613df523c2522012ff1baf)
|
+ [Fix webpack require failure due to "./" notation](https://github.com/ripple/ripple-lib/commit/8d9746d7b10be203ee613df523c2522012ff1baf)
|
||||||
|
|||||||
3
circle.yml
Normal file
3
circle.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
machine:
|
||||||
|
node:
|
||||||
|
version: 0.12.0
|
||||||
44
npm-shrinkwrap.json
generated
44
npm-shrinkwrap.json
generated
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "ripple-lib",
|
"name": "ripple-lib",
|
||||||
"version": "0.12.6",
|
"version": "0.12.9",
|
||||||
"npm-shrinkwrap-version": "5.4.0",
|
"npm-shrinkwrap-version": "5.4.0",
|
||||||
"node-version": "v0.12.6",
|
"node-version": "v0.12.7",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async": {
|
"async": {
|
||||||
"version": "0.9.2",
|
"version": "0.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
|
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
|
||||||
},
|
},
|
||||||
"babel-runtime": {
|
"babel-runtime": {
|
||||||
"version": "5.8.3",
|
"version": "5.8.24",
|
||||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.24.tgz",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "0.9.18",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-0.9.18.tgz"
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.1.4.tgz"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -27,8 +27,8 @@
|
|||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz"
|
"resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz"
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "3.10.0",
|
"version": "3.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.0.tgz"
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
|
||||||
},
|
},
|
||||||
"lru-cache": {
|
"lru-cache": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.2",
|
||||||
@@ -46,20 +46,6 @@
|
|||||||
"version": "0.7.2",
|
"version": "0.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-0.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-0.7.2.tgz",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bufferutil": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.1.0.tgz",
|
|
||||||
"dependencies": {
|
|
||||||
"bindings": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
|
|
||||||
},
|
|
||||||
"nan": {
|
|
||||||
"version": "1.8.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"options": {
|
"options": {
|
||||||
"version": "0.0.6",
|
"version": "0.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz"
|
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz"
|
||||||
@@ -67,20 +53,6 @@
|
|||||||
"ultron": {
|
"ultron": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz"
|
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz"
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-1.1.0.tgz",
|
|
||||||
"dependencies": {
|
|
||||||
"bindings": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
|
|
||||||
},
|
|
||||||
"nan": {
|
|
||||||
"version": "1.8.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ripple-lib",
|
"name": "ripple-lib",
|
||||||
"version": "0.12.6",
|
"version": "0.12.9",
|
||||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||||
"files": [
|
"files": [
|
||||||
"dist/npm/*",
|
"dist/npm/*",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async": "~0.9.0",
|
"async": "~0.9.0",
|
||||||
"babel-runtime": "^5.3.2",
|
"babel-runtime": "^5.8.20",
|
||||||
"bignumber.js": "^2.0.3",
|
"bignumber.js": "^2.0.3",
|
||||||
"extend": "~1.2.1",
|
"extend": "~1.2.1",
|
||||||
"lodash": "^3.1.0",
|
"lodash": "^3.1.0",
|
||||||
@@ -27,10 +27,10 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"assert-diff": "^1.0.1",
|
"assert-diff": "^1.0.1",
|
||||||
"babel": "^5.3.3",
|
"babel": "^5.3.3",
|
||||||
"babel-core": "^5.3.2",
|
"babel-core": "^5.8.23",
|
||||||
"babel-loader": "^5.0.0",
|
"babel-loader": "^5.3.2",
|
||||||
"coveralls": "~2.10.0",
|
"coveralls": "~2.10.0",
|
||||||
"eslint": "^0.18.0",
|
"eslint": "^1.3.1",
|
||||||
"gulp": "~3.8.10",
|
"gulp": "~3.8.10",
|
||||||
"gulp-bump": "~0.1.13",
|
"gulp-bump": "~0.1.13",
|
||||||
"gulp-clean-dest": "^0.1.0",
|
"gulp-clean-dest": "^0.1.0",
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ Amount.prototype._copy = function(value) {
|
|||||||
Amount.prototype.compareTo = function(to) {
|
Amount.prototype.compareTo = function(to) {
|
||||||
var toAmount = Amount.from_json(to);
|
var toAmount = Amount.from_json(to);
|
||||||
if (!this.is_comparable(toAmount)) {
|
if (!this.is_comparable(toAmount)) {
|
||||||
return new Amount(NaN);
|
return 0;
|
||||||
}
|
}
|
||||||
return this._value.comparedTo(toAmount._value);
|
return this._value.comparedTo(toAmount._value);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const UInt160 = require('./uint160').UInt160;
|
|
||||||
const Amount = require('./amount').Amount;
|
const Amount = require('./amount').Amount;
|
||||||
const Utils = require('./orderbookutils');
|
const Utils = require('./orderbookutils');
|
||||||
|
|
||||||
@@ -20,7 +19,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,21 +29,47 @@ 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
|
||||||
*
|
*
|
||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AutobridgeCalculator.prototype.calculate = function() {
|
AutobridgeCalculator.prototype.calculate = function(callback) {
|
||||||
let legOnePointer = 0;
|
const legOnePointer = 0;
|
||||||
let legTwoPointer = 0;
|
const legTwoPointer = 0;
|
||||||
|
|
||||||
let offersAutobridged = [];
|
const offersAutobridged = [];
|
||||||
|
|
||||||
this.clearOwnerFundsLeftover();
|
this.clearOwnerFundsLeftover();
|
||||||
|
|
||||||
|
this._calculateInternal(legOnePointer, legTwoPointer, offersAutobridged,
|
||||||
|
callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
AutobridgeCalculator.prototype._calculateInternal = function(
|
||||||
|
legOnePointer_, legTwoPointer_, offersAutobridged, callback
|
||||||
|
) {
|
||||||
|
|
||||||
|
let legOnePointer = legOnePointer_;
|
||||||
|
let legTwoPointer = legTwoPointer_;
|
||||||
|
|
||||||
|
const startTime = Date.now();
|
||||||
|
|
||||||
while (this.legOneOffers[legOnePointer] && this.legTwoOffers[legTwoPointer]) {
|
while (this.legOneOffers[legOnePointer] && this.legTwoOffers[legTwoPointer]) {
|
||||||
|
// manually implement cooperative multitasking that yields after 30ms
|
||||||
|
// of execution so user's browser stays responsive
|
||||||
|
const lasted = (Date.now() - startTime);
|
||||||
|
if (lasted > 30) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this._calculateInternal(legOnePointer, legTwoPointer, offersAutobridged,
|
||||||
|
callback);
|
||||||
|
}, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const legOneOffer = this.legOneOffers[legOnePointer];
|
const legOneOffer = this.legOneOffers[legOnePointer];
|
||||||
const legTwoOffer = this.legTwoOffers[legTwoPointer];
|
const legTwoOffer = this.legTwoOffers[legTwoPointer];
|
||||||
const leftoverFunds = this.getLeftoverOwnerFunds(legOneOffer.Account);
|
const leftoverFunds = this.getLeftoverOwnerFunds(legOneOffer.Account);
|
||||||
@@ -70,14 +96,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
|
||||||
@@ -97,7 +126,7 @@ AutobridgeCalculator.prototype.calculate = function() {
|
|||||||
offersAutobridged.push(autobridgedOffer);
|
offersAutobridged.push(autobridgedOffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return offersAutobridged;
|
callback(offersAutobridged);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,8 +239,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 +253,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 +273,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 +290,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 +314,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 +331,9 @@ 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;
|
||||||
};
|
};
|
||||||
@@ -431,7 +456,7 @@ function(legOneOffer, takerGets) {
|
|||||||
const legOneQuality = Utils.getOfferQuality(legOneOffer, this._currencyGets);
|
const legOneQuality = Utils.getOfferQuality(legOneOffer, this._currencyGets);
|
||||||
|
|
||||||
legOneOffer.TakerGets = takerGets.to_text();
|
legOneOffer.TakerGets = takerGets.to_text();
|
||||||
legOneOffer.TakerPays = takerGets.multiply(legOneQuality);
|
legOneOffer.TakerPays = takerGets.multiply(legOneQuality).to_json();
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = AutobridgeCalculator;
|
module.exports = AutobridgeCalculator;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
426
src/orderbook.js
426
src/orderbook.js
@@ -23,10 +23,6 @@ const AutobridgeCalculator = require('./autobridgecalculator');
|
|||||||
const OrderBookUtils = require('./orderbookutils');
|
const OrderBookUtils = require('./orderbookutils');
|
||||||
const log = require('./log').internal.sub('orderbook');
|
const log = require('./log').internal.sub('orderbook');
|
||||||
|
|
||||||
function assertValidNumber(number, message) {
|
|
||||||
assert(!_.isNull(number) && !isNaN(number), message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor OrderBook
|
* @constructor OrderBook
|
||||||
* @param {Remote} remote
|
* @param {Remote} remote
|
||||||
@@ -35,11 +31,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;
|
||||||
@@ -60,6 +57,8 @@ function OrderBook(remote,
|
|||||||
this._ownerFundsUnadjusted = {};
|
this._ownerFundsUnadjusted = {};
|
||||||
this._ownerFunds = {};
|
this._ownerFunds = {};
|
||||||
this._ownerOffersTotal = {};
|
this._ownerOffersTotal = {};
|
||||||
|
this._validAccounts = {};
|
||||||
|
this._validAccountsCount = 0;
|
||||||
|
|
||||||
// We consider ourselves synchronized if we have a current
|
// We consider ourselves synchronized 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
|
||||||
@@ -72,13 +71,45 @@ 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._waitingForOffers = false;
|
||||||
|
this._offersModifiedAt = 0;
|
||||||
|
this._transactionsLeft = 0;
|
||||||
|
this._calculatorRunning = false;
|
||||||
|
|
||||||
|
|
||||||
|
this.sortOffers = this._currencyGets.has_interest() ?
|
||||||
|
_sortOffers.bind(this) : _sortOffersQuick;
|
||||||
|
|
||||||
this._isAutobridgeable = !this._currencyGets.is_native()
|
this._isAutobridgeable = !this._currencyGets.is_native()
|
||||||
&& !this._currencyPays.is_native();
|
&& !this._currencyPays.is_native();
|
||||||
|
|
||||||
function computeAutobridgedOffersWrapper() {
|
function computeAutobridgedOffersWrapperOne() {
|
||||||
self.computeAutobridgedOffers();
|
if (!self._gotOffersFromLegOne) {
|
||||||
self.mergeDirectAndAutobridgedBooks();
|
self._gotOffersFromLegOne = true;
|
||||||
|
self.computeAutobridgedOffersWrapper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeAutobridgedOffersWrapperTwo() {
|
||||||
|
if (!self._gotOffersFromLegTwo) {
|
||||||
|
self._gotOffersFromLegTwo = true;
|
||||||
|
self.computeAutobridgedOffersWrapper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
@@ -88,15 +119,19 @@ 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 onTransactionWrapper(transaction) {
|
||||||
|
self.onTransaction(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onLedgerClosedWrapper(message) {
|
||||||
|
self.onLedgerClosed(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
function listenersModified(action, event) {
|
function listenersModified(action, event) {
|
||||||
@@ -106,7 +141,17 @@ 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', onTransactionWrapper);
|
||||||
|
self._remote.on('ledger_closed', onLedgerClosedWrapper);
|
||||||
|
self._remote.once('disconnect', onDisconnect);
|
||||||
|
|
||||||
|
if (self._isAutobridgeable) {
|
||||||
|
self._legOneBook.on('model', computeAutobridgedOffersWrapperOne);
|
||||||
|
self._legTwoBook.on('model', computeAutobridgedOffersWrapperTwo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'remove':
|
case 'remove':
|
||||||
@@ -118,10 +163,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);
|
||||||
});
|
});
|
||||||
@@ -130,23 +171,22 @@ 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', onTransactionWrapper);
|
||||||
});
|
self._remote.removeListener('ledger_closed', onLedgerClosedWrapper);
|
||||||
|
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;
|
||||||
@@ -164,7 +204,11 @@ 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.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
|
||||||
@@ -191,18 +235,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +261,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);
|
||||||
@@ -228,6 +274,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() {
|
||||||
@@ -249,36 +296,88 @@ 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) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._synchronized = false;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
self._waitingForOffers = false;
|
||||||
|
|
||||||
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'));
|
||||||
|
self.emit('model', []);
|
||||||
|
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._synchronized = true;
|
self._synchronized = true;
|
||||||
self.notifyDirectOffersChanged();
|
|
||||||
|
if (self._isAutobridgeable) {
|
||||||
|
self.computeAutobridgedOffersWrapper();
|
||||||
|
} else {
|
||||||
|
self.emit('model', self._offers);
|
||||||
|
}
|
||||||
|
|
||||||
callback(null, self._offers);
|
callback(null, self._offers);
|
||||||
}
|
}
|
||||||
@@ -289,9 +388,12 @@ OrderBook.prototype.requestOffers = function(callback) {
|
|||||||
log.info('failed to request offers', self._key, err);
|
log.info('failed to request offers', self._key, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._waitingForOffers = false;
|
||||||
callback(err);
|
callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._waitingForOffers = true;
|
||||||
|
|
||||||
const request = this._remote.requestBookOffers(this.toJSON());
|
const request = this._remote.requestBookOffers(this.toJSON());
|
||||||
request.once('success', handleOffers);
|
request.once('success', handleOffers);
|
||||||
request.once('error', handleError);
|
request.once('error', handleError);
|
||||||
@@ -330,8 +432,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);
|
||||||
}
|
}
|
||||||
@@ -386,18 +489,6 @@ OrderBook.prototype.subscribeTransactions = function(callback) {
|
|||||||
return request;
|
return request;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles notifying listeners that direct offers have changed. For autobridged
|
|
||||||
* books, an additional merge step is also performed
|
|
||||||
*/
|
|
||||||
|
|
||||||
OrderBook.prototype.notifyDirectOffersChanged = function() {
|
|
||||||
if (this._isAutobridgeable) {
|
|
||||||
this.mergeDirectAndAutobridgedBooks();
|
|
||||||
} else {
|
|
||||||
this.emit('model', this._offers);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset cached owner's funds, offer counts, and offer sums
|
* Reset cached owner's funds, offer counts, and offer sums
|
||||||
@@ -407,7 +498,13 @@ OrderBook.prototype.resetCache = function() {
|
|||||||
this._ownerFunds = {};
|
this._ownerFunds = {};
|
||||||
this._ownerOffersTotal = {};
|
this._ownerOffersTotal = {};
|
||||||
this._offerCounts = {};
|
this._offerCounts = {};
|
||||||
|
this._offers = [];
|
||||||
this._synchronized = false;
|
this._synchronized = false;
|
||||||
|
|
||||||
|
if (this._validAccountsCount > 3000) {
|
||||||
|
this._validAccounts = {};
|
||||||
|
this._validAccountsCount = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -417,7 +514,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -429,7 +525,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;
|
||||||
@@ -446,11 +541,11 @@ 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 = OrderBookUtils.normalizeAmount(balance)
|
const adjustedBalance = OrderBookUtils.normalizeAmount(balance)
|
||||||
.divide(this._issuerTransferRate)
|
.divide(this._issuerTransferRate)
|
||||||
.multiply(Amount.from_json(OrderBook.DEFAULT_TRANSFER_RATE))
|
.multiply(OrderBook.DEFAULT_TRANSFER_RATE)
|
||||||
.to_json()
|
.to_json()
|
||||||
.value;
|
.value;
|
||||||
|
|
||||||
@@ -465,7 +560,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]);
|
||||||
@@ -482,7 +576,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];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -493,7 +586,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -505,7 +597,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -517,7 +608,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;
|
||||||
@@ -532,7 +622,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;
|
||||||
|
|
||||||
@@ -553,8 +642,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));
|
||||||
|
|
||||||
@@ -573,14 +660,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -592,15 +677,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();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -611,11 +695,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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -633,17 +716,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();
|
||||||
@@ -699,7 +783,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;
|
||||||
};
|
};
|
||||||
@@ -738,6 +826,32 @@ OrderBook.prototype.isBalanceChangeNode = function(node) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
OrderBook.prototype._canRunAutobridgeCalc = function(): boolean {
|
||||||
|
return !this._calculatorRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrderBook.prototype.onTransaction = function(transaction) {
|
||||||
|
this.updateFundedAmounts(transaction);
|
||||||
|
|
||||||
|
|
||||||
|
if (--this._transactionsLeft === 0 && !this._waitingForOffers) {
|
||||||
|
const lastClosedLedger = this._remote.getLedgerSequence() - 1;
|
||||||
|
if (this._isAutobridgeable) {
|
||||||
|
if (this._canRunAutobridgeCalc()) {
|
||||||
|
if (this._legOneBook._offersModifiedAt === lastClosedLedger ||
|
||||||
|
this._legTwoBook._offersModifiedAt === lastClosedLedger
|
||||||
|
) {
|
||||||
|
this.computeAutobridgedOffersWrapper();
|
||||||
|
} else if (this._offersModifiedAt === lastClosedLedger) {
|
||||||
|
this.mergeDirectAndAutobridgedBooks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this._offersModifiedAt === lastClosedLedger) {
|
||||||
|
this.emit('model', this._offers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates funded amounts/balances using modified balance nodes
|
* Updates funded amounts/balances using modified balance nodes
|
||||||
*
|
*
|
||||||
@@ -781,6 +895,7 @@ OrderBook.prototype.updateFundedAmounts = function(transaction) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update offers' funded amount with their owner's funds
|
* Update offers' funded amount with their owner's funds
|
||||||
*
|
*
|
||||||
@@ -788,10 +903,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,
|
||||||
@@ -833,6 +953,16 @@ OrderBook.prototype.updateOwnerOffersFundedAmount = function(account) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
OrderBook.prototype.onLedgerClosed = function(message) {
|
||||||
|
if (!message || (message && !_.isNumber(message.txn_count)) ||
|
||||||
|
!this._subscribed || this._destroyed || this._waitingForOffers
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._transactionsLeft = message.txn_count;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify orderbook of a relevant transaction
|
* Notify orderbook of a relevant transaction
|
||||||
*
|
*
|
||||||
@@ -843,7 +973,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) {
|
if (!this._subscribed || this._destroyed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -879,6 +1009,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
|
||||||
@@ -889,6 +1025,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
|
||||||
@@ -901,6 +1043,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 ?
|
||||||
@@ -914,7 +1062,9 @@ OrderBook.prototype.notify = function(transaction) {
|
|||||||
_.each(affectedNodes, handleNode);
|
_.each(affectedNodes, handleNode);
|
||||||
|
|
||||||
this.emit('transaction', transaction);
|
this.emit('transaction', transaction);
|
||||||
this.notifyDirectOffersChanged();
|
|
||||||
|
this._offersModifiedAt = this._remote.getLedgerSequence() - 1;
|
||||||
|
|
||||||
if (!takerGetsTotal.is_zero()) {
|
if (!takerGetsTotal.is_zero()) {
|
||||||
this.emit('trade', takerPaysTotal, takerGetsTotal);
|
this.emit('trade', takerPaysTotal, takerGetsTotal);
|
||||||
}
|
}
|
||||||
@@ -946,17 +1096,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1062,28 +1222,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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1181,10 +1346,16 @@ OrderBook.prototype.is_valid = function() {
|
|||||||
* IOU:XRP and XRP:IOU books
|
* IOU:XRP and XRP:IOU books
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OrderBook.prototype.computeAutobridgedOffers = function() {
|
OrderBook.prototype.computeAutobridgedOffers = function(callback = 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;
|
||||||
|
}
|
||||||
|
|
||||||
const autobridgeCalculator = new AutobridgeCalculator(
|
const autobridgeCalculator = new AutobridgeCalculator(
|
||||||
this._currencyGets,
|
this._currencyGets,
|
||||||
this._currencyPays,
|
this._currencyPays,
|
||||||
@@ -1194,9 +1365,40 @@ OrderBook.prototype.computeAutobridgedOffers = function() {
|
|||||||
this._issuerPays
|
this._issuerPays
|
||||||
);
|
);
|
||||||
|
|
||||||
this._offersAutobridged = autobridgeCalculator.calculate();
|
const lastClosedLedger = this._remote.getLedgerSequence() - 1;
|
||||||
|
|
||||||
|
autobridgeCalculator.calculate((autobridgedOffers) => {
|
||||||
|
this._offersAutobridged = autobridgedOffers;
|
||||||
|
callback();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
OrderBook.prototype.computeAutobridgedOffersWrapper = function() {
|
||||||
|
if (!this._gotOffersFromLegOne || !this._gotOffersFromLegTwo ||
|
||||||
|
!this._synchronized || this._destroyed || this._calculatorRunning
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._calculatorRunning = true;
|
||||||
|
const startTime = Date.now();
|
||||||
|
this.computeAutobridgedOffers(() => {
|
||||||
|
this.mergeDirectAndAutobridgedBooks();
|
||||||
|
this._calculatorRunning = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
*
|
*
|
||||||
@@ -1204,20 +1406,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)) {
|
||||||
|
if (this._synchronized && this._gotOffersFromLegOne &&
|
||||||
|
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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,18 +1,31 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _ = require('lodash');
|
const _ = require('lodash');
|
||||||
var assert = require('assert');
|
const assert = require('assert');
|
||||||
var SerializedObject = require('./serializedobject').SerializedObject;
|
const SerializedObject = require('./serializedobject').SerializedObject;
|
||||||
var Types = require('./serializedtypes');
|
const Types = require('./serializedtypes');
|
||||||
var Amount = require('./amount').Amount;
|
const Amount = require('./amount').Amount;
|
||||||
|
const Currency = require('./currency').Currency;
|
||||||
|
const UInt160 = require('./uint160').UInt160;
|
||||||
|
|
||||||
var IOU_SUFFIX = '/000/rrrrrrrrrrrrrrrrrrrrrhoLvTp';
|
// const IOU_SUFFIX = '/000/rrrrrrrrrrrrrrrrrrrrrhoLvTp';
|
||||||
var OrderBookUtils = {};
|
const IOU_SUFFIX_CURRENCY = Currency.from_json('000');
|
||||||
|
const IOU_SUFFIX_ISSUER = UInt160.from_json('rrrrrrrrrrrrrrrrrrrrrhoLvTp');
|
||||||
|
const OrderBookUtils = {};
|
||||||
|
|
||||||
function assertValidNumber(number, message) {
|
function assertValidNumber(number, message) {
|
||||||
assert(!_.isNull(number) && !isNaN(number), message);
|
assert(!_.isNull(number) && !isNaN(number), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createAmount(number) {
|
||||||
|
const amount = new Amount();
|
||||||
|
amount.set_issuer(IOU_SUFFIX_ISSUER);
|
||||||
|
amount._currency = IOU_SUFFIX_CURRENCY;
|
||||||
|
amount.parse_value(number);
|
||||||
|
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Casts and returns offer's taker gets funded amount as a default IOU amount
|
* Casts and returns offer's taker gets funded amount as a default IOU amount
|
||||||
*
|
*
|
||||||
@@ -23,7 +36,7 @@ function assertValidNumber(number, message) {
|
|||||||
OrderBookUtils.getOfferTakerGetsFunded = function(offer) {
|
OrderBookUtils.getOfferTakerGetsFunded = function(offer) {
|
||||||
assertValidNumber(offer.taker_gets_funded, 'Taker gets funded is invalid');
|
assertValidNumber(offer.taker_gets_funded, 'Taker gets funded is invalid');
|
||||||
|
|
||||||
return Amount.from_json(offer.taker_gets_funded + IOU_SUFFIX);
|
return createAmount(offer.taker_gets_funded);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,7 +49,7 @@ OrderBookUtils.getOfferTakerGetsFunded = function(offer) {
|
|||||||
OrderBookUtils.getOfferTakerPaysFunded = function(offer) {
|
OrderBookUtils.getOfferTakerPaysFunded = function(offer) {
|
||||||
assertValidNumber(offer.taker_pays_funded, 'Taker gets funded is invalid');
|
assertValidNumber(offer.taker_pays_funded, 'Taker gets funded is invalid');
|
||||||
|
|
||||||
return Amount.from_json(offer.taker_pays_funded + IOU_SUFFIX);
|
return createAmount(offer.taker_pays_funded);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +63,7 @@ OrderBookUtils.getOfferTakerPaysFunded = function(offer) {
|
|||||||
OrderBookUtils.getOfferTakerGets = function(offer) {
|
OrderBookUtils.getOfferTakerGets = function(offer) {
|
||||||
assert(typeof offer, 'object', 'Offer is invalid');
|
assert(typeof offer, 'object', 'Offer is invalid');
|
||||||
|
|
||||||
return Amount.from_json(offer.TakerGets + IOU_SUFFIX);
|
return createAmount(offer.TakerGets);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,7 +74,7 @@ OrderBookUtils.getOfferTakerGets = function(offer) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
OrderBookUtils.getOfferQuality = function(offer, currencyGets) {
|
OrderBookUtils.getOfferQuality = function(offer, currencyGets) {
|
||||||
var amount;
|
let amount;
|
||||||
|
|
||||||
if (currencyGets.has_interest()) {
|
if (currencyGets.has_interest()) {
|
||||||
// XXX Should use Amount#from_quality
|
// XXX Should use Amount#from_quality
|
||||||
@@ -71,7 +84,7 @@ OrderBookUtils.getOfferQuality = function(offer, currencyGets) {
|
|||||||
reference_date: new Date()
|
reference_date: new Date()
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
amount = Amount.from_json(offer.quality + IOU_SUFFIX);
|
amount = createAmount(offer.quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
return amount;
|
return amount;
|
||||||
@@ -89,8 +102,25 @@ OrderBookUtils.getOfferQuality = function(offer, currencyGets) {
|
|||||||
OrderBookUtils.convertOfferQualityToHex = function(quality) {
|
OrderBookUtils.convertOfferQualityToHex = function(quality) {
|
||||||
assert(quality instanceof Amount, 'Quality is not an amount');
|
assert(quality instanceof Amount, 'Quality is not an amount');
|
||||||
|
|
||||||
var so = new SerializedObject();
|
const so = new SerializedObject();
|
||||||
Types.Quality.serialize(so, quality.to_text() + IOU_SUFFIX);
|
Types.Quality.serialize(so, createAmount(quality.to_text()));
|
||||||
|
|
||||||
|
return so.to_hex();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats an offer quality amount to a hex that can be parsed by
|
||||||
|
* Amount.parse_quality
|
||||||
|
*
|
||||||
|
* @param {String} quality
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
|
||||||
|
OrderBookUtils.convertOfferQualityToHexFromText = function(quality) {
|
||||||
|
|
||||||
|
const so = new SerializedObject();
|
||||||
|
Types.Quality.serialize(so, createAmount(quality));
|
||||||
|
|
||||||
return so.to_hex();
|
return so.to_hex();
|
||||||
};
|
};
|
||||||
@@ -100,7 +130,7 @@ OrderBookUtils.convertOfferQualityToHex = function(quality) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
OrderBookUtils.normalizeAmount = function(value) {
|
OrderBookUtils.normalizeAmount = function(value) {
|
||||||
return Amount.from_json(value + IOU_SUFFIX);
|
return createAmount(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = OrderBookUtils;
|
module.exports = OrderBookUtils;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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' +
|
||||||
|
|||||||
22
test/fixtures/orderbook.js
vendored
22
test/fixtures/orderbook.js
vendored
@@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _ = require('lodash');
|
const _ = require('lodash');
|
||||||
var addresses = require('./addresses');
|
const addresses = require('./addresses');
|
||||||
var 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,6 +821,15 @@ module.exports.transactionWithCreatedOffer = function(options) {
|
|||||||
amount: '1.9951'
|
amount: '1.9951'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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({
|
var meta = new Meta({
|
||||||
AffectedNodes: [
|
AffectedNodes: [
|
||||||
{
|
{
|
||||||
@@ -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: {
|
||||||
|
|||||||
@@ -1,19 +1,31 @@
|
|||||||
/*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._ledger_current_index = 32570;
|
||||||
|
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',
|
||||||
@@ -26,139 +38,155 @@ describe('OrderBook Autobridging', function() {
|
|||||||
assert.deepEqual(book._legTwoBook._currencyPays.to_hex(), Currency.from_json('XRP').to_hex());
|
assert.deepEqual(book._legTwoBook._currencyPays.to_hex(), Currency.from_json('XRP').to_hex());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers', function() {
|
it('Compute autobridged offers', function(done) {
|
||||||
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.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 1);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 1);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
assert.strictEqual(book._offersAutobridged[0].taker_gets_funded, '17.07639524223001');
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
assert.strictEqual(book._offersAutobridged[0].taker_pays_funded, '58.61727326122974');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].taker_gets_funded, '17.07639524223001');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].taker_pays_funded, '58.61727326122974');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - leg one partially funded', function() {
|
it('Compute autobridged offers - leg one partially funded', function(done) {
|
||||||
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.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 1);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 1);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '7.273651248813431');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '24.96789265329184');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '7.273651248813431');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '24.96789265329184');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - leg two partially funded', function() {
|
it('Compute autobridged offers - leg two partially funded', function(done) {
|
||||||
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.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 1);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 1);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '10');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '34.32649132449533');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '10');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '34.32649132449533');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - leg two transfer rate', function() {
|
it('Compute autobridged offers - leg two transfer rate', function(done) {
|
||||||
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.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '9.980039920159681');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '34.25797537722665');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '9.980039920159681');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '34.25797537722665');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - taker funds < leg two in', function() {
|
it('Compute autobridged offers - taker funds < leg two in', function(done) {
|
||||||
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,30 +197,34 @@ describe('OrderBook Autobridging', function() {
|
|||||||
book._legOneBook.setOffers(legOneOffers);
|
book._legOneBook.setOffers(legOneOffers);
|
||||||
book._legTwoBook.setOffers(legTwoOffers);
|
book._legTwoBook.setOffers(legTwoOffers);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 1);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 1);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '108.6682345172846');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '373.019921005');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '108.6682345172846');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '373.019921005');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - leg one partially funded - owners equal', function() {
|
it('Compute autobridged offers - leg one partially funded - owners equal', function(done) {
|
||||||
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,30 +233,34 @@ describe('OrderBook Autobridging', function() {
|
|||||||
book._legOneBook.setOffers(legOneOffers);
|
book._legOneBook.setOffers(legOneOffers);
|
||||||
book._legTwoBook.setOffers(legTwoOffers);
|
book._legTwoBook.setOffers(legTwoOffers);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 1);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 1);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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(done) {
|
||||||
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,63 +272,71 @@ describe('OrderBook Autobridging', function() {
|
|||||||
book._legOneBook.setOffers(legOneOffers);
|
book._legOneBook.setOffers(legOneOffers);
|
||||||
book._legTwoBook.setOffers(legTwoOffers);
|
book._legTwoBook.setOffers(legTwoOffers);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 1);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 1);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '108.6682345172846');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '373.0199210049999');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '108.6682345172846');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '373.0199210049999');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - leg one consumes leg two fully', function() {
|
it('Compute autobridged offers - leg one consumes leg two fully', function(done) {
|
||||||
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.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 2);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 2);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5.038346688725268');
|
||||||
|
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '314.4026477437702');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5.038346688725268');
|
assert(book._offersAutobridged[1].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '314.4026477437702');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[1].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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(done) {
|
||||||
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,35 +345,39 @@ describe('OrderBook Autobridging', function() {
|
|||||||
book._legOneBook.setOffers(legOneOffers);
|
book._legOneBook.setOffers(legOneOffers);
|
||||||
book._legTwoBook.setOffers(legTwoOffers);
|
book._legTwoBook.setOffers(legTwoOffers);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 2);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 2);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '108.6682345172846');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '373.019921005');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '108.6682345172846');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '373.019921005');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '62.0957179050155');
|
||||||
|
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '213.1791399943838');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '62.0957179050155');
|
assert(book._offersAutobridged[1].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '213.1791399943838');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[1].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - owners equal', function() {
|
it('Compute autobridged offers - owners equal', function(done) {
|
||||||
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,35 +387,39 @@ describe('OrderBook Autobridging', function() {
|
|||||||
book._legOneBook.setOffers(legOneOffers);
|
book._legOneBook.setOffers(legOneOffers);
|
||||||
book._legTwoBook.setOffers(legTwoOffers);
|
book._legTwoBook.setOffers(legTwoOffers);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 2);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 2);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '0.4001139945128008');
|
||||||
|
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '24.96789265329184');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '0.4001139945128008');
|
assert(book._offersAutobridged[1].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '24.96789265329184');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[1].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - owners equal - leg one overfunded', function() {
|
it('Compute autobridged offers - owners equal - leg one overfunded', function(done) {
|
||||||
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,36 +430,41 @@ describe('OrderBook Autobridging', function() {
|
|||||||
book._legOneBook.setOffers(legOneOffers);
|
book._legOneBook.setOffers(legOneOffers);
|
||||||
book._legTwoBook.setOffers(legTwoOffers);
|
book._legTwoBook.setOffers(legTwoOffers);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 2);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 2);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '17.07639524223001');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '58.61727326122974');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5.038346688725268');
|
||||||
|
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '314.4026477437702');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5.038346688725268');
|
assert(book._offersAutobridged[1].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '314.4026477437702');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[1].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - TakerPays < Quality * TakerGets', function() {
|
it('Compute autobridged offers - TakerPays < Quality * TakerGets', function(done) {
|
||||||
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 +479,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,31 +491,36 @@ describe('OrderBook Autobridging', function() {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 1);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 1);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '75');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '75');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '75');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '75');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - update funded amount', function() {
|
it('Compute autobridged offers - update funded amount', function(done) {
|
||||||
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 +532,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 +546,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 +558,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,41 +570,46 @@ describe('OrderBook Autobridging', function() {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 3);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 3);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '90');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '90');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '90');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '90');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5');
|
||||||
|
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '10');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5');
|
assert(book._offersAutobridged[1].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '10');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[1].autobridged);
|
assert.strictEqual(book._offersAutobridged[2].TakerGets.value, '20');
|
||||||
|
assert.strictEqual(book._offersAutobridged[2].TakerPays.value, '80');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[2].TakerGets.value, '20');
|
assert(book._offersAutobridged[2].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[2].TakerPays.value, '80');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[2].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - update funded amount - owners equal', function() {
|
it('Compute autobridged offers - update funded amount - owners equal', function(done) {
|
||||||
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 +621,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 +635,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 +647,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,41 +659,46 @@ describe('OrderBook Autobridging', function() {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 3);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 3);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '90');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '90');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '90');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '90');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5');
|
||||||
|
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '10');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5');
|
assert(book._offersAutobridged[1].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '10');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[1].autobridged);
|
assert.strictEqual(book._offersAutobridged[2].TakerGets.value, '10');
|
||||||
|
assert.strictEqual(book._offersAutobridged[2].TakerPays.value, '100');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[2].TakerGets.value, '10');
|
assert(book._offersAutobridged[2].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[2].TakerPays.value, '100');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[2].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - update funded amount - first two owners equal', function() {
|
it('Compute autobridged offers - update funded amount - first two owners equal', function(done) {
|
||||||
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 +710,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 +724,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 +736,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 +747,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,46 +759,51 @@ describe('OrderBook Autobridging', function() {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 4);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 4);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '90');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '90');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '90');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '90');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5');
|
||||||
|
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '10');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerGets.value, '5');
|
assert(book._offersAutobridged[1].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[1].TakerPays.value, '10');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[1].autobridged);
|
assert.strictEqual(book._offersAutobridged[2].TakerGets.value, '25');
|
||||||
|
assert.strictEqual(book._offersAutobridged[2].TakerPays.value, '100');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[2].TakerGets.value, '25');
|
assert(book._offersAutobridged[2].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[2].TakerPays.value, '100');
|
|
||||||
|
|
||||||
assert(book._offersAutobridged[2].autobridged);
|
assert.strictEqual(book._offersAutobridged[3].TakerGets.value, '20');
|
||||||
|
assert.strictEqual(book._offersAutobridged[3].TakerPays.value, '80');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[3].TakerGets.value, '20');
|
assert(book._offersAutobridged[3].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[3].TakerPays.value, '80');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[3].autobridged);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Compute autobridged offers - unfunded offer - owners equal', function() {
|
it('Compute autobridged offers - unfunded offer - owners equal', function(done) {
|
||||||
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 +818,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,13 +830,17 @@ describe('OrderBook Autobridging', function() {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
book.computeAutobridgedOffers();
|
book._gotOffersFromLegOne = book._gotOffersFromLegTwo = true;
|
||||||
|
book.computeAutobridgedOffers(() => {
|
||||||
|
assert.strictEqual(book._offersAutobridged.length, 1);
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged.length, 1);
|
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '75');
|
||||||
|
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '75');
|
||||||
|
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerGets.value, '75');
|
assert(book._offersAutobridged[0].autobridged);
|
||||||
assert.strictEqual(book._offersAutobridged[0].TakerPays.value, '75');
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
assert(book._offersAutobridged[0].autobridged);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -671,6 +671,7 @@ describe('Remote', function() {
|
|||||||
function() {
|
function() {
|
||||||
const message = require('./fixtures/transaction-offercreate');
|
const message = require('./fixtures/transaction-offercreate');
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
remote._ledger_current_index = 32570;
|
||||||
const orderbook = remote.createOrderBook({
|
const orderbook = remote.createOrderBook({
|
||||||
currency_gets: 'USD',
|
currency_gets: 'USD',
|
||||||
issuer_gets: 'rJy64aCJLP3vf8o3WPKn4iQKtfpjh6voAR',
|
issuer_gets: 'rJy64aCJLP3vf8o3WPKn4iQKtfpjh6voAR',
|
||||||
|
|||||||
Reference in New Issue
Block a user