mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-19 11:45:49 +00:00
Merge pull request #133 from ripple/develop
Track unfunded orders in the orderbook
This commit is contained in:
@@ -160,157 +160,64 @@ Amount.prototype.add = function(v) {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn this amount into its inverse.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
Amount.prototype._invert = function() {
|
||||
this._value = consts.bi_1e32.divide(this._value);
|
||||
this._offset = -32 - this._offset;
|
||||
this.canonicalize();
|
||||
|
||||
return this;
|
||||
// Result in terms of this currency and issuer.
|
||||
Amount.prototype.subtract = function(v) {
|
||||
// Correctness over speed, less code has less bugs, reuse add code.
|
||||
return this.add(Amount.from_json(v).negate());
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the inverse of this amount.
|
||||
*
|
||||
* @return {Amount} New Amount object with same currency and issuer, but the
|
||||
* inverse of the value.
|
||||
*/
|
||||
Amount.prototype.invert = function() {
|
||||
return this.copy()._invert();
|
||||
};
|
||||
|
||||
Amount.prototype.canonicalize = function() {
|
||||
if (!(this._value instanceof BigInteger)) {
|
||||
// NaN.
|
||||
// nothing
|
||||
} else if (this._is_native) {
|
||||
// Native.
|
||||
if (this._value.equals(BigInteger.ZERO)) {
|
||||
this._offset = 0;
|
||||
this._is_negative = false;
|
||||
} else {
|
||||
// Normalize _offset to 0.
|
||||
|
||||
while (this._offset < 0) {
|
||||
this._value = this._value.divide(consts.bi_10);
|
||||
this._offset += 1;
|
||||
}
|
||||
|
||||
while (this._offset > 0) {
|
||||
this._value = this._value.multiply(consts.bi_10);
|
||||
this._offset -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Make sure not bigger than supported. Throw if so.
|
||||
} else if (this.is_zero()) {
|
||||
this._offset = -100;
|
||||
this._is_negative = false;
|
||||
} else {
|
||||
// Normalize mantissa to valid range.
|
||||
|
||||
while (this._value.compareTo(consts.bi_man_min_value) < 0) {
|
||||
this._value = this._value.multiply(consts.bi_10);
|
||||
this._offset -= 1;
|
||||
}
|
||||
|
||||
while (this._value.compareTo(consts.bi_man_max_value) > 0) {
|
||||
this._value = this._value.divide(consts.bi_10);
|
||||
this._offset += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Amount.prototype.clone = function(negate) {
|
||||
return this.copyTo(new Amount(), negate);
|
||||
};
|
||||
|
||||
Amount.prototype.compareTo = function(v) {
|
||||
// Result in terms of this' currency and issuer.
|
||||
// XXX Diverges from cpp.
|
||||
Amount.prototype.multiply = function(v) {
|
||||
var result;
|
||||
|
||||
if (!this.is_comparable(v)) {
|
||||
result = Amount.NaN();
|
||||
} else if (this._is_negative !== v._is_negative) {
|
||||
// Different sign.
|
||||
result = this._is_negative ? -1 : 1;
|
||||
} else if (this._value.equals(BigInteger.ZERO)) {
|
||||
// Same sign: positive.
|
||||
result = v._value.equals(BigInteger.ZERO) ? 0 : -1;
|
||||
} else if (v._value.equals(BigInteger.ZERO)) {
|
||||
// Same sign: positive.
|
||||
result = 1;
|
||||
} else if (!this._is_native && this._offset > v._offset) {
|
||||
result = this._is_negative ? -1 : 1;
|
||||
} else if (!this._is_native && this._offset < v._offset) {
|
||||
result = this._is_negative ? 1 : -1;
|
||||
v = Amount.from_json(v);
|
||||
|
||||
if (this.is_zero()) {
|
||||
result = this;
|
||||
} else if (v.is_zero()) {
|
||||
result = this.clone();
|
||||
result._value = BigInteger.ZERO;
|
||||
} else {
|
||||
result = this._value.compareTo(v._value);
|
||||
if (result > 0) {
|
||||
result = this._is_negative ? -1 : 1;
|
||||
} else if (result < 0) {
|
||||
result = this._is_negative ? 1 : -1;
|
||||
var v1 = this._value;
|
||||
var o1 = this._offset;
|
||||
var v2 = v._value;
|
||||
var o2 = v._offset;
|
||||
|
||||
if (this.is_native()) {
|
||||
while (v1.compareTo(consts.bi_man_min_value) < 0) {
|
||||
v1 = v1.multiply(consts.bi_10);
|
||||
o1 -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (v.is_native()) {
|
||||
while (v2.compareTo(consts.bi_man_min_value) < 0) {
|
||||
v2 = v2.multiply(consts.bi_10);
|
||||
o2 -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
result = new Amount();
|
||||
result._offset = o1 + o2 + 14;
|
||||
result._value = v1.multiply(v2).divide(consts.bi_1e14).add(consts.bi_7);
|
||||
result._is_native = this._is_native;
|
||||
result._is_negative = this._is_negative !== v._is_negative;
|
||||
result._currency = this._currency;
|
||||
result._issuer = this._issuer;
|
||||
|
||||
result.canonicalize();
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Make d a copy of this. Returns d.
|
||||
// Modification of objects internally refered to is not allowed.
|
||||
Amount.prototype.copyTo = function(d, negate) {
|
||||
if (typeof this._value === 'object') {
|
||||
this._value.copyTo(d._value);
|
||||
} else {
|
||||
d._value = this._value;
|
||||
}
|
||||
|
||||
d._offset = this._offset;
|
||||
d._is_native = this._is_native;
|
||||
d._is_negative = negate
|
||||
? !this._is_negative // Negating.
|
||||
: this._is_negative; // Just copying.
|
||||
|
||||
d._currency = this._currency;
|
||||
d._issuer = this._issuer;
|
||||
|
||||
// Prevent negative zero
|
||||
if (d.is_zero()) {
|
||||
d._is_negative = false;
|
||||
}
|
||||
|
||||
return d;
|
||||
};
|
||||
|
||||
Amount.prototype.currency = function() {
|
||||
return this._currency;
|
||||
};
|
||||
|
||||
Amount.prototype.equals = function(d, ignore_issuer) {
|
||||
if (typeof d === 'string') {
|
||||
return this.equals(Amount.from_json(d));
|
||||
}
|
||||
|
||||
var result = true;
|
||||
|
||||
result = !((!this.is_valid() || !d.is_valid())
|
||||
|| (this._is_native !== d._is_native)
|
||||
|| (!this._value.equals(d._value) || this._offset !== d._offset)
|
||||
|| (this._is_negative !== d._is_negative)
|
||||
|| (!this._is_native && (!this._currency.equals(d._currency) || !ignore_issuer && !this._issuer.equals(d._issuer))));
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Result in terms of this' currency and issuer.
|
||||
Amount.prototype.divide = function(d) {
|
||||
var result;
|
||||
|
||||
d = Amount.from_json(d);
|
||||
|
||||
if (d.is_zero()) {
|
||||
throw new Error('divide by zero');
|
||||
}
|
||||
@@ -359,8 +266,6 @@ Amount.prototype.divide = function(d) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate a ratio between two amounts.
|
||||
*
|
||||
* This function calculates a ratio - such as a price - between two Amount
|
||||
* objects.
|
||||
*
|
||||
@@ -382,14 +287,15 @@ Amount.prototype.divide = function(d) {
|
||||
Amount.prototype.ratio_human = function(denominator, opts) {
|
||||
opts = extend({ }, opts);
|
||||
|
||||
var numerator = this;
|
||||
|
||||
if (typeof denominator === 'number' && parseInt(denominator, 10) === denominator) {
|
||||
// Special handling of integer arguments
|
||||
denominator = Amount.from_json('' + denominator + '.0');
|
||||
denominator = Amount.from_json(String(denominator) + '.0');
|
||||
} else {
|
||||
denominator = Amount.from_json(denominator);
|
||||
}
|
||||
|
||||
var numerator = this;
|
||||
denominator = Amount.from_json(denominator);
|
||||
|
||||
// If either operand is NaN, the result is NaN.
|
||||
@@ -397,6 +303,10 @@ Amount.prototype.ratio_human = function(denominator, opts) {
|
||||
return Amount.NaN();
|
||||
}
|
||||
|
||||
if (denominator.is_zero()) {
|
||||
return Amount.NaN();
|
||||
}
|
||||
|
||||
// Apply interest/demurrage
|
||||
//
|
||||
// We only need to apply it to the second factor, because the currency unit of
|
||||
@@ -482,6 +392,155 @@ Amount.prototype.product_human = function(factor, opts) {
|
||||
return product;
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn this amount into its inverse.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
Amount.prototype._invert = function() {
|
||||
this._value = consts.bi_1e32.divide(this._value);
|
||||
this._offset = -32 - this._offset;
|
||||
this.canonicalize();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the inverse of this amount.
|
||||
*
|
||||
* @return {Amount} New Amount object with same currency and issuer, but the
|
||||
* inverse of the value.
|
||||
*/
|
||||
Amount.prototype.invert = function() {
|
||||
return this.copy()._invert();
|
||||
};
|
||||
|
||||
Amount.prototype.canonicalize = function() {
|
||||
if (!(this._value instanceof BigInteger)) {
|
||||
// NaN.
|
||||
// nothing
|
||||
} else if (this._is_native) {
|
||||
// Native.
|
||||
if (this._value.equals(BigInteger.ZERO)) {
|
||||
this._offset = 0;
|
||||
this._is_negative = false;
|
||||
} else {
|
||||
// Normalize _offset to 0.
|
||||
|
||||
while (this._offset < 0) {
|
||||
this._value = this._value.divide(consts.bi_10);
|
||||
this._offset += 1;
|
||||
}
|
||||
|
||||
while (this._offset > 0) {
|
||||
this._value = this._value.multiply(consts.bi_10);
|
||||
this._offset -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Make sure not bigger than supported. Throw if so.
|
||||
} else if (this.is_zero()) {
|
||||
this._offset = -100;
|
||||
this._is_negative = false;
|
||||
} else {
|
||||
// Normalize mantissa to valid range.
|
||||
|
||||
while (this._value.compareTo(consts.bi_man_min_value) < 0) {
|
||||
this._value = this._value.multiply(consts.bi_10);
|
||||
this._offset -= 1;
|
||||
}
|
||||
|
||||
while (this._value.compareTo(consts.bi_man_max_value) > 0) {
|
||||
this._value = this._value.divide(consts.bi_10);
|
||||
this._offset += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Amount.prototype.clone = function(negate) {
|
||||
return this.copyTo(new Amount(), negate);
|
||||
};
|
||||
|
||||
Amount.prototype.compareTo = function(v) {
|
||||
var result;
|
||||
|
||||
v = Amount.from_json(v);
|
||||
|
||||
if (!this.is_comparable(v)) {
|
||||
result = Amount.NaN();
|
||||
} else if (this._is_negative !== v._is_negative) {
|
||||
// Different sign.
|
||||
result = this._is_negative ? -1 : 1;
|
||||
} else if (this._value.equals(BigInteger.ZERO)) {
|
||||
// Same sign: positive.
|
||||
result = v._value.equals(BigInteger.ZERO) ? 0 : -1;
|
||||
} else if (v._value.equals(BigInteger.ZERO)) {
|
||||
// Same sign: positive.
|
||||
result = 1;
|
||||
} else if (!this._is_native && this._offset > v._offset) {
|
||||
result = this._is_negative ? -1 : 1;
|
||||
} else if (!this._is_native && this._offset < v._offset) {
|
||||
result = this._is_negative ? 1 : -1;
|
||||
} else {
|
||||
result = this._value.compareTo(v._value);
|
||||
if (result > 0) {
|
||||
result = this._is_negative ? -1 : 1;
|
||||
} else if (result < 0) {
|
||||
result = this._is_negative ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Make d a copy of this. Returns d.
|
||||
// Modification of objects internally refered to is not allowed.
|
||||
Amount.prototype.copyTo = function(d, negate) {
|
||||
if (typeof this._value === 'object') {
|
||||
this._value.copyTo(d._value);
|
||||
} else {
|
||||
d._value = this._value;
|
||||
}
|
||||
|
||||
d._offset = this._offset;
|
||||
d._is_native = this._is_native;
|
||||
d._is_negative = negate
|
||||
? !this._is_negative // Negating.
|
||||
: this._is_negative; // Just copying.
|
||||
|
||||
d._currency = this._currency;
|
||||
d._issuer = this._issuer;
|
||||
|
||||
// Prevent negative zero
|
||||
if (d.is_zero()) {
|
||||
d._is_negative = false;
|
||||
}
|
||||
|
||||
return d;
|
||||
};
|
||||
|
||||
Amount.prototype.currency = function() {
|
||||
return this._currency;
|
||||
};
|
||||
|
||||
Amount.prototype.equals = function(d, ignore_issuer) {
|
||||
if (typeof d === 'string') {
|
||||
return this.equals(Amount.from_json(d));
|
||||
}
|
||||
|
||||
var result = true;
|
||||
|
||||
result = !((!this.is_valid() || !d.is_valid())
|
||||
|| (this._is_native !== d._is_native)
|
||||
|| (!this._value.equals(d._value) || this._offset !== d._offset)
|
||||
|| (this._is_negative !== d._is_negative)
|
||||
|| (!this._is_native && (!this._currency.equals(d._currency) || !ignore_issuer && !this._issuer.equals(d._issuer))));
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// True if Amounts are valid and both native or non-native.
|
||||
Amount.prototype.is_comparable = function(v) {
|
||||
return this._value instanceof BigInteger
|
||||
@@ -520,50 +579,6 @@ Amount.prototype.issuer = function() {
|
||||
return this._issuer;
|
||||
};
|
||||
|
||||
// Result in terms of this' currency and issuer.
|
||||
// XXX Diverges from cpp.
|
||||
Amount.prototype.multiply = function(v) {
|
||||
var result;
|
||||
|
||||
if (this.is_zero()) {
|
||||
result = this;
|
||||
} else if (v.is_zero()) {
|
||||
result = this.clone();
|
||||
result._value = BigInteger.ZERO;
|
||||
} else {
|
||||
var v1 = this._value;
|
||||
var o1 = this._offset;
|
||||
var v2 = v._value;
|
||||
var o2 = v._offset;
|
||||
|
||||
if (this.is_native()) {
|
||||
while (v1.compareTo(consts.bi_man_min_value) < 0) {
|
||||
v1 = v1.multiply(consts.bi_10);
|
||||
o1 -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (v.is_native()) {
|
||||
while (v2.compareTo(consts.bi_man_min_value) < 0) {
|
||||
v2 = v2.multiply(consts.bi_10);
|
||||
o2 -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
result = new Amount();
|
||||
result._offset = o1 + o2 + 14;
|
||||
result._value = v1.multiply(v2).divide(consts.bi_1e14).add(consts.bi_7);
|
||||
result._is_native = this._is_native;
|
||||
result._is_negative = this._is_negative !== v._is_negative;
|
||||
result._currency = this._currency;
|
||||
result._issuer = this._issuer;
|
||||
|
||||
result.canonicalize();
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return a new value.
|
||||
Amount.prototype.negate = function() {
|
||||
return this.clone('NEGATE');
|
||||
@@ -953,12 +968,6 @@ Amount.prototype.set_issuer = function(issuer) {
|
||||
return this;
|
||||
};
|
||||
|
||||
// Result in terms of this' currency and issuer.
|
||||
Amount.prototype.subtract = function(v) {
|
||||
// Correctness over speed, less code has less bugs, reuse add code.
|
||||
return this.add(Amount.from_json(v).negate());
|
||||
};
|
||||
|
||||
Amount.prototype.to_number = function(allow_nan) {
|
||||
var s = this.to_text(allow_nan);
|
||||
return typeof s === 'string' ? Number(s) : s;
|
||||
|
||||
@@ -5,47 +5,51 @@ var Amount = require('./amount').Amount;
|
||||
|
||||
/**
|
||||
* Meta data processing facility
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} transaction metadata
|
||||
*/
|
||||
|
||||
function Meta(raw_data) {
|
||||
function Meta(data) {
|
||||
var self = this;
|
||||
|
||||
this.nodes = [ ];
|
||||
|
||||
raw_data.AffectedNodes.forEach(function(an) {
|
||||
var result = { };
|
||||
if (typeof data !== 'object') {
|
||||
throw new TypeError('Missing metadata');
|
||||
}
|
||||
|
||||
if ((result.diffType = self.diffType(an))) {
|
||||
an = an[result.diffType];
|
||||
if (!Array.isArray(data.AffectedNodes)) {
|
||||
throw new TypeError('Metadata missing AffectedNodes');
|
||||
}
|
||||
|
||||
result.entryType = an.LedgerEntryType;
|
||||
result.ledgerIndex = an.LedgerIndex;
|
||||
result.fields = extend({}, an.PreviousFields, an.NewFields, an.FinalFields);
|
||||
result.fieldsPrev = an.PreviousFields || {};
|
||||
result.fieldsNew = an.NewFields || {};
|
||||
result.fieldsFinal = an.FinalFields || {};
|
||||
|
||||
// getAffectedBooks will set this
|
||||
// result.bookKey = undefined;
|
||||
|
||||
self.nodes.push(result);
|
||||
}
|
||||
});
|
||||
data.AffectedNodes.forEach(this.addNode, this);
|
||||
};
|
||||
|
||||
Meta.node_types = [
|
||||
Meta.nodeTypes = [
|
||||
'CreatedNode',
|
||||
'ModifiedNode',
|
||||
'DeletedNode'
|
||||
];
|
||||
|
||||
Meta.prototype.diffType = function(an) {
|
||||
var result = false;
|
||||
Meta.amountFieldsAffectingIssuer = [
|
||||
'LowLimit',
|
||||
'HighLimit',
|
||||
'TakerPays',
|
||||
'TakerGets'
|
||||
];
|
||||
|
||||
for (var i=0; i<Meta.node_types.length; i++) {
|
||||
var x = Meta.node_types[i];
|
||||
if (an.hasOwnProperty(x)) {
|
||||
result = x;
|
||||
/**
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Meta.prototype.getNodeType = function(node) {
|
||||
var result = null;
|
||||
|
||||
for (var i=0; i<Meta.nodeTypes.length; i++) {
|
||||
var type = Meta.nodeTypes[i];
|
||||
if (node.hasOwnProperty(type)) {
|
||||
result = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -53,6 +57,63 @@ Meta.prototype.diffType = function(an) {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add node to metadata
|
||||
*
|
||||
* @param {Object} node
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Meta.prototype.addNode = function(node) {
|
||||
this._affectedAccounts = void(0);
|
||||
this._affectedBooks = void(0);
|
||||
|
||||
var result = { };
|
||||
|
||||
if ((result.nodeType = this.getNodeType(node))) {
|
||||
node = node[result.nodeType];
|
||||
|
||||
result.diffType = result.nodeType;
|
||||
result.entryType = node.LedgerEntryType;
|
||||
result.ledgerIndex = node.LedgerIndex;
|
||||
result.fields = extend({ }, node.PreviousFields, node.NewFields, node.FinalFields);
|
||||
result.fieldsPrev = node.PreviousFields || { };
|
||||
result.fieldsNew = node.NewFields || { };
|
||||
result.fieldsFinal = node.FinalFields || { };
|
||||
|
||||
// getAffectedBooks will set this
|
||||
// result.bookKey = undefined;
|
||||
|
||||
this.nodes.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get affected nodes array
|
||||
*
|
||||
* @param {Object} filter options
|
||||
* @return {Array} nodes
|
||||
*/
|
||||
|
||||
Meta.prototype.getNodes = function(options) {
|
||||
if (typeof options === 'object') {
|
||||
return this.nodes.filter(function(node) {
|
||||
if (options.nodeType && options.nodeType !== node.nodeType) {
|
||||
return false;
|
||||
}
|
||||
if (options.entryType && options.entryType !== node.entryType) {
|
||||
return false;
|
||||
}
|
||||
if (options.bookKey && options.bookKey !== node.bookKey) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
return this.nodes;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute a function on each affected node.
|
||||
*
|
||||
@@ -61,7 +122,7 @@ Meta.prototype.diffType = function(an) {
|
||||
*
|
||||
* {
|
||||
* // Type of diff, e.g. CreatedNode, ModifiedNode
|
||||
* diffType: 'CreatedNode'
|
||||
* nodeType: 'CreatedNode'
|
||||
*
|
||||
* // Type of node affected, e.g. RippleState, AccountRoot
|
||||
* entryType: 'RippleState',
|
||||
@@ -72,7 +133,7 @@ Meta.prototype.diffType = function(an) {
|
||||
* // Contains all fields with later versions taking precedence
|
||||
* //
|
||||
* // This is a shorthand for doing things like checking which account
|
||||
* // this affected without having to check the diffType.
|
||||
* // this affected without having to check the nodeType.
|
||||
* fields: {...},
|
||||
*
|
||||
* // Old fields (before the change)
|
||||
@@ -88,43 +149,39 @@ Meta.prototype.diffType = function(an) {
|
||||
* The second parameter to the callback is the index of the node in the metadata
|
||||
* (first entry is index 0).
|
||||
*/
|
||||
Meta.prototype.each = function(fn) {
|
||||
for (var i = 0, l = this.nodes.length; i < l; i++) {
|
||||
fn(this.nodes[i], i);
|
||||
}
|
||||
};
|
||||
|
||||
([
|
||||
[
|
||||
'forEach',
|
||||
'map',
|
||||
'filter',
|
||||
'every',
|
||||
'some',
|
||||
'reduce'
|
||||
]).forEach(function(fn) {
|
||||
].forEach(function(fn) {
|
||||
Meta.prototype[fn] = function() {
|
||||
return Array.prototype[fn].apply(this.nodes, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
var amountFieldsAffectingIssuer = [
|
||||
'LowLimit',
|
||||
'HighLimit',
|
||||
'TakerPays',
|
||||
'TakerGets'
|
||||
];
|
||||
Meta.prototype.each = Meta.prototype.forEach;
|
||||
|
||||
Meta.prototype.getAffectedAccounts = function(from) {
|
||||
if (this._affectedAccounts) {
|
||||
return this._affectedAccounts;
|
||||
}
|
||||
|
||||
Meta.prototype.getAffectedAccounts = function() {
|
||||
var accounts = [ ];
|
||||
|
||||
// This code should match the behavior of the C++ method:
|
||||
// TransactionMetaSet::getAffectedAccounts
|
||||
this.nodes.forEach(function(an) {
|
||||
var fields = (an.diffType === 'CreatedNode') ? an.fieldsNew : an.fieldsFinal;
|
||||
for (var i in fields) {
|
||||
var field = fields[i];
|
||||
for (var i=0; i<this.nodes.length; i++) {
|
||||
var node = this.nodes[i];
|
||||
var fields = (node.nodeType === 'CreatedNode') ? node.fieldsNew : node.fieldsFinal;
|
||||
for (var fieldName in fields) {
|
||||
var field = fields[fieldName];
|
||||
if (typeof field === 'string' && UInt160.is_valid(field)) {
|
||||
accounts.push(field);
|
||||
} else if (amountFieldsAffectingIssuer.indexOf(i) !== -1) {
|
||||
} else if (~Meta.amountFieldsAffectingIssuer.indexOf(fieldName)) {
|
||||
var amount = Amount.from_json(field);
|
||||
var issuer = amount.issuer();
|
||||
if (issuer.is_valid() && !issuer.is_zero()) {
|
||||
@@ -132,43 +189,53 @@ Meta.prototype.getAffectedAccounts = function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return utils.arrayUnique(accounts);
|
||||
this._affectedAccounts = utils.arrayUnique(accounts);
|
||||
|
||||
return this._affectedAccounts;
|
||||
};
|
||||
|
||||
Meta.prototype.getAffectedBooks = function() {
|
||||
if (this._affectedBooks) {
|
||||
return this._affectedBooks;
|
||||
}
|
||||
|
||||
var books = [ ];
|
||||
|
||||
this.nodes.forEach(function(an) {
|
||||
if (an.entryType !== 'Offer') {
|
||||
return;
|
||||
for (var i=0; i<this.nodes.length; i++) {
|
||||
var node = this.nodes[i];
|
||||
|
||||
if (node.entryType !== 'Offer') {
|
||||
continue;
|
||||
}
|
||||
|
||||
var gets = Amount.from_json(an.fields.TakerGets);
|
||||
var pays = Amount.from_json(an.fields.TakerPays);
|
||||
|
||||
var gets = Amount.from_json(node.fields.TakerGets);
|
||||
var pays = Amount.from_json(node.fields.TakerPays);
|
||||
var getsKey = gets.currency().to_json();
|
||||
var paysKey = pays.currency().to_json();
|
||||
|
||||
if (getsKey !== 'XRP') {
|
||||
getsKey += '/' + gets.issuer().to_json();
|
||||
}
|
||||
|
||||
var paysKey = pays.currency().to_json();
|
||||
if (paysKey !== 'XRP') {
|
||||
paysKey += '/' + pays.issuer().to_json();
|
||||
}
|
||||
|
||||
var key = [ getsKey, paysKey ].join(':');
|
||||
var key = getsKey + ':' + paysKey;
|
||||
|
||||
// Hell of a lot of work, so we are going to cache this. We can use this
|
||||
// later to good effect in OrderBook.notify to make sure we only process
|
||||
// pertinent offers.
|
||||
an.bookKey = key;
|
||||
node.bookKey = key;
|
||||
|
||||
books.push(key);
|
||||
});
|
||||
}
|
||||
|
||||
return utils.arrayUnique(books);
|
||||
this._affectedBooks = utils.arrayUnique(books);
|
||||
|
||||
return this._affectedBooks;
|
||||
};
|
||||
|
||||
exports.Meta = Meta;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1480,19 +1480,19 @@ Remote.prototype.requestTxHistory = function(start, callback) {
|
||||
*/
|
||||
|
||||
Remote.prototype.requestBookOffers = function(gets, pays, taker, callback) {
|
||||
var lastArg = arguments[arguments.length - 1];
|
||||
|
||||
if (gets.hasOwnProperty('gets') || gets.hasOwnProperty('taker_gets')) {
|
||||
var options = gets;
|
||||
// This would mutate the `lastArg` in `arguments` to be `null` and is
|
||||
// redundant. Once upon a time, some awkward code was written f(g, null,
|
||||
// null, cb) ...
|
||||
// callback = pays;
|
||||
callback = pays;
|
||||
taker = options.taker;
|
||||
pays = options.pays || options.taker_pays;
|
||||
gets = options.gets || options.taker_gets;
|
||||
}
|
||||
|
||||
var lastArg = arguments[arguments.length - 1];
|
||||
|
||||
if (typeof lastArg === 'function') {
|
||||
callback = lastArg;
|
||||
}
|
||||
|
||||
1057
test/orderbook-test.js
Normal file
1057
test/orderbook-test.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user