diff --git a/src/js/ripple/account.js b/src/js/ripple/account.js index b1a0f144..7c30b0f9 100644 --- a/src/js/ripple/account.js +++ b/src/js/ripple/account.js @@ -9,11 +9,11 @@ // balance_proposed // -// var network = require("./network.js"); +// var network = require('./network.js'); var async = require('async'); -var EventEmitter = require('events').EventEmitter; var util = require('util'); var extend = require('extend'); +var EventEmitter = require('events').EventEmitter; var Amount = require('./amount').Amount; var UInt160 = require('./uint160').UInt160; var TransactionManager = require('./transactionmanager').TransactionManager; @@ -31,10 +31,10 @@ function Account(remote, account) { var self = this; - this._remote = remote; - this._account = UInt160.from_json(account); + this._remote = remote; + this._account = UInt160.from_json(account); this._account_id = this._account.to_json(); - this._subs = 0; + this._subs = 0; // Ledger entry object // Important: This must never be overwritten, only extend()-ed @@ -75,7 +75,9 @@ function Account(remote, account) { this._remote.on('prepare_subscribe', attachAccount); function handleTransaction(transaction) { - if (!transaction.mmeta) return; + if (!transaction.mmeta) { + return; + } var changed = false; @@ -137,7 +139,7 @@ Account.prototype.getInfo = function(callback) { * Retrieve the current AccountRoot entry. * * To keep up-to-date with changes to the AccountRoot entry, subscribe to the - * "entry" event. + * 'entry' event. * * @param {Function} callback */ @@ -164,11 +166,14 @@ Account.prototype.entry = function(callback) { Account.prototype.getNextSequence = function(callback) { var callback = typeof callback === 'function' ? callback : function(){}; + function isNotFound(err) { + return err && typeof err === 'object' + && typeof err.remote === 'object' + && err.remote.error === 'actNotFound'; + }; + function accountInfo(err, info) { - if (err && - "object" === typeof err && - "object" === typeof err.remote && - err.remote.error === "actNotFound") { + if (isNotFound(err)) { // New accounts will start out as sequence zero callback(null, 0); } else if (err) { @@ -187,7 +192,7 @@ Account.prototype.getNextSequence = function(callback) { * Retrieve this account's Ripple trust lines. * * To keep up-to-date with changes to the AccountRoot entry, subscribe to the - * "lines" event. (Not yet implemented.) + * 'lines' event. (Not yet implemented.) * * @param {function(err, lines)} callback Called with the result */ @@ -220,23 +225,27 @@ Account.prototype.lines = function(callback) { * @returns {Account} */ -Account.prototype.line = function(currency,address,callback) { +Account.prototype.line = function(currency, address, callback) { var self = this; - var found; var callback = typeof callback === 'function' ? callback : function(){}; self.lines(function(err, data) { if (err) { - callback(err); - } else { - var line = data.lines.filter(function(line) { - if (line.account === address && line.currency === currency) { - return line; - } - })[0]; - - callback(null, line); + return callback(err); } + + var line; + + top: + for (var i=0; i j -Amount.prototype.parse_json = function (j) { +Amount.prototype.parse_json = function(j) { switch (typeof j) { case 'string': // .../.../... notation is not a wire format. But allowed for easier testing. @@ -785,7 +785,10 @@ Amount.prototype.parse_json = function (j) { break; case 'object': - if (j === null) break; + if (j === null) { + break; + } + if (j instanceof Amount) { j.copyTo(this); } else if (j.hasOwnProperty('value')) { @@ -811,7 +814,7 @@ Amount.prototype.parse_json = function (j) { // - integer = raw units // - float = with precision 6 // XXX Improvements: disallow leading zeros. -Amount.prototype.parse_native = function (j) { +Amount.prototype.parse_native = function(j) { var m; if (typeof j === 'string') { @@ -846,7 +849,7 @@ Amount.prototype.parse_native = function (j) { // Parse a non-native value for the json wire format. // Requires _currency to be set! -Amount.prototype.parse_value = function (j) { +Amount.prototype.parse_value = function(j) { this._is_native = false; switch (typeof j) { @@ -900,14 +903,14 @@ Amount.prototype.parse_value = function (j) { return this; }; -Amount.prototype.set_currency = function (c) { +Amount.prototype.set_currency = function(c) { this._currency = Currency.from_json(c); this._is_native = this._currency.is_native(); return this; }; -Amount.prototype.set_issuer = function (issuer) { +Amount.prototype.set_issuer = function(issuer) { if (issuer instanceof UInt160) { this._issuer = issuer; } else { @@ -918,18 +921,18 @@ Amount.prototype.set_issuer = function (issuer) { }; // Result in terms of this' currency and issuer. -Amount.prototype.subtract = function (v) { +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) { +Amount.prototype.to_number = function(allow_nan) { var s = this.to_text(allow_nan); return typeof s === 'string' ? Number(s) : s; }; // Convert only value to JSON wire format. -Amount.prototype.to_text = function (allow_nan) { +Amount.prototype.to_text = function(allow_nan) { var result = NaN; if (this._is_native) { @@ -975,7 +978,7 @@ Amount.prototype.to_text = function (allow_nan) { * should be applied. Can be given as JavaScript Date or int for Ripple epoch. * @return {Amount} The amount with interest applied. */ -Amount.prototype.applyInterest = function (referenceDate) { +Amount.prototype.applyInterest = function(referenceDate) { if (this._currency.has_interest()) { var interest = this._currency.get_interest_at(referenceDate); @@ -986,7 +989,7 @@ Amount.prototype.applyInterest = function (referenceDate) { // The correct way to solve this is probably to switch to a proper // BigDecimal for our internal representation and then use that across // the board instead of instantiating these dummy Amount objects. - var interestTempAmount = Amount.from_json(""+interest+"/1/1"); + var interestTempAmount = Amount.from_json(String(interest) + '/1/1'); if (interestTempAmount.is_valid()) { return this.multiply(interestTempAmount); @@ -1018,14 +1021,20 @@ Amount.prototype.applyInterest = function (referenceDate) { * @param opts.reference_date {Date|Number} Date based on which demurrage/interest * should be applied. Can be given as JavaScript Date or int for Ripple epoch. */ -Amount.prototype.to_human = function (opts) { +Amount.prototype.to_human = function(opts) { opts = opts || {}; - if (!this.is_valid()) return ''; + if (!this.is_valid()) { + return ''; + } // Default options - if (typeof opts.signed === 'undefined') opts.signed = true; - if (typeof opts.group_sep === 'undefined') opts.group_sep = true; + if (typeof opts.signed === 'undefined') { + opts.signed = true; + } + if (typeof opts.group_sep === 'undefined') { + opts.group_sep = true; + } opts.group_width = opts.group_width || 3; @@ -1045,7 +1054,7 @@ Amount.prototype.to_human = function (opts) { fraction_part = '0' + fraction_part; } - int_part = int_part.replace(/^0*/, ''); + int_part = int_part.replace(/^0*/, ''); fraction_part = fraction_part.replace(/0*$/, ''); if (fraction_part.length || !opts.skip_empty_fraction) { @@ -1080,7 +1089,9 @@ Amount.prototype.to_human = function (opts) { rounding = Math.min(rounding, fraction_part.length); // Now we cut `rounding` digits off the right. - if (rounding > 0) fraction_part = fraction_part.slice(0, -rounding); + if (rounding > 0) { + fraction_part = fraction_part.slice(0, -rounding); + } } // Enforce the minimum number of decimal digits (min_precision) @@ -1112,7 +1123,7 @@ Amount.prototype.to_human = function (opts) { return formatted; }; -Amount.prototype.to_human_full = function (opts) { +Amount.prototype.to_human_full = function(opts) { opts = opts || {}; var a = this.to_human(opts); var c = this._currency.to_human(); @@ -1121,7 +1132,7 @@ Amount.prototype.to_human_full = function (opts) { return o; }; -Amount.prototype.to_json = function () { +Amount.prototype.to_json = function() { var result; if (this._is_native) { @@ -1140,7 +1151,7 @@ Amount.prototype.to_json = function () { return result; }; -Amount.prototype.to_text_full = function (opts) { +Amount.prototype.to_text_full = function(opts) { return this._value instanceof BigInteger ? this._is_native ? this.to_human() + '/XRP' @@ -1149,33 +1160,35 @@ Amount.prototype.to_text_full = function (opts) { }; // For debugging. -Amount.prototype.not_equals_why = function (d, ignore_issuer) { +Amount.prototype.not_equals_why = function(d, ignore_issuer) { + if (typeof d === 'string') { + return this.not_equals_why(Amount.from_json(d)); + } + + if (!(d instanceof Amount)) { + return 'Not an Amount'; + } + var result = false; - if (typeof d === 'string') { - result = this.not_equals_why(Amount.from_json(d)); - } else if (d instanceof Amount) { - if (!this.is_valid() || !d.is_valid()) { - result = 'Invalid amount.'; - } else if (this._is_native !== d._is_native) { - result = 'Native mismatch.'; - } else { - var type = this._is_native ? 'XRP' : 'Non-XRP'; + if (!this.is_valid() || !d.is_valid()) { + result = 'Invalid amount.'; + } else if (this._is_native !== d._is_native) { + result = 'Native mismatch.'; + } else { + var type = this._is_native ? 'XRP' : 'Non-XRP'; - if (!this._value.equals(d._value) || this._offset !== d._offset) { - result = type + ' value differs.'; - } else if (this._is_negative !== d._is_negative) { - result = type + ' sign differs.'; - } else if (!this._is_native) { - if (!this._currency.equals(d._currency)) { - result = 'Non-XRP currency differs.'; - } else if (!ignore_issuer && !this._issuer.equals(d._issuer)) { - result = 'Non-XRP issuer differs: ' + d._issuer.to_json() + '/' + this._issuer.to_json(); - } + if (!this._value.equals(d._value) || this._offset !== d._offset) { + result = type + ' value differs.'; + } else if (this._is_negative !== d._is_negative) { + result = type + ' sign differs.'; + } else if (!this._is_native) { + if (!this._currency.equals(d._currency)) { + result = 'Non-XRP currency differs.'; + } else if (!ignore_issuer && !this._issuer.equals(d._issuer)) { + result = 'Non-XRP issuer differs: ' + d._issuer.to_json() + '/' + this._issuer.to_json(); } } - } else { - result = 'Wrong constructor.'; } return result; diff --git a/src/js/ripple/base.js b/src/js/ripple/base.js index 97619d5f..ef6a5fb6 100644 --- a/src/js/ripple/base.js +++ b/src/js/ripple/base.js @@ -7,9 +7,9 @@ var BigInteger = utils.jsbn.BigInteger; var Base = {}; var alphabets = Base.alphabets = { - ripple : "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", - tipple : "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz", - bitcoin : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + ripple: 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz', + tipple: 'RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz', + bitcoin: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' }; extend(Base, { @@ -33,7 +33,7 @@ function sha256hash(bytes) { // --> input: big-endian array of bytes. // <-- string at least as long as input. -Base.encode = function (input, alpha) { +Base.encode = function(input, alpha) { var alphabet = alphabets[alpha || 'ripple']; var bi_base = new BigInteger(String(alphabet.length)); var bi_q = new BigInteger(); @@ -56,7 +56,7 @@ Base.encode = function (input, alpha) { // --> input: String // <-- array of bytes or undefined. -Base.decode = function (input, alpha) { +Base.decode = function(input, alpha) { if (typeof input !== 'string') { return void(0); } @@ -66,8 +66,8 @@ Base.decode = function (input, alpha) { var bi_value = new BigInteger(); var i; - for (i = 0; i != input.length && input[i] === alphabet[0]; i += 1) - ; + for (i = 0; i !== input.length && input[i] === alphabet[0]; i += 1) { + } for (; i !== input.length; i += 1) { var v = alphabet.indexOf(input[i]); @@ -84,10 +84,10 @@ Base.decode = function (input, alpha) { // toByteArray: // - Returns leading zeros! // - Returns signed bytes! - var bytes = bi_value.toByteArray().map(function (b) { return b ? b < 0 ? 256+b : b : 0; }); + var bytes = bi_value.toByteArray().map(function(b) { return b ? b < 0 ? 256+b : b : 0; }); var extra = 0; - while (extra != bytes.length && !bytes[extra]) { + while (extra !== bytes.length && !bytes[extra]) { extra += 1; } @@ -104,7 +104,7 @@ Base.decode = function (input, alpha) { return [].concat(utils.arraySet(zeros, 0), bytes); }; -Base.verify_checksum = function (bytes) { +Base.verify_checksum = function(bytes) { var computed = sha256hash(bytes.slice(0, -4)).slice(0, 4); var checksum = bytes.slice(-4); var result = true; @@ -121,7 +121,7 @@ Base.verify_checksum = function (bytes) { // --> input: Array // <-- String -Base.encode_check = function (version, input, alphabet) { +Base.encode_check = function(version, input, alphabet) { var buffer = [].concat(version, input); var check = sha256(sha256(buffer)).slice(0, 4); @@ -130,7 +130,7 @@ Base.encode_check = function (version, input, alphabet) { // --> input : String // <-- NaN || BigInteger -Base.decode_check = function (version, input, alphabet) { +Base.decode_check = function(version, input, alphabet) { var buffer = Base.decode(input, alphabet); if (!buffer || buffer.length < 5) { diff --git a/src/js/ripple/config.js b/src/js/ripple/config.js index b8095cc6..f6d17a16 100644 --- a/src/js/ripple/config.js +++ b/src/js/ripple/config.js @@ -1,6 +1,6 @@ // This object serves as a singleton to store config options -var extend = require("extend"); +var extend = require('extend'); var config = module.exports = { load: function (newOpts) { diff --git a/src/js/ripple/currency.js b/src/js/ripple/currency.js index 2e812b30..e4fda84e 100644 --- a/src/js/ripple/currency.js +++ b/src/js/ripple/currency.js @@ -1,6 +1,4 @@ - var extend = require('extend'); - var UInt160 = require('./uint160').UInt160; var Float = require('./float').Float; var utils = require('./utils'); @@ -9,7 +7,7 @@ var utils = require('./utils'); // Currency support // -var Currency = extend(function () { +var Currency = extend(function() { // Internal form: 0 = XRP. 3 letter-code. // XXX Internal should be 0 or hex with three letter annotation when valid. @@ -26,9 +24,9 @@ var Currency = extend(function () { Currency.prototype = extend({}, UInt160.prototype); Currency.prototype.constructor = Currency; -Currency.HEX_CURRENCY_BAD = "0000000000000000000000005852500000000000"; +Currency.HEX_CURRENCY_BAD = '0000000000000000000000005852500000000000'; -Currency.from_json = function (j, shouldInterpretXrpAsIou) { +Currency.from_json = function(j, shouldInterpretXrpAsIou) { if (j instanceof this) { return j.clone(); } else { @@ -37,7 +35,7 @@ Currency.from_json = function (j, shouldInterpretXrpAsIou) { }; // this._value = NaN on error. -Currency.prototype.parse_json = function (j, shouldInterpretXrpAsIou) { +Currency.prototype.parse_json = function(j, shouldInterpretXrpAsIou) { this._value = NaN; switch (typeof j) { @@ -82,14 +80,14 @@ Currency.prototype.parse_json = function (j, shouldInterpretXrpAsIou) { * * You should never need to call this. */ -Currency.prototype._update = function () { +Currency.prototype._update = function() { var bytes = this.to_bytes(); // is it 0 everywhere except 12, 13, 14? var isZeroExceptInStandardPositions = true; if (!bytes) { - return "XRP"; + return 'XRP'; } this._native = false; @@ -107,9 +105,9 @@ Currency.prototype._update = function () { + String.fromCharCode(bytes[13]) + String.fromCharCode(bytes[14]); - if (this._iso_code === "\0\0\0") { + if (this._iso_code === '\0\0\0') { this._native = true; - this._iso_code = "XRP"; + this._iso_code = 'XRP'; } this._type = 0; @@ -129,7 +127,7 @@ Currency.prototype._update = function () { // XXX Probably not needed anymore? /* -Currency.prototype.parse_bytes = function (byte_array) { +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? @@ -143,9 +141,9 @@ Currency.prototype.parse_bytes = function (byte_array) { var currencyCode = String.fromCharCode(byte_array[12]) + String.fromCharCode(byte_array[13]) + String.fromCharCode(byte_array[14]); - if (/^[A-Z0-9]{3}$/.test(currencyCode) && currencyCode !== "XRP" ) { + if (/^[A-Z0-9]{3}$/.test(currencyCode) && currencyCode !== 'XRP' ) { this._value = currencyCode; - } else if (currencyCode === "\0\0\0") { + } else if (currencyCode === '\0\0\0') { this._value = 0; } else { this._value = NaN; @@ -161,19 +159,21 @@ Currency.prototype.parse_bytes = function (byte_array) { }; */ -Currency.prototype.is_native = function () { +Currency.prototype.is_native = function() { return this._native; }; /** * Whether this currency is an interest-bearing/demurring currency. */ -Currency.prototype.has_interest = function () { +Currency.prototype.has_interest = function() { return this._type === 1 && this._interest_start && !isNaN(this._interest_period); }; -Currency.prototype.get_interest_at = function (referenceDate) { - if (!this.has_interest) return 1; +Currency.prototype.get_interest_at = function(referenceDate) { + if (!this.has_interest) { + return 1; + } if (referenceDate instanceof Date) { referenceDate = utils.fromTimestamp(referenceDate.getTime()); @@ -187,14 +187,14 @@ Currency.prototype.get_interest_at = function (referenceDate) { // We could be doing further checks into the internal format of the // currency data, since there are some values that are invalid. // -//Currency.prototype.is_valid = function () { +//Currency.prototype.is_valid = function() { // return this._value instanceof BigInteger && ...; //}; -Currency.prototype.to_json = function () { +Currency.prototype.to_json = function() { if (!this.is_valid()) { // XXX This is backwards compatible behavior, but probably not very good. - return "XRP"; + return 'XRP'; } // Any currency with standard properties and a valid code can be abbreviated @@ -216,7 +216,7 @@ Currency.prototype.to_json = function () { return currencyHex; }; -Currency.prototype.to_human = function () { +Currency.prototype.to_human = function() { // to_human() will always print the human-readable currency code if available. if (/^[A-Z0-9]{3}$/.test(this._iso_code)) { return this._iso_code; diff --git a/src/js/ripple/float.js b/src/js/ripple/float.js index 23aab200..f71e4451 100644 --- a/src/js/ripple/float.js +++ b/src/js/ripple/float.js @@ -8,12 +8,17 @@ var Float = exports.Float = {}; var allZeros = /^0+$/; var allOnes = /^1+$/; -Float.fromBytes = function (bytes) { +Float.fromBytes = function(bytes) { // Render in binary. Hackish. - var b = ""; + var b = ''; + for (var i = 0, n = bytes.length; i < n; i++) { var bits = (bytes[i] & 0xff).toString(2); - while (bits.length < 8) bits = "0" + bits; + + while (bits.length < 8) { + bits = '0' + bits; + } + b += bits; } @@ -29,13 +34,11 @@ Float.fromBytes = function (bytes) { var m = b.substring(exponentBits + 1); var value = 0; - var multiplier = (s === "0" ? 1 : -1); + var multiplier = (s === '0' ? 1 : -1); if (allZeros.test(e)) { // Zero or denormalized - if (allZeros.test(m)) { - // Value is zero - } else { + if (!allZeros.test(m)) { value = parseInt(m, 2) * Math.pow(2, minExponent); } } else if (allOnes.test(e)) { diff --git a/src/js/ripple/index.js b/src/js/ripple/index.js index a6cfa2ce..f09d74c0 100644 --- a/src/js/ripple/index.js +++ b/src/js/ripple/index.js @@ -12,7 +12,6 @@ exports.Meta = require('./meta').Meta; exports.SerializedObject = require('./serializedobject').SerializedObject; exports.RippleError = require('./rippleerror').RippleError; exports.Message = require('./message'); - exports.binformat = require('./binformat'); exports.utils = require('./utils'); exports.Server = require('./server').Server; @@ -35,7 +34,9 @@ function attachUnderscored(c) { Object.keys(o.prototype).forEach(function(key) { var UPPERCASE = /([A-Z]{1})[a-z]+/g; - if (!UPPERCASE.test(key)) return; + if (!UPPERCASE.test(key)) { + return; + } var underscored = key.replace(UPPERCASE, function(c) { return '_' + c.toLowerCase(); diff --git a/src/js/ripple/keypair.js b/src/js/ripple/keypair.js index 518ae70d..a5f4a8e1 100644 --- a/src/js/ripple/keypair.js +++ b/src/js/ripple/keypair.js @@ -5,17 +5,17 @@ var UInt256 = require('./uint256').UInt256; var Base = require('./base').Base; function KeyPair() { - this._curve = sjcl.ecc.curves['c256']; + this._curve = sjcl.ecc.curves.c256; this._secret = null; this._pubkey = null; }; -KeyPair.from_bn_secret = function (j) { - return j instanceof this ? j.clone() : (new this()).parse_bn_secret(j); +KeyPair.from_bn_secret = function(j) { + return (j instanceof this) ? j.clone() : (new this()).parse_bn_secret(j); }; -KeyPair.prototype.parse_bn_secret = function (j) { - this._secret = new sjcl.ecc.ecdsa.secretKey(sjcl.ecc.curves['c256'], j); +KeyPair.prototype.parse_bn_secret = function(j) { + this._secret = new sjcl.ecc.ecdsa.secretKey(sjcl.ecc.curves.c256, j); return this; }; @@ -24,7 +24,7 @@ KeyPair.prototype.parse_bn_secret = function (j) { * * @private */ -KeyPair.prototype._pub = function () { +KeyPair.prototype._pub = function() { var curve = this._curve; if (!this._pubkey && this._secret) { @@ -40,7 +40,7 @@ KeyPair.prototype._pub = function () { * * @private */ -KeyPair.prototype._pub_bits = function () { +KeyPair.prototype._pub_bits = function() { var pub = this._pub(); if (!pub) { @@ -60,7 +60,7 @@ KeyPair.prototype._pub_bits = function () { * * Key will be returned as a compressed pubkey - 33 bytes converted to hex. */ -KeyPair.prototype.to_hex_pub = function () { +KeyPair.prototype.to_hex_pub = function() { var bits = this._pub_bits(); if (!bits) { @@ -74,7 +74,7 @@ function SHA256_RIPEMD160(bits) { return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits)); } -KeyPair.prototype.get_address = function () { +KeyPair.prototype.get_address = function() { var bits = this._pub_bits(); if (!bits) { @@ -88,7 +88,7 @@ KeyPair.prototype.get_address = function () { return address; }; -KeyPair.prototype.sign = function (hash) { +KeyPair.prototype.sign = function(hash) { hash = UInt256.from_json(hash); var sig = this._secret.sign(hash.to_bits(), 0); sig = this._secret.canonicalizeSignature(sig); diff --git a/src/js/ripple/log.js b/src/js/ripple/log.js index b8b7c7c9..af18991e 100644 --- a/src/js/ripple/log.js +++ b/src/js/ripple/log.js @@ -1,13 +1,13 @@ /** * Logging functionality for ripple-lib and any applications built on it. */ -var Log = function (namespace) { +function Log(namespace) { if (!namespace) { this._namespace = []; } else if (Array.isArray(namespace)) { this._namespace = namespace; } else { - this._namespace = [""+namespace]; + this._namespace = [''+namespace]; } this._prefix = this._namespace.concat(['']).join(': '); @@ -23,25 +23,29 @@ var Log = function (namespace) { * var log = require('ripple').log.sub('server'); * * log.info('connection successful'); - * // prints: "server: connection successful" + * // prints: 'server: connection successful' */ -Log.prototype.sub = function (namespace) { +Log.prototype.sub = function(namespace) { var subNamespace = this._namespace.slice(); - if (namespace && "string" === typeof namespace) subNamespace.push(namespace); + + if (namespace && typeof namespace === 'string') { + subNamespace.push(namespace); + } + var subLogger = new Log(subNamespace); subLogger._setParent(this); return subLogger; }; -Log.prototype._setParent = function (parentLogger) { +Log.prototype._setParent = function(parentLogger) { this._parent = parentLogger; }; -Log.makeLevel = function (level) { - return function () { - arguments[0] = this._prefix + arguments[0]; - - Log.engine.logObject.apply(Log, Array.prototype.slice.call(arguments)); +Log.makeLevel = function(level) { + return function() { + var args = Array.prototype.slice.call(arguments); + args[0] = this._prefix + args[0]; + Log.engine.logObject.apply(Log, args); }; }; @@ -53,7 +57,7 @@ Log.prototype.error = Log.makeLevel(4); /** * Basic logging connector. * - * This engine has no formatting and works with the most basic of "console.log" + * This engine has no formatting and works with the most basic of 'console.log' * implementations. This is the logging engine used in Node.js. */ var BasicLogEngine = { @@ -77,12 +81,14 @@ var BasicLogEngine = { * available. */ var NullLogEngine = { - logObject: function () {} + logObject: function() {} }; Log.engine = NullLogEngine; -if (console && console.log) Log.engine = BasicLogEngine; +if (console && console.log) { + Log.engine = BasicLogEngine; +} /** * Provide a root logger as our main export. diff --git a/src/js/ripple/meta.js b/src/js/ripple/meta.js index 23d40b5c..bbdb475c 100644 --- a/src/js/ripple/meta.js +++ b/src/js/ripple/meta.js @@ -15,7 +15,7 @@ function Meta(raw_data) { raw_data.AffectedNodes.forEach(function(an) { var result = { }; - if (result.diffType = self.diffType(an)) { + if ((result.diffType = self.diffType(an))) { an = an[result.diffType]; result.entryType = an.LedgerEntryType; @@ -88,7 +88,7 @@ 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) { +Meta.prototype.each = function(fn) { for (var i = 0, l = this.nodes.length; i < l; i++) { fn(this.nodes[i], i); } @@ -103,7 +103,7 @@ Meta.prototype.each = function (fn) { ]).forEach(function(fn) { Meta.prototype[fn] = function() { return Array.prototype[fn].apply(this.nodes, arguments); - } + }; }); var amountFieldsAffectingIssuer = [ @@ -113,12 +113,12 @@ var amountFieldsAffectingIssuer = [ 'TakerGets' ]; -Meta.prototype.getAffectedAccounts = function () { +Meta.prototype.getAffectedAccounts = function() { var accounts = [ ]; // This code should match the behavior of the C++ method: // TransactionMetaSet::getAffectedAccounts - this.nodes.forEach(function (an) { + this.nodes.forEach(function(an) { var fields = (an.diffType === 'CreatedNode') ? an.fieldsNew : an.fieldsFinal; for (var i in fields) { var field = fields[i]; @@ -137,20 +137,26 @@ Meta.prototype.getAffectedAccounts = function () { return utils.arrayUnique(accounts); }; -Meta.prototype.getAffectedBooks = function () { +Meta.prototype.getAffectedBooks = function() { var books = [ ]; - this.nodes.forEach(function (an) { - if (an.entryType !== 'Offer') return; + this.nodes.forEach(function(an) { + if (an.entryType !== 'Offer') { + return; + } var gets = Amount.from_json(an.fields.TakerGets); var pays = Amount.from_json(an.fields.TakerPays); var getsKey = gets.currency().to_json(); - if (getsKey !== 'XRP') getsKey += '/' + gets.issuer().to_json(); + if (getsKey !== 'XRP') { + getsKey += '/' + gets.issuer().to_json(); + } var paysKey = pays.currency().to_json(); - if (paysKey !== 'XRP') paysKey += '/' + pays.issuer().to_json(); + if (paysKey !== 'XRP') { + paysKey += '/' + pays.issuer().to_json(); + } var key = [ getsKey, paysKey ].join(':'); diff --git a/src/js/ripple/orderbook.js b/src/js/ripple/orderbook.js index d667289b..0799f697 100644 --- a/src/js/ripple/orderbook.js +++ b/src/js/ripple/orderbook.js @@ -8,8 +8,8 @@ // var network = require("./network.js"); -var EventEmitter = require('events').EventEmitter; var util = require('util'); +var EventEmitter = require('events').EventEmitter; var extend = require('extend'); var Amount = require('./amount').Amount; var UInt160 = require('./uint160').UInt160; @@ -18,7 +18,7 @@ var Currency = require('./currency').Currency; function OrderBook(remote, currency_gets, issuer_gets, currency_pays, issuer_pays, key) { EventEmitter.call(this); - var self = this; + var self = this; this._remote = remote; this._currency_gets = currency_gets; @@ -30,15 +30,15 @@ function OrderBook(remote, currency_gets, issuer_gets, currency_pays, issuer_pay // We consider ourselves synchronized if we have a current copy of the offers, // we are online and subscribed to updates. - this._sync = false; + this._sync = false; // Offers - this._offers = [ ]; + this._offers = [ ]; function listenerAdded(type, listener) { if (~OrderBook.subscribe_events.indexOf(type)) { self._subs += 1; - if (self._subs == 1 && self._remote._connected) { + if (self._subs === 1 && self._remote._connected) { self._subscribe(); } } @@ -140,11 +140,11 @@ OrderBook.prototype.to_json = function () { }; if (this._currency_gets !== 'XRP') { - json['taker_gets']['issuer'] = this._issuer_gets; + json.taker_gets.issuer = this._issuer_gets; } if (this._currency_pays !== 'XRP') { - json['taker_pays']['issuer'] = this._issuer_pays; + json.taker_pays.issuer = this._issuer_pays; } return json; @@ -188,7 +188,9 @@ OrderBook.prototype.notify = function (message) { var trade_pays = this.trade('pays'); function handleTransaction(an) { - if (an.entryType !== 'Offer' || an.bookKey !== self._key) return; + if (an.entryType !== 'Offer' || an.bookKey !== self._key) { + return; + } var i, l, offer; @@ -197,8 +199,9 @@ OrderBook.prototype.notify = function (message) { case 'ModifiedNode': var deletedNode = an.diffType === 'DeletedNode'; - for (i = 0, l = self._offers.length; i < l; i++) { + for (i=0, l=self._offers.length; i= this._ledger_current_index) { this._ledger_time = message.ledger_time; @@ -549,13 +553,17 @@ Remote.prototype._handleMessage = function(message, server) { // Pass the event on to any related Account objects message.mmeta.getAffectedAccounts().forEach(function(account) { account = self._accounts[account]; - if (account) account.notify(message); + if (account) { + account.notify(message); + } }); // Pass the event on to any related OrderBooks message.mmeta.getAffectedBooks().forEach(function(book) { book = self._books[book]; - if (book) book.notify(message); + if (book) { + book.notify(message); + } }); } else { [ 'Account', 'Destination' ].forEach(function(prop) { @@ -659,7 +667,9 @@ Remote.prototype._getServer = function() { // <-> request: what to send, consumed. Remote.prototype.request = function(request) { if (typeof request === 'string') { - if (!/^request_/.test(request)) request = 'request_' + request; + if (!/^request_/.test(request)) { + request = 'request_' + request; + } if (typeof this[request] === 'function') { var args = Array.prototype.slice.call(arguments, 1); return this[request].apply(this, args); @@ -678,7 +688,7 @@ Remote.prototype.request = function(request) { } else { var server = request.server || this._getServer(); if (server) { - server.request(request); + server._request(request); } else { request.emit('error', new Error('No servers available')); } @@ -1147,7 +1157,7 @@ Remote.prototype.requestBookOffers = function(gets, pays, taker, callback) { request.message.taker_pays = { currency: Currency.json_rewrite(pays.currency) - } + }; if (request.message.taker_pays.currency !== 'XRP') { request.message.taker_pays.issuer = UInt160.json_rewrite(pays.issuer); @@ -1396,7 +1406,7 @@ Remote.prototype.accountSeq = function(account, advance) { var accountInfo = this.accounts[account]; var seq; - if (account_info && account_info.seq) { + if (accountInfo && accountInfo.seq) { seq = accountInfo.seq; var change = { ADVANCE: 1, REWIND: -1 }[advance.toUpperCase()] || 0; accountInfo.seq += change; @@ -1657,7 +1667,7 @@ Remote.prototype.transaction = function(source, options, callback) { offercreate: 'offerCreate', offercancel: 'offerCancel', sign: 'sign' - } + }; var transactionType; @@ -1705,7 +1715,13 @@ Remote.prototype.transaction = function(source, options, callback) { */ Remote.prototype.feeTx = function(units) { - return this._getServer().feeTx(units); + var server = this._getServer(); + + if (!server) { + throw new Error('No connected servers'); + } + + return server._feeTx(units); }; /** @@ -1718,7 +1734,13 @@ Remote.prototype.feeTx = function(units) { */ Remote.prototype.feeTxUnit = function() { - return this._getServer().feeTxUnit(); + var server = this._getServer(); + + if (!server) { + throw new Error('No connected servers'); + } + + return server._feeTxUnit(); }; /** @@ -1728,7 +1750,13 @@ Remote.prototype.feeTxUnit = function() { */ Remote.prototype.reserve = function(owner_count) { - return this._getServer().reserve(owner_count); + var server = this._getServer(); + + if (!server) { + throw new Error('No connected servers'); + } + + return server._reserve(owner_count); }; Remote.prototype.requestPing = diff --git a/src/js/ripple/request.js b/src/js/ripple/request.js index c7261bc6..9224f205 100644 --- a/src/js/ripple/request.js +++ b/src/js/ripple/request.js @@ -2,10 +2,6 @@ var EventEmitter = require('events').EventEmitter; var util = require('util'); var UInt160 = require('./uint160').UInt160; var Currency = require('./currency').Currency; -var Transaction = require('./transaction').Transaction; -var Account = require('./account').Account; -var Meta = require('./meta').Meta; -var OrderBook = require('./orderbook').OrderBook; var RippleError = require('./rippleerror').RippleError; var Server = require('./server').Server; @@ -18,9 +14,13 @@ var Server = require('./server').Server; function Request(remote, command) { EventEmitter.call(this); - this.remote = remote; + this.remote = remote; this.requested = false; - this.message = { command: command, id: void(0) }; + + this.message = { + command: command, + id: void(0) + }; }; util.inherits(Request, EventEmitter); @@ -32,11 +32,13 @@ Request.prototype.broadcast = function() { // Send the request to a remote. Request.prototype.request = function(remote) { - if (this.requested) return; + if (this.requested) { + return; + } this.requested = true; - this.on('error', new Function); + this.on('error', function(){}); this.emit('request', remote); if (this._broadcast) { @@ -93,7 +95,11 @@ Request.prototype.timeout = function(duration, callback) { var timeout = setTimeout(function() { timed_out = true; - if (typeof callback === 'function') callback(); + + if (typeof callback === 'function') { + callback(); + } + emit.call(self, 'timeout'); }, duration); @@ -119,7 +125,7 @@ Request.prototype.setServer = function(server) { // Find server with hostname string var servers = this.remote._servers; - for (var i=0, s; s=servers[i]; i++) { + for (var i=0, s; (s=servers[i]); i++) { if (s._host === server) { selected = s; break; @@ -148,7 +154,7 @@ Request.prototype.buildPath = function(build) { } else { // ND: rippled currently intreprets the mere presence of `build_path` as the // value being `truthy` - delete this.message.build_path + delete this.message.build_path; } return this; @@ -184,13 +190,13 @@ Request.prototype.ledgerSelect = function(ledger) { case 'current': case 'closed': case 'verified': - this.message.ledger_index = ledger_spec; + this.message.ledger_index = ledger; break; default: if (isNaN(ledger)) { this.message.ledger_hash = ledger; - } else if (ledger = Number(ledger)) { + } else if ((ledger = Number(ledger))) { this.message.ledger_index = ledger; } break; @@ -222,34 +228,34 @@ Request.prototype.offerId = function(account, sequence) { // --> index : ledger entry index. Request.prototype.offerIndex = function(index) { - this.message.offer = index; + this.message.offer = index; return this; }; Request.prototype.secret = function(secret) { if (secret) { - this.message.secret = secret; + this.message.secret = secret; } return this; }; Request.prototype.txHash = function(hash) { - this.message.tx_hash = hash; + this.message.tx_hash = hash; return this; }; Request.prototype.txJson = function(json) { - this.message.tx_json = json; + this.message.tx_json = json; return this; }; Request.prototype.txBlob = function(json) { - this.message.tx_blob = json; + this.message.tx_blob = json; return this; }; Request.prototype.rippleState = function(account, issuer, currency) { - this.message.ripple_state = { + this.message.ripple_state = { currency : currency, accounts : [ UInt160.json_rewrite(account), @@ -303,7 +309,7 @@ Request.prototype.books = function(books, snapshot) { // Reset list of books (this method overwrites the current list) this.message.books = [ ]; - for (var i = 0, l = books.length; i < l; i++) { + for (var i=0, l=books.length; i= 0; i--) { + + for (var i=typedef.length - 1; i>=0; i--) { var spec = typedef[i]; - var field = spec[0] + var field = spec[0]; var requirement = spec[1]; - if (binformat.REQUIRED === requirement && obj[field] == null) { + if (binformat.REQUIRED === requirement && obj[field] === void(0)) { missing_fields.push(field); }; }; - + if (missing_fields.length > 0) { var object_name; - if (obj.TransactionType != null) { + + if (obj.TransactionType !== void(0)) { object_name = SerializedObject.lookup_type_tx(obj.TransactionType); } else { - object_name = "TransactionMetaData"; + object_name = 'TransactionMetaData'; } /*else { - TODO: LedgerEntryType ... + TODO: LedgerEntryType ... }*/ - throw new Error(object_name + " is missing fields: " + - JSON.stringify(missing_fields)); - }; -} -SerializedObject.prototype.append = function (bytes) { + throw new Error(object_name + ' is missing fields: ' + JSON.stringify(missing_fields)); + }; +}; + +SerializedObject.prototype.append = function(bytes) { if (bytes instanceof SerializedObject) { bytes = bytes.buffer; } + this.buffer = this.buffer.concat(bytes); this.pointer += bytes.length; }; -SerializedObject.prototype.resetPointer = function () { +SerializedObject.prototype.resetPointer = function() { this.pointer = 0; }; function readOrPeek(advance) { return function(bytes) { var start = this.pointer; - var end = start + bytes; + var end = start + bytes; if (end > this.buffer.length) { throw new Error('Buffer length exceeded'); @@ -134,18 +134,18 @@ function readOrPeek(advance) { } return result; - } + }; }; SerializedObject.prototype.read = readOrPeek(true); SerializedObject.prototype.peek = readOrPeek(false); -SerializedObject.prototype.to_bits = function () { +SerializedObject.prototype.to_bits = function() { return sjcl.codec.bytes.toBits(this.buffer); }; -SerializedObject.prototype.to_hex = function () { +SerializedObject.prototype.to_hex = function() { return sjcl.codec.hex.fromBits(this.to_bits()).toUpperCase(); }; @@ -164,7 +164,7 @@ SerializedObject.prototype.to_json = function() { this.pointer = old_pointer; return output; -} +}; SerializedObject.jsonify_structure = function(structure, field_name) { var output; @@ -186,14 +186,20 @@ SerializedObject.jsonify_structure = function(structure, field_name) { } break; case 'object': - if (!structure) break; //null + if (structure === null) { + break; + } + if (typeof structure.to_json === 'function') { output = structure.to_json(); } else if (structure instanceof BigInteger) { output = structure.toString(16).toUpperCase(); } else { - output = new structure.constructor; //new Array or Object + //new Array or Object + output = new structure.constructor(); + var keys = Object.keys(structure); + for (var i=0, l=keys.length; i 0xF) { @@ -280,7 +286,7 @@ SerializedObject.get_field_header = function (type_id, field_id) { return buffer; }; -SerializedObject.sort_typedef = function (typedef) { +SerializedObject.sort_typedef = function(typedef) { assert(Array.isArray(typedef)); function sort_field_compare(a, b) { @@ -291,8 +297,8 @@ SerializedObject.sort_typedef = function (typedef) { return typedef.sort(sort_field_compare); }; -SerializedObject.lookup_type_tx = function (id) { - assert(typeof id === 'number'); +SerializedObject.lookup_type_tx = function(id) { + assert.strictEqual(typeof id, 'number'); return TRANSACTION_TYPES[id]; }; diff --git a/src/js/ripple/serializedtypes.js b/src/js/ripple/serializedtypes.js index a79d3535..7f90158b 100644 --- a/src/js/ripple/serializedtypes.js +++ b/src/js/ripple/serializedtypes.js @@ -22,8 +22,8 @@ var Amount = amount.Amount; var Currency = amount.Currency; // Shortcuts -var hex = sjcl.codec.hex; -var bytes = sjcl.codec.bytes; +var hex = sjcl.codec.hex; +var bytes = sjcl.codec.bytes; var BigInteger = utils.jsbn.BigInteger; @@ -79,11 +79,7 @@ SerializedType.serialize_varint = function (so, val) { so.append([193 + (val >>> 8), val & 0xff]); } else if (val <= 918744) { val -= 12481; - so.append([ - 241 + (val >>> 16), - val >>> 8 & 0xff, - val & 0xff - ]); + so.append([ 241 + (val >>> 16), val >>> 8 & 0xff, val & 0xff ]); } else { throw new Error('Variable integer overflow.'); } @@ -105,7 +101,7 @@ SerializedType.prototype.parse_varint = function (so) { } else if (b1 <= 254) { b2 = so.read(1)[0]; b3 = so.read(1)[0]; - result = 12481 + (b1 - 241) * 65536 + b2 * 256 + b3 + result = 12481 + (b1 - 241) * 65536 + b2 * 256 + b3; } return result; @@ -142,7 +138,7 @@ function readAndSum(so, bytes) { var sum = 0; if (bytes > 4) { - throw new Error("This function only supports up to four bytes."); + throw new Error('This function only supports up to four bytes.'); } for (var i=0; i>> 0 !== parseFloat(opts.port) || // is integer? - opts.port < 1 || - opts.port > 65535) { + // We want to allow integer strings as valid port numbers for backward compatibility + if (typeof opts.port !== 'number') { + opts.port = Number(opts.port); + } + + if (opts.port < 1 || opts.port > 65535) { throw new TypeError('Server "port" must be an integer in range 1-65535'); } @@ -86,7 +99,9 @@ function Server(remote, opts) { }); function checkServerActivity() { - if (isNaN(self._lastLedgerClose)) return; + if (isNaN(self._lastLedgerClose)) { + return; + } var delta = (Date.now() - self._lastLedgerClose); @@ -111,6 +126,8 @@ function Server(remote, opts) { util.inherits(Server, EventEmitter); +Server.domainRE = /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?)*\.?$/; + /** * Server states that we will treat as the server being online. * @@ -135,7 +152,10 @@ Server.onlineStates = [ Server.prototype._setState = function(state) { if (state !== this._state) { - this._remote.trace && log.info('set_state:', state); + if (this._remote.trace) { + log.info('set_state:', state); + } + this._state = state; this.emit('state', state); @@ -158,7 +178,11 @@ Server.prototype._setState = function(state) { */ Server.prototype._remoteAddress = function() { - try { var address = this._ws._socket.remoteAddress; } catch (e) { } + var address; + try { + address = this._ws._socket.remoteAddress; + } catch (e) { + } return address; }; @@ -187,7 +211,9 @@ Server.websocketConstructor = function() { Server.prototype.disconnect = function() { this._shouldConnect = false; this._setState('offline'); - if (this._ws) this._ws.close(); + if (this._ws) { + this._ws.close(); + } }; /** @@ -218,12 +244,18 @@ Server.prototype.connect = function() { // recently received a message from the server and the WebSocket has not // reported any issues either. If we do fail to ping or the connection drops, // we will automatically reconnect. - if (this._connected) return; + if (this._connected) { + return; + } - this._remote.trace && log.info('connect:', this._opts.url); + if (this._remote.trace) { + log.info('connect:', this._opts.url); + } // Ensure any existing socket is given the command to close first. - if (this._ws) this._ws.close(); + if (this._ws) { + this._ws.close(); + } var WebSocket = Server.websocketConstructor(); @@ -246,7 +278,7 @@ Server.prototype.connect = function() { if (ws === self._ws) { self.emit('socket_open'); // Subscribe to events - self.request(self._remote._serverPrepareSubscribe()); + self._request(self._remote._serverPrepareSubscribe()); } }; @@ -254,7 +286,10 @@ Server.prototype.connect = function() { // If we are no longer the active socket, simply ignore any event if (ws === self._ws) { self.emit('socket_error'); - self._remote.trace && log.info('onerror:', self._opts.url, e.data || e); + + if (self._remote.trace) { + log.info('onerror:', self._opts.url, e.data || e); + } // Most connection errors for WebSockets are conveyed as 'close' events with // code 1006. This is done for security purposes and therefore unlikely to @@ -278,7 +313,9 @@ Server.prototype.connect = function() { ws.onclose = function onClose() { // If we are no longer the active socket, simply ignore any event if (ws === self._ws) { - self._remote.trace && log.info('onclose:', self._opts.url, ws.readyState); + if (self._remote.trace) { + log.info('onclose:', self._opts.url, ws.readyState); + } self._handleClose(); } }; @@ -305,7 +342,9 @@ Server.prototype._retryConnect = function() { function connectionRetry() { if (self._shouldConnect) { - self._remote.trace && log.info('retry', self._opts.url); + if (self._remote.trace) { + log.info('retry', self._opts.url); + } self.connect(); } }; @@ -344,9 +383,14 @@ Server.prototype._handleClose = function() { Server.prototype._handleMessage = function(message) { var self = this; - try { message = JSON.parse(message); } catch(e) { } + try { + message = JSON.parse(message); + } catch(e) { + } - if (!Server.isValidMessage(message)) return; + if (!Server.isValidMessage(message)) { + return; + } switch (message.type) { case 'ledgerClosed': @@ -364,10 +408,8 @@ Server.prototype._handleMessage = function(message) { self.emit('load', message, self); self._remote.emit('load', message, self); - var loadChanged = ((message.load_base !== self._load_base) || - (message.load_factor !== self._load_factor)); - - if (loadChanged) { + if (message.load_base !== self._load_base || message.load_factor !== self._load_factor) { + // Load changed self._load_base = message.load_base; self._load_factor = message.load_factor; self.emit('load_changed', message, self); @@ -382,9 +424,16 @@ Server.prototype._handleMessage = function(message) { delete self._requests[message.id]; if (!request) { - this._remote.trace && log.info('UNEXPECTED:', self._opts.url, message); - } else if (message.status === 'success') { - this._remote.trace && log.info('response:', self._opts.url, message); + if (this._remote.trace) { + log.info('UNEXPECTED:', self._opts.url, message); + } + return; + } + + if (message.status === 'success') { + if (this._remote.trace) { + log.info('response:', self._opts.url, message); + } request.emit('success', message.result); @@ -392,20 +441,23 @@ Server.prototype._handleMessage = function(message) { emitter.emit('response_' + request.message.command, message.result, request, message); }); } else if (message.error) { - this._remote.trace && log.info('error:', self._opts.url, message); + if (this._remote.trace) { + log.info('error:', self._opts.url, message); + } request.emit('error', { - error : 'remoteError', - error_message : 'Remote reported an error.', - remote : message + error: 'remoteError', + error_message: 'Remote reported an error.', + remote: message }); } break; case 'path_find': - this._remote.trace && log.info('path_find:', self._opts.url, message); + if (this._remote.trace) { + log.info('path_find:', self._opts.url, message); + } break; - } }; @@ -460,9 +512,11 @@ Server.prototype._handleResponseSubscribe = function(message) { * @api private */ -Server.prototype.sendMessage = function(message) { +Server.prototype._sendMessage = function(message) { if (this._ws) { - this._remote.trace && log.info('request:', this._opts.url, message); + if (this._remote.trace) { + log.info('request:', this._opts.url, message); + } this._ws.send(JSON.stringify(message)); } }; @@ -477,12 +531,14 @@ Server.prototype.sendMessage = function(message) { * @api private */ -Server.prototype.request = function(request) { +Server.prototype._request = function(request) { var self = this; // Only bother if we are still connected. if (!this._ws) { - this._remote.trace && log.info('request: DROPPING:', self._opts.url, request.message); + if (this._remote.trace) { + log.info('request: DROPPING:', self._opts.url, request.message); + } return; } @@ -494,14 +550,15 @@ Server.prototype.request = function(request) { // Advance message ID this._id++; + function sendRequest() { + self._sendMessage(request.message); + }; + if (this._isConnected(request)) { - this.sendMessage(request.message); + sendRequest(); } else { // XXX There are many ways to make this smarter. - function serverReconnected() { - self.sendMessage(request.message); - } - this.once('connect', serverReconnected); + this.once('connect', sendRequest); } }; @@ -521,7 +578,7 @@ Server.prototype._isConnected = function(request) { * @api private */ -Server.prototype.computeFee = function(transaction) { +Server.prototype._computeFee = function(transaction) { var units; if (transaction instanceof Transaction) { @@ -532,7 +589,7 @@ Server.prototype.computeFee = function(transaction) { throw new Error('Invalid argument'); } - return this.feeTx(units).to_json(); + return this._feeTx(units).to_json(); }; /** @@ -544,8 +601,8 @@ Server.prototype.computeFee = function(transaction) { * @return {Amount} Final fee in XRP for specified number of fee units. */ -Server.prototype.feeTx = function(units) { - var fee_unit = this.feeTxUnit(); +Server.prototype._feeTx = function(units) { + var fee_unit = this._feeTxUnit(); return Amount.from_json(String(Math.ceil(units * fee_unit))); }; @@ -558,7 +615,7 @@ Server.prototype.feeTx = function(units) { * @return {Number} Recommended amount for one fee unit as float. */ -Server.prototype.feeTxUnit = function() { +Server.prototype._feeTxUnit = function() { var fee_unit = this._fee_base / this._fee_ref; // Apply load fees @@ -576,10 +633,10 @@ Server.prototype.feeTxUnit = function() { * Returns the base reserve with load fees and safety margin applied. */ -Server.prototype.reserve = function(owner_count) { +Server.prototype._reserve = function(ownerCount) { var reserve_base = Amount.from_json(String(this._reserve_base)); var reserve_inc = Amount.from_json(String(this._reserve_inc)); - var owner_count = owner_count || 0; + var owner_count = ownerCount || 0; if (owner_count < 0) { throw new Error('Owner count must not be negative.'); diff --git a/src/js/ripple/shamap.js b/src/js/ripple/shamap.js index bc2823ab..cc0f66a6 100644 --- a/src/js/ripple/shamap.js +++ b/src/js/ripple/shamap.js @@ -10,12 +10,12 @@ function SHAMap() { this.root = new SHAMapTreeNodeInner(); }; -SHAMap.prototype.add_item = function (tag, node, type) { +SHAMap.prototype.add_item = function(tag, node, type) { var node = new SHAMapTreeNodeLeaf(tag, node, type); this.root.add_item(tag, node); }; -SHAMap.prototype.hash = function () { +SHAMap.prototype.hash = function() { return this.root.hash(); }; @@ -24,21 +24,19 @@ SHAMap.prototype.hash = function () { * * Can be either SHAMapTreeNodeInner or SHAMapTreeNodeLeaf. */ -function SHAMapTreeNode() { - -}; +function SHAMapTreeNode() { }; SHAMapTreeNode.TYPE_INNER = 1; SHAMapTreeNode.TYPE_TRANSACTION_NM = 2; SHAMapTreeNode.TYPE_TRANSACTION_MD = 3; SHAMapTreeNode.TYPE_ACCOUNT_STATE = 4; -SHAMapTreeNode.prototype.add_item = function (tag_segment, node) { - throw new Error("Called unimplemented virtual method SHAMapTreeNode#add_item."); +SHAMapTreeNode.prototype.add_item = function(tag_segment, node) { + throw new Error('Called unimplemented virtual method SHAMapTreeNode#add_item.'); }; -SHAMapTreeNode.prototype.hash = function () { - throw new Error("Called unimplemented virtual method SHAMapTreeNode#hash."); +SHAMapTreeNode.prototype.hash = function() { + throw new Error('Called unimplemented virtual method SHAMapTreeNode#hash.'); }; /** @@ -56,7 +54,7 @@ function SHAMapTreeNodeInner() { util.inherits(SHAMapTreeNodeInner, SHAMapTreeNode); -SHAMapTreeNodeInner.prototype.add_item = function (tag_segment, node) { +SHAMapTreeNodeInner.prototype.add_item = function(tag_segment, node) { var current_node = this.get_node(tag_segment[0]); if (current_node) { @@ -67,7 +65,7 @@ SHAMapTreeNodeInner.prototype.add_item = function (tag_segment, node) { current_node.add_item(tag_segment.slice(1), node); } else if (current_node.get_segment() === tag_segment) { // Collision - throw new Error("Tried to add a node to a SHAMap that was already in there."); + throw new Error('Tried to add a node to a SHAMap that was already in there.'); } else { // Turn it into an inner node var new_inner_node = new SHAMapTreeNodeInner(); @@ -92,28 +90,31 @@ SHAMapTreeNodeInner.prototype.add_item = function (tag_segment, node) { /** * Overwrite the node that is currently in a given slot. */ -SHAMapTreeNodeInner.prototype.set_node = function (slot, node) { +SHAMapTreeNodeInner.prototype.set_node = function(slot, node) { this.leaves[slot] = node; this.empty = false; }; -SHAMapTreeNodeInner.prototype.get_node = function (slot) { +SHAMapTreeNodeInner.prototype.get_node = function(slot) { return this.leaves[slot]; }; -SHAMapTreeNodeInner.prototype.hash = function () { +SHAMapTreeNodeInner.prototype.hash = function() { if (this.empty) { return UInt256.from_hex(UInt256.HEX_ZERO); } var hash_buffer = new SerializedObject(); - var buffer = []; - for (var i = 0; i < 16; i++) { + var buffer = [ ]; + + for (var i=0; i<16; i++) { var leafHash = UInt256.from_hex(UInt256.HEX_ZERO); var slot = i.toString(16).toUpperCase(); - if ("object" === typeof this.leaves[slot]) { + + if (typeof this.leaves[slot] === 'object') { leafHash = this.leaves[slot].hash(); } + hash_buffer.append(leafHash.to_bytes()); } @@ -128,32 +129,30 @@ SHAMapTreeNodeInner.prototype.hash = function () { function SHAMapTreeNodeLeaf(tag, node, type) { SHAMapTreeNode.call(this); - if ("string" === typeof tag) { + if (typeof tag === 'string') { tag = UInt256.from_hex(tag); - } else if (tag instanceof UInt256) { - // Type is already the right one - } else { - throw new Error("Tag is unexpected type."); + } else if (!(tag instanceof UInt256)){ + throw new Error('Tag is unexpected type.'); } this.tag = tag; this.tag_segment = null; this.type = type; - this.node = node; -} +}; + util.inherits(SHAMapTreeNodeLeaf, SHAMapTreeNode); -SHAMapTreeNodeLeaf.prototype.get_segment = function (segment) { +SHAMapTreeNodeLeaf.prototype.get_segment = function(segment) { return this.tag_segment; }; -SHAMapTreeNodeLeaf.prototype.set_segment = function (segment) { +SHAMapTreeNodeLeaf.prototype.set_segment = function(segment) { this.tag_segment = segment; }; -SHAMapTreeNodeLeaf.prototype.hash = function () { +SHAMapTreeNodeLeaf.prototype.hash = function() { var buffer = new SerializedObject(); switch (this.type) { case SHAMapTreeNode.TYPE_TRANSACTION_NM: @@ -163,7 +162,7 @@ SHAMapTreeNodeLeaf.prototype.hash = function () { buffer.append(this.tag.to_bytes()); return buffer.hash(hashprefixes.HASH_TX_NODE); default: - throw new Error("Tried to hash a SHAMap node of unknown type."); + throw new Error('Tried to hash a SHAMap node of unknown type.'); } }; diff --git a/src/js/ripple/transaction.js b/src/js/ripple/transaction.js index 6ea4055f..061630d5 100644 --- a/src/js/ripple/transaction.js +++ b/src/js/ripple/transaction.js @@ -71,11 +71,12 @@ function Transaction(remote) { this.state = 'unsubmitted'; this.finalized = false; this.previousSigningHash = void(0); + // Index at which transaction was submitted this.submitIndex = void(0); // Canonical signing setting defaults to the Remote's configuration - this.canonical = "object" === typeof remote ? !!remote.canonical_signing : true; + this.canonical = (typeof remote === 'object') ? !!remote.canonical_signing : true; // We aren't clever enough to eschew preventative measures so we keep an array // of all submitted transactionIDs (which can change due to load_factor @@ -261,11 +262,16 @@ Transaction.prototype._getServer = function() { for (var i=0; i this._maxFee) { - tx.emit('error', new RippleError('tejMaxFeeExceeded', 'Max fee exceeded')); + this.emit('error', new RippleError('tejMaxFeeExceeded', 'Max fee exceeded')); return false; } @@ -346,7 +352,7 @@ Transaction.prototype.hash = function(prefix, as_uint256) { } prefix = hashprefixes[prefix]; } else if (!prefix) { - prefix = hashprefixes['HASH_TX_ID']; + prefix = hashprefixes.HASH_TX_ID; } var hash = SerializedObject.from_json(this.tx_json).hash(prefix); @@ -403,7 +409,9 @@ Transaction.prototype.findId = function(cache) { for (var i=0; i flags: undefined, _flag_, or [ _flags_ ] Transaction.prototype.setFlags = function(flags) { - if (!flags) return this; + if (flags === void(0)) { + return this; + } + + if (typeof flags === 'number') { + this.tx_json.Flags = flags; + return this; + } var flag_set = Array.isArray(flags) ? flags : Array.prototype.slice.call(arguments); var transaction_flags = Transaction.flags[this.tx_json.TransactionType] || { }; @@ -919,7 +936,7 @@ Transaction.summary = function() { state: this.state, server: this._server ? this._server._opts.url : void(0), finalized: this.finalized - } + }; if (this.result) { result.result = { @@ -928,7 +945,7 @@ Transaction.summary = function() { ledger_hash : this.result.ledger_hash, ledger_index : this.result.ledger_index, transaction_hash : this.result.tx_json.hash - } + }; } return result; diff --git a/src/js/ripple/transactionmanager.js b/src/js/ripple/transactionmanager.js index 56f9bd4a..14887c47 100644 --- a/src/js/ripple/transactionmanager.js +++ b/src/js/ripple/transactionmanager.js @@ -3,6 +3,7 @@ var EventEmitter = require('events').EventEmitter; var Transaction = require('./transaction').Transaction; var RippleError = require('./rippleerror').RippleError; var PendingQueue = require('./transactionqueue').TransactionQueue; +var log = require('./log').internal.sub('transactionmanager'); /** * @constructor TransactionManager @@ -20,24 +21,28 @@ function TransactionManager(account) { this._nextSequence = void(0); this._maxFee = this._remote.max_fee; this._submissionTimeout = this._remote._submission_timeout; - this._pending = new PendingQueue; + this._pending = new PendingQueue(); // Query remote server for next account sequence number this._loadSequence(); function transactionReceived(res) { var transaction = TransactionManager.normalizeTransaction(res); - var sequence = transaction.transaction.Sequence; - var hash = transaction.transaction.hash; + var sequence = transaction.tx_json.Sequence; + var hash = transaction.tx_json.hash; - if (!transaction.validated) return; + if (!transaction.validated) { + return; + } self._pending.addReceivedSequence(sequence); // ND: we need to check against all submissions IDs var submission = self._pending.getSubmission(hash); - self._remote._trace('transactionmanager: transaction_received:', transaction.transaction); + if (self._remote.trace) { + log.info('transaction received:', transaction.transaction); + } if (submission) { // ND: A `success` handler will `finalize` this later @@ -52,10 +57,13 @@ function TransactionManager(account) { function adjustFees(loadData, server) { // ND: note, that `Fee` is a component of a transactionID self._pending.forEach(function(pending) { - var shouldAdjust = pending._server === server - && self._remote.local_fee && pending.tx_json.Fee; + if (pending._server !== server) { + return; + } - if (!shouldAdjust) return; + if (!(self._remote.local_fee && pending.tx_json.Fee)) { + return; + } var oldFee = pending.tx_json.Fee; var newFee = server.computeFee(pending); @@ -69,7 +77,9 @@ function TransactionManager(account) { pending.tx_json.Fee = newFee; pending.emit('fee_adjusted', oldFee, newFee); - self._remote._trace('transactionmanager: adjusting_fees:', pending.tx_json, oldFee, newFee); + if (self._remote.trace) { + log.info('fee adjusted:', pending.tx_json, oldFee, newFee); + } }); }; @@ -80,7 +90,6 @@ function TransactionManager(account) { switch (ledger.ledger_index - pending.submitIndex) { case 8: pending.emit('lost', ledger); - self._remote._trace('transactionmanager: update_pending:', pending.tx_json); break; case 4: pending.emit('missing', ledger); @@ -106,7 +115,7 @@ function TransactionManager(account) { binary: true, limit: 100, filter: 'outbound' - } + }; function accountTx(err, transactions) { if (!err && Array.isArray(transactions.transactions)) { @@ -116,9 +125,7 @@ function TransactionManager(account) { self._remote.on('ledger_closed', updatePendingStatus); //Load next transaction sequence - self._loadSequence(function sequenceLoaded() { - self._resubmit(); - }); + self._loadSequence(self._resubmit.bind(self)); callback(); }; @@ -149,29 +156,40 @@ util.inherits(TransactionManager, EventEmitter); //Normalize transactions received from account //transaction stream and account_tx TransactionManager.normalizeTransaction = function(tx) { - var transaction = tx; + var transaction = { }; + + Object.keys(tx).forEach(function(key) { + transaction[key] = tx[key]; + }); if (!tx.engine_result) { // account_tx transaction = { engine_result: tx.meta.TransactionResult, - transaction: tx.tx, + tx_json: tx.tx, hash: tx.tx.hash, ledger_index: tx.tx.ledger_index, meta: tx.meta, type: 'transaction', validated: true - } - transaction.result = transaction.engine_result; + }; + + transaction.result = transaction.engine_result; transaction.result_message = transaction.engine_result_message; } - transaction.metadata = transaction.meta; + if (!transaction.metadata) { + transaction.metadata = transaction.meta; + } if (!transaction.tx_json) { transaction.tx_json = transaction.transaction; } + delete transaction.transaction; + delete transaction.mmeta; + delete transaction.meta; + return transaction; }; @@ -202,7 +220,9 @@ TransactionManager.prototype._fillSequence = function(tx, callback) { var submitted = 0; ;(function nextFill(sequence) { - if (sequence >= tx.tx_json.Sequence) return; + if (sequence >= tx.tx_json.Sequence) { + return; + } submitFill(sequence, function() { if (++submitted === sequenceDif) { @@ -250,7 +270,9 @@ TransactionManager.prototype._resubmit = function(ledgers, pending) { var hashCached = pending.findId(self._pending._idCache); - self._remote._trace('transactionmanager: resubmit:', pending.tx_json); + if (self._remote.trace) { + log.info('resubmit:', pending.tx_json); + } if (hashCached) { return pending.emit('success', hashCached); @@ -259,7 +281,9 @@ TransactionManager.prototype._resubmit = function(ledgers, pending) { while (self._pending.hasSequence(pending.tx_json.Sequence)) { //Sequence number has been consumed by another transaction pending.tx_json.Sequence += 1; - self._remote._trace('transactionmanager: incrementing sequence:', pending.tx_json); + if (self._remote.trace) { + log.info('incrementing sequence:', pending.tx_json); + } } self._request(pending); @@ -269,14 +293,18 @@ TransactionManager.prototype._resubmit = function(ledgers, pending) { ;(function nextTransaction(i) { var transaction = pending[i]; - if (!(transaction instanceof Transaction)) return; + if (!(transaction instanceof Transaction)) { + return; + } transaction.once('submitted', function(m) { transaction.emit('resubmitted', m); self._loadSequence(); - if (++i < pending.length) nextTransaction(i); + if (++i < pending.length) { + nextTransaction(i); + } }); resubmitTransaction(transaction); @@ -287,16 +315,20 @@ TransactionManager.prototype._resubmit = function(ledgers, pending) { }; TransactionManager.prototype._waitLedgers = function(ledgers, callback) { - if (ledgers < 1) return callback(); + if (ledgers < 1) { + return callback(); + } var self = this; var closes = 0; function ledgerClosed() { - if (++closes === ledgers) { - self._remote.removeListener('ledger_closed', ledgerClosed); - callback(); + if (++closes < ledgers) { + return; } + + self._remote.removeListener('ledger_closed', ledgerClosed); + callback(); }; this._remote.on('ledger_closed', ledgerClosed); @@ -326,19 +358,30 @@ TransactionManager.prototype._request = function(tx) { tx.emit('presubmit'); - if (tx.finalized) return; + if (tx.finalized) { + return; + } - remote._trace('transactionmanager: submit:', tx.tx_json); + if (remote.trace) { + log.info('submit transaction:', tx.tx_json); + } function transactionProposed(message) { - if (tx.finalized) return; + if (tx.finalized) { + return; + } + // If server is honest, don't expect a final if rejected. message.rejected = tx.isRejected(message.engine_result_code); + tx.emit('proposed', message); }; function transactionFailed(message) { - if (tx.finalized) return; + if (tx.finalized) { + return; + } + switch (message.engine_result) { case 'tefPAST_SEQ': self._resubmit(1, tx); @@ -349,7 +392,9 @@ TransactionManager.prototype._request = function(tx) { }; function transactionRetry(message) { - if (tx.finalized) return; + if (tx.finalized) { + return; + } self._fillSequence(tx, function() { self._resubmit(1, tx); @@ -357,17 +402,19 @@ TransactionManager.prototype._request = function(tx) { }; function transactionFeeClaimed(message) { - if (tx.finalized) return; + if (tx.finalized) { + return; + } + tx.emit('error', message); }; function transactionFailedLocal(message) { - if (tx.finalized) return; + if (tx.finalized) { + return; + } - var shouldAdjustFee = self._remote.local_fee - && (message.engine_result === 'telINSUF_FEE_P'); - - if (shouldAdjustFee) { + if (self._remote.local_fee && (message.engine_result === 'telINSUF_FEE_P')) { self._resubmit(1, tx); } else { submissionError(message); @@ -376,7 +423,9 @@ TransactionManager.prototype._request = function(tx) { function submissionError(error) { // Finalized (e.g. aborted) transactions must stop all activity - if (tx.finalized) return; + if (tx.finalized) { + return; + } if (TransactionManager._isTooBusy(error)) { self._resubmit(1, tx); @@ -388,7 +437,9 @@ TransactionManager.prototype._request = function(tx) { function submitted(message) { // Finalized (e.g. aborted) transactions must stop all activity - if (tx.finalized) return; + if (tx.finalized) { + return; + } // ND: If for some unknown reason our hash wasn't computed correctly this is // an extra measure. @@ -400,7 +451,9 @@ TransactionManager.prototype._request = function(tx) { tx.result = message; - remote._trace('transactionmanager: submit_response:', message); + if (remote.trace) { + log.info('submit response:', message); + } tx.emit('submitted', message); @@ -480,18 +533,24 @@ TransactionManager.prototype._request = function(tx) { // that ALL transactionIDs sent over network are tracked. // Finalized (e.g. aborted) transactions must stop all activity - if (tx.finalized) return; + if (tx.finalized) { + return; + } tx.emit('timeout'); if (remote._connected) { - remote._trace('transactionmanager: timeout:', tx.tx_json); + if (remote.trace) { + log.info('timeout:', tx.tx_json); + } self._resubmit(3, tx); } }; function submitTransaction() { - if (tx.finalized) return; + if (tx.finalized) { + return; + } submitRequest.timeout(self._submissionTimeout, requestTimeout); submitRequest.request(); @@ -557,22 +616,23 @@ TransactionManager.prototype.submit = function(tx) { var remote = this._remote; // If sequence number is not yet known, defer until it is. - if (typeof this._nextSequence === 'undefined') { - function sequenceLoaded() { - self.submit(tx); - }; - this.once('sequence_loaded', sequenceLoaded); + if (typeof this._nextSequence !== 'number') { + this.once('sequence_loaded', this.submit.bind(this, tx)); return; } // Finalized (e.g. aborted) transactions must stop all activity - if (tx.finalized) return; + if (tx.finalized) { + return; + } function cleanup(message) { // ND: We can just remove this `tx` by identity self._pending.remove(tx); tx.emit('final', message); - remote._trace('transactionmanager: finalize_transaction:', tx.tx_json); + if (remote.trace) { + log.info('transaction finalized:', tx.tx_json, self._pending.getLength()); + } }; tx.once('cleanup', cleanup); diff --git a/src/js/ripple/transactionqueue.js b/src/js/ripple/transactionqueue.js index b9968dd9..6fa8ac0d 100644 --- a/src/js/ripple/transactionqueue.js +++ b/src/js/ripple/transactionqueue.js @@ -3,27 +3,12 @@ * Manager for pending transactions */ -var Transaction = require('./transaction').Transaction; var LRU = require('lru-cache'); function TransactionQueue() { - var self = this; - - this._queue = [ ]; - this._idCache = LRU({ max: 100 }); - this._sequenceCache = LRU({ max: 100 }); - this._save = void(0); -}; - -TransactionQueue.prototype.save = function() { - if (typeof this._save !== 'function') return; - - this._save(this._queue.map(function(tx) { - return { - tx_json: tx.tx_json, - submittedIDs: tx.submittedIDs - } - })); + this._queue = [ ]; + this._idCache = LRU(); + this._sequenceCache = LRU(); }; /** @@ -64,10 +49,10 @@ TransactionQueue.prototype.hasSequence = function(sequence) { * may have multiple associated IDs. */ -TransactionQueue.prototype.getSubmission = function(id, callback) { +TransactionQueue.prototype.getSubmission = function(id) { var result = false; - for (var i=0, tx; tx=this._queue[i]; i++) { + for (var i=0, tx; (tx=this._queue[i]); i++) { if (~tx.submittedIDs.indexOf(id)) { result = tx; break; @@ -91,20 +76,18 @@ TransactionQueue.prototype.remove = function(tx) { break; } } - - this.save(); }; TransactionQueue.prototype.push = function(tx) { this._queue.push(tx); - this.save(); }; TransactionQueue.prototype.forEach = function(fn) { this._queue.forEach(fn); }; -TransactionQueue.prototype.length = function() { +TransactionQueue.prototype.length = +TransactionQueue.prototype.getLength = function() { return this._queue.length; }; diff --git a/src/js/ripple/uint.js b/src/js/ripple/uint.js index e44f7fbc..37500cd2 100644 --- a/src/js/ripple/uint.js +++ b/src/js/ripple/uint.js @@ -4,27 +4,25 @@ var config = require('./config'); var BigInteger = utils.jsbn.BigInteger; -var Base = require('./base').Base; - // // Abstract UInt class // -// Base class for UInt??? classes +// Base class for UInt classes // -var UInt = function () { +var UInt = function() { // Internal form: NaN or BigInteger this._value = NaN; this._update(); }; -UInt.json_rewrite = function (j, opts) { +UInt.json_rewrite = function(j, opts) { return this.from_json(j).to_json(opts); }; // Return a new UInt from j. -UInt.from_generic = function (j) { +UInt.from_generic = function(j) { if (j instanceof this) { return j.clone(); } else { @@ -33,7 +31,7 @@ UInt.from_generic = function (j) { }; // Return a new UInt from j. -UInt.from_hex = function (j) { +UInt.from_hex = function(j) { if (j instanceof this) { return j.clone(); } else { @@ -42,7 +40,7 @@ UInt.from_hex = function (j) { }; // Return a new UInt from j. -UInt.from_json = function (j) { +UInt.from_json = function(j) { if (j instanceof this) { return j.clone(); } else { @@ -51,7 +49,7 @@ UInt.from_json = function (j) { }; // Return a new UInt from j. -UInt.from_bits = function (j) { +UInt.from_bits = function(j) { if (j instanceof this) { return j.clone(); } else { @@ -60,7 +58,7 @@ UInt.from_bits = function (j) { }; // Return a new UInt from j. -UInt.from_bytes = function (j) { +UInt.from_bytes = function(j) { if (j instanceof this) { return j.clone(); } else { @@ -69,7 +67,7 @@ UInt.from_bytes = function (j) { }; // Return a new UInt from j. -UInt.from_bn = function (j) { +UInt.from_bn = function(j) { if (j instanceof this) { return j.clone(); } else { @@ -78,7 +76,7 @@ UInt.from_bn = function (j) { }; // Return a new UInt from j. -UInt.from_number = function (j) { +UInt.from_number = function(j) { if (j instanceof this) { return j.clone(); } else { @@ -86,32 +84,34 @@ UInt.from_number = function (j) { } }; -UInt.is_valid = function (j) { +UInt.is_valid = function(j) { return this.from_json(j).is_valid(); }; -UInt.prototype.clone = function () { +UInt.prototype.clone = function() { return this.copyTo(new this.constructor()); }; // Returns copy. -UInt.prototype.copyTo = function (d) { +UInt.prototype.copyTo = function(d) { d._value = this._value; - if ("function" === typeof d._update) d._update(); + if (typeof d._update === 'function') { + d._update(); + } return d; }; -UInt.prototype.equals = function (d) { +UInt.prototype.equals = function(d) { return this._value instanceof BigInteger && d._value instanceof BigInteger && this._value.equals(d._value); }; -UInt.prototype.is_valid = function () { +UInt.prototype.is_valid = function() { return this._value instanceof BigInteger; }; -UInt.prototype.is_zero = function () { +UInt.prototype.is_zero = function() { return this._value.equals(BigInteger.ZERO); }; @@ -125,47 +125,44 @@ UInt.prototype.is_zero = function () { * The reason for keeping this mechanism in this class is so every subclass can * call it whenever it modifies the internal state. */ -UInt.prototype._update = function () { +UInt.prototype._update = function() { // Nothing to do by default. Subclasses will override this. }; // value = NaN on error. -UInt.prototype.parse_generic = function (j) { +UInt.prototype.parse_generic = function(j) { // Canonicalize and validate - if (config.accounts && j in config.accounts) + if (config.accounts && (j in config.accounts)) { j = config.accounts[j].account; + } switch (j) { - case undefined: - case "0": - case this.constructor.STR_ZERO: - case this.constructor.ACCOUNT_ZERO: - case this.constructor.HEX_ZERO: - this._value = BigInteger.valueOf(); - break; + case undefined: + case '0': + case this.constructor.STR_ZERO: + case this.constructor.ACCOUNT_ZERO: + case this.constructor.HEX_ZERO: + this._value = BigInteger.valueOf(); + break; - case "1": - case this.constructor.STR_ONE: - case this.constructor.ACCOUNT_ONE: - case this.constructor.HEX_ONE: - this._value = new BigInteger([1]); + case '1': + case this.constructor.STR_ONE: + case this.constructor.ACCOUNT_ONE: + case this.constructor.HEX_ONE: + this._value = new BigInteger([1]); + break; - break; - - default: - if ('string' !== typeof j) { - this._value = NaN; - } - else if (this.constructor.width === j.length) { - this._value = new BigInteger(utils.stringToArray(j), 256); - } - else if ((this.constructor.width*2) === j.length) { - // XXX Check char set! - this._value = new BigInteger(j, 16); - } - else { - this._value = NaN; - } + default: + if (typeof j !== 'string') { + this._value = NaN; + } else if (this.constructor.width === j.length) { + this._value = new BigInteger(utils.stringToArray(j), 256); + } else if ((this.constructor.width * 2) === j.length) { + // XXX Check char set! + this._value = new BigInteger(j, 16); + } else { + this._value = NaN; + } } this._update(); @@ -173,12 +170,11 @@ UInt.prototype.parse_generic = function (j) { return this; }; -UInt.prototype.parse_hex = function (j) { - if ('string' === typeof j && - j.length === (this.constructor.width * 2)) { - this._value = new BigInteger(j, 16); +UInt.prototype.parse_hex = function(j) { + if (typeof j === 'string' && j.length === (this.constructor.width * 2)) { + this._value = new BigInteger(j, 16); } else { - this._value = NaN; + this._value = NaN; } this._update(); @@ -186,7 +182,7 @@ UInt.prototype.parse_hex = function (j) { return this; }; -UInt.prototype.parse_bits = function (j) { +UInt.prototype.parse_bits = function(j) { if (sjcl.bitArray.bitLength(j) !== this.constructor.width * 8) { this._value = NaN; } else { @@ -200,11 +196,11 @@ UInt.prototype.parse_bits = function (j) { }; -UInt.prototype.parse_bytes = function (j) { +UInt.prototype.parse_bytes = function(j) { if (!Array.isArray(j) || j.length !== this.constructor.width) { - this._value = NaN; + this._value = NaN; } else { - this._value = new BigInteger([0].concat(j), 256); + this._value = new BigInteger([0].concat(j), 256); } this._update(); @@ -215,11 +211,10 @@ UInt.prototype.parse_bytes = function (j) { UInt.prototype.parse_json = UInt.prototype.parse_hex; -UInt.prototype.parse_bn = function (j) { - if (j instanceof sjcl.bn && - j.bitLength() <= this.constructor.width * 8) { +UInt.prototype.parse_bn = function(j) { + if ((j instanceof sjcl.bn) && j.bitLength() <= this.constructor.width * 8) { var bytes = sjcl.codec.bytes.fromBits(j.toBits()); - this._value = new BigInteger(bytes, 256); + this._value = new BigInteger(bytes, 256); } else { this._value = NaN; } @@ -229,14 +224,11 @@ UInt.prototype.parse_bn = function (j) { return this; }; -UInt.prototype.parse_number = function (j) { +UInt.prototype.parse_number = function(j) { this._value = NaN; - if ("number" === typeof j && - j === +j && - j >= 0) { - // XXX Better, faster way to get BigInteger from JS int? - this._value = new BigInteger(""+j); + if (typeof j === 'number' && isFinite(j) && j >= 0) { + this._value = new BigInteger(String(j)); } this._update(); @@ -245,24 +237,33 @@ UInt.prototype.parse_number = function (j) { }; // Convert from internal form. -UInt.prototype.to_bytes = function () { - if (!(this._value instanceof BigInteger)) +UInt.prototype.to_bytes = function() { + if (!(this._value instanceof BigInteger)) { return null; + } var bytes = this._value.toByteArray(); - bytes = bytes.map(function (b) { return (b+256) % 256; }); + + bytes = bytes.map(function(b) { + return (b + 256) % 256; + }); + var target = this.constructor.width; // XXX Make sure only trim off leading zeros. bytes = bytes.slice(-target); - while (bytes.length < target) bytes.unshift(0); + + while (bytes.length < target) { + bytes.unshift(0); + } return bytes; }; -UInt.prototype.to_hex = function () { - if (!(this._value instanceof BigInteger)) +UInt.prototype.to_hex = function() { + if (!(this._value instanceof BigInteger)) { return null; + } var bytes = this.to_bytes(); return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(bytes)).toUpperCase(); @@ -270,18 +271,20 @@ UInt.prototype.to_hex = function () { UInt.prototype.to_json = UInt.prototype.to_hex; -UInt.prototype.to_bits = function () { - if (!(this._value instanceof BigInteger)) +UInt.prototype.to_bits = function() { + if (!(this._value instanceof BigInteger)) { return null; + } var bytes = this.to_bytes(); return sjcl.codec.bytes.toBits(bytes); }; -UInt.prototype.to_bn = function () { - if (!(this._value instanceof BigInteger)) +UInt.prototype.to_bn = function() { + if (!(this._value instanceof BigInteger)) { return null; + } var bits = this.to_bits(); diff --git a/src/js/ripple/uint128.js b/src/js/ripple/uint128.js index a82b9166..fbf875dd 100644 --- a/src/js/ripple/uint128.js +++ b/src/js/ripple/uint128.js @@ -1,12 +1,6 @@ -var sjcl = require('./utils').sjcl; -var utils = require('./utils'); -var config = require('./config'); -var extend = require('extend'); - -var BigInteger = utils.jsbn.BigInteger; - -var UInt = require('./uint').UInt, - Base = require('./base').Base; +var utils = require('./utils'); +var extend = require('extend'); +var UInt = require('./uint').UInt; // // UInt128 support @@ -21,9 +15,9 @@ 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); +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; diff --git a/src/js/ripple/uint160.js b/src/js/ripple/uint160.js index 55fc4d0d..a3d02c7b 100644 --- a/src/js/ripple/uint160.js +++ b/src/js/ripple/uint160.js @@ -1,4 +1,3 @@ -var sjcl = require('./utils').sjcl; var utils = require('./utils'); var config = require('./config'); var extend = require('extend'); @@ -12,11 +11,10 @@ var Base = require('./base').Base; // UInt160 support // -var UInt160 = extend(function () { +var UInt160 = extend(function() { // Internal form: NaN or BigInteger this._value = NaN; this._version_byte = void(0); - this._update(); }, UInt); @@ -31,20 +29,19 @@ var HEX_ONE = UInt160.HEX_ONE = '0000000000000000000000000000000000000 var STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO); var STR_ONE = UInt160.STR_ONE = utils.hexToString(HEX_ONE); -UInt160.prototype.set_version = function (j) { +UInt160.prototype.set_version = function(j) { this._version_byte = j; - return this; }; -UInt160.prototype.get_version = function () { +UInt160.prototype.get_version = function() { return this._version_byte; }; // value = NaN on error. -UInt160.prototype.parse_json = function (j) { +UInt160.prototype.parse_json = function(j) { // Canonicalize and validate - if (config.accounts && j in config.accounts) { + if (config.accounts && (j in config.accounts)) { j = config.accounts[j].account; } @@ -68,11 +65,11 @@ UInt160.prototype.parse_json = function (j) { return this; }; -UInt160.prototype.parse_generic = function (j) { +UInt160.prototype.parse_generic = function(j) { UInt.prototype.parse_generic.call(this, j); if (isNaN(this._value)) { - if ("string" === typeof j && j[0] === 'r') { + if ((typeof j === 'string') && j[0] === 'r') { this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j); } } @@ -83,13 +80,14 @@ UInt160.prototype.parse_generic = function (j) { }; // XXX Json form should allow 0 and 1, C++ doesn't currently allow it. -UInt160.prototype.to_json = function (opts) { +UInt160.prototype.to_json = function(opts) { opts = opts || {}; if (this._value instanceof BigInteger) { // If this value has a type, return a Base58 encoded string. - if ("number" === typeof this._version_byte) { + if (typeof this._version_byte === 'number') { var output = Base.encode_check(this._version_byte, this.to_bytes()); + if (opts.gateways && output in opts.gateways) { output = opts.gateways[output]; } diff --git a/src/js/ripple/uint256.js b/src/js/ripple/uint256.js index f10c1b86..e1797654 100644 --- a/src/js/ripple/uint256.js +++ b/src/js/ripple/uint256.js @@ -1,31 +1,23 @@ -var sjcl = require('./utils').sjcl; -var utils = require('./utils'); -var config = require('./config'); -var extend = require('extend'); - -var BigInteger = utils.jsbn.BigInteger; - -var UInt = require('./uint').UInt, - Base = require('./base').Base; +var utils = require('./utils'); +var extend = require('extend'); +var UInt = require('./uint').UInt; // // UInt256 support // -var UInt256 = extend(function () { +var UInt256 = extend(function() { // Internal form: NaN or BigInteger - this._value = NaN; + this._value = NaN; }, UInt); UInt256.width = 32; UInt256.prototype = extend({}, UInt.prototype); UInt256.prototype.constructor = UInt256; -var HEX_ZERO = UInt256.HEX_ZERO = "00000000000000000000000000000000" + - "00000000000000000000000000000000"; -var HEX_ONE = UInt256.HEX_ONE = "00000000000000000000000000000000" + - "00000000000000000000000000000001"; -var STR_ZERO = UInt256.STR_ZERO = utils.hexToString(HEX_ZERO); -var STR_ONE = UInt256.STR_ONE = utils.hexToString(HEX_ONE); +var HEX_ZERO = UInt256.HEX_ZERO = '00000000000000000000000000000000' + '00000000000000000000000000000000'; +var HEX_ONE = UInt256.HEX_ONE = '00000000000000000000000000000000' + '00000000000000000000000000000001'; +var STR_ZERO = UInt256.STR_ZERO = utils.hexToString(HEX_ZERO); +var STR_ONE = UInt256.STR_ONE = utils.hexToString(HEX_ONE); exports.UInt256 = UInt256; diff --git a/src/js/ripple/utils.js b/src/js/ripple/utils.js index a678feab..393fca31 100644 --- a/src/js/ripple/utils.js +++ b/src/js/ripple/utils.js @@ -1,8 +1,3 @@ -Function.prototype.method = function(name, func) { - this.prototype[name] = func; - return this; -}; - function filterErr(code, done) { return function(e) { done(e.code !== code ? e : void(0)); @@ -20,7 +15,7 @@ function throwErr(done) { function trace(comment, func) { return function() { - console.log("%s: %s", trace, arguments.toString); + console.log('%s: %s', trace, arguments.toString); func(arguments); }; }; @@ -94,7 +89,7 @@ function chunkString(str, n, leftAlign) { function assert(assertion, msg) { if (!assertion) { - throw new Error("Assertion failed" + (msg ? ": "+msg : ".")); + throw new Error('Assertion failed' + (msg ? ': ' + msg : '.')); } }; @@ -139,8 +134,8 @@ function fromTimestamp(rpepoch) { }; exports.time = { - fromRipple: toTimestamp, - toRipple: fromTimestamp + fromRipple: toTimestamp, + toRipple: fromTimestamp }; exports.trace = trace;