diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index cab896f8..e274f7a0 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -133,8 +133,8 @@ } }, "ripple-binary-codec": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.0.5.tgz", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.0.6.tgz", "dependencies": { "bn.js": { "version": "3.2.0", diff --git a/package.json b/package.json index 7d1adeb6..083b3b87 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "lodash": "^3.1.0", "lru-cache": "~2.5.0", "ripple-address-codec": "^2.0.1", - "ripple-binary-codec": "^0.0.5", + "ripple-binary-codec": "^0.0.6", "ripple-keypairs": "^0.9.0", "ripple-lib-transactionparser": "^0.5.1", "ripple-lib-value": "0.1.0", diff --git a/src/api/ledger/parse/utils.js b/src/api/ledger/parse/utils.js index bf5d34c7..9fbac78b 100644 --- a/src/api/ledger/parse/utils.js +++ b/src/api/ledger/parse/utils.js @@ -67,15 +67,19 @@ function parseOutcome(tx: Object): ?Object { }; } +function hexToString(hex) { + return hex ? new Buffer(hex, 'hex').toString('utf-8') : undefined; +} + function parseMemos(tx: Object): ?Array { if (!Array.isArray(tx.Memos) || tx.Memos.length === 0) { return undefined; } return tx.Memos.map((m) => { return removeUndefined({ - type: m.Memo.parsed_memo_type, - format: m.Memo.parsed_memo_format, - data: m.Memo.parsed_memo_data + type: m.Memo.parsed_memo_type || hexToString(m.Memo.MemoType), + format: m.Memo.parsed_memo_format || hexToString(m.Memo.MemoFormat), + data: m.Memo.parsed_memo_data || hexToString(m.Memo.MemoData) }); }); } diff --git a/src/core/base.js b/src/core/base.js deleted file mode 100644 index bab273ed..00000000 --- a/src/core/base.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; - -const BN = require('bn.js'); -const extend = require('extend'); -const {encode, decode} = require('ripple-address-codec'); - -const Base = {}; - -extend(Base, { - VER_NONE: 1, - VER_NODE_PUBLIC: 28, - VER_NODE_PRIVATE: 32, - VER_ACCOUNT_ID: 0, - VER_ACCOUNT_PUBLIC: 35, - VER_ACCOUNT_PRIVATE: 34, - VER_FAMILY_GENERATOR: 41, - VER_FAMILY_SEED: 33, - VER_ED25519_SEED: [0x01, 0xE1, 0x4B] -}); - -// --> input: big-endian array of bytes. -// <-- string at least as long as input. -Base.encode = function(input, alphabet) { - return encode(input, {alphabet}); -}; - -// --> input: String -// <-- array of bytes or undefined. -Base.decode = function(input, alphabet) { - if (typeof input !== 'string') { - return undefined; - } - try { - return decode(input, {alphabet}); - } catch (e) { - return undefined; - } -}; - -// --> input: Array -// <-- String -Base.encode_check = function(version, input, alphabet) { - return encode(input, {version, alphabet}); -}; - -// --> input : String -// <-- NaN || BN -Base.decode_check = function(version, input, alphabet) { - try { - const decoded = decode(input, {version, alphabet}); - return new BN(decoded); - } catch (e) { - return NaN; - } -}; - -exports.Base = Base; diff --git a/src/core/baseconverter.js b/src/core/baseconverter.js deleted file mode 100644 index 34650dbf..00000000 --- a/src/core/baseconverter.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - - -function normalize(digitArray) { - let i = 0; - while (digitArray[i] === 0) { - ++i; - } - if (i > 0) { - digitArray.splice(0, i); - } - return digitArray; -} - -function divmod(digitArray, base, divisor) { - let remainder = 0; - let temp; - let divided; - let j = -1; - - const length = digitArray.length; - const quotient = new Array(length); - - while (++j < length) { - temp = remainder * base + digitArray[j]; - divided = temp / divisor; - quotient[j] = divided << 0; - remainder = temp % divisor; - } - return {quotient: normalize(quotient), remainder: remainder}; -} - -function convertBase(digitArray, fromBase, toBase) { - const result = []; - let dividend = digitArray; - let qr; - while (dividend.length > 0) { - qr = divmod(dividend, fromBase, toBase); - result.unshift(qr.remainder); - dividend = qr.quotient; - } - return normalize(result); -} - -module.exports = convertBase; diff --git a/src/core/index.js b/src/core/index.js index a8d946f9..5495bfb7 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -5,28 +5,19 @@ exports.Amount = require('./amount').Amount; exports.Account = require('./account').Account; exports.Transaction = require('./transaction').Transaction; exports.Currency = require('./currency').Currency; -exports.Base = require('./base').Base; exports.Meta = require('./meta').Meta; -exports.SerializedObject = require('./serializedobject').SerializedObject; exports.RippleError = require('./rippleerror').RippleError; -exports.binformat = require('./binformat'); exports.utils = require('./utils'); exports.Server = require('./server').Server; exports.Ledger = require('./ledger').Ledger; -exports.TransactionQueue = require('./transactionqueue').TransactionQueue; -exports.convertBase = require('./baseconverter'); exports._test = { Log: require('./log'), PathFind: require('./pathfind').PathFind, TransactionManager: require('./transactionmanager').TransactionManager, + TransactionQueue: require('./transactionqueue').TransactionQueue, RangeSet: require('./rangeset').RangeSet, HashPrefixes: require('./hashprefixes'), - UInt128: require('./uint128').UInt128, - UInt160: require('./uint160').UInt160, - UInt256: require('./uint256').UInt256, OrderbookUtils: require('./orderbookutils'), constants: require('./constants') }; - -exports.types = require('./serializedtypes'); diff --git a/src/core/remote.js b/src/core/remote.js index 290c6cba..a5e16b1b 100644 --- a/src/core/remote.js +++ b/src/core/remote.js @@ -29,12 +29,11 @@ const Account = require('./account').Account; const Meta = require('./meta').Meta; const OrderBook = require('./orderbook').OrderBook; const PathFind = require('./pathfind').PathFind; -const SerializedObject = require('./serializedobject').SerializedObject; const RippleError = require('./rippleerror').RippleError; const utils = require('./utils'); -const hashprefixes = require('./hashprefixes'); const log = require('./log').internal.sub('remote'); const {isValidAddress} = require('ripple-address-codec'); +const binary = require('ripple-binary-codec'); export type GetLedgerSequenceCallback = (err?: ?Error, index?: number) => void; @@ -1412,27 +1411,26 @@ Remote.prototype.requestAccountTx = function(options, callback) { */ Remote.parseBinaryAccountTransaction = function(transaction) { - const tx_obj = new SerializedObject(transaction.tx_blob); - const tx_obj_json = tx_obj.to_json(); - const meta = new SerializedObject(transaction.meta).to_json(); + const tx_json = binary.decode(transaction.tx_blob); + const meta = binary.decode(transaction.meta); const tx_result = { validated: transaction.validated }; tx_result.meta = meta; - tx_result.tx = tx_obj_json; - tx_result.tx.hash = tx_obj.hash(hashprefixes.HASH_TX_ID).to_hex(); + tx_result.tx = tx_json; + tx_result.tx.hash = Transaction.from_json(tx_json).hash(); tx_result.tx.ledger_index = transaction.ledger_index; tx_result.tx.inLedger = transaction.ledger_index; if (typeof meta.DeliveredAmount === 'object') { tx_result.meta.delivered_amount = meta.DeliveredAmount; } else { - switch (typeof tx_obj_json.Amount) { + switch (typeof tx_json.Amount) { case 'string': case 'object': - tx_result.meta.delivered_amount = tx_obj_json.Amount; + tx_result.meta.delivered_amount = tx_json.Amount; break; } } @@ -1441,10 +1439,10 @@ Remote.parseBinaryAccountTransaction = function(transaction) { }; Remote.parseBinaryTransaction = function(transaction) { - const tx_obj = new SerializedObject(transaction.tx).to_json(); - const meta = new SerializedObject(transaction.meta).to_json(); + const tx_json = binary.decode(transaction.tx); + const meta = binary.decode(transaction.meta); - const tx_result = tx_obj; + const tx_result = tx_json; tx_result.date = transaction.date; tx_result.hash = transaction.hash; @@ -1459,10 +1457,10 @@ Remote.parseBinaryTransaction = function(transaction) { tx_result.meta.delivered_amount = meta.DeliveredAmount; break; default: - switch (typeof tx_obj.Amount) { + switch (typeof tx_json.Amount) { case 'string': case 'object': - tx_result.meta.delivered_amount = tx_obj.Amount; + tx_result.meta.delivered_amount = tx_json.Amount; break; } } @@ -1481,7 +1479,7 @@ Remote.parseBinaryTransaction = function(transaction) { */ Remote.parseBinaryLedgerData = function(ledgerData) { - const data = new SerializedObject(ledgerData.data).to_json(); + const data = binary.decode(ledgerData.data); data.index = ledgerData.index; return data; }; diff --git a/src/core/serializedobject.js b/src/core/serializedobject.js deleted file mode 100644 index fc06cf96..00000000 --- a/src/core/serializedobject.js +++ /dev/null @@ -1,369 +0,0 @@ -'use strict'; - -const assert = require('assert'); -const extend = require('extend'); -const BN = require('bn.js'); -const hashjs = require('hash.js'); -const sjclcodec = require('sjcl-codec'); -const binformat = require('./binformat'); -const stypes = require('./serializedtypes'); -const utils = require('./utils'); -const UInt256 = require('./uint256').UInt256; - -const TRANSACTION_TYPES = { }; - -Object.keys(binformat.tx).forEach(function(key) { - TRANSACTION_TYPES[binformat.tx[key][0]] = key; -}); - -const LEDGER_ENTRY_TYPES = {}; - -Object.keys(binformat.ledger).forEach(function(key) { - LEDGER_ENTRY_TYPES[binformat.ledger[key][0]] = key; -}); - -const TRANSACTION_RESULTS = {}; - -Object.keys(binformat.ter).forEach(function(key) { - TRANSACTION_RESULTS[binformat.ter[key]] = key; -}); - -function fieldType(fieldName) { - const fieldDef = binformat.fieldsInverseMap[fieldName]; - return binformat.types[fieldDef[0]]; -} - -function SerializedObject(buf) { - if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf))) { - this.buffer = buf; - } else if (typeof buf === 'string') { - this.buffer = sjclcodec.bytes.fromBits(sjclcodec.hex.toBits(buf)); - } else if (!buf) { - this.buffer = []; - } else { - throw new Error('Invalid buffer passed.'); - } - this.pointer = 0; -} - -SerializedObject.from_json = function(obj) { - const so = new SerializedObject(); - so.parse_json(obj); - return so; -}; - -SerializedObject.check_fields = function(typedef, obj) { - const missingFields = []; - const unknownFields = []; - const fieldsMap = {}; - - // Get missing required fields - typedef.forEach(function(field) { - const fieldName = field[0]; - const isRequired = field[1] === binformat.REQUIRED; - - if (isRequired && obj[fieldName] === undefined) { - missingFields.push(fieldName); - } else { - fieldsMap[fieldName] = true; - } - }); - - // Get fields that are not specified in format - Object.keys(obj).forEach(function(key) { - if (!fieldsMap[key] && /^[A-Z]/.test(key)) { - unknownFields.push(key); - } - }); - - if (!(missingFields.length || unknownFields.length)) { - // No missing or unknown fields - return; - } - - let errorMessage; - - if (obj.TransactionType !== undefined) { - errorMessage = SerializedObject.lookup_type_tx(obj.TransactionType); - } else if (obj.LedgerEntryType !== undefined) { - errorMessage = SerializedObject.lookup_type_le(obj.LedgerEntryType); - } else { - errorMessage = 'TransactionMetaData'; - } - - if (missingFields.length > 0) { - errorMessage += ' is missing fields: ' + JSON.stringify(missingFields); - } - if (unknownFields.length > 0) { - errorMessage += (missingFields.length ? ' and' : '') - + ' has unknown fields: ' + JSON.stringify(unknownFields); - } - - throw new Error(errorMessage); -}; - -SerializedObject.prototype.parse_json = function(obj_) { - // Create a copy of the object so we don't modify it - const obj = extend(true, {}, obj_); - let typedef; - - if (typeof obj.TransactionType === 'number') { - obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType); - if (!obj.TransactionType) { - throw new Error('Transaction type ID is invalid.'); - } - } - - if (typeof obj.LedgerEntryType === 'number') { - obj.LedgerEntryType = SerializedObject.lookup_type_le(obj.LedgerEntryType); - - if (!obj.LedgerEntryType) { - throw new Error('LedgerEntryType ID is invalid.'); - } - } - - if (typeof obj.TransactionType === 'string') { - typedef = binformat.tx[obj.TransactionType]; - if (!Array.isArray(typedef)) { - throw new Error('Transaction type is invalid'); - } - - typedef = typedef.slice(); - obj.TransactionType = typedef.shift(); - } else if (typeof obj.LedgerEntryType === 'string') { - typedef = binformat.ledger[obj.LedgerEntryType]; - - if (!Array.isArray(typedef)) { - throw new Error('LedgerEntryType is invalid'); - } - - typedef = typedef.slice(); - obj.LedgerEntryType = typedef.shift(); - - } else if (typeof obj.AffectedNodes === 'object') { - typedef = binformat.metadata; - } else { - throw new Error('Object to be serialized must contain either' + - ' TransactionType, LedgerEntryType or AffectedNodes.'); - } - - SerializedObject.check_fields(typedef, obj); - this.serialize(typedef, obj); -}; - -SerializedObject.prototype.append = function(bytes_) { - const bytes = bytes_ instanceof SerializedObject ? bytes_.buffer : bytes_; - - // Make sure both buffer and bytes are Array. Either could be a Buffer. - if (Array.isArray(this.buffer) && Array.isArray(bytes)) { - // `this.buffer = this.buffer.concat(bytes)` can be unbearably slow for - // large bytes length and acceptable bytes length is limited for - // `Array.prototype.push.apply(this.buffer, bytes)` as every element in the - // bytes array is pushed onto the stack, potentially causing a RangeError - // exception. Both of these solutions are known to be problematic for - // ledger 7501326. KISS instead - - for (let i = 0; i < bytes.length; i++) { - this.buffer.push(bytes[i]); - } - } else { - this.buffer = this.buffer.concat(bytes); - } - - this.pointer += bytes.length; -}; - -SerializedObject.prototype.resetPointer = function() { - this.pointer = 0; -}; - -function readOrPeek(advance) { - return function(bytes) { - const start = this.pointer; - const end = start + bytes; - - if (end > this.buffer.length) { - throw new Error('Buffer length exceeded'); - } - - const result = this.buffer.slice(start, end); - - if (advance) { - this.pointer = end; - } - - return result; - }; -} - -SerializedObject.prototype.read = readOrPeek(true); - -SerializedObject.prototype.peek = readOrPeek(false); - -SerializedObject.prototype.to_bits = function() { - return sjclcodec.bytes.toBits(this.buffer); -}; - -SerializedObject.prototype.to_hex = function() { - return sjclcodec.hex.fromBits(this.to_bits()).toUpperCase(); -}; - -SerializedObject.prototype.to_json = function() { - const old_pointer = this.pointer; - - this.resetPointer(); - - const output = { }; - - while (this.pointer < this.buffer.length) { - const key_and_value = stypes.parse(this); - const key = key_and_value[0]; - const value = key_and_value[1]; - output[key] = SerializedObject.jsonify_structure(value, key); - } - - this.pointer = old_pointer; - - return output; -}; - -SerializedObject.jsonify_structure = function(structure, fieldName) { - let output; - - switch (typeof structure) { - case 'number': - switch (fieldName) { - case 'LedgerEntryType': - output = LEDGER_ENTRY_TYPES[structure]; - break; - case 'TransactionResult': - output = TRANSACTION_RESULTS[structure]; - break; - case 'TransactionType': - output = TRANSACTION_TYPES[structure]; - break; - default: - output = structure; - } - break; - case 'object': - if (structure === null) { - break; - } - - if (typeof structure.to_json === 'function') { - output = structure.to_json(); - } else if (structure instanceof BN) { - // We assume that any BN is a UInt64 field - assert.equal(fieldType(fieldName), 'Int64'); - output = utils.arrayToHex(structure.toArray('bn', 8)); - } else { - // new Array or Object - output = new structure.constructor(); - - const keys = Object.keys(structure); - - for (let i = 0, l = keys.length; i < l; i++) { - const key = keys[i]; - output[key] = SerializedObject.jsonify_structure(structure[key], key); - } - } - break; - default: - output = structure; - } - - return output; -}; - -SerializedObject.prototype.serialize = function(typedef, obj) { - // Serialize object without end marker - stypes.Object.serialize(this, obj, true); - - // ST: Old serialization - /* - // Ensure canonical order - typedef = SerializedObject.sort_typedef(typedef); - - // Serialize fields - for (let i=0, l=typedef.length; i 0xF) { - buffer.push(type_id & 0xFF); - } else { - buffer[0] += (type_id & 0xF) << 4; - } - - if (field_id > 0xF) { - buffer.push(field_id & 0xFF); - } else { - buffer[0] += field_id & 0xF; - } - - return buffer; -}; - -SerializedObject.sort_typedef = function(typedef) { - assert(Array.isArray(typedef)); - - function sort_field_compare(a, b) { - // Sort by type id first, then by field id - return a[3] !== b[3] ? stypes[a[3]].id - stypes[b[3]].id : a[2] - b[2]; - } - - return typedef.sort(sort_field_compare); -}; - -SerializedObject.lookup_type_tx = function(id) { - assert.strictEqual(typeof id, 'number'); - return TRANSACTION_TYPES[id]; -}; - -SerializedObject.lookup_type_le = function(id) { - assert(typeof id === 'number'); - return LEDGER_ENTRY_TYPES[id]; -}; - -exports.SerializedObject = SerializedObject; diff --git a/src/core/serializedtypes.js b/src/core/serializedtypes.js deleted file mode 100644 index ce0298bd..00000000 --- a/src/core/serializedtypes.js +++ /dev/null @@ -1,935 +0,0 @@ -'use strict'; - -/** - * Type definitions for binary format. - * - * This file should not be included directly. Instead, find the format you're - * trying to parse or serialize in binformat.js and pass that to - * SerializedObject.parse() or SerializedObject.serialize(). - */ - -const _ = require('lodash'); -const assert = require('assert'); -const extend = require('extend'); -const BN = require('bn.js'); -const GlobalBigNumber = require('bignumber.js'); -const sjclcodec = require('sjcl-codec'); -const Amount = require('./amount').Amount; -const Currency = require('./currency').Currency; -const binformat = require('./binformat'); -const utils = require('./utils'); - -const UInt128 = require('./uint128').UInt128; -const UInt160 = require('./uint160').UInt160; -const UInt256 = require('./uint256').UInt256; -const Base = require('./base').Base; - -const BigNumber = GlobalBigNumber.another({ - ROUNDING_MODE: GlobalBigNumber.ROUND_HALF_UP, - DECIMAL_PLACES: 40 -}); - -function SerializedType(methods) { - extend(this, methods); -} - -function isNumber(val) { - return typeof val === 'number' && isFinite(val); -} - -function isString(val) { - return typeof val === 'string'; -} - -function isHexInt64String(val) { - return isString(val) && /^[0-9A-F]{0,16}$/i.test(val); -} - -function serializeBytes(so, byteData, noLength) { - if (!noLength) { - SerializedType.serialize_varint(so, byteData.length); - } - so.append(byteData); -} - -function serializeHex(so, hexData, noLength) { - serializeBytes(so, utils.hexToArray(hexData), noLength); -} - -function convertHexToString(hexString) { - const bits = sjclcodec.hex.toBits(hexString); - return sjclcodec.utf8String.fromBits(bits); -} - -function sort_fields(keys) { - function sort_field_compare(a, b) { - const a_field_coordinates = binformat.fieldsInverseMap[a]; - const a_type_bits = a_field_coordinates[0]; - const a_field_bits = a_field_coordinates[1]; - const b_field_coordinates = binformat.fieldsInverseMap[b]; - const b_type_bits = b_field_coordinates[0]; - const b_field_bits = b_field_coordinates[1]; - - // Sort by type id first, then by field id - return a_type_bits !== b_type_bits - ? a_type_bits - b_type_bits - : a_field_bits - b_field_bits; - } - - return keys.sort(sort_field_compare); -} - -SerializedType.serialize_varint = function(so, val) { - let value = val; - if (value < 0) { - throw new Error('Variable integers are unsigned.'); - } - - if (value <= 192) { - so.append([value]); - } else if (value <= 12480) { - value -= 193; - so.append([193 + (value >>> 8), value & 0xff]); - } else if (value <= 918744) { - value -= 12481; - so.append([241 + (value >>> 16), value >>> 8 & 0xff, value & 0xff]); - } else { - throw new Error('Variable integer overflow.'); - } -}; - -SerializedType.prototype.parse_varint = function(so) { - const b1 = so.read(1)[0]; - let b2; - let b3; - let result; - - if (b1 > 254) { - throw new Error('Invalid varint length indicator'); - } - - if (b1 <= 192) { - result = b1; - } else if (b1 <= 240) { - b2 = so.read(1)[0]; - result = 193 + (b1 - 193) * 256 + b2; - } else if (b1 <= 254) { - b2 = so.read(1)[0]; - b3 = so.read(1)[0]; - result = 12481 + (b1 - 241) * 65536 + b2 * 256 + b3; - } - - return result; -}; - -// 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'). - * - * @param {Number} val value - * @param {Number} bytes byte size - * @return {Array} byte array - */ -function convertIntegerToByteArray(val, bytes) { - if (!isNumber(val)) { - throw new Error('Value is not a number', bytes); - } - - if (val < 0 || val >= Math.pow(256, bytes)) { - throw new Error('Value out of bounds '); - } - - const newBytes = [ ]; - - for (let i = 0; i < bytes; i++) { - newBytes.unshift(val >>> (i * 8) & 0xff); - } - - return newBytes; -} - -// Convert a certain number of bytes from the serialized object ('so') into an -// integer. -function readAndSum(so, bytes) { - let sum = 0; - - if (bytes > 4) { - throw new Error('This function only supports up to four bytes.'); - } - - for (let i = 0; i < bytes; i++) { - const byte = so.read(1)[0]; - sum += (byte << (8 * (bytes - i - 1))); - } - - // Convert to unsigned integer - return sum >>> 0; -} - -const STInt8 = exports.Int8 = new SerializedType({ - serialize: function(so, val) { - so.append(convertIntegerToByteArray(val, 1)); - }, - parse: function(so) { - return readAndSum(so, 1); - } -}); - -STInt8.id = 16; - -function serialize(so, field_name, value) { - // so: a byte-stream to serialize into. - // field_name: a string for the field name ('LedgerEntryType' etc.) - // value: the value of that field. - const field_coordinates = binformat.fieldsInverseMap[field_name]; - const type_bits = field_coordinates[0]; - const field_bits = field_coordinates[1]; - const tag_byte = (type_bits < 16 - ? type_bits << 4 - : 0) | (field_bits < 16 - ? field_bits - : 0); - let val = value; - - if (field_name === 'LedgerEntryType' && typeof val === 'string') { - val = binformat.ledger[val][0]; - } - - if (field_name === 'TransactionResult' && typeof val === 'string') { - val = binformat.ter[val]; - } - - STInt8.serialize(so, tag_byte); - - if (type_bits >= 16) { - STInt8.serialize(so, type_bits); - } - - if (field_bits >= 16) { - STInt8.serialize(so, field_bits); - } - - // Get the serializer class (ST...) - let serialized_object_type; - - if (field_name === 'Memo' && typeof val === 'object') { - // for Memo we override the default behavior with our STMemo serializer - serialized_object_type = exports.STMemo; - } else { - // for a field based on the type bits. - serialized_object_type = exports[binformat.types[type_bits]]; - } - - try { - serialized_object_type.serialize(so, val); - } catch (e) { - e.message += ' (' + field_name + ')'; - throw e; - } -} - -exports.serialize = exports.serialize_whatever = serialize; - -// Take the serialized object, figure out what type/field it is, and return the -// parsing of that. - -function parse(so) { - const tag_byte = so.read(1)[0]; - let type_bits = tag_byte >> 4; - - if (type_bits === 0) { - type_bits = so.read(1)[0]; - } - - const field_bits = tag_byte & 0x0f; - const field_name = (field_bits === 0) - ? binformat.fields[type_bits][so.read(1)[0]] - : binformat.fields[type_bits][field_bits]; - - assert(field_name, 'Unknown field - header byte is 0x' - + tag_byte.toString(16)); - - // Get the parser class (ST...) for a field based on the type bits. - const type = (field_name === 'Memo') - ? exports.STMemo - : exports[binformat.types[type_bits]]; - - assert(type, 'Unknown type - header byte is 0x' + tag_byte.toString(16)); - - return [field_name, type.parse(so)]; // key, value -} - -exports.parse = exports.parse_whatever = parse; - -const STInt16 = exports.Int16 = new SerializedType({ - serialize: function(so, val) { - so.append(convertIntegerToByteArray(val, 2)); - }, - parse: function(so) { - return readAndSum(so, 2); - } -}); - -STInt16.id = 1; - -const STInt32 = exports.Int32 = new SerializedType({ - serialize: function(so, val) { - so.append(convertIntegerToByteArray(val, 4)); - }, - parse: function(so) { - return readAndSum(so, 4); - } -}); - -STInt32.id = 2; - -const STInt64 = exports.Int64 = new SerializedType({ - serialize: function(so, val) { - let bigNumObject; - let value = val; - - if (isNumber(value)) { - value = Math.floor(value); - if (value < 0) { - throw new Error('Negative value for unsigned Int64 is invalid.'); - } - bigNumObject = new BN(value, 10); - } else if (isString(value)) { - if (!isHexInt64String(value)) { - throw new Error('Not a valid hex Int64.'); - } - bigNumObject = new BN(value, 16); - } else if (value instanceof BN) { - if (value.cmpn(0) < 0) { - throw new Error('Negative value for unsigned Int64 is invalid.'); - } - bigNumObject = value; - } else { - throw new Error('Invalid type for Int64: ' + (typeof value) + ' value'); - } - // `'be'` means big endian, and the following arg is the byte length, which - // it will pad with 0s to if not enough bytes, or throw if over - serializeBytes(so, bigNumObject.toArray('be', 8), /* noLength= */true); - }, - parse: function(so) { - const bytes = so.read(8); - return new BN(bytes); - } -}); - -STInt64.id = 3; - -const STHash128 = exports.Hash128 = new SerializedType({ - serialize: function(so, val) { - const hash = UInt128.from_json(val); - if (!hash.is_valid()) { - throw new Error('Invalid Hash128'); - } - serializeBytes(so, hash.to_bytes(), true); // noLength = true - }, - parse: function(so) { - return UInt128.from_bytes(so.read(16)); - } -}); - -STHash128.id = 4; - -const STHash256 = exports.Hash256 = new SerializedType({ - serialize: function(so, val) { - const hash = UInt256.from_json(val); - if (!hash.is_valid()) { - throw new Error('Invalid Hash256'); - } - serializeBytes(so, hash.to_bytes(), true); // noLength = true - }, - parse: function(so) { - return UInt256.from_bytes(so.read(32)); - } -}); - -STHash256.id = 5; - -const STHash160 = exports.Hash160 = new SerializedType({ - serialize: function(so, val) { - const hash = UInt160.from_json(val); - if (!hash.is_valid()) { - throw new Error('Invalid Hash160'); - } - serializeBytes(so, hash.to_bytes(), true); // noLength = true - }, - parse: function(so) { - return UInt160.from_bytes(so.read(20)); - } -}); - -STHash160.id = 17; - -// Internal -const STCurrency = new SerializedType({ - serialize: function(so, val) { - const currencyData = val.to_bytes(); - - if (!currencyData) { - throw new Error( - 'Tried to serialize invalid/unimplemented currency type.'); - } - - so.append(currencyData); - }, - parse: function(so) { - const bytes = so.read(20); - const currency = Currency.from_bytes(bytes); - // XXX Disabled check. Theoretically, the Currency class should support any - // UInt160 value and consider it valid. But it doesn't, so for the - // deserialization to be usable, we need to allow invalid results for - // now. - // if (!currency.is_valid()) { - // throw new Error('Invalid currency: '+convertByteArrayToHex(bytes)); - // } - return currency; - } -}); - -/** - * Quality is encoded into 64 bits: - * (8 bits offset) (56 bits mantissa) - * - * Quality differs from Amount because it does not need the first two bits - * to represent non-native and non-negative - */ -exports.Quality = new SerializedType({ - serialize: function(so, val) { - let value; - // if in format: amount/currency/issuer - if (_.includes(val, '/')) { - const amount = Amount.from_json(val); - - if (!amount.is_valid()) { - throw new Error('Not a valid Amount object.'); - } - value = new BigNumber(amount.to_text()); - } else { - value = new BigNumber(val); - } - - let hi = 0; - let lo = 0; - - const offset = value.e - 15; - if (val !== 0) { - // First eight bits: offset/exponent - hi |= ((100 + offset) & 0xff) << 24; - - // Remaining 56 bits: mantissa - const mantissaDecimal = utils.getMantissaDecimalString(value.abs()); - const mantissaHex = (new BigNumber(mantissaDecimal)).toString(16); - assert(mantissaHex.length <= 16, - 'Mantissa hex representation ' + mantissaHex + - ' exceeds the maximum length of 16'); - hi |= parseInt(mantissaHex.slice(0, -8), 16) & 0xffffff; - lo = parseInt(mantissaHex.slice(-8), 16); - } - - const valueBytes = sjclcodec.bytes.fromBits([hi, lo]); - - so.append(valueBytes); - } -}); - -/* - * Amount is encoded into 64 bits: - * (1 bit non-native) (1 bit non-negative) (8 bits offset) (54 bits mantissa) - */ -const STAmount = exports.Amount = new SerializedType({ - serialize: function(so, val) { - const amount = Amount.from_json(val); - - if (!amount.is_valid()) { - throw new Error('Not a valid Amount object.'); - } - - const value = new BigNumber(amount.to_text()); - const offset = value.e - 15; - - // Amount (64-bit integer) - let valueBytes = utils.arraySet(8, 0); - - if (amount.is_native()) { - let valueHex = value.abs().toString(16); - - if (Amount.strict_mode && value.abs().greaterThan(Amount.bi_xns_max)) { - throw new Error('Value out of bounds'); - } - - // Enforce correct length (64 bits) - if (Amount.strict_mode && valueHex.length > 16) { - throw new Error('Value out of bounds'); - } - - while (valueHex.length < 16) { - valueHex = '0' + valueHex; - } - - valueBytes = sjclcodec.bytes.fromBits(sjclcodec.hex.toBits(valueHex)); - // Clear most significant two bits - these bits should already be 0 if - // Amount enforces the range correctly, but we'll clear them anyway just - // so this code can make certain guarantees about the encoded value. - valueBytes[0] &= 0x3f; - - if (!amount.is_negative()) { - valueBytes[0] |= 0x40; - } - } else { - let hi = 0; - let lo = 0; - - // First bit: non-native - hi |= 1 << 31; - - if (!amount.is_zero()) { - // Second bit: non-negative? - if (!amount.is_negative()) { - hi |= 1 << 30; - } - - // Next eight bits: offset/exponent - hi |= ((97 + offset) & 0xff) << 22; - - // Remaining 54 bits: mantissa - const mantissaDecimal = utils.getMantissaDecimalString(value.abs()); - const mantissaHex = (new BigNumber(mantissaDecimal)).toString(16); - assert(mantissaHex.length <= 16, - 'Mantissa hex representation ' + mantissaHex + - ' exceeds the maximum length of 16'); - hi |= parseInt(mantissaHex.slice(0, -8), 16) & 0x3fffff; - lo = parseInt(mantissaHex.slice(-8), 16); - } - - valueBytes = sjclcodec.bytes.fromBits([hi, lo]); - } - - so.append(valueBytes); - - if (!amount.is_native()) { - // Currency (160-bit hash) - const currency = amount.currency(); - STCurrency.serialize(so, currency, true); - - // Issuer (160-bit hash) - so.append(UInt160.from_json(amount.issuer()).to_bytes()); - } - }, - parse: function(so) { - const value_bytes = so.read(8); - let is_zero = !(value_bytes[0] & 0x7f); - - for (let i = 1; i < 8; i++) { - is_zero = is_zero && !value_bytes[i]; - } - - const is_negative = !is_zero && !(value_bytes[0] & 0x40); - - if (value_bytes[0] & 0x80) { - // non-native - const currency = STCurrency.parse(so); - const issuer_bytes = so.read(20); - const issuer = UInt160.from_bytes(issuer_bytes); - issuer.set_version(Base.VER_ACCOUNT_ID); - const offset = - ((value_bytes[0] & 0x3f) << 2) + (value_bytes[1] >>> 6) - 97; - const mantissa_bytes = value_bytes.slice(1); - mantissa_bytes[0] &= 0x3f; - const mantissa = new BigNumber(utils.arrayToHex(mantissa_bytes), 16); - const sign = is_negative ? '-' : ''; - const valueString = sign + mantissa.toString() + 'e' + offset.toString(); - - return Amount.from_json({ - currency: currency, - issuer: issuer.to_json(), - value: valueString - }); - } - - // native - const integer_bytes = value_bytes.slice(); - integer_bytes[0] &= 0x3f; - const integer_hex = utils.arrayToHex(integer_bytes); - const value = new BigNumber(integer_hex, 16); - return Amount.from_json((is_negative ? '-' : '') + value.toString()); - } -}); - -STAmount.id = 6; - -const STVL = exports.VariableLength = exports.VL = new SerializedType({ - serialize: function(so, val) { - if (typeof val === 'string') { - serializeHex(so, val); - } else { - throw new Error('Unknown datatype.'); - } - }, - parse: function(so) { - const len = this.parse_varint(so); - return utils.arrayToHex(so.read(len)); - } -}); - -STVL.id = 7; - -const STAccount = exports.Account = new SerializedType({ - serialize: function(so, val) { - const account = UInt160.from_json(val); - if (!account.is_valid()) { - throw new Error('Invalid account!'); - } - serializeBytes(so, account.to_bytes()); - }, - parse: function(so) { - const len = this.parse_varint(so); - - if (len !== 20) { - throw new Error('Non-standard-length account ID'); - } - - const result = UInt160.from_bytes(so.read(len)); - result.set_version(Base.VER_ACCOUNT_ID); - - if (false && !result.is_valid()) { - throw new Error('Invalid Account'); - } - - return result; - } -}); - -STAccount.id = 8; - -const STPathSet = exports.PathSet = new SerializedType({ - typeBoundary: 0xff, - typeEnd: 0x00, - typeAccount: 0x01, - typeCurrency: 0x10, - typeIssuer: 0x20, - serialize: function(so, val) { - for (let i = 0, l = val.length; i < l; i++) { - // Boundary - if (i) { - STInt8.serialize(so, this.typeBoundary); - } - - for (let j = 0, l2 = val[i].length; j < l2; j++) { - const entry = val[i][j]; - // if (entry.hasOwnProperty('_value')) {entry = entry._value;} - let type = 0; - - if (entry.account) { - type |= this.typeAccount; - } - if (entry.currency) { - type |= this.typeCurrency; - } - if (entry.issuer) { - type |= this.typeIssuer; - } - - STInt8.serialize(so, type); - - if (entry.account) { - STHash160.serialize(so, entry.account); - } - - if (entry.currency) { - const currency = Currency.from_json(entry.currency, entry.non_native); - STCurrency.serialize(so, currency); - } - - if (entry.issuer) { - STHash160.serialize(so, entry.issuer); - } - } - } - - STInt8.serialize(so, this.typeEnd); - }, - parse: function(so) { - // should return a list of lists: - /* - [ - [entry, entry], - [entry, entry, entry], - [entry], - [] - ] - - each entry has one or more of the following attributes: - amount, currency, issuer. - */ - - const path_list = []; - let current_path = []; - let tag_byte; - - /* eslint-disable no-cond-assign */ - - while ((tag_byte = so.read(1)[0]) !== this.typeEnd) { - // TODO: try/catch this loop, and catch when we run out of data without - // reaching the end of the data structure. - // Now determine: is this an end, boundary, or entry-begin-tag? - // console.log('Tag byte:', tag_byte); - if (tag_byte === this.typeBoundary) { - if (current_path) { // close the current path, if there is one, - path_list.push(current_path); - } - current_path = [ ]; // and start a new one. - continue; - } - - // It's an entry-begin tag. - const entry = {}; - let type = 0; - - if (tag_byte & this.typeAccount) { - entry.account = STHash160.parse(so); - entry.account.set_version(Base.VER_ACCOUNT_ID); - type = type | this.typeAccount; - } - if (tag_byte & this.typeCurrency) { - entry.currency = STCurrency.parse(so); - if (entry.currency.to_json() === 'XRP' && !entry.currency.is_native()) { - entry.non_native = true; - } - type = type | this.typeCurrency; - } - if (tag_byte & this.typeIssuer) { - entry.issuer = STHash160.parse(so); - // Enable and set correct type of base-58 encoding - entry.issuer.set_version(Base.VER_ACCOUNT_ID); - type = type | this.typeIssuer; - } - - if (entry.account || entry.currency || entry.issuer) { - entry.type = type; - entry.type_hex = ('000000000000000' + type.toString(16)).slice(-16); - current_path.push(entry); - } else { - // It must have at least something in it. - throw new Error('Invalid path entry'); - } - } - - if (current_path) { - // close the current path, if there is one, - path_list.push(current_path); - } - - return path_list; - } -}); - -STPathSet.id = 18; - -const STVector256 = exports.Vector256 = new SerializedType({ - serialize: function(so, val) { - // Assume val is an array of STHash256 objects. - SerializedType.serialize_varint(so, val.length * 32); - for (let i = 0, l = val.length; i < l; i++) { - STHash256.serialize(so, val[i]); - } - }, - parse: function(so) { - const length = this.parse_varint(so); - const output = []; - // length is number of bytes not number of Hash256 - for (let i = 0; i < length / 32; i++) { - output.push(STHash256.parse(so)); - } - return output; - } -}); - -STVector256.id = 19; - -// Internal -exports.STMemo = new SerializedType({ - serialize: function(so, val, no_marker) { - let keys = []; - - Object.keys(val).forEach(function(key) { - // Ignore lowercase field names - they're non-serializable fields by - // convention. - if (key[0] === key[0].toLowerCase()) { - return; - } - - if (typeof binformat.fieldsInverseMap[key] === 'undefined') { - throw new Error('JSON contains unknown field: "' + key + '"'); - } - - keys.push(key); - }); - - // Sort fields - keys = sort_fields(keys); - - keys.forEach(function(key) { - serialize(so, key, val[key]); - }); - - if (!no_marker) { - // Object ending marker - STInt8.serialize(so, 0xe1); - } - }, - parse: function(so) { - const output = {}; - - while (so.peek(1)[0] !== 0xe1) { - const keyval = parse(so); - output[keyval[0]] = keyval[1]; - } - - if (output.MemoType !== undefined) { - try { - const parsedType = convertHexToString(output.MemoType); - - if (parsedType !== 'unformatted_memo') { - output.parsed_memo_type = parsedType; - } - /* eslint-disable no-empty */ - } catch (e) { - // empty - // we don't know what's in the binary, apparently it's not a UTF-8 - // string - // this is fine, we won't add the parsed_memo_type field - } - /* eslint-enable no-empty */ - } - - if (output.MemoFormat !== undefined) { - try { - output.parsed_memo_format = convertHexToString(output.MemoFormat); - /* eslint-disable no-empty */ - } catch (e) { - // empty - // we don't know what's in the binary, apparently it's not a UTF-8 - // string - // this is fine, we won't add the parsed_memo_format field - } - /* eslint-enable no-empty */ - } - - if (output.MemoData !== undefined) { - - try { - if (output.parsed_memo_format === 'json') { - // see if we can parse JSON - output.parsed_memo_data = - JSON.parse(convertHexToString(output.MemoData)); - - } else if (output.parsed_memo_format === 'text') { - // otherwise see if we can parse text - output.parsed_memo_data = convertHexToString(output.MemoData); - } - /* eslint-disable no-empty */ - } catch (e) { - // empty - // we'll fail in case the content does not match what the MemoFormat - // described - // this is fine, we won't add the parsed_memo_data, the user has to - // parse themselves - } - /* eslint-enable no-empty */ - } - - so.read(1); - return output; - } - -}); - -const STObject = exports.Object = new SerializedType({ - serialize: function(so, val, no_marker) { - let keys = []; - - Object.keys(val).forEach(function(key) { - // Ignore lowercase field names - they're non-serializable fields by - // convention. - if (key[0] === key[0].toLowerCase()) { - return; - } - - if (typeof binformat.fieldsInverseMap[key] === 'undefined') { - throw new Error('JSON contains unknown field: "' + key + '"'); - } - - keys.push(key); - }); - - // Sort fields - keys = sort_fields(keys); - - for (let i = 0; i < keys.length; i++) { - serialize(so, keys[i], val[keys[i]]); - } - - if (!no_marker) { - // Object ending marker - STInt8.serialize(so, 0xe1); - } - }, - - parse: function(so) { - const output = {}; - while (so.peek(1)[0] !== 0xe1) { - const keyval = parse(so); - output[keyval[0]] = keyval[1]; - } - so.read(1); - return output; - } -}); - -STObject.id = 14; - -const STArray = exports.Array = new SerializedType({ - serialize: function(so, val) { - for (let i = 0, l = val.length; i < l; i++) { - const keys = Object.keys(val[i]); - - if (keys.length !== 1) { - throw new Error( - 'Cannot serialize an array containing non-single-key objects'); - } - - const field_name = keys[0]; - const value = val[i][field_name]; - serialize(so, field_name, value); - } - - // Array ending marker - STInt8.serialize(so, 0xf1); - }, - - parse: function(so) { - const output = [ ]; - - while (so.peek(1)[0] !== 0xf1) { - const keyval = parse(so); - const obj = { }; - obj[keyval[0]] = keyval[1]; - output.push(obj); - } - - so.read(1); - - return output; - } -}); - -STArray.id = 15; diff --git a/src/core/uint.js b/src/core/uint.js deleted file mode 100644 index e15e197f..00000000 --- a/src/core/uint.js +++ /dev/null @@ -1,269 +0,0 @@ -'use strict'; - -/* eslint new-cap: 1 */ - -const assert = require('assert'); -const lodash = require('lodash'); -const sjclcodec = require('sjcl-codec'); -const utils = require('./utils'); -const BN = require('bn.js'); - -// -// Abstract UInt class -// -// Base class for UInt classes -// - -function UInt() { - // Internal form: NaN or BN - this._value = NaN; -} - -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) { - if (j instanceof this) { - return j.clone(); - } - - return (new this()).parse_generic(j); -}; - -// Return a new UInt from j. -UInt.from_hex = function(j) { - if (j instanceof this) { - return j.clone(); - } - - return (new this()).parse_hex(j); -}; - -// Return a new UInt from j. -UInt.from_json = function(j) { - if (j instanceof this) { - return j.clone(); - } - - return (new this()).parse_json(j); -}; - -// Return a new UInt from j. -UInt.from_bits = function(j) { - if (j instanceof this) { - return j.clone(); - } - - return (new this()).parse_bits(j); -}; - -// Return a new UInt from j. -UInt.from_bytes = function(j) { - if (j instanceof this) { - return j.clone(); - } - - return (new this()).parse_bytes(j); -}; - -// Return a new UInt from j. -UInt.from_number = function(j) { - if (j instanceof this) { - return j.clone(); - } - - return (new this()).parse_number(j); -}; - -UInt.is_valid = function(j) { - return this.from_json(j).is_valid(); -}; - -UInt.prototype.clone = function() { - return this.copyTo(new this.constructor()); -}; - -// Returns copy. -UInt.prototype.copyTo = function(d) { - d._value = this._value; - - if (this._version_byte !== undefined) { - d._version_byte = this._version_byte; - } - - if (typeof d._update === 'function') { - d._update(); - } - - return d; -}; - -UInt.prototype.equals = function(o) { - return this.is_valid() && - o.is_valid() && - // This throws but the expression will short circuit - this.cmp(o) === 0; -}; - -UInt.prototype.cmp = function(o) { - assert(this.is_valid() && o.is_valid()); - return this._value.cmp(o._value); -}; - -UInt.prototype.greater_than = function(o) { - return this.cmp(o) > 0; -}; - -UInt.prototype.less_than = function(o) { - return this.cmp(o) < 0; -}; - -UInt.prototype.is_valid = function() { - return this._value instanceof BN; -}; - -UInt.prototype.is_zero = function() { - // cmpn means cmp with N)umber - return this.is_valid() && this._value.cmpn(0) === 0; -}; - -/** - * Update any derivative values. - * - * This allows subclasses to maintain caches of any data that they derive from - * the main _value. For example, the Currency class keeps the currency type, the - * currency code and other information about the currency cached. - * - * The reason for keeping this mechanism in this class is so every subclass can - * call it whenever it modifies the internal state. - * - * @return {void} - */ -UInt.prototype._update = function() { - // Nothing to do by default. Subclasses will override this. -}; - -// value = NaN on error. -UInt.prototype.parse_generic = function(j) { - const subclass = this.constructor; - - assert(typeof subclass.width === 'number', 'UInt missing width'); - - this._value = NaN; - - switch (j) { - case undefined: - case '0': - case subclass.STR_ZERO: - case subclass.ACCOUNT_ZERO: - case subclass.HEX_ZERO: - this._value = new BN(0); - break; - - case '1': - case subclass.STR_ONE: - case subclass.ACCOUNT_ONE: - case subclass.HEX_ONE: - this._value = new BN(1); - break; - - default: - if (lodash.isString(j)) { - switch (j.length) { - case subclass.width: - const hex = utils.arrayToHex(utils.stringToArray(j)); - this._value = new BN(hex, 16); - break; - case subclass.width * 2: - // Assume hex, check char set - this.parse_hex(j); - break; - } - } else if (lodash.isNumber(j)) { - this.parse_number(j); - } else if (lodash.isArray(j)) { - // Assume bytes array - this.parse_bytes(j); - } - } - - this._update(); - - return this; -}; - -UInt.prototype.parse_hex = function(j) { - if (new RegExp(`^[0-9A-Fa-f]{${this.constructor.width * 2}}$`).test(j)) { - this._value = new BN(j, 16); - } else { - this._value = NaN; - } - - this._update(); - - return this; -}; - -UInt.prototype.parse_bits = function(j) { - return this.parse_bytes(sjclcodec.bytes.fromBits(j)); -}; - -UInt.prototype.parse_bytes = function(j) { - if (Array.isArray(j) && j.length === this.constructor.width) { - this._value = new BN(j); - } else { - this._value = NaN; - } - - this._update(); - - return this; -}; - -UInt.prototype.parse_json = UInt.prototype.parse_hex; - -UInt.prototype.parse_number = function(j) { - this._value = NaN; - - if (typeof j === 'number' && isFinite(j) && j >= 0) { - this._value = new BN(j); - } - - this._update(); - - return this; -}; - -// Convert from internal form. -UInt.prototype.to_bytes = function() { - if (!this.is_valid()) { - return null; - } - - return this._value.toArray('be', this.constructor.width); -}; - -UInt.prototype.to_hex = function() { - if (!this.is_valid()) { - return null; - } - - return utils.arrayToHex(this.to_bytes()); -}; - -UInt.prototype.to_json = UInt.prototype.to_hex; - -// Convert from internal form. -UInt.prototype.to_bits = function() { - if (!this.is_valid()) { - return null; - } - - return sjclcodec.bytes.toBits(this.to_bytes()); -}; - -exports.UInt = UInt; - -// vim:sw=2:sts=2:ts=8:et diff --git a/src/core/uint128.js b/src/core/uint128.js deleted file mode 100644 index cfcd088e..00000000 --- a/src/core/uint128.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -const utils = require('./utils'); -const extend = require('extend'); -const UInt = require('./uint').UInt; - -// -// UInt128 support -// - -const UInt128 = extend(function() { - this._value = NaN; -}, UInt); - -UInt128.width = 16; -UInt128.prototype = Object.create(extend({}, UInt.prototype)); -UInt128.prototype.constructor = UInt128; - -const HEX_ZERO = UInt128.HEX_ZERO = '00000000000000000000000000000000'; -const HEX_ONE = UInt128.HEX_ONE = '00000000000000000000000000000000'; - -UInt128.STR_ZERO = utils.hexToString(HEX_ZERO); -UInt128.STR_ONE = utils.hexToString(HEX_ONE); - -exports.UInt128 = UInt128; diff --git a/src/core/uint160.js b/src/core/uint160.js deleted file mode 100644 index 878cb7de..00000000 --- a/src/core/uint160.js +++ /dev/null @@ -1,97 +0,0 @@ -'use strict'; - -const utils = require('./utils'); -const extend = require('extend'); - -const UInt = require('./uint').UInt; -const Base = require('./base').Base; - -// -// UInt160 support -// - -const UInt160 = extend(function() { - this._value = NaN; - this._version_byte = undefined; - this._update(); -}, UInt); - -UInt160.width = 20; -UInt160.prototype = Object.create(extend({}, UInt.prototype)); -UInt160.prototype.constructor = UInt160; - -const HEX_ZERO = UInt160.HEX_ZERO = '0000000000000000000000000000000000000000'; -const HEX_ONE = UInt160.HEX_ONE = '0000000000000000000000000000000000000001'; - -UInt160.ACCOUNT_ZERO = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp'; -UInt160.ACCOUNT_ONE = 'rrrrrrrrrrrrrrrrrrrrBZbvji'; -UInt160.STR_ZERO = utils.hexToString(HEX_ZERO); -UInt160.STR_ONE = utils.hexToString(HEX_ONE); - -UInt160.prototype.set_version = function(j) { - this._version_byte = j; - return this; -}; - -UInt160.prototype.get_version = function() { - return this._version_byte; -}; - -// value = NaN on error. -UInt160.prototype.parse_json = function(j) { - if (typeof j === 'number' && !isNaN(j)) { - // Allow raw numbers - DEPRECATED - // This is used mostly by the test suite and is supported - // as a legacy feature only. DO NOT RELY ON THIS BEHAVIOR. - this.parse_number(j); - this._version_byte = Base.VER_ACCOUNT_ID; - } else if (typeof j !== 'string') { - this._value = NaN; - } else if (j[0] === 'r') { - this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j); - this._version_byte = Base.VER_ACCOUNT_ID; - } else { - this.parse_hex(j); - } - - this._update(); - - return this; -}; - -UInt160.prototype.parse_generic = function(j) { - UInt.prototype.parse_generic.call(this, j); - - if (isNaN(this._value)) { - if ((typeof j === 'string') && j[0] === 'r') { - this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j); - } - } - - this._update(); - - return this; -}; - -// XXX Json form should allow 0 and 1, C++ doesn't currently allow it. -UInt160.prototype.to_json = function(opts = {}) { - - if (this.is_valid()) { - // If this value has a type, return a Base58 encoded string. - if (typeof this._version_byte === 'number') { - let output = Base.encode_check(this._version_byte, this.to_bytes()); - - if (opts.gateways && output in opts.gateways) { - output = opts.gateways[output]; - } - - return output; - } - return this.to_hex(); - } - return NaN; -}; - -exports.UInt160 = UInt160; - -// vim:sw=2:sts=2:ts=8:et diff --git a/src/core/uint256.js b/src/core/uint256.js deleted file mode 100644 index 9127466a..00000000 --- a/src/core/uint256.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -const utils = require('./utils'); -const extend = require('extend'); -const UInt = require('./uint').UInt; - -// -// UInt256 support -// - -const UInt256 = extend(function() { - this._value = NaN; -}, UInt); - -UInt256.width = 32; -UInt256.prototype = Object.create(extend({}, UInt.prototype)); -UInt256.prototype.constructor = UInt256; - -const HEX_ZERO = UInt256.HEX_ZERO = '00000000000000000000000000000000' + - '00000000000000000000000000000000'; - -const HEX_ONE = UInt256.HEX_ONE = '00000000000000000000000000000000' + - '00000000000000000000000000000001'; - -UInt256.STR_ZERO = utils.hexToString(HEX_ZERO); -UInt256.STR_ONE = utils.hexToString(HEX_ONE); - -exports.UInt256 = UInt256; diff --git a/test/base-test.js b/test/base-test.js deleted file mode 100644 index 43efb264..00000000 --- a/test/base-test.js +++ /dev/null @@ -1,66 +0,0 @@ -'use strict'; -const assert = require('assert'); -const Base = require('ripple-lib').Base; -const fixtures = require('./fixtures/base58.json'); - -function digitArray(str) { - return str.split('').map(function(d) { - return parseInt(d, 10); - }); -} - -function hexToByteArray(hex) { - const byteArray = []; - for (let i = 0; i < hex.length / 2; i++) { - byteArray.push(parseInt(hex.slice(2 * i, 2 * i + 2), 16)); - } - return byteArray; -} - -describe('Base', function() { - describe('encode_check', function() { - it('0', function() { - const encoded = Base.encode_check(0, digitArray('00000000000000000000')); - assert.strictEqual(encoded, 'rrrrrrrrrrrrrrrrrrrrrhoLvTp'); - }); - it('1', function() { - const encoded = Base.encode_check(0, digitArray('00000000000000000001')); - assert.strictEqual(encoded, 'rrrrrrrrrrrrrrrrrrrrBZbvji'); - }); - }); - describe('decode_check', function() { - it('rrrrrrrrrrrrrrrrrrrrrhoLvTp', function() { - const decoded = Base.decode_check(0, 'rrrrrrrrrrrrrrrrrrrrrhoLvTp'); - assert(decoded.cmpn(0) === 0); - }); - it('rrrrrrrrrrrrrrrrrrrrBZbvji', function() { - const decoded = Base.decode_check(0, 'rrrrrrrrrrrrrrrrrrrrBZbvji'); - assert(decoded.cmpn(1) === 0); - }); - }); - describe('decode-encode identity', function() { - it('rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const decoded = Base.decode('rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - const encoded = Base.encode(decoded); - assert.strictEqual(encoded, 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - }); - }); - describe('encode', function() { - it('fixtures', function() { - for (let i = 0; i < fixtures.ripple.length; i++) { - const testCase = fixtures.ripple[i]; - const encoded = Base.encode(hexToByteArray(testCase.hex)); - assert.strictEqual(encoded, testCase.string); - } - }); - }); - describe('decode', function() { - it('fixtures', function() { - for (let i = 0; i < fixtures.ripple.length; i++) { - const testCase = fixtures.ripple[i]; - const decoded = Base.decode(testCase.string); - assert.deepEqual(decoded, hexToByteArray(testCase.hex)); - } - }); - }); -}); diff --git a/test/baseconverter-test.js b/test/baseconverter-test.js deleted file mode 100644 index d34cab80..00000000 --- a/test/baseconverter-test.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; -var assert = require('assert'); -var convertBase = require('ripple-lib').convertBase; - -// Test cases from RFC-1924 (a joke RFC) -var BASE85 = ('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' - + 'abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~'); -var BASE10 = BASE85.slice(0, 10); -var BASE16 = BASE85.slice(0, 16); - -var DATA16 = '108000000000000000080800200C417A'; -var DATA10 = '21932261930451111902915077091070067066'; -var DATA85 = '4)+k&C#VzJ4br>0wv%Yp'; - -function encode(digitArray, encoding) { - return digitArray.map(function(i) { - return encoding.charAt(i); - }).join(''); -} - -function decode(encoded, encoding) { - return encoded.split('').map(function(c) { - return encoding.indexOf(c); - }); -} - -function convertBaseEncoded(value, fromEncoding, toEncoding) { - var digitArray = decode(value, fromEncoding); - var converted = convertBase(digitArray, fromEncoding.length, - toEncoding.length); - return encode(converted, toEncoding); -} - -describe('convertBase', function() { - it('DEC -> HEX', function () { - assert.strictEqual(convertBaseEncoded(DATA10, BASE10, BASE16), DATA16); - }); - it('HEX -> DEC', function () { - assert.strictEqual(convertBaseEncoded(DATA16, BASE16, BASE10), DATA10); - }); - it('DEC -> B85', function () { - assert.strictEqual(convertBaseEncoded(DATA10, BASE10, BASE85), DATA85); - }); - it('HEX -> B85', function () { - assert.strictEqual(convertBaseEncoded(DATA16, BASE16, BASE85), DATA85); - }); - it('B85 -> DEC', function () { - assert.strictEqual(convertBaseEncoded(DATA85, BASE85, BASE10), DATA10); - }); - it('B85 -> HEX', function () { - assert.strictEqual(convertBaseEncoded(DATA85, BASE85, BASE16), DATA16); - }); -}); diff --git a/test/fixtures/api/responses/get-transactions.json b/test/fixtures/api/responses/get-transactions.json index a026a502..f83ef635 100644 --- a/test/fixtures/api/responses/get-transactions.json +++ b/test/fixtures/api/responses/get-transactions.json @@ -25,7 +25,7 @@ "value": "0.001" } }, - "paths": "[[{\"currency\":\"USD\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"currency\":\"USD\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"type\":49,\"type_hex\":\"0000000000000031\"}]]" + "paths": "[[{\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"currency\":\"USD\"},{\"account\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"currency\":\"USD\"}]]" }, "outcome": { "result": "tesSUCCESS", @@ -117,7 +117,7 @@ "value": "0.001" } }, - "paths": "[[{\"currency\":\"USD\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"currency\":\"USD\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"type\":49,\"type_hex\":\"0000000000000031\"}]]" + "paths": "[[{\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"currency\":\"USD\"},{\"account\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"currency\":\"USD\"}]]" }, "outcome": { "result": "tesSUCCESS", diff --git a/test/fixtures/api/rippled/account-tx.js b/test/fixtures/api/rippled/account-tx.js index 1d18fb45..27cbb2e2 100644 --- a/test/fixtures/api/rippled/account-tx.js +++ b/test/fixtures/api/rippled/account-tx.js @@ -3,9 +3,9 @@ const _ = require('lodash'); const hashes = require('../../hashes'); const addresses = require('../../addresses'); -const SerializedObject = require('ripple-lib').SerializedObject; const AccountSet = require('./tx/account-set.json'); const NotFound = require('./tx/not-found.json'); +const binary = require('ripple-binary-codec'); module.exports = function(request, options = {}) { _.defaults(options, { @@ -229,8 +229,8 @@ module.exports = function(request, options = {}) { transactions: [ { ledger_index: 348860 - Number(marker || 100), - tx_blob: SerializedObject.from_json(tx).to_hex(), - meta: SerializedObject.from_json(meta).to_hex(), + tx_blob: binary.encode(tx), + meta: binary.encode(meta), validated: options.validated } ] diff --git a/test/fixtures/binary-account-transaction.json b/test/fixtures/binary-account-transaction.json index 483ede9b..0b51d191 100644 --- a/test/fixtures/binary-account-transaction.json +++ b/test/fixtures/binary-account-transaction.json @@ -368,84 +368,56 @@ "Paths": [ [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { "currency": "USD", - "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" }, { "currency": "USD", - "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" }, { "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" } ] ], @@ -697,84 +669,56 @@ "Paths": [ [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { "currency": "USD", - "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" }, { "currency": "USD", - "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" }, { "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" } ] ], @@ -794,4 +738,4 @@ "validated": true } } -} \ No newline at end of file +} diff --git a/test/fixtures/binary-transaction.json b/test/fixtures/binary-transaction.json index ceb9ed0b..9e3649c8 100644 --- a/test/fixtures/binary-transaction.json +++ b/test/fixtures/binary-transaction.json @@ -104,61 +104,41 @@ "Paths": [ [ { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { "currency": "USD", - "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ], [ { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" } ], [ { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rP9Lt7SZUEErkXAXyggceibTCEYbfSyx6n", - "type": 1, - "type_hex": "0000000000000001" + "account": "rP9Lt7SZUEErkXAXyggceibTCEYbfSyx6n" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ], [ { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rwBWBFZrbLzHoe3PhwWYv89iHJdxAFrxcB", - "type": 1, - "type_hex": "0000000000000001" + "account": "rwBWBFZrbLzHoe3PhwWYv89iHJdxAFrxcB" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ] ], @@ -405,84 +385,56 @@ "Paths": [ [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { "currency": "USD", - "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" }, { "currency": "USD", - "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" }, { "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" } ], [ { - "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6" }, { "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 48, - "type_hex": "0000000000000030" + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" } ] ], @@ -871,60 +823,40 @@ "Paths": [ [ { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" } ], [ { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" } ], [ { - "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 1, - "type_hex": "0000000000000001" + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" }, { - "account": "rULnR9YhAkj9HrcxAcudzBhaXRSqT7zJkq", - "type": 1, - "type_hex": "0000000000000001" + "account": "rULnR9YhAkj9HrcxAcudzBhaXRSqT7zJkq" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" } ], [ { - "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "type": 1, - "type_hex": "0000000000000001" + "account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" }, { - "account": "rP5ShE8dGBH6hHtNvRESdMceen36XFBQmh", - "type": 1, - "type_hex": "0000000000000001" + "account": "rP5ShE8dGBH6hHtNvRESdMceen36XFBQmh" }, { - "currency": "XRP", - "type": 16, - "type_hex": "0000000000000010" + "currency": "XRP" } ] ], @@ -1225,4 +1157,4 @@ "validated": true } } -} \ No newline at end of file +} diff --git a/test/fixtures/orderbook.js b/test/fixtures/orderbook.js index 4fe2c564..eb6933ee 100644 --- a/test/fixtures/orderbook.js +++ b/test/fixtures/orderbook.js @@ -5,9 +5,8 @@ const _ = require('lodash'); const addresses = require('./addresses'); const Meta = require('ripple-lib').Meta; -const SerializedObject = require('ripple-lib').SerializedObject; -const Types = require('ripple-lib').types; const IOUValue = require('ripple-lib-value').IOUValue; +const binary = require('ripple-binary-codec'); module.exports.FIAT_BALANCE = '10'; module.exports.NATIVE_BALANCE = '55'; @@ -824,10 +823,7 @@ module.exports.transactionWithCreatedOffer = function(options) { const takerPays = new IOUValue(module.exports.TAKER_PAYS); const quality = takerPays.divide(takerGets); - const so = new SerializedObject(); - Types.Quality.serialize(so, quality); - - const BookDirectory = so.to_hex(); + const BookDirectory = binary.encodeQuality(quality.toString()); const meta = new Meta({ AffectedNodes: [ diff --git a/test/serializedobject-test.js b/test/serializedobject-test.js deleted file mode 100644 index f5449acd..00000000 --- a/test/serializedobject-test.js +++ /dev/null @@ -1,352 +0,0 @@ -'use strict'; - -/* eslint-disable max-len*/ - -const assert = require('assert'); -const lodash = require('lodash'); -const SerializedObject = require('ripple-lib').SerializedObject; -const Amount = require('ripple-lib').Amount; -const sjclcodec = require('sjcl-codec'); - -// Shortcuts -const hex = sjclcodec.hex; -const utf8 = sjclcodec.utf8String; - -describe('Serialized object', function() { - - function convertStringToHex(string) { - return hex.fromBits(utf8.toBits(string)).toUpperCase(); - } - - describe('#from_json(v).to_json() == v', function() { - it('outputs same as passed to from_json', function() { - const input_json = { - Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Amount: '274579388', - Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Fee: '15', - Flags: 0, - Paths: [[ - { - account: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV', - currency: 'USD', - issuer: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV', - type: 49, - type_hex: '0000000000000031' - }, - { - currency: 'XRP', - type: 16, - type_hex: '0000000000000010' - } - ]], - SendMax: { - currency: 'USD', - issuer: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - value: '2.74579388' - }, - Sequence: 351, - SigningPubKey: '02854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A', - TransactionType: 'Payment', - TxnSignature: '30450221009DA3A42DD25E3B22EC45AD8BA8FC7A954264264A816D300B2DF69F814D7D4DD2022072C9627F97EEC6DA13DE841E06E2CD985EF06A0FBB15DDBF0800D0730C8986BF' - }; - const output_json = SerializedObject.from_json(input_json).to_json(); - assert.deepEqual(input_json, output_json); - }); - }); - - describe('#from_json(v).to_json() == v -- invalid amount', function() { - it('outputs same as passed to from_json', function() { - const input_json = { - Account: 'rUR9gTCcrUY9fMkz9rwcM9urPREh3LKXoW', - Fee: '10', - Flags: 0, - Sequence: 65, - SigningPubKey: '033D0B1FB932E0408C119107483190B61561DCE8529E29CB5D1C69128DA54DA715', - TakerGets: '2188313981504612096', - TakerPays: { - currency: 'USD', - issuer: 'r9rp9MUFRJVCVLRm3MTmUvSPNBSL3BuEFx', - value: '99999999999' - }, - TransactionType: 'OfferCreate', - TxnSignature: '304602210085C6AE945643150E6D450CF796E45D74FB24B4E03E964A29CC6AFFEB346C77C80221009BE1B6678CF6C2E61F8F2696144C75AFAF66DF4FC0733DF9118EDEFEEFE33243' - }; - - assert.throws(function() { - SerializedObject.from_json(input_json).to_json(); - }); - }); - }); - - describe('#from_json(v).to_json() == v -- invalid amount, strict_mode = false', function() { - it('outputs same as passed to from_json', function() { - const input_json = { - Account: 'rUR9gTCcrUY9fMkz9rwcM9urPREh3LKXoW', - Fee: '10', - Flags: 0, - Sequence: 65, - SigningPubKey: '033D0B1FB932E0408C119107483190B61561DCE8529E29CB5D1C69128DA54DA715', - TakerGets: '2188313981504612096', - TakerPays: { - currency: 'USD', - issuer: 'r9rp9MUFRJVCVLRm3MTmUvSPNBSL3BuEFx', - value: '99999999999' - }, - TransactionType: 'OfferCreate', - TxnSignature: 'FFFFFF210085C6AE945643150E6D450CF796E45D74FB24B4E03E964A29CC6AFFEB346C77C80221009BE1B6678CF6C2E61F8F2696144C75AFAF66DF4FC0733DF9118EDEFEEFE33243' - }; - - const strictMode = Amount.strict_mode; - Amount.strict_mode = false; - const output_json = SerializedObject.from_json(input_json).to_json(); - assert.deepEqual(input_json, output_json); - Amount.strict_mode = strictMode; - }); - }); - - describe('#from_json', function() { - it('understands TransactionType as a Number', function() { - const input_json = { - // no non required fields - Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Amount: '274579388', - Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Fee: '15', - Sequence: 351, - SigningPubKey: '02',// VL field ;) - TransactionType: 0 // - }; - const output_json = SerializedObject.from_json(input_json).to_json(); - - assert.equal(0, input_json.TransactionType); - assert.equal('Payment', output_json.TransactionType); - }); - - it('understands LedgerEntryType as a Number', function() { - const input_json = { - // no, non required fields - LedgerEntryType: 100, - Flags: 0, - Indexes: [], - RootIndex: '000360186E008422E06B72D5B275E29EE3BE9D87A370F424E0E7BF613C465909' - }; - - const output_json = SerializedObject.from_json(input_json).to_json(); - assert.equal(100, input_json.LedgerEntryType); - assert.equal('DirectoryNode', output_json.LedgerEntryType); - }); - - it('checks for missing required fields', function() { - const input_json = { - TransactionType: 'Payment', - // no non required fields - Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Amount: '274579388', - Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Fee: '15', - Sequence: 351, - SigningPubKey: '02' - }; - - Object.keys(input_json).slice(1).forEach(function(k) { - const bad_json = lodash.merge({}, input_json); - delete bad_json[k]; - - assert.strictEqual(bad_json[k], undefined); - assert.throws(function() { - SerializedObject.from_json(bad_json); - }, new RegExp('Payment is missing fields: \\["' + k + '"\\]')); - - }); - }); - it('checks for unknown fields', function() { - const input_json = { - TransactionType: 'Payment', - // no non required fields - Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Amount: '274579388', - Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Fee: '15', - Sequence: 351, - SigningPubKey: '02' - }; - - Object.keys(input_json).slice(1).forEach(function(k) { - const bad_json = lodash.merge({}, input_json); - bad_json[k + 'z'] = bad_json[k]; - - assert.throws(function() { - SerializedObject.from_json(bad_json); - }, new RegExp('Payment has unknown fields: \\["' + k + 'z"\\]')); - - }); - }); - - describe('Format validation', function() { - // Peercover actually had a problem submitting transactions without a `Fee` - // and rippled was only informing of 'transaction is invalid' - it('should throw an Error when there is a missing field', function() { - const input_json = { - Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Amount: '274579388', - Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', - Sequence: 351, - SigningPubKey: '02854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A', - TransactionType: 'Payment', - TxnSignature: '30450221009DA3A42DD25E3B22EC45AD8BA8FC7A954264264A816D300B2DF69F814D7D4DD2022072C9627F97EEC6DA13DE841E06E2CD985EF06A0FBB15DDBF0800D0730C8986BF' - }; - assert.throws( - function() { - SerializedObject.from_json(input_json); - }, - /Payment is missing fields: \["Fee"\]/ - ); - }); - }); - - describe('Memos', function() { - let input_json; - - beforeEach(function() { - input_json = { - 'Flags': 2147483648, - 'TransactionType': 'Payment', - 'Account': 'rhXzSyt1q9J8uiFXpK3qSugAAPJKXLtnrF', - 'Amount': '1', - 'Destination': 'radqi6ppXFxVhJdjzaATRBxdrPcVTf1Ung', - 'Sequence': 281, - 'SigningPubKey': '03D642E6457B8AB4D140E2C66EB4C484FAFB1BF267CB578EC4815FE6CD06379C51', - 'Fee': '12000', - 'LastLedgerSequence': 10074214, - 'TxnSignature': '304402201180636F2CE215CE97A29CD302618FAE60D63EBFC8903DE17A356E857A449C430220290F4A54F9DE4AC79034C8BEA5F1F8757F7505F1A6FF04D2E19B6D62E867256B' - }; - }); - - it('should serialize and parse - full memo, all strings text/plain ', function() { - input_json.Memos = [ - { - Memo: { - MemoType: '74657374', - MemoFormat: '74657874', - MemoData: '736F6D652064617461' - } - } - ]; - - const so = SerializedObject.from_json(input_json).to_json(); - input_json.Memos[0].Memo.parsed_memo_type = 'test'; - input_json.Memos[0].Memo.parsed_memo_format = 'text'; - input_json.Memos[0].Memo.parsed_memo_data = 'some data'; - input_json.Memos[0].Memo.MemoType = convertStringToHex('test'); - input_json.Memos[0].Memo.MemoFormat = convertStringToHex('text'); - input_json.Memos[0].Memo.MemoData = convertStringToHex('some data'); - - assert.deepEqual(so, input_json); - }); - - it('should serialize and parse - full memo, all strings, invalid MemoFormat', function() { - input_json.Memos = [ - { - 'Memo': - { - MemoType: '74657374', - MemoFormat: '6170706C69636174696F6E2F6A736F6E', - MemoData: '736F6D652064617461' - } - } - ]; - - const so = SerializedObject.from_json(input_json).to_json(); - input_json.Memos[0].Memo.parsed_memo_type = 'test'; - input_json.Memos[0].Memo.parsed_memo_format = 'application/json'; - input_json.Memos[0].Memo.MemoType = convertStringToHex('test'); - input_json.Memos[0].Memo.MemoFormat = convertStringToHex('application/json'); - input_json.Memos[0].Memo.MemoData = convertStringToHex('some data'); - - assert.deepEqual(so, input_json); - assert.strictEqual(input_json.Memos[0].Memo.parsed_memo_data, undefined); - }); - - it('should serialize and parse - full memo, json data, valid MemoFormat, ignored field', function() { - input_json.Memos = [ - { - Memo: { - MemoType: '74657374', - MemoFormat: '6A736F6E', - ignored: 'ignored', - MemoData: '7B22737472696E67223A22736F6D655F737472696E67222C22626F6F6C65616E223A747275657D' - } - } - ]; - - const so = SerializedObject.from_json(input_json).to_json(); - delete input_json.Memos[0].Memo.ignored; - input_json.Memos[0].Memo.parsed_memo_type = 'test'; - input_json.Memos[0].Memo.parsed_memo_format = 'json'; - input_json.Memos[0].Memo.parsed_memo_data = { - 'string': 'some_string', - 'boolean': true - }; - input_json.Memos[0].Memo.MemoType = convertStringToHex('test'); - input_json.Memos[0].Memo.MemoFormat = convertStringToHex('json'); - input_json.Memos[0].Memo.MemoData = convertStringToHex(JSON.stringify( - { - 'string': 'some_string', - 'boolean': true - } - )); - - assert.deepEqual(so, input_json); - }); - - it('should throw an error - invalid Memo field', function() { - input_json.Memos = [ - { - Memo: { - MemoType: '74657374', - MemoField: '6A736F6E', - MemoData: '7B22737472696E67223A22736F6D655F737472696E67222C22626F6F6C65616E223A747275657D' - } - } - ]; - - assert.throws(function() { - SerializedObject.from_json(input_json); - }, /^Error: JSON contains unknown field: "MemoField" \(Memo\) \(Memos\)/); - }); - - - it('should serialize json with memo - match hex output', function() { - input_json = { - Flags: 2147483648, - TransactionType: 'Payment', - Account: 'rhXzSyt1q9J8uiFXpK3qSugAAPJKXLtnrF', - Amount: '1', - Destination: 'radqi6ppXFxVhJdjzaATRBxdrPcVTf1Ung', - Memos: [ - { - Memo: { - MemoType: '696D616765' - } - } - ], - Sequence: 294, - SigningPubKey: '03D642E6457B8AB4D140E2C66EB4C484FAFB1BF267CB578EC4815FE6CD06379C51', - Fee: '12000', - LastLedgerSequence: 10404607, - TxnSignature: '304402206B53EDFA6EFCF6FE5BA76C81BABB60A3B55E9DE8A1462DEDC5F387879575E498022015AE7B59AA49E735D7F2E252802C4406CD00689BCE5057C477FE979D38D2DAC9' - }; - - const serializedHex = '12000022800000002400000126201B009EC2FF614000000000000001684000000000002EE0732103D642E6457B8AB4D140E2C66EB4C484FAFB1BF267CB578EC4815FE6CD06379C517446304402206B53EDFA6EFCF6FE5BA76C81BABB60A3B55E9DE8A1462DEDC5F387879575E498022015AE7B59AA49E735D7F2E252802C4406CD00689BCE5057C477FE979D38D2DAC9811426C4CFB3BD05A9AA23936F2E81634C66A9820C9483143DD06317D19C6110CAFF150AE528F58843BE2CA1F9EA7C05696D616765E1F1'; - assert.strictEqual(SerializedObject.from_json(input_json).to_hex(), serializedHex); - - }); - - }); - - }); - -}); - -// vim:sw=2:sts=2:ts=8:et diff --git a/test/serializedtypes-test.js b/test/serializedtypes-test.js deleted file mode 100644 index ae1039bb..00000000 --- a/test/serializedtypes-test.js +++ /dev/null @@ -1,1124 +0,0 @@ -/* eslint-disable max-len */ - -'use strict'; - -const assert = require('assert'); -const BN = require('bn.js'); -const BigNumber = require('bignumber.js'); -const SerializedObject = require('ripple-lib').SerializedObject; -const types = require('ripple-lib').types; -const Amount = require('ripple-lib').Amount; - -describe('Serialized types', function() { - describe('Int8', function() { - it('Serialize 0', function() { - const so = new SerializedObject(); - types.Int8.serialize(so, 0); - assert.strictEqual(so.to_hex(), '00'); - }); - it('Serialize 123', function() { - const so = new SerializedObject(); - types.Int8.serialize(so, 123); - assert.strictEqual(so.to_hex(), '7B'); - }); - it('Serialize 255', function() { - const so = new SerializedObject(); - types.Int8.serialize(so, 255); - assert.strictEqual(so.to_hex(), 'FF'); - }); - it('Fail to serialize 256', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int8.serialize(so, 256); - }); - }); - it('Fail to serialize -1', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int8.serialize(so, -1); - }); - }); - it('Serialize 5.5 (should floor)', function() { - const so = new SerializedObject(); - types.Int8.serialize(so, 5.5); - assert.strictEqual(so.to_hex(), '05'); - }); - it('Serialize 255.9 (should floor)', function() { - const so = new SerializedObject(); - types.Int8.serialize(so, 255.9); - assert.strictEqual(so.to_hex(), 'FF'); - }); - it('Fail to serialize null', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int8.serialize(so, null); - }); - }); - it('Fail to serialize "bla"', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int8.serialize(so, 'bla'); - }); - }); - it('Fail to serialize {}', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int8.serialize(so, {}); - }); - }); - }); - - describe('Int16', function() { - it('Serialize 0', function() { - const so = new SerializedObject(); - types.Int16.serialize(so, 0); - assert.strictEqual(so.to_hex(), '0000'); - }); - it('Serialize 123', function() { - const so = new SerializedObject(); - types.Int16.serialize(so, 123); - assert.strictEqual(so.to_hex(), '007B'); - }); - it('Serialize 255', function() { - const so = new SerializedObject(); - types.Int16.serialize(so, 255); - assert.strictEqual(so.to_hex(), '00FF'); - }); - it('Serialize 256', function() { - const so = new SerializedObject(); - types.Int16.serialize(so, 256); - assert.strictEqual(so.to_hex(), '0100'); - }); - it('Serialize 65535', function() { - const so = new SerializedObject(); - types.Int16.serialize(so, 65535); - assert.strictEqual(so.to_hex(), 'FFFF'); - }); - it('Fail to serialize 65536', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int8.serialize(so, 65536); - }); - }); - it('Fail to serialize -1', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int16.serialize(so, -1); - }); - }); - it('Serialize 123.5 (should floor)', function() { - const so = new SerializedObject(); - types.Int16.serialize(so, 123.5); - assert.strictEqual(so.to_hex(), '007B'); - }); - it('Serialize 65535.5 (should floor)', function() { - const so = new SerializedObject(); - types.Int16.serialize(so, 65535.5); - assert.strictEqual(so.to_hex(), 'FFFF'); - }); - it('Fail to serialize null', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int16.serialize(so, null); - }); - }); - it('Fail to serialize "bla"', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int16.serialize(so, 'bla'); - }); - }); - it('Fail to serialize {}', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int16.serialize(so, {}); - }); - }); - }); - - describe('Int32', function() { - it('Serialize 0', function() { - const so = new SerializedObject(); - types.Int32.serialize(so, 0); - assert.strictEqual(so.to_hex(), '00000000'); - }); - it('Serialize 123', function() { - const so = new SerializedObject(); - types.Int32.serialize(so, 123); - assert.strictEqual(so.to_hex(), '0000007B'); - }); - it('Serialize 255', function() { - const so = new SerializedObject(); - types.Int32.serialize(so, 255); - assert.strictEqual(so.to_hex(), '000000FF'); - }); - it('Serialize 256', function() { - const so = new SerializedObject(); - types.Int32.serialize(so, 256); - assert.strictEqual(so.to_hex(), '00000100'); - }); - it('Serialize 0xF0F0F0F0', function() { - const so = new SerializedObject(); - types.Int32.serialize(so, 0xF0F0F0F0); - assert.strictEqual(so.to_hex(), 'F0F0F0F0'); - }); - it('Serialize 0xFFFFFFFF', function() { - const so = new SerializedObject(); - types.Int32.serialize(so, 0xFFFFFFFF); - assert.strictEqual(so.to_hex(), 'FFFFFFFF'); - }); - it('Fail to serialize 0x100000000', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int8.serialize(so, 0x100000000); - }); - }); - it('Fail to serialize -1', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int32.serialize(so, -1); - }); - }); - it('Serialize 123.5 (should floor)', function() { - const so = new SerializedObject(); - types.Int32.serialize(so, 123.5); - assert.strictEqual(so.to_hex(), '0000007B'); - }); - it('Serialize 4294967295.5 (should floor)', function() { - const so = new SerializedObject(); - types.Int32.serialize(so, 4294967295.5); - assert.strictEqual(so.to_hex(), 'FFFFFFFF'); - }); - it('Fail to serialize null', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int32.serialize(so, null); - }); - }); - it('Fail to serialize "bla"', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int32.serialize(so, 'bla'); - }); - }); - it('Fail to serialize {}', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int32.serialize(so, {}); - }); - }); - it('Parse 0', function() { - const val = '00000000'; - const so = new SerializedObject(val); - const num = types.Int32.parse(so); - assert.strictEqual(num, parseInt(val, 16)); - }); - it('Parse 1', function() { - const val = '00000001'; - const so = new SerializedObject(val); - const num = types.Int32.parse(so); - assert.strictEqual(num, parseInt(val, 16)); - }); - it('Parse UINT32_MAX', function() { - const val = 'FFFFFFFF'; - const so = new SerializedObject(val); - const num = types.Int32.parse(so); - assert.strictEqual(num, parseInt(val, 16)); - }); - }); - - describe('Int64', function() { - it('Serialize 0', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 0); - assert.strictEqual(so.to_hex(), '0000000000000000'); - }); - it('Serialize 123', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 123); - assert.strictEqual(so.to_hex(), '000000000000007B'); - }); - it('Serialize 255', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 255); - assert.strictEqual(so.to_hex(), '00000000000000FF'); - }); - it('Serialize 256', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 256); - assert.strictEqual(so.to_hex(), '0000000000000100'); - }); - it('Serialize 0xF0F0F0F0', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 0xF0F0F0F0); - assert.strictEqual(so.to_hex(), '00000000F0F0F0F0'); - }); - it('Serialize 0xFFFFFFFF', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 0xFFFFFFFF); - assert.strictEqual(so.to_hex(), '00000000FFFFFFFF'); - }); - it('Serialize 0x100000000', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 0x100000000); - assert.strictEqual(so.to_hex(), '0000000100000000'); - }); - it('Fail to serialize 0x100000000', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int8.serialize(so, 0x100000000); - }); - }); - it('Fail to serialize -1', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int64.serialize(so, -1); - }); - }); - it('Serialize 123.5 (should floor)', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 123.5); - assert.strictEqual(so.to_hex(), '000000000000007B'); - }); - it('Serialize 4294967295.5 (should floor)', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 4294967295.5); - assert.strictEqual(so.to_hex(), '00000000FFFFFFFF'); - }); - it('Does not get confused when the high bit is set', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, '8B2386F26F8E232B'); - assert.strictEqual(so.to_hex(), '8B2386F26F8E232B'); - const so2 = new SerializedObject('8B2386F26F8E232B'); - const num = types.Int64.parse(so2); - // We get a positive number - assert.strictEqual(num.toString(16), '8b2386f26f8e232b'); - }); - it('Serialize "0123456789ABCDEF"', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, '0123456789ABCDEF'); - assert.strictEqual(so.to_hex(), '0123456789ABCDEF'); - }); - it('Serialize "F0E1D2C3B4A59687"', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, 'F0E1D2C3B4A59687'); - assert.strictEqual(so.to_hex(), 'F0E1D2C3B4A59687'); - }); - it('Serialize bn("FFEEDDCCBBAA9988")', function() { - const so = new SerializedObject(); - types.Int64.serialize(so, new BN('FFEEDDCCBBAA9988', 16)); - assert.strictEqual(so.to_hex(), 'FFEEDDCCBBAA9988'); - }); - it('Fail to serialize BigNumber("-1")', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int64.serialize(so, new BigNumber('-1', 10)); - }); - }); - it('Fail to serialize "10000000000000000"', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int64.serialize(so, '10000000000000000'); - }); - }); - it('Fail to serialize "110000000000000000"', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int64.serialize(so, '110000000000000000'); - }); - }); - it('Fail to serialize null', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int64.serialize(so, null); - }); - }); - it('Fail to serialize "bla"', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int64.serialize(so, 'bla'); - }); - }); - it('Fail to serialize {}', function() { - const so = new SerializedObject(); - assert.throws(function() { - types.Int64.serialize(so, {}); - }); - }); - it('Parse "0123456789ABCDEF"', function() { - const so = new SerializedObject('0123456789ABCDEF'); - const num = types.Int64.parse(so); - assert.strictEqual(num.toString(16), '123456789abcdef'); - }); - }); - - describe('Hash128', function() { - it('Serialize 0', function() { - const so = new SerializedObject(); - types.Hash128.serialize(so, '00000000000000000000000000000000'); - assert.strictEqual(so.to_hex(), '00000000000000000000000000000000'); - }); - it('Serialize 102030405060708090A0B0C0D0E0F000', function() { - const so = new SerializedObject(); - types.Hash128.serialize(so, '102030405060708090A0B0C0D0E0F000'); - assert.strictEqual(so.to_hex(), '102030405060708090A0B0C0D0E0F000'); - }); - it('Serialize HASH128_MAX', function() { - const so = new SerializedObject(); - types.Hash128.serialize(so, 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'); - assert.strictEqual(so.to_hex(), 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'); - }); - it('Parse 0', function() { - const val = '00000000000000000000000000000000'; - const so = new SerializedObject(val); - const num = types.Hash128.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - it('Parse 1', function() { - const val = '00000000000000000000000000000001'; - const so = new SerializedObject(val); - const num = types.Hash128.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - it('Parse HASH128_MAX', function() { - const val = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - const so = new SerializedObject(val); - const num = types.Hash128.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - }); - - describe('Hash160', function() { - it('Serialize 0', function() { - const hex = '0000000000000000000000000000000000000000'; - const base58 = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp'; - const so = new SerializedObject(); - types.Hash160.serialize(so, base58); - assert.strictEqual(so.to_hex(), hex); - - const so2 = new SerializedObject(); - types.Hash160.serialize(so2, hex); - assert.strictEqual(so2.to_hex(), hex); - }); - it('Serialize 1', function() { - const hex = '0000000000000000000000000000000000000001'; - const base58 = 'rrrrrrrrrrrrrrrrrrrrBZbvji'; - const so = new SerializedObject(); - types.Hash160.serialize(so, base58); - assert.strictEqual(so.to_hex(), hex); - - const so2 = new SerializedObject(); - types.Hash160.serialize(so2, hex); - assert.strictEqual(so2.to_hex(), hex); - }); - it('Serialize FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', function() { - const hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - const base58 = 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi'; - const so = new SerializedObject(); - types.Hash160.serialize(so, base58); - assert.strictEqual(so.to_hex(), hex); - - const so2 = new SerializedObject(); - types.Hash160.serialize(so2, hex); - assert.strictEqual(so2.to_hex(), hex); - }); - it('Parse 0', function() { - const val = '0000000000000000000000000000000000000000'; - const so = new SerializedObject(val); - const num = types.Hash160.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - it('Parse 1', function() { - const val = '0000000000000000000000000000000000000001'; - const so = new SerializedObject(val); - const num = types.Hash160.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - it('Parse HASH160_MAX', function() { - const val = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - const so = new SerializedObject(val); - const num = types.Hash160.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - it('Parse 0 as JSON', function() { - // Hash160 should be returned as hex in JSON, unlike - // addresses. - const val = '0000000000000000000000000000000000000000'; - const so = new SerializedObject(val); - const num = types.Hash160.parse(so); - assert.strictEqual(num.to_json(), val); - }); - }); - - describe('Hash256', function() { - it('Serialize 0', function() { - const so = new SerializedObject(); - types.Hash256.serialize(so, '0000000000000000000000000000000000000000000000000000000000000000'); - assert.strictEqual(so.to_hex(), '0000000000000000000000000000000000000000000000000000000000000000'); - }); - it('Serialize 1', function() { - const so = new SerializedObject(); - types.Hash256.serialize(so, '0000000000000000000000000000000000000000000000000000000000000001'); - assert.strictEqual(so.to_hex(), '0000000000000000000000000000000000000000000000000000000000000001'); - }); - it('Serialize HASH256_MAX', function() { - const so = new SerializedObject(); - types.Hash256.serialize(so, 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'); - assert.strictEqual(so.to_hex(), 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'); - }); - it('Parse 0', function() { - const val = '0000000000000000000000000000000000000000000000000000000000000000'; - const so = new SerializedObject(val); - const num = types.Hash256.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - it('Parse 1', function() { - const val = '0000000000000000000000000000000000000000000000000000000000000000'; - const so = new SerializedObject(val); - const num = types.Hash256.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - it('Parse HASH256_MAX', function() { - const val = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - const so = new SerializedObject(val); - const num = types.Hash256.parse(so); - assert.strictEqual(num.to_hex(), val); - }); - }); - - describe('Quality', function() { - it('Serialize 1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject(); - types.Quality.serialize(so, '1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - assert.strictEqual(so.to_hex(), '55038D7EA4C68000'); - }); - it('Serialize 87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject(); - types.Quality.serialize(so, '87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - assert.strictEqual(so.to_hex(), '5C1F241D335BF24E'); - }); - }); - - describe('Amount', function() { - it('Serialize 0 XRP', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, '0'); - assert.strictEqual(so.to_hex(), '4000000000000000'); - }); - it('Serialize 1 XRP', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, '1'); - assert.strictEqual(so.to_hex(), '4000000000000001'); - }); - it('Serialize -1 XRP', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, '-1'); - assert.strictEqual(so.to_hex(), '0000000000000001'); - }); - it('Serialize 213 XRP', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, '213'); - assert.strictEqual(so.to_hex(), '40000000000000D5'); - }); - it('Serialize 270544960 XRP', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, '270544960'); - assert.strictEqual(so.to_hex(), '4000000010203040'); - }); - it('Serialize 1161981756646125568 XRP', function() { - const so = new SerializedObject(); - assert.throws(function() { - const amt = Amount.from_json('1161981756646125696'); - types.Amount.serialize(so, amt); - }); - }); - it('Serialize 1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, '1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - assert.strictEqual(so.to_hex(), 'D4838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8'); - }); - it('Serialize 87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, '87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - assert.strictEqual(so.to_hex(), 'D65F241D335BF24E0000000000000000000000004555520000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8'); - }); - it('Serialize -1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, '-1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - assert.strictEqual(so.to_hex(), '94838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8'); - }); - it('Serialize 15/XRP/rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo', function() { - // This actually appears in the ledger, so we need to be able to serialize - // Transaction #A2AD66C93C7B7277CD5AEB718A4E82D88C7099129948BC66A394EE38B34657A9 - const so = new SerializedObject(); - types.Amount.serialize(so, { - value: '1000', - currency: 'XRP', - issuer: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo' - }); - assert.strictEqual(so.to_hex(), 'D5438D7EA4C680000000000000000000000000005852500000000000E4FE687C90257D3D2D694C8531CDEECBE84F3367'); - }); - // Test support for 20-byte hex raw currency codes - it('Serialize 15/015841551A748AD23FEFFFFFFFEA028000000000/1', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, { - value: '1000', - currency: '015841551A748AD23FEFFFFFFFEA028000000000', - issuer: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo' - }); - assert.strictEqual(so.to_hex(), 'D5438D7EA4C68000015841551A748AD23FEFFFFFFFEA028000000000E4FE687C90257D3D2D694C8531CDEECBE84F3367'); - }); - it('Serialize max_value/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject(); - types.Amount.serialize(so, Amount.max_value + '/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - assert.strictEqual(so.to_hex(), 'EC6386F26FC0FFFF0000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8'); - }); - it('Parse 1 XRP', function() { - const so = new SerializedObject('4000000000000001'); - assert.strictEqual(types.Amount.parse(so).to_json(), '1'); - }); - it('Parse -1 XRP', function() { - const so = new SerializedObject('0000000000000001'); - assert.strictEqual(types.Amount.parse(so).to_json(), '-1'); - }); - it('Parse 213 XRP', function() { - const so = new SerializedObject('40000000000000D5'); - assert.strictEqual(types.Amount.parse(so).to_json(), '213'); - }); - it('Parse 270544960 XRP', function() { - const so = new SerializedObject('4000000010203040'); - assert.strictEqual(types.Amount.parse(so).to_json(), '270544960'); - }); - it('Parse 1161981756646125568 XRP', function() { - assert.throws(function() { - // hex(1161981756646125568) = 1020304050607000 - const so = new SerializedObject('1020304050607000'); - types.Amount.parse(so).to_json(); - }); - }); - it('Parse 1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject('D4838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8'); - assert.strictEqual(types.Amount.parse(so).to_text_full(), '1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - }); - it('Parse 87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject('D65F241D335BF24E0000000000000000000000004555520000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8'); - assert.strictEqual(types.Amount.parse(so).to_text_full(), '87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - }); - it('Parse -1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject('94838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8'); - assert.strictEqual(types.Amount.parse(so).to_text_full(), '-1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - }); - it('Parse max_value/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() { - const so = new SerializedObject('EC6386F26FC0FFFF0000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8'); - assert.strictEqual(types.Amount.parse(so).to_text_full(), Amount.max_value + '/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - }); - }); - - describe('Account', function() { - it('Serialize 0', function() { - const hex = '0000000000000000000000000000000000000000'; - const base58 = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp'; - const so = new SerializedObject(); - types.Account.serialize(so, base58); - assert.strictEqual(so.to_hex(), '14' + hex); - - const so2 = new SerializedObject(); - types.Account.serialize(so2, hex); - assert.strictEqual(so2.to_hex(), '14' + hex); - }); - it('Serialize 1', function() { - const hex = '0000000000000000000000000000000000000001'; - const base58 = 'rrrrrrrrrrrrrrrrrrrrBZbvji'; - const so = new SerializedObject(); - types.Account.serialize(so, base58); - assert.strictEqual(so.to_hex(), '14' + hex); - - const so2 = new SerializedObject(); - types.Account.serialize(so2, hex); - assert.strictEqual(so2.to_hex(), '14' + hex); - }); - it('Serialize FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', function() { - const hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - const base58 = 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi'; - const so = new SerializedObject(); - types.Account.serialize(so, base58); - assert.strictEqual(so.to_hex(), '14' + hex); - - const so2 = new SerializedObject(); - types.Account.serialize(so2, hex); - assert.strictEqual(so2.to_hex(), '14' + hex); - }); - it('Parse 0', function() { - const val = '140000000000000000000000000000000000000000'; - const so = new SerializedObject(val); - const num = types.Account.parse(so); - assert.strictEqual(num.to_json(), 'rrrrrrrrrrrrrrrrrrrrrhoLvTp'); - }); - it('Parse 1', function() { - const val = '140000000000000000000000000000000000000001'; - const so = new SerializedObject(val); - const num = types.Account.parse(so); - assert.strictEqual(num.to_json(), 'rrrrrrrrrrrrrrrrrrrrBZbvji'); - }); - it('Parse HASH160_MAX', function() { - const val = '14FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; - const so = new SerializedObject(val); - const num = types.Account.parse(so); - assert.strictEqual(num.to_json(), 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi'); - }); - }); - - describe('PathSet', function() { - it('Serialize single empty path [[]]', function() { - const so = new SerializedObject(); - types.PathSet.serialize(so, [[]]); - assert.strictEqual(so.to_hex(), '00'); - }); - it('Serialize [[e],[e,e]]', function() { - const so = new SerializedObject(); - types.PathSet.serialize(so, [[{ - account: 123, - currency: 'USD', - issuer: 789 - }], - [{ - account: 123, - currency: 'BTC', - issuer: 789 - }, - { - account: 987, - currency: 'EUR', - issuer: 321 - }]]); - assert.strictEqual(so.to_hex(), '31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF31000000000000000000000000000000000000007B000000000000000000000000425443000000000000000000000000000000000000000000000003153100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100'); // TODO: Check this independently - }); - it('Serialize path through XRP', function() { - const hex = '31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF1000000000000000000000000000000000000000003100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100'; - const json = [ - [{ - account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza', - currency: 'USD', - issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf' - }], - [{ - currency: 'XRP' - }, { - account: 'rrrrrrrrrrrrrrrrrrrpvQsW3V3', - currency: 'EUR', - issuer: 'rrrrrrrrrrrrrrrrrrrdHRtqg2' - }] - ]; - - const result_json = [ - [{ - account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza', - currency: 'USD', - issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf', - type: 49, - type_hex: '0000000000000031' - }], - [{ - currency: 'XRP', - type: 16, - type_hex: '0000000000000010' - }, { - account: 'rrrrrrrrrrrrrrrrrrrpvQsW3V3', - currency: 'EUR', - issuer: 'rrrrrrrrrrrrrrrrrrrdHRtqg2', - type: 49, - type_hex: '0000000000000031' - }] - ]; - - const so = new SerializedObject(); - types.PathSet.serialize(so, json); - assert.strictEqual(so.to_hex(), hex); - - const so2 = new SerializedObject(hex); - const parsed_path = SerializedObject.jsonify_structure(types.PathSet.parse(so2)); - assert.deepEqual(parsed_path, result_json); - }); - it('Serialize path through XRP IOUs', function() { - const hex = '31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF1000000000000000000000000058525000000000003100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100'; - const json = [ - [{ - account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza', - currency: 'USD', - issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf' - }], - [{ - currency: 'XRP', - non_native: true - }, { - account: 'rrrrrrrrrrrrrrrrrrrpvQsW3V3', - currency: 'EUR', - issuer: 'rrrrrrrrrrrrrrrrrrrdHRtqg2' - }] - ]; - - const result_json = [ - [{ - account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza', - currency: 'USD', - issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf', - type: 49, - type_hex: '0000000000000031' - }], - [{ - currency: 'XRP', - non_native: true, - type: 16, - type_hex: '0000000000000010' - }, { - account: 'rrrrrrrrrrrrrrrrrrrpvQsW3V3', - currency: 'EUR', - issuer: 'rrrrrrrrrrrrrrrrrrrdHRtqg2', - type: 49, - type_hex: '0000000000000031' - }] - ]; - - const so = new SerializedObject(); - types.PathSet.serialize(so, json); - assert.strictEqual(so.to_hex(), hex); - - const so2 = new SerializedObject(hex); - const parsed_path = SerializedObject.jsonify_structure(types.PathSet.parse(so2)); - assert.deepEqual(parsed_path, result_json); - }); - it('Serialize path through XRP IOUs (realistic example)', function() { - // Appears in the history - // TX #0CBB429C456ED999CC691DFCC8E62E8C8C7E9522C2BEA967FED0D7E2A9B28D13 - // Note that XRP IOUs are no longer allowed, so this functionality is - // for historic transactions only. - - const hex = '31585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C131E4FE687C90257D3D2D694C8531CDEECBE84F33670000000000000000000000004254430000000000E4FE687C90257D3D2D694C8531CDEECBE84F3367310A20B3C85F482532A9578DBB3950B85CA06594D100000000000000000000000042544300000000000A20B3C85F482532A9578DBB3950B85CA06594D13000000000000000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA06594D1FF31585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C131E4FE687C90257D3D2D694C8531CDEECBE84F33670000000000000000000000004254430000000000E4FE687C90257D3D2D694C8531CDEECBE84F33673115036E2D3F5437A83E5AC3CAEE34FF2C21DEB618000000000000000000000000425443000000000015036E2D3F5437A83E5AC3CAEE34FF2C21DEB6183000000000000000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA06594D1FF31585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C13157180C769B66D942EE69E6DCC940CA48D82337AD000000000000000000000000425443000000000057180C769B66D942EE69E6DCC940CA48D82337AD1000000000000000000000000058525000000000003000000000000000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA06594D100'; - const json = [ - [{ - account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - currency: 'BTC', - issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K' - }, { - account: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo', - currency: 'BTC', - issuer: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo' - }, { - account: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B', - currency: 'BTC', - issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' - }, { - currency: 'USD', - issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' - }], - [{ - account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - currency: 'BTC', - issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K' - }, { - account: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo', - currency: 'BTC', - issuer: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo' - }, { - account: 'rpvfJ4mR6QQAeogpXEKnuyGBx8mYCSnYZi', - currency: 'BTC', - issuer: 'rpvfJ4mR6QQAeogpXEKnuyGBx8mYCSnYZi' - }, { - currency: 'USD', - issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' - }], - [{ - account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - currency: 'BTC', - issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K' - }, { - account: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn', - currency: 'BTC', - issuer: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn' - }, { - currency: 'XRP', - non_native: true - }, { - currency: 'USD', - issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' - }] - ]; - - const result_json = [ - [{ - account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - currency: 'BTC', - issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - type: 49, - type_hex: '0000000000000031' - }, { - account: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo', - currency: 'BTC', - issuer: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo', - type: 49, - type_hex: '0000000000000031' - }, { - account: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B', - currency: 'BTC', - issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B', - type: 49, - type_hex: '0000000000000031' - }, { - currency: 'USD', - issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B', - type: 48, - type_hex: '0000000000000030' - }], - [{ - account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - currency: 'BTC', - issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - type: 49, - type_hex: '0000000000000031' - }, { - account: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo', - currency: 'BTC', - issuer: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo', - type: 49, - type_hex: '0000000000000031' - }, { - account: 'rpvfJ4mR6QQAeogpXEKnuyGBx8mYCSnYZi', - currency: 'BTC', - issuer: 'rpvfJ4mR6QQAeogpXEKnuyGBx8mYCSnYZi', - type: 49, - type_hex: '0000000000000031' - }, { - currency: 'USD', - issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B', - type: 48, - type_hex: '0000000000000030' - }], - [{ - account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - currency: 'BTC', - issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K', - type: 49, - type_hex: '0000000000000031' - }, { - account: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn', - currency: 'BTC', - issuer: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn', - type: 49, - type_hex: '0000000000000031' - }, { - currency: 'XRP', - non_native: true, - type: 16, - type_hex: '0000000000000010' - }, { - currency: 'USD', - issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B', - type: 48, - type_hex: '0000000000000030' - }] - ]; - - const so = new SerializedObject(); - types.PathSet.serialize(so, json); - assert.strictEqual(so.to_hex(), hex); - - const so2 = new SerializedObject(hex); - const parsed_path = SerializedObject.jsonify_structure(types.PathSet.parse(so2)); - assert.deepEqual(parsed_path, result_json); - }); - it('Parse single empty path [[]]', function() { - const so = new SerializedObject('00'); - const parsed_path = SerializedObject.jsonify_structure(types.PathSet.parse(so)); - assert.deepEqual(parsed_path, [[]]); - }); - it('Parse [[e],[e,e]]', function() { - const so = new SerializedObject('31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF31000000000000000000000000000000000000007B000000000000000000000000425443000000000000000000000000000000000000000000000003153100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100'); - - const parsed_path = types.PathSet.parse(so); - const comp = [ - [ - { - account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza', - currency: 'USD', - issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf', - type: 49, - type_hex: '0000000000000031' - } - ], - [ - { - account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza', - currency: 'BTC', - issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf', - type: 49, - type_hex: '0000000000000031' - }, - { - account: 'rrrrrrrrrrrrrrrrrrrpvQsW3V3', - currency: 'EUR', - issuer: 'rrrrrrrrrrrrrrrrrrrdHRtqg2', - type: 49, - type_hex: '0000000000000031' - } - ] - ]; - - assert.deepEqual(SerializedObject.jsonify_structure(parsed_path, ''), comp); - }); - }); - - describe('Object', function() { - it('Can parse objects with VL encoded Vector256', function() { - const hex = '110064220000000058000360186E008422E06B72D5B275E29EE3BE9D87A370F424E0E7BF613C4659098214289D19799C892637306AAAF03805EDFCDF6C28B8011320081342A0AB45459A54D8E4FA1842339A102680216CF9A152BCE4F4CE467D8246'; - const so = new SerializedObject(hex); - const as_json = so.to_json(); - const expected_json = { - LedgerEntryType: 'DirectoryNode', - Owner: 'rh6kN9s7spSb3vdv6H8ZGYzsddSLeEUGmc', - Flags: 0, - Indexes: [ - '081342A0AB45459A54D8E4FA1842339A102680216CF9A152BCE4F4CE467D8246' - ], - RootIndex: '000360186E008422E06B72D5B275E29EE3BE9D87A370F424E0E7BF613C465909' - }; - assert.deepEqual(as_json, expected_json); - assert.strictEqual(SerializedObject.from_json(expected_json).to_hex(), hex); - }); - it('Serialize empty object {}', function() { - const so = new SerializedObject(); - types.Object.serialize(so, {}); - assert.strictEqual(so.to_hex(), 'E1'); - }); - it('Parse empty object {}', function() { - const so = new SerializedObject('E1'); - const parsed_object = types.Object.parse(so); - assert.deepEqual(parsed_object, {}); - }); - it('Serialize simple object {TakerPays:"87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", TakerGets:213, Fee:"789"}', function() { - const so = new SerializedObject(); - types.Object.serialize(so, { - TakerPays: '87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', - TakerGets: '213', - Fee: 789 - }); - assert.strictEqual(so.to_hex(), '64D65F241D335BF24E0000000000000000000000004555520000000000B5F762798A53D543A014CAF8B297CFF8F2F937E86540000000000000D5684000000000000315E1'); - // TODO: Check independently. - }); - it('Parse same object', function() { - const so = new SerializedObject('64D65F241D335BF24E0000000000000000000000004555520000000000B5F762798A53D543A014CAF8B297CFF8F2F937E86540000000000000D5684000000000000315E1'); - const parsed_object = types.Object.parse(so); - const comp = { - TakerPays: { - value: '87654321.12345678', - currency: 'EUR', - issuer: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh' - }, - TakerGets: '213', - Fee: '789' - }; - assert.deepEqual(SerializedObject.jsonify_structure(parsed_object, ''), comp); - // TODO: Check independently. - }); - - it('Serialize simple object {DestinationTag:123, QualityIn:456, QualityOut:789}', function() { - const so = new SerializedObject(); - types.Object.serialize(so, { - DestinationTag: 123, - QualityIn: 456, - QualityOut: 789 - }); - assert.strictEqual(so.to_hex(), '2E0000007B2014000001C8201500000315E1'); - // TODO: Check independently. - }); - it('Parse simple object {DestinationTag:123, QualityIn:456, QualityOut:789}', function() {// 2E0000007B22000001C82400000315E1 2E0000007B2002000001C8200200000315E1 - const so = new SerializedObject('2E0000007B2014000001C8201500000315E1'); - const parsed_object = types.Object.parse(so); - assert.deepEqual(parsed_object, { - DestinationTag: 123, - QualityIn: 456, - QualityOut: 789 - }); - // TODO: Check independently. - }); - }); - - describe('Array', function() { - it('Serialize empty array []', function() { - const so = new SerializedObject(); - types.Array.serialize(so, []); - assert.strictEqual(so.to_hex(), 'F1'); - }); - it('Parse empty array []', function() { - const so = new SerializedObject('F1'); - const parsed_object = types.Array.parse(so); - assert.deepEqual(parsed_object, []); - }); - it('Serialize 3-length array [{TakerPays:123}); {TakerGets:456}, {Fee:789}]', function() { - const so = new SerializedObject(); - types.Array.serialize(so, [ - { - TakerPays: 123 - }, - { - TakerGets: 456 - }, - { - Fee: 789 - } - ]); - // TODO: Check this manually - assert.strictEqual(so.to_hex(), '64400000000000007B6540000000000001C8684000000000000315F1'); - }); - it('Parse the same array', function() { - const so = new SerializedObject('64400000000000007B6540000000000001C8684000000000000315F1'); - const parsed_object = types.Array.parse(so); - const comp = [ - { - TakerPays: '123' - }, - { - TakerGets: '456' - }, - { - Fee: '789' - } - ]; - assert.deepEqual(SerializedObject.jsonify_structure(parsed_object, ''), comp); - }); - it('Serialize 3-length array [{DestinationTag:123}); {QualityIn:456}, {Fee:789}]', function() { - const so = new SerializedObject(); - types.Array.serialize(so, [ - { - DestinationTag: 123 - }, - { - QualityIn: 456 - }, - { - Fee: 789 - } - ]); - // TODO: Check this manually - assert.strictEqual(so.to_hex(), '2E0000007B2014000001C8684000000000000315F1'); - }); - it('Parse the same array 2', function() { - const so = new SerializedObject('2E0000007B2014000001C8684000000000000315F1'); - const parsed_object = types.Array.parse(so); - const comp = [ - { - DestinationTag: 123 - }, - { - QualityIn: 456 - }, - { - Fee: '789' - } - ]; - // TODO: Is this correct? Return some things as integers, and others as objects? - assert.deepEqual(SerializedObject.jsonify_structure(parsed_object, ''), comp); - }); - }); -}); - -// vim:sw=2:sts=2:ts=8:et diff --git a/test/transaction-manager-test.js b/test/transaction-manager-test.js index aecd04c2..b904889b 100644 --- a/test/transaction-manager-test.js +++ b/test/transaction-manager-test.js @@ -6,7 +6,8 @@ const ws = require('ws'); const lodash = require('lodash'); const assert = require('assert-diff'); const Remote = require('ripple-lib').Remote; -const SerializedObject = require('ripple-lib').SerializedObject; +const binary = require('ripple-binary-codec'); +const utils = require('ripple-lib').utils; const Transaction = require('ripple-lib').Transaction; const TransactionManager = require('ripple-lib')._test.TransactionManager; @@ -335,11 +336,12 @@ describe('TransactionManager', function() { const binaryTx = lodash.extend({}, ACCOUNT_TX_TRANSACTION, { ledger_index: ACCOUNT_TX_TRANSACTION.tx.ledger_index, - tx_blob: SerializedObject.from_json(ACCOUNT_TX_TRANSACTION.tx).to_hex(), - meta: SerializedObject.from_json(ACCOUNT_TX_TRANSACTION.meta).to_hex() + tx_blob: binary.encode(ACCOUNT_TX_TRANSACTION.tx), + meta: binary.encode(ACCOUNT_TX_TRANSACTION.meta) }); - const hash = new SerializedObject(binaryTx.tx_blob).hash(0x54584E00).to_hex(); + const prefix = (0x54584E00).toString(16); + const hash = utils.sha512half(new Buffer(prefix + binaryTx.tx_blob, 'hex')); transaction.addId(hash); @@ -364,8 +366,8 @@ describe('TransactionManager', function() { const binaryTx = lodash.extend({}, ACCOUNT_TX_TRANSACTION, { ledger_index: ACCOUNT_TX_TRANSACTION.tx.ledger_index, - tx_blob: SerializedObject.from_json(ACCOUNT_TX_TRANSACTION.tx).to_hex(), - meta: SerializedObject.from_json(ACCOUNT_TX_TRANSACTION.meta).to_hex() + tx_blob: binary.encode(ACCOUNT_TX_TRANSACTION.tx), + meta: binary.encode(ACCOUNT_TX_TRANSACTION.meta) }); transactionManager._request = function() { @@ -417,9 +419,8 @@ describe('TransactionManager', function() { }); rippled.once('request_submit', function(m, req) { - assert.strictEqual(m.tx_blob, SerializedObject.from_json( - transaction.tx_json).to_hex()); - assert.strictEqual(new SerializedObject(m.tx_blob).to_json().Sequence, + assert.strictEqual(m.tx_blob, binary.encode(transaction.tx_json)); + assert.strictEqual(binary.decode(m.tx_blob).Sequence, ACCOUNT_INFO_RESPONSE.result.account_data.Sequence); assert.strictEqual(transactionManager.getPending().length(), 1); req.sendResponse(SUBMIT_RESPONSE, {id: m.id}); @@ -457,9 +458,8 @@ describe('TransactionManager', function() { }); rippled.once('request_submit', function(m, req) { - assert.strictEqual(m.tx_blob, SerializedObject.from_json( - transaction.tx_json).to_hex()); - assert.strictEqual(new SerializedObject(m.tx_blob).to_json().Sequence, + assert.strictEqual(m.tx_blob, binary.encode(transaction.tx_json)); + assert.strictEqual(binary.decode(m.tx_blob).Sequence, ACCOUNT_INFO_RESPONSE.result.account_data.Sequence); assert.strictEqual(transactionManager.getPending().length(), 1); req.sendResponse(SUBMIT_TEC_RESPONSE, {id: m.id}); @@ -500,7 +500,7 @@ describe('TransactionManager', function() { }); rippled.on('request_submit', function(m, req) { - const deserialized = new SerializedObject(m.tx_blob).to_json(); + const deserialized = binary.decode(m.tx_blob); switch (deserialized.TransactionType) { case 'Payment': @@ -570,8 +570,7 @@ describe('TransactionManager', function() { }); rippled.on('request_submit', function(m, req) { - assert.strictEqual(m.tx_blob, SerializedObject.from_json( - transaction.tx_json).to_hex()); + assert.strictEqual(m.tx_blob, binary.encode(transaction.tx_json)); assert.strictEqual(transactionManager.getPending().length(), 1); req.sendResponse(SUBMIT_TEF_RESPONSE, {id: m.id}); }); @@ -630,9 +629,8 @@ describe('TransactionManager', function() { }); rippled.on('request_submit', function(m, req) { - assert.strictEqual(m.tx_blob, SerializedObject.from_json( - transaction.tx_json).to_hex()); - assert.strictEqual(new SerializedObject(m.tx_blob).to_json().Sequence, + assert.strictEqual(m.tx_blob, binary.encode(transaction.tx_json)); + assert.strictEqual(binary.decode(m.tx_blob).Sequence, ACCOUNT_INFO_RESPONSE.result.account_data.Sequence); assert.strictEqual(transactionManager.getPending().length(), 1); req.sendResponse(SUBMIT_TEL_RESPONSE, {id: m.id}); @@ -737,9 +735,8 @@ describe('TransactionManager', function() { }); rippled.on('request_submit', function(m, req) { - assert.strictEqual(m.tx_blob, SerializedObject.from_json( - transaction.tx_json).to_hex()); - assert.strictEqual(new SerializedObject(m.tx_blob).to_json().Sequence, + assert.strictEqual(m.tx_blob, binary.encode(transaction.tx_json)); + assert.strictEqual(binary.decode(m.tx_blob).Sequence, ACCOUNT_INFO_RESPONSE.result.account_data.Sequence); assert.strictEqual(transactionManager.getPending().length(), 1); @@ -797,9 +794,8 @@ describe('TransactionManager', function() { }); rippled.on('request_submit', function(m, req) { - assert.strictEqual(m.tx_blob, SerializedObject.from_json( - transaction.tx_json).to_hex()); - assert.strictEqual(new SerializedObject(m.tx_blob).to_json().Sequence, + assert.strictEqual(m.tx_blob, binary.encode(transaction.tx_json)); + assert.strictEqual(binary.decode(m.tx_blob).Sequence, ACCOUNT_INFO_RESPONSE.result.account_data.Sequence); assert.strictEqual(transactionManager.getPending().length(), 1); req.sendResponse(SUBMIT_TEL_RESPONSE, {id: m.id}); @@ -867,9 +863,8 @@ describe('TransactionManager', function() { /* eslint-disable no-unused-vars */ rippled.on('request_submit', function(m, req) { - assert.strictEqual(m.tx_blob, SerializedObject.from_json( - transaction.tx_json).to_hex()); - assert.strictEqual(new SerializedObject(m.tx_blob).to_json().Sequence, + assert.strictEqual(m.tx_blob, binary.encode(transaction.tx_json)); + assert.strictEqual(binary.decode(m.tx_blob).Sequence, ACCOUNT_INFO_RESPONSE.result.account_data.Sequence); assert.strictEqual(transactionManager.getPending().length(), 1); diff --git a/test/transaction-queue-test.js b/test/transaction-queue-test.js index 0d38484d..391c1e94 100644 --- a/test/transaction-queue-test.js +++ b/test/transaction-queue-test.js @@ -1,11 +1,12 @@ -var assert = require('assert'); -var Transaction = require('ripple-lib').Transaction; -var TransactionQueue = require('ripple-lib').TransactionQueue; +'use strict'; +const assert = require('assert'); +const Transaction = require('ripple-lib').Transaction; +const TransactionQueue = require('ripple-lib')._test.TransactionQueue; describe('Transaction queue', function() { it('Push transaction', function() { - var queue = new TransactionQueue(); - var tx = new Transaction(); + const queue = new TransactionQueue(); + const tx = new Transaction(); queue.push(tx); @@ -13,8 +14,8 @@ describe('Transaction queue', function() { }); it('Remove transaction', function() { - var queue = new TransactionQueue(); - var tx = new Transaction(); + const queue = new TransactionQueue(); + const tx = new Transaction(); queue.push(tx); queue.remove(tx); @@ -23,8 +24,8 @@ describe('Transaction queue', function() { }); it('Remove transaction by ID', function() { - var queue = new TransactionQueue(); - var tx = new Transaction(); + const queue = new TransactionQueue(); + const tx = new Transaction(); queue.push(tx); @@ -33,32 +34,38 @@ describe('Transaction queue', function() { '2A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B' ]; - queue.remove('3A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'); + queue.remove( + '3A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'); assert.strictEqual(queue.length(), 1); - queue.remove('2A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'); + queue.remove( + '2A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'); assert.strictEqual(queue.length(), 0); }); it('Add sequence', function() { - var queue = new TransactionQueue(); + const queue = new TransactionQueue(); queue.addReceivedSequence(1); assert(queue.hasSequence(1)); }); it('Add ID', function() { - var queue = new TransactionQueue(); - var tx = new Transaction(); - queue.addReceivedId('1A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B', tx); - assert.strictEqual(queue.getReceived('2A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), void(0)); - assert.strictEqual(queue.getReceived('1A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), tx); + const queue = new TransactionQueue(); + const tx = new Transaction(); + queue.addReceivedId( + '1A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B', tx); + assert.strictEqual(queue.getReceived( + '2A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), + undefined); + assert.strictEqual(queue.getReceived( + '1A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), tx); }); it('Get submission', function() { - var queue = new TransactionQueue(); - var tx = new Transaction(); + const queue = new TransactionQueue(); + const tx = new Transaction(); queue.push(tx); @@ -67,16 +74,20 @@ describe('Transaction queue', function() { '2A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B' ]; - assert.strictEqual(queue.getSubmission('1A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), tx); - assert.strictEqual(queue.getSubmission('2A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), tx); - assert.strictEqual(queue.getSubmission('3A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), void(0)); + assert.strictEqual(queue.getSubmission( + '1A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), tx); + assert.strictEqual(queue.getSubmission( + '2A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), tx); + assert.strictEqual(queue.getSubmission( + '3A4DEBF37496464145AA301F0AA77712E3A2BFE3480D24C3584663F800B85B5B'), + undefined); }); it('Iterate over queue', function() { - var queue = new TransactionQueue(); - var count = 10; + const queue = new TransactionQueue(); + let count = 10; - for (var i=0; i ${test.expected}`); - - result = result[test.outputMethod](); - - if (test.expected === 'null') { - // XXX - // UInt160.to_json() returns NaN rather than null if input is invalid - assert.strictEqual(lodash.isNaN(result), true, resultError(test, result)); - } else { - assert.deepEqual(result, test.expected, resultError(test, result)); - } - }); - }); - }); -} - -describe('UInt160', function() { - it('Parse 0 export', function() { - assert.strictEqual(UInt160.ACCOUNT_ZERO, UInt160.from_generic('0').set_version(0).to_json()); - }); - it('Parse 1', function() { - assert.deepEqual(UInt160.ACCOUNT_ONE, UInt160.from_generic('1').set_version(0).to_json()); - }); - it('Parse rrrrrrrrrrrrrrrrrrrrrhoLvTp export', function() { - assert.strictEqual(UInt160.ACCOUNT_ZERO, UInt160.from_json('rrrrrrrrrrrrrrrrrrrrrhoLvTp').to_json()); - }); - it('Parse rrrrrrrrrrrrrrrrrrrrBZbvji export', function() { - assert.strictEqual(UInt160.ACCOUNT_ONE, UInt160.from_json('rrrrrrrrrrrrrrrrrrrrBZbvji').to_json()); - }); - it('is_valid rrrrrrrrrrrrrrrrrrrrrhoLvTp', function() { - assert(UInt160.is_valid('rrrrrrrrrrrrrrrrrrrrrhoLvTp')); - }); - it('!is_valid rrrrrrrrrrrrrrrrrrrrrhoLvT', function() { - assert(!UInt160.is_valid('rrrrrrrrrrrrrrrrrrrrrhoLvT')); - }); -}); - -['UInt128', 'UInt160', 'UInt256'].forEach(makeTests);