mirror of
https://github.com/Xahau/xahau.js.git
synced 2026-08-23 00:20:52 +00:00
Merge branch 'develop' of https://github.com/ripple/ripple-lib into develop
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.7.17",
|
||||
"version": "0.7.18",
|
||||
"description": "Ripple JavaScript client library",
|
||||
"files": [
|
||||
"src/js/ripple/*.js",
|
||||
|
||||
@@ -739,7 +739,7 @@ Amount.prototype.parse_value = function (j) {
|
||||
|
||||
if ('number' === typeof j) {
|
||||
this._is_negative = j < 0;
|
||||
this._value = new BigInteger(this._is_negative ? -j : j);
|
||||
this._value = new BigInteger(Math.abs(j));
|
||||
this._offset = 0;
|
||||
|
||||
this.canonicalize();
|
||||
@@ -795,13 +795,7 @@ Amount.prototype.parse_value = function (j) {
|
||||
};
|
||||
|
||||
Amount.prototype.set_currency = function (c) {
|
||||
if ('string' === typeof c) {
|
||||
this._currency = Currency.from_json(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._currency = c;
|
||||
}
|
||||
this._currency = Currency.from_json(c);
|
||||
this._is_native = this._currency.is_native();
|
||||
|
||||
return this;
|
||||
|
||||
@@ -22,9 +22,19 @@ Currency.json_rewrite = function (j) {
|
||||
};
|
||||
|
||||
Currency.from_json = function (j) {
|
||||
if (j instanceof Currency) return j.clone();
|
||||
else if ('string' === typeof j || 'number' === typeof j) return (new Currency()).parse_json(j);
|
||||
else return new Currency(); // NaN
|
||||
if (j instanceof Currency) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return new Currency().parse_json(j);
|
||||
}
|
||||
};
|
||||
|
||||
Currency.from_bytes = function (j) {
|
||||
if (j instanceof Currency) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return new Currency().parse_bytes(j);
|
||||
}
|
||||
};
|
||||
|
||||
Currency.is_valid = function (j) {
|
||||
@@ -49,23 +59,56 @@ Currency.prototype.equals = function (d) {
|
||||
|
||||
// this._value = NaN on error.
|
||||
Currency.prototype.parse_json = function (j) {
|
||||
if ("" === j || "0" === j || "XRP" === j) {
|
||||
this._value = 0;
|
||||
}
|
||||
else if ('number' === typeof j) {
|
||||
if (j instanceof Currency) {
|
||||
this._value = j;
|
||||
} else if ('string' === typeof j) {
|
||||
if (j === "" || j === "0" || j === "XRP") {
|
||||
// XRP is never allowed as a Currency object
|
||||
this._value = 0;
|
||||
} else if (j.length === 3) {
|
||||
this._value = j;
|
||||
} else {
|
||||
this._value = NaN;
|
||||
}
|
||||
} else if ('number' === typeof j) {
|
||||
// XXX This is a hack
|
||||
this._value = j;
|
||||
}
|
||||
else if ('string' != typeof j || 3 !== j.length) {
|
||||
this._value = NaN;
|
||||
}
|
||||
else {
|
||||
this._value = j;
|
||||
this._value = j;
|
||||
} else if ('string' != typeof j || 3 !== j.length) {
|
||||
this._value = NaN;
|
||||
} else {
|
||||
this._value = j;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Currency.prototype.parse_bytes = function (byte_array) {
|
||||
if (Array.isArray(byte_array) && byte_array.length == 20) {
|
||||
var result;
|
||||
// is it 0 everywhere except 12, 13, 14?
|
||||
var isZeroExceptInStandardPositions = true;
|
||||
for (var i=0; i<20; i++) {
|
||||
isZeroExceptInStandardPositions = isZeroExceptInStandardPositions && (i===12 || i===13 || i===14 || byte_array[0]===0)
|
||||
}
|
||||
if (isZeroExceptInStandardPositions) {
|
||||
var currencyCode = String.fromCharCode(byte_array[12]) + String.fromCharCode(byte_array[13]) + String.fromCharCode(byte_array[14]);
|
||||
if (/^[A-Z]{3}$/.test(currencyCode) && currencyCode !== "XRP" ) {
|
||||
this._value = currencyCode;
|
||||
} else if (currencyCode === "\0\0\0") {
|
||||
this._value = 0;
|
||||
} else {
|
||||
this._value = NaN;
|
||||
}
|
||||
} else {
|
||||
// XXX Should support non-standard currency codes
|
||||
this._value = NaN;
|
||||
}
|
||||
} else {
|
||||
this._value = NaN;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Currency.prototype.is_native = function () {
|
||||
return !isNaN(this._value) && !this._value;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,9 @@ exports.UInt160 = require('./amount').UInt160;
|
||||
exports.Seed = require('./amount').Seed;
|
||||
exports.Transaction = require('./transaction').Transaction;
|
||||
exports.Meta = require('./meta').Meta;
|
||||
exports.SerializedObject = require('./serializedobject').SerializedObject;
|
||||
|
||||
exports.binformat = require('./binformat');
|
||||
exports.utils = require('./utils');
|
||||
|
||||
// Important: We do not guarantee any specific version of SJCL or for any
|
||||
|
||||
@@ -5,8 +5,16 @@ var binformat = require('./binformat'),
|
||||
|
||||
var UInt256 = require('./uint256').UInt256;
|
||||
|
||||
var SerializedObject = function () {
|
||||
this.buffer = [];
|
||||
var SerializedObject = function (buf) {
|
||||
if (Array.isArray(buf)) {
|
||||
this.buffer = buf;
|
||||
} else if ("string" === typeof buf) {
|
||||
this.buffer = sjcl.codec.bytes.fromBits(sjcl.codec.hex.toBits(buf));
|
||||
} else if (!buf) {
|
||||
this.buffer = [];
|
||||
} else {
|
||||
throw new Error("Invalid buffer passed.");
|
||||
}
|
||||
this.pointer = 0;
|
||||
};
|
||||
|
||||
@@ -45,6 +53,23 @@ SerializedObject.prototype.append = function (bytes) {
|
||||
this.pointer += bytes.length;
|
||||
};
|
||||
|
||||
SerializedObject.prototype.resetPointer = function () {
|
||||
this.pointer = 0;
|
||||
};
|
||||
|
||||
SerializedObject.prototype.read = function (numberOfBytes) {
|
||||
var start = this.pointer;
|
||||
var end = start+numberOfBytes;
|
||||
if (end > this.buffer.length) {
|
||||
throw new Error("There aren't that many bytes left to read.");
|
||||
} else {
|
||||
var result = this.buffer.slice(start,end);
|
||||
this.pointer = end;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SerializedObject.prototype.to_bits = function ()
|
||||
{
|
||||
return sjcl.codec.bytes.toBits(this.buffer);
|
||||
|
||||
@@ -11,7 +11,8 @@ var extend = require('extend'),
|
||||
sjcl = require('../../../build/sjcl');
|
||||
|
||||
var amount = require('./amount'),
|
||||
UInt160 = amount.UInt160,
|
||||
UInt128 = require('./uint128').UInt128,
|
||||
UInt160 = require('./uint160').UInt160,
|
||||
UInt256 = require('./uint256').UInt256,
|
||||
Amount = amount.Amount,
|
||||
Currency= amount.Currency;
|
||||
@@ -20,17 +21,32 @@ var amount = require('./amount'),
|
||||
var hex = sjcl.codec.hex,
|
||||
bytes = sjcl.codec.bytes;
|
||||
|
||||
var jsbn = require('./jsbn');
|
||||
var BigInteger = jsbn.BigInteger;
|
||||
|
||||
|
||||
var SerializedType = function (methods) {
|
||||
extend(this, methods);
|
||||
};
|
||||
|
||||
SerializedType.prototype.serialize_hex = function (so, hexData) {
|
||||
function serialize_hex(so, hexData, noLength) {
|
||||
var byteData = bytes.fromBits(hex.toBits(hexData));
|
||||
this.serialize_varint(so, byteData.length);
|
||||
if (!noLength) {
|
||||
SerializedType.serialize_varint(so, byteData.length);
|
||||
}
|
||||
so.append(byteData);
|
||||
};
|
||||
|
||||
SerializedType.prototype.serialize_varint = function (so, val) {
|
||||
|
||||
|
||||
/**
|
||||
* parses bytes as hex
|
||||
*/
|
||||
function convert_bytes_to_hex (byte_array) {
|
||||
return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(byte_array));
|
||||
}
|
||||
|
||||
SerializedType.serialize_varint = function (so, val) {
|
||||
if (val < 0) {
|
||||
throw new Error("Variable integers are unsigned.");
|
||||
}
|
||||
@@ -49,84 +65,174 @@ SerializedType.prototype.serialize_varint = function (so, val) {
|
||||
} else throw new Error("Variable integer overflow.");
|
||||
};
|
||||
|
||||
|
||||
SerializedType.parse_varint = function (so) {
|
||||
var b1 = so.read(1)[0], b2, b3;
|
||||
if (b1 <= 192) {
|
||||
return b1;
|
||||
} else if (b1 <= 240) {
|
||||
b2 = so.read(1)[0];
|
||||
return 193 + (b1-193)*256 + b2;
|
||||
} else if (b1 <= 254) {
|
||||
b2 = so.read(1)[0];
|
||||
b3 = so.read(1)[0];
|
||||
return 12481 + (b1-241)*65536 + b2*256 + b3
|
||||
}
|
||||
else {
|
||||
throw new Error("Invalid varint length indicator");
|
||||
}
|
||||
};
|
||||
|
||||
// In the following, we assume that the inputs are in the proper range. Is this correct?
|
||||
|
||||
// Helper functions for 1-, 2-, and 4-byte integers.
|
||||
|
||||
/**
|
||||
* Convert an integer value into an array of bytes.
|
||||
*
|
||||
* The result is appended to the serialized object ("so").
|
||||
*/
|
||||
function append_byte_array(so, val, bytes) {
|
||||
if ("number" !== typeof val) {
|
||||
throw new Error("Integer is not a number");
|
||||
}
|
||||
if (val < 0 || val >= (Math.pow(256, bytes))) {
|
||||
throw new Error("Integer out of bounds");
|
||||
}
|
||||
var newBytes = [];
|
||||
for (var i=0; i<bytes; i++) {
|
||||
newBytes.unshift(val >>> (i*8) & 0xff);
|
||||
}
|
||||
so.append(newBytes);
|
||||
}
|
||||
|
||||
// Convert a certain number of bytes from the serialized object ("so") into an integer.
|
||||
function readAndSum(so, bytes) {
|
||||
var sum = 0;
|
||||
for (var i = 0; i<bytes; i++) {
|
||||
sum += (so.read(1)[0] << (8*(bytes-1-i)) );
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
var STInt8 = exports.Int8 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append([val & 0xff]);
|
||||
append_byte_array(so, val, 1);
|
||||
},
|
||||
parse: function (so) {
|
||||
return so.read(1)[0];
|
||||
return readAndSum(so, 1);
|
||||
}
|
||||
});
|
||||
|
||||
var STInt16 = exports.Int16 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append([
|
||||
val >>> 8 & 0xff,
|
||||
val & 0xff
|
||||
]);
|
||||
append_byte_array(so, val, 2);
|
||||
/*so.append([
|
||||
val >>> 8 & 0xff,
|
||||
val & 0xff
|
||||
]);*/
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Int16 not implemented");
|
||||
return readAndSum(so, 2);
|
||||
}
|
||||
});
|
||||
|
||||
var STInt32 = exports.Int32 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append([
|
||||
val >>> 24 & 0xff,
|
||||
val >>> 16 & 0xff,
|
||||
val >>> 8 & 0xff,
|
||||
val & 0xff
|
||||
]);
|
||||
append_byte_array(so, val, 4)
|
||||
/*so.append([
|
||||
val >>> 24 & 0xff,
|
||||
val >>> 16 & 0xff,
|
||||
val >>> 8 & 0xff,
|
||||
val & 0xff
|
||||
]);*/
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Int32 not implemented");
|
||||
return readAndSum(so, 4);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var STInt64 = exports.Int64 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Int64 not implemented");
|
||||
var bigNumObject;
|
||||
if ("number" === typeof val) {
|
||||
val = Math.floor(val);
|
||||
if (val < 0) {
|
||||
throw new Error("Negative value for unsigned Int64 is invalid.");
|
||||
}
|
||||
bigNumObject = new BigInteger(""+val, 10);
|
||||
} else if ("string" === typeof val) {
|
||||
if (!/^[0-9A-F]{0,16}$/i.test(val)) {
|
||||
throw new Error("Not a valid hex Int64.");
|
||||
}
|
||||
bigNumObject = new BigInteger(val, 16);
|
||||
} else if (val instanceof BigInteger) {
|
||||
if (val.compareTo(BigInteger.ZERO) < 0) {
|
||||
throw new Error("Negative value for unsigned Int64 is invalid.");
|
||||
}
|
||||
bigNumObject = val;
|
||||
} else {
|
||||
throw new Error("Invalid type for Int64");
|
||||
}
|
||||
|
||||
var hex = bigNumObject.toString(16);
|
||||
if (hex.length > 16) {
|
||||
throw new Error("Int64 is too large");
|
||||
}
|
||||
while (hex.length < 16) {
|
||||
hex = "0" + hex;
|
||||
}
|
||||
return serialize_hex(so, hex, true); //noLength = true
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Int64 not implemented");
|
||||
var hi = readAndSum(so, 4);
|
||||
var lo = readAndSum(so, 4);
|
||||
|
||||
var result = new BigInteger(hi);
|
||||
result.shiftLeft(32);
|
||||
result.add(lo);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
var STHash128 = exports.Hash128 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Hash128 not implemented");
|
||||
var hash = UInt128.from_json(val);
|
||||
if (!hash.is_valid()) {
|
||||
throw new Error("Invalid Hash128");
|
||||
}
|
||||
serialize_hex(so, hash.to_hex(), true); //noLength = true
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Hash128 not implemented");
|
||||
return UInt128.from_bytes(so.read(16));
|
||||
}
|
||||
});
|
||||
|
||||
var STHash256 = exports.Hash256 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
var hash = UInt256.from_json(val);
|
||||
this.serialize_hex(so, hash.to_hex());
|
||||
if (!hash.is_valid()) {
|
||||
throw new Error("Invalid Hash256");
|
||||
}
|
||||
serialize_hex(so, hash.to_hex(), true); //noLength = true
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Hash256 not implemented");
|
||||
return UInt256.from_bytes(so.read(32));
|
||||
}
|
||||
});
|
||||
|
||||
var STHash160 = exports.Hash160 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Hash160 not implemented");
|
||||
var hash = UInt160.from_json(val);
|
||||
if (!hash.is_valid()) {
|
||||
throw new Error("Invalid Hash160");
|
||||
}
|
||||
serialize_hex(so, hash.to_hex(), true); //noLength = true
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Hash160 not implemented");
|
||||
return UInt160.from_bytes(so.read(20));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -134,11 +240,13 @@ var STHash160 = exports.Hash160 = new SerializedType({
|
||||
var STCurrency = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
var currency = val.to_json();
|
||||
if ("string" === typeof currency && currency.length === 3) {
|
||||
if ("XRP" === currency) {
|
||||
serialize_hex(so, UInt160.HEX_ZERO, true);
|
||||
} else if ("string" === typeof currency && currency.length === 3) {
|
||||
var currencyCode = currency.toUpperCase(),
|
||||
currencyData = utils.arraySet(20, 0);
|
||||
|
||||
if (!/^[A-Z]{3}$/.test(currencyCode)) {
|
||||
if (!/^[A-Z]{3}$/.test(currencyCode) || currencyCode === "XRP" ) {
|
||||
throw new Error('Invalid currency code');
|
||||
}
|
||||
|
||||
@@ -152,8 +260,11 @@ var STCurrency = new SerializedType({
|
||||
}
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Currency not implemented");
|
||||
var currency = Currency.from_bytes(so.read(20));
|
||||
if (!currency.is_valid()) {
|
||||
throw new Error("Invalid currency");
|
||||
}
|
||||
return currency;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -216,30 +327,71 @@ var STAmount = exports.Amount = new SerializedType({
|
||||
}
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Amount not implemented");
|
||||
var amount = new Amount();
|
||||
var value_bytes = so.read(8);
|
||||
var is_zero = !(value_bytes[0] & 0x7f);
|
||||
for (var i=1; i<8; i++) {
|
||||
is_zero = is_zero && !value_bytes[i];
|
||||
}
|
||||
if (value_bytes[0] & 0x80) {
|
||||
//non-native
|
||||
var currency = STCurrency.parse(so);
|
||||
var issuer_bytes = so.read(20);
|
||||
var issuer = UInt160.from_bytes(issuer_bytes);
|
||||
|
||||
var offset = ((value_bytes[0] & 0x3f) << 2) + (value_bytes[1] >>> 6) - 97;
|
||||
var mantissa_bytes = value_bytes.slice(1);
|
||||
mantissa_bytes[0] &= 0x3f;
|
||||
var value = new BigInteger(mantissa_bytes, 256);
|
||||
|
||||
if (value.equals(BigInteger.ZERO) && !is_zero ) {
|
||||
throw new Error("Invalid zero representation");
|
||||
}
|
||||
|
||||
amount._value = value;
|
||||
amount._offset = offset;
|
||||
amount._currency = currency;
|
||||
amount._issuer = issuer;
|
||||
amount._is_native = false;
|
||||
|
||||
} else {
|
||||
//native
|
||||
var integer_bytes = value_bytes.slice();
|
||||
integer_bytes[0] &= 0x3f;
|
||||
amount._value = new BigInteger(integer_bytes, 256);
|
||||
amount._is_native = true;
|
||||
}
|
||||
amount._is_negative = !is_zero && !(value_bytes[0] & 0x40);
|
||||
return amount;
|
||||
}
|
||||
});
|
||||
|
||||
var STVL = exports.VariableLength = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
if ("string" === typeof val) this.serialize_hex(so, val);
|
||||
if ("string" === typeof val) serialize_hex(so, val);
|
||||
else throw new Error("Unknown datatype.");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing VL not implemented");
|
||||
var len = this.parse_varint(so);
|
||||
return convert_bytes_to_hex(so.read(len));
|
||||
}
|
||||
});
|
||||
|
||||
var STAccount = exports.Account = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
var account = UInt160.from_json(val);
|
||||
this.serialize_hex(so, account.to_hex());
|
||||
serialize_hex(so, account.to_hex());
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Account not implemented");
|
||||
var len = this.parse_varint(so);
|
||||
if (len !== 20) {
|
||||
throw new Error("Non-standard-length account ID");
|
||||
}
|
||||
var result = UInt160.from_bytes(so.read(len));
|
||||
if (!result.is_valid()) {
|
||||
throw new Error("Invalid Account");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -60,6 +60,15 @@ UInt.from_bits = function (j) {
|
||||
}
|
||||
};
|
||||
|
||||
// Return a new UInt from j.
|
||||
UInt.from_bytes = function (j) {
|
||||
if (j instanceof this) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return (new this()).parse_bytes(j);
|
||||
}
|
||||
};
|
||||
|
||||
// Return a new UInt from j.
|
||||
UInt.from_bn = function (j) {
|
||||
if (j instanceof this) {
|
||||
@@ -157,7 +166,17 @@ UInt.prototype.parse_bits = function (j) {
|
||||
this._value = NaN;
|
||||
} else {
|
||||
var bytes = sjcl.codec.bytes.fromBits(j);
|
||||
this._value = new BigInteger(bytes, 256);
|
||||
this.parse_bytes(bytes);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
UInt.prototype.parse_bytes = function (j) {
|
||||
if (!Array.isArray(j) || j.length !== this.constructor.width) {
|
||||
this._value = NaN;
|
||||
} else {
|
||||
this._value = new BigInteger(j, 256);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
32
src/js/ripple/uint128.js
Normal file
32
src/js/ripple/uint128.js
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
var sjcl = require('../../../build/sjcl');
|
||||
var utils = require('./utils');
|
||||
var config = require('./config');
|
||||
var jsbn = require('./jsbn');
|
||||
var extend = require('extend');
|
||||
|
||||
var BigInteger = jsbn.BigInteger;
|
||||
var nbi = jsbn.nbi;
|
||||
|
||||
var UInt = require('./uint').UInt,
|
||||
Base = require('./base').Base;
|
||||
|
||||
//
|
||||
// UInt128 support
|
||||
//
|
||||
|
||||
var UInt128 = extend(function () {
|
||||
// Internal form: NaN or BigInteger
|
||||
this._value = NaN;
|
||||
}, UInt);
|
||||
|
||||
UInt128.width = 16;
|
||||
UInt128.prototype = extend({}, UInt.prototype);
|
||||
UInt128.prototype.constructor = UInt128;
|
||||
|
||||
var HEX_ZERO = UInt128.HEX_ZERO = "00000000000000000000000000000000";
|
||||
var HEX_ONE = UInt128.HEX_ONE = "00000000000000000000000000000000";
|
||||
var STR_ZERO = UInt128.STR_ZERO = utils.hexToString(HEX_ZERO);
|
||||
var STR_ONE = UInt128.STR_ONE = utils.hexToString(HEX_ONE);
|
||||
|
||||
exports.UInt128 = UInt128;
|
||||
439
test/serializedtypes-test.js
Normal file
439
test/serializedtypes-test.js
Normal file
@@ -0,0 +1,439 @@
|
||||
var buster = require("buster");
|
||||
|
||||
var SerializedObject = require("../src/js/ripple/serializedobject").SerializedObject;
|
||||
var types = require("../src/js/ripple/serializedtypes");
|
||||
|
||||
var jsbn = require('../src/js/ripple/jsbn');
|
||||
var BigInteger = jsbn.BigInteger;
|
||||
|
||||
try {
|
||||
var conf = require('./config');
|
||||
} catch(exception) {
|
||||
var conf = require('./config-example');
|
||||
}
|
||||
|
||||
var config = require('../src/js/ripple/config').load(conf);
|
||||
|
||||
buster.testCase("Serialized types", {
|
||||
"Int8" : {
|
||||
"Serialize 0" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int8.serialize(so, 0);
|
||||
assert.equals(so.to_hex(), "00");
|
||||
},
|
||||
"Serialize 123" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int8.serialize(so, 123);
|
||||
assert.equals(so.to_hex(), "7B");
|
||||
},
|
||||
"Serialize 255" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int8.serialize(so, 255);
|
||||
assert.equals(so.to_hex(), "FF");
|
||||
},
|
||||
"Fail to serialize 256" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int8.serialize(so, 256);
|
||||
});
|
||||
},
|
||||
"Fail to serialize -1" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int8.serialize(so, -1);
|
||||
});
|
||||
},
|
||||
"Serialize 5.5 (should floor)" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int8.serialize(so, 5.5);
|
||||
assert.equals(so.to_hex(), "05");
|
||||
},
|
||||
"Serialize 255.9 (should floor)" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int8.serialize(so, 255.9);
|
||||
assert.equals(so.to_hex(), "FF");
|
||||
},
|
||||
"Fail to serialize null" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int8.serialize(so, null);
|
||||
});
|
||||
},
|
||||
"Fail to serialize 'bla'" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int8.serialize(so, 'bla');
|
||||
});
|
||||
},
|
||||
"Fail to serialize {}" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int8.serialize(so, {});
|
||||
});
|
||||
}
|
||||
},
|
||||
"Int16" : {
|
||||
"Serialize 0" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int16.serialize(so, 0);
|
||||
assert.equals(so.to_hex(), "0000");
|
||||
},
|
||||
"Serialize 123" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int16.serialize(so, 123);
|
||||
assert.equals(so.to_hex(), "007B");
|
||||
},
|
||||
"Serialize 255" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int16.serialize(so, 255);
|
||||
assert.equals(so.to_hex(), "00FF");
|
||||
},
|
||||
"Serialize 256" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int16.serialize(so, 256);
|
||||
assert.equals(so.to_hex(), "0100");
|
||||
},
|
||||
"Serialize 65535" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int16.serialize(so, 65535);
|
||||
assert.equals(so.to_hex(), "FFFF");
|
||||
},
|
||||
"Fail to serialize 65536" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int8.serialize(so, 65536);
|
||||
});
|
||||
},
|
||||
"Fail to serialize -1" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int16.serialize(so, -1);
|
||||
});
|
||||
},
|
||||
"Serialize 123.5 (should floor)" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int16.serialize(so, 123.5);
|
||||
assert.equals(so.to_hex(), "007B");
|
||||
},
|
||||
"Serialize 65535.5 (should floor)" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int16.serialize(so, 65535.5);
|
||||
assert.equals(so.to_hex(), "FFFF");
|
||||
},
|
||||
"Fail to serialize null" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int16.serialize(so, null);
|
||||
});
|
||||
},
|
||||
"Fail to serialize 'bla'" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int16.serialize(so, 'bla');
|
||||
});
|
||||
},
|
||||
"Fail to serialize {}" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int16.serialize(so, {});
|
||||
});
|
||||
}
|
||||
},
|
||||
"Int32" : {
|
||||
"Serialize 0" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int32.serialize(so, 0);
|
||||
assert.equals(so.to_hex(), "00000000");
|
||||
},
|
||||
"Serialize 123" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int32.serialize(so, 123);
|
||||
assert.equals(so.to_hex(), "0000007B");
|
||||
},
|
||||
"Serialize 255" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int32.serialize(so, 255);
|
||||
assert.equals(so.to_hex(), "000000FF");
|
||||
},
|
||||
"Serialize 256" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int32.serialize(so, 256);
|
||||
assert.equals(so.to_hex(), "00000100");
|
||||
},
|
||||
"Serialize 0xF0F0F0F0" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int32.serialize(so, 0xF0F0F0F0);
|
||||
assert.equals(so.to_hex(), "F0F0F0F0");
|
||||
},
|
||||
"Serialize 0xFFFFFFFF" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int32.serialize(so, 0xFFFFFFFF);
|
||||
assert.equals(so.to_hex(), "FFFFFFFF");
|
||||
},
|
||||
"Fail to serialize 0x100000000" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int8.serialize(so, 0x100000000);
|
||||
});
|
||||
},
|
||||
"Fail to serialize -1" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int32.serialize(so, -1);
|
||||
});
|
||||
},
|
||||
"Serialize 123.5 (should floor)" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int32.serialize(so, 123.5);
|
||||
assert.equals(so.to_hex(), "0000007B");
|
||||
},
|
||||
"Serialize 4294967295.5 (should floor)" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int32.serialize(so, 4294967295.5);
|
||||
assert.equals(so.to_hex(), "FFFFFFFF");
|
||||
},
|
||||
"Fail to serialize null" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int32.serialize(so, null);
|
||||
});
|
||||
},
|
||||
"Fail to serialize 'bla'" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int32.serialize(so, 'bla');
|
||||
});
|
||||
},
|
||||
"Fail to serialize {}" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int32.serialize(so, {});
|
||||
});
|
||||
}
|
||||
},
|
||||
"Int64" : {
|
||||
"Serialize 0" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 0);
|
||||
assert.equals(so.to_hex(), "0000000000000000");
|
||||
},
|
||||
"Serialize 123" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 123);
|
||||
assert.equals(so.to_hex(), "000000000000007B");
|
||||
},
|
||||
"Serialize 255" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 255);
|
||||
assert.equals(so.to_hex(), "00000000000000FF");
|
||||
},
|
||||
"Serialize 256" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 256);
|
||||
assert.equals(so.to_hex(), "0000000000000100");
|
||||
},
|
||||
"Serialize 0xF0F0F0F0" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 0xF0F0F0F0);
|
||||
assert.equals(so.to_hex(), "00000000F0F0F0F0");
|
||||
},
|
||||
"Serialize 0xFFFFFFFF" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 0xFFFFFFFF);
|
||||
assert.equals(so.to_hex(), "00000000FFFFFFFF");
|
||||
},
|
||||
"Serialize 0x100000000" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 0x100000000);
|
||||
assert.equals(so.to_hex(), "0000000100000000");
|
||||
},
|
||||
"Fail to serialize 0x100000000" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int8.serialize(so, 0x100000000);
|
||||
});
|
||||
},
|
||||
"Fail to serialize -1" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int64.serialize(so, -1);
|
||||
});
|
||||
},
|
||||
"Serialize 123.5 (should floor)" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 123.5);
|
||||
assert.equals(so.to_hex(), "000000000000007B");
|
||||
},
|
||||
"Serialize 4294967295.5 (should floor)" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, 4294967295.5);
|
||||
assert.equals(so.to_hex(), "00000000FFFFFFFF");
|
||||
},
|
||||
"Serialize '0123456789ABCDEF'" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, "0123456789ABCDEF");
|
||||
assert.equals(so.to_hex(), "0123456789ABCDEF");
|
||||
},
|
||||
"Serialize 'F0E1D2C3B4A59687'" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, "F0E1D2C3B4A59687");
|
||||
assert.equals(so.to_hex(), "F0E1D2C3B4A59687");
|
||||
},
|
||||
"Serialize BigInteger('FFEEDDCCBBAA9988')" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Int64.serialize(so, new BigInteger("FFEEDDCCBBAA9988", 16));
|
||||
assert.equals(so.to_hex(), "FFEEDDCCBBAA9988");
|
||||
},
|
||||
"Fail to serialize BigInteger('-1')" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int64.serialize(so, new BigInteger("-1", 10));
|
||||
});
|
||||
},
|
||||
"Fail to serialize '10000000000000000'" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int64.serialize(so, "10000000000000000");
|
||||
});
|
||||
},
|
||||
"Fail to serialize '110000000000000000'" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int64.serialize(so, "110000000000000000");
|
||||
});
|
||||
},
|
||||
"Fail to serialize null" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int64.serialize(so, null);
|
||||
});
|
||||
},
|
||||
"Fail to serialize 'bla'" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int64.serialize(so, 'bla');
|
||||
});
|
||||
},
|
||||
"Fail to serialize {}" : function () {
|
||||
var so = new SerializedObject();
|
||||
assert.exception(function () {
|
||||
types.Int64.serialize(so, {});
|
||||
});
|
||||
}
|
||||
},
|
||||
"Hash128" : {
|
||||
"Serialize 0" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Hash128.serialize(so, "00000000000000000000000000000000");
|
||||
assert.equals(so.to_hex(), "00000000000000000000000000000000");
|
||||
},
|
||||
"Serialize 102030405060708090A0B0C0D0E0F000" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Hash128.serialize(so, "102030405060708090A0B0C0D0E0F000");
|
||||
assert.equals(so.to_hex(), "102030405060708090A0B0C0D0E0F000");
|
||||
},
|
||||
"Serialize FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Hash128.serialize(so, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
|
||||
assert.equals(so.to_hex(), "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
|
||||
},
|
||||
},
|
||||
"Hash160" : {
|
||||
"Serialize 0" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Hash160.serialize(so, "rrrrrrrrrrrrrrrrrrrrrhoLvTp");
|
||||
assert.equals(so.to_hex(), "0000000000000000000000000000000000000000");
|
||||
},
|
||||
"Serialize 1" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Hash160.serialize(so, "rrrrrrrrrrrrrrrrrrrrBZbvji");
|
||||
assert.equals(so.to_hex(), "0000000000000000000000000000000000000001");
|
||||
},
|
||||
"Serialize FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Hash160.serialize(so, "rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi");
|
||||
assert.equals(so.to_hex(), "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
|
||||
},
|
||||
},
|
||||
"Amount" : {
|
||||
"Serialize 0 XRP" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "0");
|
||||
assert.equals(so.to_hex(), "4000000000000000");
|
||||
},
|
||||
"Serialize 1 XRP" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "1");
|
||||
assert.equals(so.to_hex(), "4000000000000001");
|
||||
},
|
||||
"Serialize -1 XRP" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "-1");
|
||||
assert.equals(so.to_hex(), "0000000000000001");
|
||||
},
|
||||
"Serialize 213 XRP" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "213");
|
||||
assert.equals(so.to_hex(), "40000000000000D5");
|
||||
},
|
||||
"Serialize 270544960 XRP" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "270544960");
|
||||
assert.equals(so.to_hex(), "4000000010203040");
|
||||
},
|
||||
"Serialize 1161981756646125568 XRP" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "1161981756646125696");
|
||||
assert.equals(so.to_hex(), "5020304050607080");
|
||||
},
|
||||
"Serialize 1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
|
||||
assert.equals(so.to_hex(), "D4838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8");
|
||||
},
|
||||
"Serialize 87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
|
||||
assert.equals(so.to_hex(), "D65F241D335BF24E0000000000000000000000004555520000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8");
|
||||
},
|
||||
"Serialize -1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Amount.serialize(so, "-1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
|
||||
assert.equals(so.to_hex(), "94838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8");
|
||||
},
|
||||
"Parse 1 XRP" : function () {
|
||||
var so = new SerializedObject("4000000000000001");
|
||||
assert.equals(types.Amount.parse(so).to_json(), "1");
|
||||
},
|
||||
"Parse -1 XRP" : function () {
|
||||
var so = new SerializedObject("0000000000000001");
|
||||
assert.equals(types.Amount.parse(so).to_json(), "-1");
|
||||
},
|
||||
"Parse 213 XRP" : function () {
|
||||
var so = new SerializedObject("40000000000000D5");
|
||||
assert.equals(types.Amount.parse(so).to_json(), "213");
|
||||
},
|
||||
"Parse 270544960 XRP" : function () {
|
||||
var so = new SerializedObject("4000000010203040");
|
||||
assert.equals(types.Amount.parse(so).to_json(), "270544960");
|
||||
},
|
||||
"Parse 1161981756646125568 XRP" : function () {
|
||||
var so = new SerializedObject("5020304050607080");
|
||||
assert.equals(types.Amount.parse(so).to_json(), "1161981756646125696");
|
||||
},
|
||||
"Parse 1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
|
||||
var so = new SerializedObject("D4838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8");
|
||||
assert.equals(types.Amount.parse(so).to_text_full(), "1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
|
||||
},
|
||||
"Parse 87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
|
||||
var so = new SerializedObject("D65F241D335BF24E0000000000000000000000004555520000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8");
|
||||
assert.equals(types.Amount.parse(so).to_text_full(), "87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
|
||||
},
|
||||
"Parse -1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
|
||||
var so = new SerializedObject("94838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8");
|
||||
assert.equals(types.Amount.parse(so).to_text_full(), "-1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
@@ -1,484 +0,0 @@
|
||||
var async = require("async");
|
||||
|
||||
var Amount = require("../src/js/ripple/amount").Amount;
|
||||
var Remote = require("../src/js/ripple/remote").Remote;
|
||||
var Server = require("./server").Server;
|
||||
|
||||
var config = require('../src/js/ripple/config').load(require('./config'));
|
||||
|
||||
var account_dump = function (remote, account, callback) {
|
||||
var self = this;
|
||||
|
||||
async.waterfall([
|
||||
function (callback) {
|
||||
self.what = "Get latest account_root";
|
||||
|
||||
remote
|
||||
.request_ledger_entry('account_root')
|
||||
.ledger_hash(remote.ledger_hash())
|
||||
.account_root("root")
|
||||
.on('success', function (r) {
|
||||
//console.log("account_root: %s", JSON.stringify(r, undefined, 2));
|
||||
|
||||
callback();
|
||||
})
|
||||
.on('error', function(m) {
|
||||
console.log("error: %s", m);
|
||||
|
||||
buster.assert(false);
|
||||
callback();
|
||||
})
|
||||
.request();
|
||||
},
|
||||
], function (error) {
|
||||
callback(error);
|
||||
});
|
||||
|
||||
// get closed ledger hash
|
||||
// get account root
|
||||
// construct a json result
|
||||
//
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper called by test cases to generate a setUp routine.
|
||||
*
|
||||
* By default you would call this without options, but it is useful to
|
||||
* be able to plug options in during development for quick and easy
|
||||
* debugging.
|
||||
*
|
||||
* @example
|
||||
* buster.testCase("Foobar", {
|
||||
* setUp: testutils.build_setup({verbose: true}),
|
||||
* // ...
|
||||
* });
|
||||
*
|
||||
* @param opts {Object} These options allow quick-and-dirty test-specific
|
||||
* customizations of your test environment.
|
||||
* @param opts.verbose {Bool} Enable all debug output (then cover your ears
|
||||
* and run)
|
||||
* @param opts.verbose_ws {Bool} Enable tracing in the Remote class. Prints
|
||||
* websocket traffic.
|
||||
* @param opts.verbose_server {Bool} Set the -v option when running rippled.
|
||||
* @param opts.no_server {Bool} Don't auto-run rippled.
|
||||
* @param host {String} Identifier for the host configuration to be used.
|
||||
*/
|
||||
var build_setup = function (opts, host) {
|
||||
opts = opts || {};
|
||||
|
||||
// Normalize options
|
||||
if (opts.verbose) {
|
||||
opts.verbose_ws = true;
|
||||
opts.verbose_server = true;
|
||||
};
|
||||
|
||||
return function (done) {
|
||||
var self = this;
|
||||
|
||||
host = host || config.server_default;
|
||||
|
||||
this.store = this.store || {};
|
||||
|
||||
var data = this.store[host] = this.store[host] || {};
|
||||
|
||||
data.opts = opts;
|
||||
|
||||
async.series([
|
||||
function runServerStep(callback) {
|
||||
if (opts.no_server) return callback();
|
||||
|
||||
data.server = Server
|
||||
.from_config(host, !!opts.verbose_server)
|
||||
.on('started', callback)
|
||||
.on('exited', function () {
|
||||
// If know the remote, tell it server is gone.
|
||||
if (self.remote)
|
||||
self.remote.server_fatal();
|
||||
})
|
||||
.start();
|
||||
},
|
||||
function connectWebsocketStep(callback) {
|
||||
self.remote = data.remote =
|
||||
Remote
|
||||
.from_config(host, !!opts.verbose_ws)
|
||||
.once('ledger_closed', callback)
|
||||
.connect();
|
||||
}
|
||||
], done);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate tearDown routine.
|
||||
*
|
||||
* @param host {String} Identifier for the host configuration to be used.
|
||||
*/
|
||||
var build_teardown = function (host) {
|
||||
|
||||
return function (done) {
|
||||
host = host || config.server_default;
|
||||
|
||||
var data = this.store[host];
|
||||
var opts = data.opts;
|
||||
|
||||
async.series([
|
||||
function disconnectWebsocketStep(callback) {
|
||||
|
||||
data.remote
|
||||
.on('disconnected', callback)
|
||||
.connect(false);
|
||||
},
|
||||
function stopServerStep(callback) {
|
||||
if (opts.no_server)
|
||||
{
|
||||
return callback();
|
||||
}
|
||||
|
||||
data.server
|
||||
.on('stopped', callback)
|
||||
.stop();
|
||||
}
|
||||
], done);
|
||||
};
|
||||
};
|
||||
|
||||
var create_accounts = function (remote, src, amount, accounts, callback) {
|
||||
assert(5 === arguments.length);
|
||||
|
||||
remote.set_account_seq(src, 1);
|
||||
|
||||
async.forEach(accounts, function (account, callback) {
|
||||
// Cache the seq as 1.
|
||||
// Otherwise, when other operations attempt to opperate async against the account they may get confused.
|
||||
remote.set_account_seq(account, 1);
|
||||
|
||||
remote.transaction()
|
||||
.payment(src, account, amount)
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
if (m.result != 'tesSUCCESS') {
|
||||
callback(new Error("Transaction did not succeed."));
|
||||
} else callback(null);
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
})
|
||||
.submit();
|
||||
}, callback);
|
||||
};
|
||||
|
||||
var credit_limit = function (remote, src, amount, callback) {
|
||||
assert(4 === arguments.length);
|
||||
|
||||
var _m = amount.match(/^(\d+\/...\/[^\:]+)(?::(\d+)(?:,(\d+))?)?$/);
|
||||
if (!_m) {
|
||||
console.log("credit_limit: parse error: %s", amount);
|
||||
|
||||
callback('parse_error');
|
||||
}
|
||||
else
|
||||
{
|
||||
// console.log("credit_limit: parsed: %s", JSON.stringify(_m, undefined, 2));
|
||||
var _account_limit = _m[1];
|
||||
var _quality_in = _m[2];
|
||||
var _quality_out = _m[3];
|
||||
|
||||
remote.transaction()
|
||||
.ripple_line_set(src, _account_limit, _quality_in, _quality_out)
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
})
|
||||
.submit();
|
||||
}
|
||||
};
|
||||
|
||||
var verify_limit = function (remote, src, amount, callback) {
|
||||
assert(4 === arguments.length);
|
||||
|
||||
var _m = amount.match(/^(\d+\/...\/[^\:]+)(?::(\d+)(?:,(\d+))?)?$/);
|
||||
if (!_m) {
|
||||
// console.log("credit_limit: parse error: %s", amount);
|
||||
|
||||
callback('parse_error');
|
||||
}
|
||||
else
|
||||
{
|
||||
// console.log("verify_limit: parsed: %s", JSON.stringify(_m, undefined, 2));
|
||||
var _account_limit = _m[1];
|
||||
var _quality_in = _m[2];
|
||||
var _quality_out = _m[3];
|
||||
|
||||
var _limit = Amount.from_json(_account_limit);
|
||||
|
||||
remote.request_ripple_balance(src, _limit.issuer().to_json(), _limit.currency().to_json(), 'CURRENT')
|
||||
.once('ripple_state', function (m) {
|
||||
buster.assert(m.account_limit.equals(_limit));
|
||||
buster.assert('undefined' === _quality_in || m.account_quality_in == _quality_in);
|
||||
buster.assert('undefined' === _quality_out || m.account_quality_out == _quality_out);
|
||||
|
||||
callback();
|
||||
})
|
||||
.once('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
})
|
||||
.request();
|
||||
}
|
||||
};
|
||||
|
||||
var credit_limits = function (remote, balances, callback) {
|
||||
assert(3 === arguments.length);
|
||||
|
||||
var limits = [];
|
||||
|
||||
for (var src in balances) {
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
|
||||
for (var index in values) {
|
||||
limits.push( { "source" : src, "amount" : values[index] } );
|
||||
}
|
||||
}
|
||||
|
||||
async.every(limits,
|
||||
function (limit, callback) {
|
||||
credit_limit(remote, limit.source, limit.amount,
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
},
|
||||
function (every) {
|
||||
callback(!every);
|
||||
});
|
||||
};
|
||||
|
||||
var ledger_close = function (remote, callback) {
|
||||
remote.once('ledger_closed', function (m) { callback(); }).ledger_accept();
|
||||
}
|
||||
|
||||
var payment = function (remote, src, dst, amount, callback) {
|
||||
assert(5 === arguments.length);
|
||||
|
||||
remote.transaction()
|
||||
.payment(src, dst, amount)
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
})
|
||||
.submit();
|
||||
};
|
||||
|
||||
var payments = function (remote, balances, callback) {
|
||||
assert(3 === arguments.length);
|
||||
|
||||
var sends = [];
|
||||
|
||||
for (var src in balances) {
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
|
||||
for (var index in values) {
|
||||
var amount_json = values[index];
|
||||
var amount = Amount.from_json(amount_json);
|
||||
|
||||
sends.push( { "source" : src, "destination" : amount.issuer().to_json(), "amount" : amount_json } );
|
||||
}
|
||||
}
|
||||
|
||||
async.every(sends,
|
||||
function (send, callback) {
|
||||
payment(remote, send.source, send.destination, send.amount,
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
},
|
||||
function (every) {
|
||||
callback(!every);
|
||||
});
|
||||
};
|
||||
|
||||
var transfer_rate = function (remote, src, billionths, callback) {
|
||||
assert(4 === arguments.length);
|
||||
|
||||
remote.transaction()
|
||||
.account_set(src)
|
||||
.transfer_rate(billionths)
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
callback(m.result != 'tesSUCCESS');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("error: %s", JSON.stringify(m));
|
||||
|
||||
callback(m);
|
||||
})
|
||||
.submit();
|
||||
};
|
||||
|
||||
var verify_balance = function (remote, src, amount_json, callback) {
|
||||
assert(4 === arguments.length);
|
||||
var amount_req = Amount.from_json(amount_json);
|
||||
|
||||
if (amount_req.is_native()) {
|
||||
remote.request_account_balance(src, 'CURRENT')
|
||||
.once('account_balance', function (amount_act) {
|
||||
if (!amount_act.equals(amount_req, true)) {
|
||||
console.log("verify_balance: failed: %s / %s",
|
||||
amount_act.to_text_full(),
|
||||
amount_req.to_text_full());
|
||||
}
|
||||
|
||||
callback(!amount_act.equals(amount_req, true));
|
||||
})
|
||||
.request();
|
||||
}
|
||||
else {
|
||||
remote.request_ripple_balance(src, amount_req.issuer().to_json(), amount_req.currency().to_json(), 'CURRENT')
|
||||
.once('ripple_state', function (m) {
|
||||
// console.log("BALANCE: %s", JSON.stringify(m));
|
||||
// console.log("account_balance: %s", m.account_balance.to_text_full());
|
||||
// console.log("account_limit: %s", m.account_limit.to_text_full());
|
||||
// console.log("issuer_balance: %s", m.issuer_balance.to_text_full());
|
||||
// console.log("issuer_limit: %s", m.issuer_limit.to_text_full());
|
||||
|
||||
var account_balance = Amount.from_json(m.account_balance);
|
||||
|
||||
if (!account_balance.equals(amount_req, true)) {
|
||||
console.log("verify_balance: failed: %s vs %s / %s: %s",
|
||||
src,
|
||||
account_balance.to_text_full(),
|
||||
amount_req.to_text_full(),
|
||||
account_balance.not_equals_why(amount_req, true));
|
||||
}
|
||||
|
||||
callback(!account_balance.equals(amount_req, true));
|
||||
})
|
||||
.request();
|
||||
}
|
||||
};
|
||||
|
||||
var verify_balances = function (remote, balances, callback) {
|
||||
var tests = [];
|
||||
|
||||
for (var src in balances) {
|
||||
var values_src = balances[src];
|
||||
var values = 'string' === typeof values_src ? [ values_src ] : values_src;
|
||||
|
||||
for (var index in values) {
|
||||
tests.push( { "source" : src, "amount" : values[index] } );
|
||||
}
|
||||
}
|
||||
|
||||
async.every(tests,
|
||||
function (check, callback) {
|
||||
verify_balance(remote, check.source, check.amount,
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
},
|
||||
function (every) {
|
||||
callback(!every);
|
||||
});
|
||||
};
|
||||
|
||||
// --> owner: account
|
||||
// --> seq: sequence number of creating transaction.
|
||||
// --> taker_gets: json amount
|
||||
// --> taker_pays: json amount
|
||||
var verify_offer = function (remote, owner, seq, taker_pays, taker_gets, callback) {
|
||||
assert(6 === arguments.length);
|
||||
|
||||
remote.request_ledger_entry('offer')
|
||||
.offer_id(owner, seq)
|
||||
.on('success', function (m) {
|
||||
var wrong = !Amount.from_json(m.node.TakerGets).equals(Amount.from_json(taker_gets), true)
|
||||
|| !Amount.from_json(m.node.TakerPays).equals(Amount.from_json(taker_pays), true);
|
||||
|
||||
if (wrong)
|
||||
console.log("verify_offer: failed: %s", JSON.stringify(m));
|
||||
|
||||
callback(wrong);
|
||||
})
|
||||
.request();
|
||||
};
|
||||
|
||||
var verify_offer_not_found = function (remote, owner, seq, callback) {
|
||||
assert(4 === arguments.length);
|
||||
|
||||
remote.request_ledger_entry('offer')
|
||||
.offer_id(owner, seq)
|
||||
.on('success', function (m) {
|
||||
console.log("verify_offer_not_found: found offer: %s", JSON.stringify(m));
|
||||
|
||||
callback('entryFound');
|
||||
})
|
||||
.on('error', function (m) {
|
||||
// console.log("verify_offer_not_found: success: %s", JSON.stringify(m));
|
||||
|
||||
callback('remoteError' !== m.error
|
||||
|| 'entryNotFound' !== m.remote.error);
|
||||
})
|
||||
.request();
|
||||
};
|
||||
|
||||
var verify_owner_count = function (remote, account, value, callback) {
|
||||
assert(4 === arguments.length);
|
||||
|
||||
remote.request_owner_count(account, 'CURRENT')
|
||||
.once('owner_count', function (owner_count) {
|
||||
if (owner_count !== value)
|
||||
console.log("owner_count: %s/%d", owner_count, value);
|
||||
|
||||
callback(owner_count !== value);
|
||||
})
|
||||
.request();
|
||||
};
|
||||
|
||||
var verify_owner_counts = function (remote, counts, callback) {
|
||||
var tests = [];
|
||||
|
||||
for (var src in counts) {
|
||||
tests.push( { "source" : src, "count" : counts[src] } );
|
||||
}
|
||||
|
||||
async.every(tests,
|
||||
function (check, callback) {
|
||||
verify_owner_count(remote, check.source, check.count,
|
||||
function (mismatch) { callback(!mismatch); });
|
||||
},
|
||||
function (every) {
|
||||
callback(!every);
|
||||
});
|
||||
};
|
||||
|
||||
exports.account_dump = account_dump;
|
||||
exports.build_setup = build_setup;
|
||||
exports.build_teardown = build_teardown;
|
||||
exports.create_accounts = create_accounts;
|
||||
exports.credit_limit = credit_limit;
|
||||
exports.credit_limits = credit_limits;
|
||||
exports.ledger_close = ledger_close;
|
||||
exports.payment = payment;
|
||||
exports.payments = payments;
|
||||
exports.transfer_rate = transfer_rate;
|
||||
exports.verify_balance = verify_balance;
|
||||
exports.verify_balances = verify_balances;
|
||||
exports.verify_limit = verify_limit;
|
||||
exports.verify_offer = verify_offer;
|
||||
exports.verify_offer_not_found = verify_offer_not_found;
|
||||
exports.verify_owner_count = verify_owner_count;
|
||||
exports.verify_owner_counts = verify_owner_counts;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
Reference in New Issue
Block a user