mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-14 09:35:48 +00:00
Compare commits
26 Commits
0.12.1-rc6
...
0.12.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef51490a1a | ||
|
|
c40d643238 | ||
|
|
6f23c88567 | ||
|
|
56958a6242 | ||
|
|
74dac97b36 | ||
|
|
2f2e41c781 | ||
|
|
8c872f71c6 | ||
|
|
b40b496866 | ||
|
|
569fec296e | ||
|
|
56d8aa797a | ||
|
|
fe7e30b737 | ||
|
|
a114281c60 | ||
|
|
d09548d04d | ||
|
|
a02b8e3e5c | ||
|
|
2c3f9ca202 | ||
|
|
587782820d | ||
|
|
8fad048569 | ||
|
|
f7c35b118e | ||
|
|
65a669bbb2 | ||
|
|
9985acc539 | ||
|
|
f1f0a43f21 | ||
|
|
6b856c3cc5 | ||
|
|
d92888ed73 | ||
|
|
0357840654 | ||
|
|
53cae3a66d | ||
|
|
949a1ca4ae |
16
HISTORY.md
16
HISTORY.md
@@ -1,3 +1,19 @@
|
||||
##0.12.3
|
||||
|
||||
+ [Add getLedgerSequence to Remote](https://github.com/ripple/ripple-lib/commit/d09548d04d3238fca653d482ec1d5faa7254559a)
|
||||
|
||||
+ [Improve randomness when generating ECDSA signatures](https://github.com/ripple/ripple-lib/commit/fe7e30b737ead6e71adfa466f5835ba546feab31)
|
||||
|
||||
+ [Improve SerializedObject.append performance](https://github.com/ripple/ripple-lib/commit/f7c35b118ebba549a64bcaa1a0629385ec6dbf6f)
|
||||
|
||||
+ [Add `Amount.scale`. Multiply an amount’s value by a scale factor](https://github.com/ripple/ripple-lib/commit/74dac97b368493056474468520f05671f458a69f)
|
||||
|
||||
|
||||
##0.12.2
|
||||
|
||||
+ [Check that stack trace is available, fixes logging in browser](https://github.com/ripple/ripple-lib/commit/53cae3a66d48e88e8a6bbb96d6489ce7b9e22975)
|
||||
|
||||
|
||||
##0.12.1
|
||||
|
||||
**Breaking Changes**
|
||||
|
||||
2
npm-shrinkwrap.json
generated
2
npm-shrinkwrap.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.12.1-rc6",
|
||||
"version": "0.12.3",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "0.9.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.12.1-rc6",
|
||||
"version": "0.12.3",
|
||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||
"files": [
|
||||
"src/js/*",
|
||||
@@ -27,7 +27,7 @@
|
||||
"devDependencies": {
|
||||
"assert-diff": "^1.0.1",
|
||||
"coveralls": "~2.10.0",
|
||||
"eslint": "^0.13.0",
|
||||
"eslint": "^0.18.0",
|
||||
"gulp": "~3.8.10",
|
||||
"gulp-bump": "~0.1.13",
|
||||
"gulp-clean-dest": "^0.1.0",
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var Amount = require('../src/js/ripple').Amount;
|
||||
var Ledger = require('../src/js/ripple/ledger').Ledger;
|
||||
|
||||
function parse_options(from, flags) {
|
||||
var argv = from.slice(),
|
||||
opts = {argv:argv};
|
||||
opts_ = {argv: argv};
|
||||
|
||||
flags.forEach(function(f) {
|
||||
// Do we have the flag?
|
||||
var flag_index = argv.indexOf('--' + f);
|
||||
// normalize the name of the flag
|
||||
f = f.replace('-', '_');
|
||||
// opts has Boolean value for normalized flag key
|
||||
opts[f] = !!~flag_index;
|
||||
if (opts[f]) {
|
||||
// opts_ has Boolean value for normalized flag key
|
||||
opts_[f] = flag_index !== -1;
|
||||
if (opts_[f]) {
|
||||
// remove the flag from the argv
|
||||
argv.splice(flag_index, 1);
|
||||
}
|
||||
});
|
||||
return opts;
|
||||
return opts_;
|
||||
}
|
||||
|
||||
var opts = parse_options(process.argv.slice(2), // remove `node` and `this.js`
|
||||
['sanity-test']);
|
||||
|
||||
if (opts.argv.length < 1) {
|
||||
console.error("Usage: scripts/verify_ledger_json path/to/ledger.json");
|
||||
console.error(" optional: --sanity-test (json>binary>json>binary)");
|
||||
console.error('Usage: scripts/verify_ledger_json path/to/ledger.json');
|
||||
console.error(' optional: --sanity-test (json>binary>json>binary)');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -36,14 +39,27 @@ var ledger = Ledger.from_json(JSON.parse(json));
|
||||
// before finally serializing for hashing. This is mostly to expose any issues
|
||||
// with ripple-libs binary <--> json codecs.
|
||||
if (opts.sanity_test) {
|
||||
console.log("All accountState nodes will be processed from " +
|
||||
"json->binary->json->binary. This may take some time " +
|
||||
"with large ledgers.");
|
||||
console.log('All accountState nodes will be processed from ' +
|
||||
'json->binary->json->binary. This may take some time ' +
|
||||
'with large ledgers.');
|
||||
}
|
||||
|
||||
console.log("Transaction hash in header: " + ledger.ledger_json.transaction_hash);
|
||||
console.log("Calculated transaction hash: " + ledger.calc_tx_hash().to_hex());
|
||||
console.log("Account state hash in header: " + ledger.ledger_json.account_hash);
|
||||
console.log("Calculated account state hash: " + ledger.calc_account_hash(
|
||||
{sanity_test:opts.sanity_test})
|
||||
.to_hex());
|
||||
// To recompute the hashes of some ledgers, we must allow values that slipped in
|
||||
// before strong policies were in place.
|
||||
Amount.strict_mode = false;
|
||||
|
||||
console.log('Transaction hash in header: ' +
|
||||
ledger.ledger_json.transaction_hash);
|
||||
console.log('Calculated transaction hash: ' +
|
||||
ledger.calc_tx_hash().to_hex());
|
||||
|
||||
console.log('Account state hash in header: ' +
|
||||
ledger.ledger_json.account_hash);
|
||||
|
||||
if (ledger.ledger_json.accountState) {
|
||||
console.log('Calculated account state hash: ' +
|
||||
ledger.calc_account_hash({sanity_test: opts.sanity_test})
|
||||
.to_hex());
|
||||
} else {
|
||||
console.log('Ledger has no accountState');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
// Represent Ripple amounts and currencies.
|
||||
// - Numbers in hex are big-endian.
|
||||
@@ -156,6 +156,10 @@ Amount.prototype.multiply = function(multiplicand) {
|
||||
return this._copy(this._value.times(multiplyBy));
|
||||
};
|
||||
|
||||
Amount.prototype.scale = function(scaleFactor) {
|
||||
return this._copy(this._value.times(scaleFactor));
|
||||
};
|
||||
|
||||
Amount.prototype.divide = function(divisor) {
|
||||
var divisorAmount = Amount.from_json(divisor);
|
||||
if (!this.is_valid()) {
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
var sjcl = require('./utils').sjcl;
|
||||
'use strict';
|
||||
|
||||
/*eslint new-cap: 1*/
|
||||
|
||||
var sjcl = require('./utils').sjcl;
|
||||
|
||||
var UInt160 = require('./uint160').UInt160;
|
||||
var UInt256 = require('./uint256').UInt256;
|
||||
var Base = require('./base').Base;
|
||||
var Base = require('./base').Base;
|
||||
|
||||
function KeyPair() {
|
||||
this._curve = sjcl.ecc.curves.k256;
|
||||
this._curve = sjcl.ecc.curves.k256;
|
||||
this._secret = null;
|
||||
this._pubkey = null;
|
||||
};
|
||||
}
|
||||
|
||||
KeyPair.from_bn_secret = function(j) {
|
||||
return (j instanceof this) ? j.clone() : (new this()).parse_bn_secret(j);
|
||||
@@ -20,15 +24,16 @@ KeyPair.prototype.parse_bn_secret = function(j) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns public key as sjcl public key.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @return {sjcl.ecc.ecdsa.publicKey} public key
|
||||
*/
|
||||
KeyPair.prototype._pub = function() {
|
||||
var curve = this._curve;
|
||||
|
||||
if (!this._pubkey && this._secret) {
|
||||
var exponent = this._secret._exponent;
|
||||
|
||||
this._pubkey = new sjcl.ecc.ecdsa.publicKey(curve, curve.G.mult(exponent));
|
||||
}
|
||||
|
||||
@@ -36,9 +41,9 @@ KeyPair.prototype._pub = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns public key in compressed format as bit array.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @return {sjcl.bitArray} public key bits in compressed form
|
||||
*/
|
||||
KeyPair.prototype._pub_bits = function() {
|
||||
var pub = this._pub();
|
||||
@@ -56,9 +61,7 @@ KeyPair.prototype._pub_bits = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns public key as hex.
|
||||
*
|
||||
* Key will be returned as a compressed pubkey - 33 bytes converted to hex.
|
||||
* @return {String} public key bytes in compressed form, hex encoded.
|
||||
*/
|
||||
KeyPair.prototype.to_hex_pub = function() {
|
||||
var bits = this._pub_bits();
|
||||
@@ -70,7 +73,7 @@ KeyPair.prototype.to_hex_pub = function() {
|
||||
return sjcl.codec.hex.fromBits(bits).toUpperCase();
|
||||
};
|
||||
|
||||
function SHA256_RIPEMD160(bits) {
|
||||
function sha256_ripemd160(bits) {
|
||||
return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));
|
||||
}
|
||||
|
||||
@@ -81,7 +84,7 @@ KeyPair.prototype.get_address = function() {
|
||||
return null;
|
||||
}
|
||||
|
||||
var hash = SHA256_RIPEMD160(bits);
|
||||
var hash = sha256_ripemd160(bits);
|
||||
|
||||
var address = UInt160.from_bits(hash);
|
||||
address.set_version(Base.VER_ACCOUNT_ID);
|
||||
@@ -89,8 +92,9 @@ KeyPair.prototype.get_address = function() {
|
||||
};
|
||||
|
||||
KeyPair.prototype.sign = function(hash) {
|
||||
var PARANOIA_256_BITS = 6; // sjcl constant for ensuring 256 bits of entropy
|
||||
hash = UInt256.from_json(hash);
|
||||
var sig = this._secret.sign(hash.to_bits(), 0);
|
||||
var sig = this._secret.sign(hash.to_bits(), PARANOIA_256_BITS);
|
||||
sig = this._secret.canonicalizeSignature(sig);
|
||||
return this._secret.encodeDER(sig);
|
||||
};
|
||||
|
||||
@@ -69,13 +69,15 @@ Log.prototype.error = Log.makeLevel(4);
|
||||
*/
|
||||
|
||||
function getLogInfo(message, args) {
|
||||
var stack = new Error().stack;
|
||||
|
||||
return [
|
||||
// Timestamp
|
||||
'[' + new Date().toISOString() + ']',
|
||||
message,
|
||||
'--',
|
||||
// Location
|
||||
(new Error()).stack.split('\n')[4].replace(/^\s+/, ''),
|
||||
(typeof stack === 'string') ? stack.split('\n')[4].replace(/^\s+/, '') : '',
|
||||
'\n'
|
||||
].concat(args);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
// Interface to manage connections to rippled servers
|
||||
//
|
||||
@@ -517,8 +517,13 @@ Remote.prototype.disconnect = function(callback) {
|
||||
Remote.prototype._handleMessage = function(message, server) {
|
||||
try {
|
||||
message = JSON.parse(message);
|
||||
|
||||
/*eslint-disable no-empty*/
|
||||
} catch (e) {
|
||||
// TODO: why are we suppressing this?
|
||||
console.error(e);
|
||||
}
|
||||
/*eslint-enable no-empty*/
|
||||
|
||||
if (!Remote.isValidMessage(message)) {
|
||||
// Unexpected response from remote.
|
||||
@@ -548,6 +553,15 @@ Remote.prototype._handleMessage = function(message, server) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Remote.prototype.getLedgerSequence = function() {
|
||||
if (!this._ledger_current_index) {
|
||||
throw new Error('Ledger sequence has not yet been initialized');
|
||||
}
|
||||
return this._ledger_current_index;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle server ledger_closed event
|
||||
*
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// Seed support
|
||||
//
|
||||
|
||||
var extend = require('extend');
|
||||
var utils = require('./utils');
|
||||
var sjcl = utils.sjcl;
|
||||
var utils = require('./utils');
|
||||
var sjcl = utils.sjcl;
|
||||
|
||||
var Base = require('./base').Base;
|
||||
var UInt = require('./uint').UInt;
|
||||
var UInt256 = require('./uint256').UInt256;
|
||||
var Base = require('./base').Base;
|
||||
var UInt = require('./uint').UInt;
|
||||
var UInt160 = require('./uint160').UInt160;
|
||||
var KeyPair = require('./keypair').KeyPair;
|
||||
|
||||
var Seed = extend(function () {
|
||||
var Seed = extend(function() {
|
||||
this._curve = sjcl.ecc.curves.k256;
|
||||
this._value = NaN;
|
||||
}, UInt);
|
||||
@@ -23,7 +24,7 @@ Seed.prototype.constructor = Seed;
|
||||
|
||||
// value = NaN on error.
|
||||
// One day this will support rfc1751 too.
|
||||
Seed.prototype.parse_json = function (j) {
|
||||
Seed.prototype.parse_json = function(j) {
|
||||
if (typeof j === 'string') {
|
||||
if (!j.length) {
|
||||
this._value = NaN;
|
||||
@@ -43,7 +44,7 @@ Seed.prototype.parse_json = function (j) {
|
||||
return this;
|
||||
};
|
||||
|
||||
Seed.prototype.parse_passphrase = function (j) {
|
||||
Seed.prototype.parse_passphrase = function(j) {
|
||||
if (typeof j !== 'string') {
|
||||
throw new Error('Passphrase must be a string');
|
||||
}
|
||||
@@ -56,7 +57,7 @@ Seed.prototype.parse_passphrase = function (j) {
|
||||
return this;
|
||||
};
|
||||
|
||||
Seed.prototype.to_json = function () {
|
||||
Seed.prototype.to_json = function() {
|
||||
if (!(this.is_valid())) {
|
||||
return NaN;
|
||||
}
|
||||
@@ -68,20 +69,18 @@ Seed.prototype.to_json = function () {
|
||||
|
||||
function append_int(a, i) {
|
||||
return [].concat(a, i >> 24, (i >> 16) & 0xff, (i >> 8) & 0xff, i & 0xff);
|
||||
};
|
||||
}
|
||||
|
||||
function firstHalfOfSHA512(bytes) {
|
||||
return sjcl.bitArray.bitSlice(
|
||||
sjcl.hash.sha512.hash(sjcl.codec.bytes.toBits(bytes)),
|
||||
0, 256
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
function SHA256_RIPEMD160(bits) {
|
||||
return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));
|
||||
};
|
||||
|
||||
/**
|
||||
// Removed a `*` so this JSDoc-ish syntax is ignored.
|
||||
// This will soon all change anyway.
|
||||
/*
|
||||
* @param account
|
||||
* {undefined} take first, default, KeyPair
|
||||
*
|
||||
@@ -92,10 +91,11 @@ function SHA256_RIPEMD160(bits) {
|
||||
* that is desired.
|
||||
*
|
||||
* @param maxLoops (optional)
|
||||
* {Number} specifies the amount of attempts taken to generate
|
||||
* a matching KeyPair
|
||||
* {Number} specifies the amount of attempts taken
|
||||
* to generate a matching KeyPair
|
||||
*
|
||||
*/
|
||||
Seed.prototype.get_key = function (account, maxLoops) {
|
||||
Seed.prototype.get_key = function(account, maxLoops) {
|
||||
var account_number = 0, address;
|
||||
var max_loops = maxLoops || 1;
|
||||
|
||||
@@ -105,7 +105,7 @@ Seed.prototype.get_key = function (account, maxLoops) {
|
||||
if (account) {
|
||||
if (typeof account === 'number') {
|
||||
account_number = account;
|
||||
max_loops = account_number+1;
|
||||
max_loops = account_number + 1;
|
||||
} else {
|
||||
address = UInt160.from_json(account);
|
||||
}
|
||||
@@ -116,7 +116,8 @@ Seed.prototype.get_key = function (account, maxLoops) {
|
||||
var i = 0;
|
||||
|
||||
do {
|
||||
private_gen = sjcl.bn.fromBits(firstHalfOfSHA512(append_int(this.to_bytes(), i)));
|
||||
private_gen = sjcl.bn.fromBits(
|
||||
firstHalfOfSHA512(append_int(this.to_bytes(), i)));
|
||||
i++;
|
||||
} while (!curve.r.greaterEquals(private_gen));
|
||||
|
||||
@@ -130,7 +131,13 @@ Seed.prototype.get_key = function (account, maxLoops) {
|
||||
i = 0;
|
||||
|
||||
do {
|
||||
sec = sjcl.bn.fromBits(firstHalfOfSHA512(append_int(append_int(public_gen.toBytesCompressed(), account_number), i)));
|
||||
sec = sjcl.bn.fromBits(
|
||||
firstHalfOfSHA512(
|
||||
append_int(
|
||||
append_int(public_gen.toBytesCompressed(), account_number)
|
||||
,
|
||||
i
|
||||
)));
|
||||
i++;
|
||||
} while (!curve.r.greaterEquals(sec));
|
||||
|
||||
@@ -141,12 +148,13 @@ Seed.prototype.get_key = function (account, maxLoops) {
|
||||
if (max_loops-- <= 0) {
|
||||
// We are almost certainly looking for an account that would take same
|
||||
// value of $too_long {forever, ...}
|
||||
throw new Error('Too many loops looking for KeyPair yielding '+
|
||||
address.to_json() +' from ' + this.to_json());
|
||||
throw new Error('Too many loops looking for KeyPair yielding ' +
|
||||
address.to_json() + ' from ' + this.to_json());
|
||||
}
|
||||
|
||||
} while (address && !key_pair.get_address().equals(address));
|
||||
return key_pair;
|
||||
|
||||
return key_pair;
|
||||
};
|
||||
|
||||
exports.Seed = Seed;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var extend = require('extend');
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var extend = require('extend');
|
||||
var binformat = require('./binformat');
|
||||
var stypes = require('./serializedtypes');
|
||||
var Crypt = require('./crypt').Crypt;
|
||||
var utils = require('./utils');
|
||||
var stypes = require('./serializedtypes');
|
||||
var Crypt = require('./crypt').Crypt;
|
||||
var utils = require('./utils');
|
||||
|
||||
var sjcl = utils.sjcl;
|
||||
|
||||
@@ -29,12 +31,14 @@ Object.keys(binformat.ter).forEach(function(key) {
|
||||
function normalize_sjcl_bn_hex(string) {
|
||||
var hex = string.slice(2); // remove '0x' prefix
|
||||
// now strip leading zeros
|
||||
var i = _.findIndex(hex, function(c) { return c !== '0'; });
|
||||
var i = _.findIndex(hex, function(c) {
|
||||
return c !== '0';
|
||||
});
|
||||
return i >= 0 ? hex.slice(i) : '0';
|
||||
}
|
||||
|
||||
function SerializedObject(buf) {
|
||||
if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf)) ) {
|
||||
if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf))) {
|
||||
this.buffer = buf;
|
||||
} else if (typeof buf === 'string') {
|
||||
this.buffer = sjcl.codec.bytes.fromBits(sjcl.codec.hex.toBits(buf));
|
||||
@@ -49,7 +53,7 @@ function SerializedObject(buf) {
|
||||
SerializedObject.from_json = function(obj) {
|
||||
// Create a copy of the object so we don't modify it
|
||||
obj = extend(true, {}, obj);
|
||||
var so = new SerializedObject();
|
||||
var so = new SerializedObject();
|
||||
var typedef;
|
||||
|
||||
if (typeof obj.TransactionType === 'number') {
|
||||
@@ -107,7 +111,7 @@ SerializedObject.check_no_missing_fields = function(typedef, obj) {
|
||||
var field = spec[0];
|
||||
var requirement = spec[1];
|
||||
|
||||
if (binformat.REQUIRED === requirement && obj[field] === void(0)) {
|
||||
if (binformat.REQUIRED === requirement && obj[field] === undefined) {
|
||||
missing_fields.push(field);
|
||||
}
|
||||
}
|
||||
@@ -115,9 +119,9 @@ SerializedObject.check_no_missing_fields = function(typedef, obj) {
|
||||
if (missing_fields.length > 0) {
|
||||
var object_name;
|
||||
|
||||
if (obj.TransactionType !== void(0)) {
|
||||
if (obj.TransactionType !== undefined) {
|
||||
object_name = SerializedObject.lookup_type_tx(obj.TransactionType);
|
||||
} else if (obj.LedgerEntryType != null){
|
||||
} else if (obj.LedgerEntryType !== undefined) {
|
||||
object_name = SerializedObject.lookup_type_le(obj.LedgerEntryType);
|
||||
} else {
|
||||
object_name = 'TransactionMetaData';
|
||||
@@ -133,7 +137,17 @@ SerializedObject.prototype.append = function(bytes) {
|
||||
bytes = bytes.buffer;
|
||||
}
|
||||
|
||||
this.buffer = this.buffer.concat(bytes);
|
||||
// Make sure both buffer and bytes are Array. Either could potentially be a
|
||||
// Buffer.
|
||||
if (Array.isArray(this.buffer) && Array.isArray(bytes)) {
|
||||
// Array::concat is horribly slow where buffer length is 100 kbytes + One
|
||||
// transaction with 1100 affected nodes took around 23 seconds to convert
|
||||
// from json to bytes.
|
||||
Array.prototype.push.apply(this.buffer, bytes);
|
||||
} else {
|
||||
this.buffer = this.buffer.concat(bytes);
|
||||
}
|
||||
|
||||
this.pointer += bytes.length;
|
||||
};
|
||||
|
||||
@@ -216,14 +230,17 @@ SerializedObject.jsonify_structure = function(structure, field_name) {
|
||||
if (typeof structure.to_json === 'function') {
|
||||
output = structure.to_json();
|
||||
} else if (structure instanceof sjcl.bn) {
|
||||
output = ('0000000000000000' + normalize_sjcl_bn_hex(structure.toString()).toUpperCase()).slice(-16);
|
||||
output = ('0000000000000000' +
|
||||
normalize_sjcl_bn_hex(structure.toString())
|
||||
.toUpperCase()
|
||||
).slice(-16);
|
||||
} else {
|
||||
//new Array or Object
|
||||
// new Array or Object
|
||||
output = new structure.constructor();
|
||||
|
||||
var keys = Object.keys(structure);
|
||||
|
||||
for (var i=0, l=keys.length; i<l; i++) {
|
||||
for (var i = 0, l = keys.length; i < l; i++) {
|
||||
var key = keys[i];
|
||||
output[key] = SerializedObject.jsonify_structure(structure[key], key);
|
||||
}
|
||||
@@ -256,7 +273,7 @@ SerializedObject.prototype.hash = function(prefix) {
|
||||
var sign_buffer = new SerializedObject();
|
||||
|
||||
// Add hashing prefix
|
||||
if ('undefined' !== typeof prefix) {
|
||||
if (typeof prefix !== 'undefined') {
|
||||
stypes.Int32.serialize(sign_buffer, prefix);
|
||||
}
|
||||
|
||||
@@ -272,17 +289,11 @@ SerializedObject.prototype.hash = function(prefix) {
|
||||
SerializedObject.prototype.signing_hash = SerializedObject.prototype.hash;
|
||||
|
||||
SerializedObject.prototype.serialize_field = function(spec, obj) {
|
||||
var name = spec[0];
|
||||
var name = spec[0];
|
||||
var presence = spec[1];
|
||||
var field_id = spec[2];
|
||||
var Type = stypes[spec[3]];
|
||||
|
||||
if (typeof obj[name] !== 'undefined') {
|
||||
// ST: Old serialization code
|
||||
//this.append(SerializedObject.get_field_header(Type.id, field_id));
|
||||
try {
|
||||
// ST: Old serialization code
|
||||
//Type.serialize(this, obj[name]);
|
||||
stypes.serialize(this, name, obj[name]);
|
||||
} catch (e) {
|
||||
// Add field name to message and rethrow
|
||||
@@ -295,7 +306,7 @@ SerializedObject.prototype.serialize_field = function(spec, obj) {
|
||||
};
|
||||
|
||||
SerializedObject.get_field_header = function(type_id, field_id) {
|
||||
var buffer = [ 0 ];
|
||||
var buffer = [0];
|
||||
|
||||
if (type_id > 0xF) {
|
||||
buffer.push(type_id & 0xFF);
|
||||
@@ -328,7 +339,7 @@ SerializedObject.lookup_type_tx = function(id) {
|
||||
return TRANSACTION_TYPES[id];
|
||||
};
|
||||
|
||||
SerializedObject.lookup_type_le = function (id) {
|
||||
SerializedObject.lookup_type_le = function(id) {
|
||||
assert(typeof id === 'number');
|
||||
return LEDGER_ENTRY_TYPES[id];
|
||||
};
|
||||
|
||||
@@ -1,30 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var sjcl = require('./utils').sjcl;
|
||||
var stypes = require('./serializedtypes');
|
||||
var hashprefixes = require('./hashprefixes');
|
||||
|
||||
var UInt256 = require('./uint256').UInt256;
|
||||
var SerializedObject = require('./serializedobject').SerializedObject;
|
||||
|
||||
function SHAMap() {
|
||||
this.root = new SHAMapTreeNodeInner(0);
|
||||
};
|
||||
|
||||
SHAMap.prototype.add_item = function(tag, node, type) {
|
||||
var node = new SHAMapTreeNodeLeaf(tag, node, type);
|
||||
this.root.add_item(tag, node);
|
||||
};
|
||||
|
||||
SHAMap.prototype.hash = function() {
|
||||
return this.root.hash();
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract class representing a node in a SHAMap tree.
|
||||
*
|
||||
* Can be either SHAMapTreeNodeInner or SHAMapTreeNodeLeaf.
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
function SHAMapTreeNode() { };
|
||||
function SHAMapTreeNode() { }
|
||||
|
||||
SHAMapTreeNode.TYPE_INNER = 1;
|
||||
SHAMapTreeNode.TYPE_TRANSACTION_NM = 2;
|
||||
@@ -32,11 +21,17 @@ SHAMapTreeNode.TYPE_TRANSACTION_MD = 3;
|
||||
SHAMapTreeNode.TYPE_ACCOUNT_STATE = 4;
|
||||
|
||||
/**
|
||||
* @param tag {String} 64 hexadecimal characters
|
||||
* @param {String} tag (64 hexadecimal characters)
|
||||
* @param {SHAMapTreeNode} node
|
||||
* @return {void}
|
||||
* @virtual
|
||||
*/
|
||||
/*eslint-disable no-unused-vars*/
|
||||
SHAMapTreeNode.prototype.add_item = function(tag, node) {
|
||||
throw new Error('Called unimplemented virtual method SHAMapTreeNode#add_item.');
|
||||
throw new Error(
|
||||
'Called unimplemented virtual method SHAMapTreeNode#add_item.');
|
||||
};
|
||||
/*eslint-enable no-unused-vars*/
|
||||
|
||||
SHAMapTreeNode.prototype.hash = function() {
|
||||
throw new Error('Called unimplemented virtual method SHAMapTreeNode#hash.');
|
||||
@@ -44,6 +39,8 @@ SHAMapTreeNode.prototype.hash = function() {
|
||||
|
||||
/**
|
||||
* Inner (non-leaf) node in a SHAMap tree.
|
||||
* @param {Number} depth (i.e. how many parent inner nodes)
|
||||
* @class
|
||||
*/
|
||||
function SHAMapTreeNodeInner(depth) {
|
||||
SHAMapTreeNode.call(this);
|
||||
@@ -51,7 +48,7 @@ function SHAMapTreeNodeInner(depth) {
|
||||
this.leaves = {};
|
||||
|
||||
this.type = SHAMapTreeNode.INNER;
|
||||
this.depth = depth == null ? 0 : depth;
|
||||
this.depth = depth === undefined ? 0 : depth;
|
||||
|
||||
this.empty = true;
|
||||
}
|
||||
@@ -59,9 +56,11 @@ function SHAMapTreeNodeInner(depth) {
|
||||
util.inherits(SHAMapTreeNodeInner, SHAMapTreeNode);
|
||||
|
||||
/**
|
||||
* @param tag {String} (equates to a ledger entries `index`)
|
||||
* @param {String} tag (equates to a ledger entry `index`)
|
||||
* @param {SHAMapTreeNode} node (to add)
|
||||
* @return {void}
|
||||
*/
|
||||
SHAMapTreeNodeInner.prototype.add_item = function (tag, node) {
|
||||
SHAMapTreeNodeInner.prototype.add_item = function(tag, node) {
|
||||
var depth = this.depth;
|
||||
var existing_node = this.get_node(tag[depth]);
|
||||
|
||||
@@ -72,7 +71,8 @@ SHAMapTreeNodeInner.prototype.add_item = function (tag, node) {
|
||||
existing_node.add_item(tag, node);
|
||||
} else if (existing_node.tag === tag) {
|
||||
// Collision
|
||||
throw new Error('Tried to add a node to a SHAMap that was already in there.');
|
||||
throw new Error(
|
||||
'Tried to add a node to a SHAMap that was already in there.');
|
||||
} else {
|
||||
// Turn it into an inner node
|
||||
var new_inner_node = new SHAMapTreeNodeInner(depth + 1);
|
||||
@@ -92,6 +92,9 @@ SHAMapTreeNodeInner.prototype.add_item = function (tag, node) {
|
||||
|
||||
/**
|
||||
* Overwrite the node that is currently in a given slot.
|
||||
* @param {String} slot (a character 0-F)
|
||||
* @param {SHAMapTreeNode} node (to place)
|
||||
* @return {void}
|
||||
*/
|
||||
SHAMapTreeNodeInner.prototype.set_node = function(slot, node) {
|
||||
this.leaves[slot] = node;
|
||||
@@ -108,9 +111,8 @@ SHAMapTreeNodeInner.prototype.hash = function() {
|
||||
}
|
||||
|
||||
var hash_buffer = new SerializedObject();
|
||||
var buffer = [ ];
|
||||
|
||||
for (var i=0; i<16; i++) {
|
||||
for (var i = 0; i < 16; i++) {
|
||||
var leafHash = UInt256.from_hex(UInt256.HEX_ZERO);
|
||||
var slot = i.toString(16).toUpperCase();
|
||||
|
||||
@@ -128,6 +130,10 @@ SHAMapTreeNodeInner.prototype.hash = function() {
|
||||
|
||||
/**
|
||||
* Leaf node in a SHAMap tree.
|
||||
* @param {String} tag (equates to a ledger entry `index`)
|
||||
* @param {SerializedObject} node (bytes of account state, transaction etc)
|
||||
* @param {Number} type (one of TYPE_ACCOUNT_STATE, TYPE_TRANSACTION_MD etc)
|
||||
* @class
|
||||
*/
|
||||
function SHAMapTreeNodeLeaf(tag, node, type) {
|
||||
SHAMapTreeNode.call(this);
|
||||
@@ -140,11 +146,11 @@ function SHAMapTreeNodeLeaf(tag, node, type) {
|
||||
this.tag_bytes = UInt256.from_hex(this.tag).to_bytes();
|
||||
this.type = type;
|
||||
this.node = node;
|
||||
};
|
||||
}
|
||||
|
||||
util.inherits(SHAMapTreeNodeLeaf, SHAMapTreeNode);
|
||||
|
||||
SHAMapTreeNodeLeaf.prototype.hash = function () {
|
||||
SHAMapTreeNodeLeaf.prototype.hash = function() {
|
||||
var buffer = new SerializedObject();
|
||||
switch (this.type) {
|
||||
case SHAMapTreeNode.TYPE_ACCOUNT_STATE:
|
||||
@@ -162,6 +168,19 @@ SHAMapTreeNodeLeaf.prototype.hash = function () {
|
||||
}
|
||||
};
|
||||
|
||||
function SHAMap() {
|
||||
this.root = new SHAMapTreeNodeInner(0);
|
||||
}
|
||||
|
||||
SHAMap.prototype.add_item = function(tag, node, type) {
|
||||
node = new SHAMapTreeNodeLeaf(tag, node, type);
|
||||
this.root.add_item(tag, node);
|
||||
};
|
||||
|
||||
SHAMap.prototype.hash = function() {
|
||||
return this.root.hash();
|
||||
};
|
||||
|
||||
exports.SHAMap = SHAMap;
|
||||
exports.SHAMapTreeNode = SHAMapTreeNode;
|
||||
exports.SHAMapTreeNodeInner = SHAMapTreeNodeInner;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
var util = require('util');
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var utils = require('./utils');
|
||||
var sjcl = require('./utils').sjcl;
|
||||
var Amount = require('./amount').Amount;
|
||||
var Currency = require('./amount').Currency;
|
||||
var UInt160 = require('./amount').UInt160;
|
||||
var Seed = require('./seed').Seed;
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var utils = require('./utils');
|
||||
var sjcl = require('./utils').sjcl;
|
||||
var Amount = require('./amount').Amount;
|
||||
var Currency = require('./amount').Currency;
|
||||
var UInt160 = require('./amount').UInt160;
|
||||
var Seed = require('./seed').Seed;
|
||||
var SerializedObject = require('./serializedobject').SerializedObject;
|
||||
var RippleError = require('./rippleerror').RippleError;
|
||||
var hashprefixes = require('./hashprefixes');
|
||||
var config = require('./config');
|
||||
var log = require('./log').internal.sub('transaction');
|
||||
var RippleError = require('./rippleerror').RippleError;
|
||||
var hashprefixes = require('./hashprefixes');
|
||||
var config = require('./config');
|
||||
var log = require('./log').internal.sub('transaction');
|
||||
|
||||
/**
|
||||
* @constructor Transaction
|
||||
@@ -35,14 +36,14 @@ function Transaction(remote) {
|
||||
var remoteExists = (typeof remote === 'object');
|
||||
|
||||
this.remote = remote;
|
||||
this.tx_json = { Flags: 0 };
|
||||
this._secret = void(0);
|
||||
this.tx_json = {Flags: 0};
|
||||
this._secret = undefined;
|
||||
this._build_path = false;
|
||||
this._maxFee = remoteExists ? this.remote.max_fee : void(0);
|
||||
this._maxFee = remoteExists ? this.remote.max_fee : undefined;
|
||||
this.state = 'unsubmitted';
|
||||
this.finalized = false;
|
||||
this.previousSigningHash = void(0);
|
||||
this.submitIndex = void(0);
|
||||
this.previousSigningHash = undefined;
|
||||
this.submitIndex = undefined;
|
||||
this.canonical = remoteExists ? this.remote.canonical_signing : true;
|
||||
this.submittedIDs = [ ];
|
||||
this.attempts = 0;
|
||||
@@ -76,11 +77,12 @@ function Transaction(remote) {
|
||||
// Transaction was submitted successfully to the network
|
||||
self.setState('pending');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
util.inherits(Transaction, EventEmitter);
|
||||
|
||||
// XXX This needs to be determined from the network.
|
||||
// This is currently a constant in rippled known as the "base reference"
|
||||
// https://wiki.ripple.com/Transaction_Fee#Base_Fees
|
||||
Transaction.fee_units = {
|
||||
default: 10
|
||||
};
|
||||
@@ -88,38 +90,38 @@ Transaction.fee_units = {
|
||||
Transaction.flags = {
|
||||
// Universal flags can apply to any transaction type
|
||||
Universal: {
|
||||
FullyCanonicalSig: 0x80000000
|
||||
FullyCanonicalSig: 0x80000000
|
||||
},
|
||||
|
||||
AccountSet: {
|
||||
RequireDestTag: 0x00010000,
|
||||
OptionalDestTag: 0x00020000,
|
||||
RequireAuth: 0x00040000,
|
||||
OptionalAuth: 0x00080000,
|
||||
DisallowXRP: 0x00100000,
|
||||
AllowXRP: 0x00200000
|
||||
RequireDestTag: 0x00010000,
|
||||
OptionalDestTag: 0x00020000,
|
||||
RequireAuth: 0x00040000,
|
||||
OptionalAuth: 0x00080000,
|
||||
DisallowXRP: 0x00100000,
|
||||
AllowXRP: 0x00200000
|
||||
},
|
||||
|
||||
TrustSet: {
|
||||
SetAuth: 0x00010000,
|
||||
NoRipple: 0x00020000,
|
||||
SetNoRipple: 0x00020000,
|
||||
ClearNoRipple: 0x00040000,
|
||||
SetFreeze: 0x00100000,
|
||||
ClearFreeze: 0x00200000
|
||||
SetAuth: 0x00010000,
|
||||
NoRipple: 0x00020000,
|
||||
SetNoRipple: 0x00020000,
|
||||
ClearNoRipple: 0x00040000,
|
||||
SetFreeze: 0x00100000,
|
||||
ClearFreeze: 0x00200000
|
||||
},
|
||||
|
||||
OfferCreate: {
|
||||
Passive: 0x00010000,
|
||||
ImmediateOrCancel: 0x00020000,
|
||||
FillOrKill: 0x00040000,
|
||||
Sell: 0x00080000
|
||||
Passive: 0x00010000,
|
||||
ImmediateOrCancel: 0x00020000,
|
||||
FillOrKill: 0x00040000,
|
||||
Sell: 0x00080000
|
||||
},
|
||||
|
||||
Payment: {
|
||||
NoRippleDirect: 0x00010000,
|
||||
PartialPayment: 0x00020000,
|
||||
LimitQuality: 0x00040000
|
||||
NoRippleDirect: 0x00010000,
|
||||
PartialPayment: 0x00020000,
|
||||
LimitQuality: 0x00040000
|
||||
}
|
||||
};
|
||||
|
||||
@@ -128,14 +130,14 @@ Transaction.flags = {
|
||||
// SetFlag or ClearFlag field
|
||||
Transaction.set_clear_flags = {
|
||||
AccountSet: {
|
||||
asfRequireDest: 1,
|
||||
asfRequireAuth: 2,
|
||||
asfDisallowXRP: 3,
|
||||
asfDisableMaster: 4,
|
||||
asfAccountTxnID: 5,
|
||||
asfNoFreeze: 6,
|
||||
asfGlobalFreeze: 7,
|
||||
asfDefaultRipple: 8
|
||||
asfRequireDest: 1,
|
||||
asfRequireAuth: 2,
|
||||
asfDisallowXRP: 3,
|
||||
asfDisableMaster: 4,
|
||||
asfAccountTxnID: 5,
|
||||
asfNoFreeze: 6,
|
||||
asfGlobalFreeze: 7,
|
||||
asfDefaultRipple: 8
|
||||
}
|
||||
};
|
||||
|
||||
@@ -147,12 +149,12 @@ Transaction.ASCII_REGEX = /^[\x00-\x7F]*$/;
|
||||
Transaction.formats = require('./binformat').tx;
|
||||
|
||||
Transaction.prototype.consts = {
|
||||
telLOCAL_ERROR: -399,
|
||||
temMALFORMED: -299,
|
||||
tefFAILURE: -199,
|
||||
terRETRY: -99,
|
||||
tesSUCCESS: 0,
|
||||
tecCLAIMED: 100
|
||||
telLOCAL_ERROR: -399,
|
||||
temMALFORMED: -299,
|
||||
tefFAILURE: -199,
|
||||
terRETRY: -99,
|
||||
tesSUCCESS: 0,
|
||||
tecCLAIMED: 100
|
||||
};
|
||||
|
||||
Transaction.prototype.isTelLocal = function(ter) {
|
||||
@@ -180,7 +182,9 @@ Transaction.prototype.isTecClaimed = function(ter) {
|
||||
};
|
||||
|
||||
Transaction.prototype.isRejected = function(ter) {
|
||||
return this.isTelLocal(ter) || this.isTemMalformed(ter) || this.isTefFailure(ter);
|
||||
return this.isTelLocal(ter) ||
|
||||
this.isTemMalformed(ter) ||
|
||||
this.isTefFailure(ter);
|
||||
};
|
||||
|
||||
Transaction.from_json = function(j) {
|
||||
@@ -217,7 +221,7 @@ Transaction.prototype.finalize = function(message) {
|
||||
|
||||
if (this.result) {
|
||||
this.result.ledger_index = message.ledger_index;
|
||||
this.result.ledger_hash = message.ledger_hash;
|
||||
this.result.ledger_hash = message.ledger_hash;
|
||||
} else {
|
||||
this.result = message;
|
||||
this.result.tx_json = this.tx_json;
|
||||
@@ -263,7 +267,7 @@ Transaction.prototype.getTransactionType = function() {
|
||||
|
||||
Transaction.prototype.getManager = function(account) {
|
||||
if (!this.remote) {
|
||||
return void(0);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!account) {
|
||||
@@ -282,7 +286,7 @@ Transaction.prototype.getManager = function(account) {
|
||||
Transaction.prototype.getSecret =
|
||||
Transaction.prototype._accountSecret = function(account) {
|
||||
if (!this.remote) {
|
||||
return void(0);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!account) {
|
||||
@@ -306,7 +310,7 @@ Transaction.prototype._accountSecret = function(account) {
|
||||
|
||||
Transaction.prototype._getFeeUnits =
|
||||
Transaction.prototype.feeUnits = function() {
|
||||
return Transaction.fee_units['default'];
|
||||
return Transaction.fee_units.default;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -317,13 +321,13 @@ Transaction.prototype.feeUnits = function() {
|
||||
|
||||
Transaction.prototype._computeFee = function() {
|
||||
if (!this.remote) {
|
||||
return void(0);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var servers = this.remote._servers;
|
||||
var fees = [ ];
|
||||
|
||||
for (var i=0; i<servers.length; i++) {
|
||||
for (var i = 0; i < servers.length; i++) {
|
||||
var server = servers[i];
|
||||
if (server._connected) {
|
||||
fees.push(Number(server._computeFee(this._getFeeUnits())));
|
||||
@@ -331,7 +335,7 @@ Transaction.prototype._computeFee = function() {
|
||||
}
|
||||
|
||||
switch (fees.length) {
|
||||
case 0: return;
|
||||
case 0: return undefined;
|
||||
case 1: return String(fees[0]);
|
||||
}
|
||||
|
||||
@@ -340,9 +344,8 @@ Transaction.prototype._computeFee = function() {
|
||||
return 1;
|
||||
} else if (a < b) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
var midInd = Math.floor(fees.length / 2);
|
||||
@@ -374,8 +377,12 @@ Transaction.prototype.complete = function() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._secret) {
|
||||
this._secret = this.getSecret();
|
||||
}
|
||||
|
||||
// Try to auto-fill the secret
|
||||
if (!this._secret && !(this._secret = this.getSecret())) {
|
||||
if (!this._secret) {
|
||||
this.emit('error', new RippleError('tejSecretUnknown', 'Missing secret'));
|
||||
return false;
|
||||
}
|
||||
@@ -383,7 +390,7 @@ Transaction.prototype.complete = function() {
|
||||
if (typeof this.tx_json.SigningPubKey === 'undefined') {
|
||||
try {
|
||||
var seed = Seed.from_json(this._secret);
|
||||
var key = seed.get_key(this.tx_json.Account);
|
||||
var key = seed.get_key(this.tx_json.Account);
|
||||
this.tx_json.SigningPubKey = key.to_hex_pub();
|
||||
} catch(e) {
|
||||
this.emit('error', new RippleError(
|
||||
@@ -396,7 +403,8 @@ Transaction.prototype.complete = function() {
|
||||
// an assigned server
|
||||
if (this.remote && typeof this.tx_json.Fee === 'undefined') {
|
||||
if (this.remote.local_fee || !this.remote.trusted) {
|
||||
if (!(this.tx_json.Fee = this._computeFee())) {
|
||||
this.tx_json.Fee = this._computeFee();
|
||||
if (!this.tx_json.Fee) {
|
||||
this.emit('error', new RippleError('tejUnconnected'));
|
||||
return false;
|
||||
}
|
||||
@@ -459,7 +467,7 @@ Transaction.prototype.sign = function() {
|
||||
}
|
||||
|
||||
var key = seed.get_key(this.tx_json.Account);
|
||||
var sig = key.sign(hash, 0);
|
||||
var sig = key.sign(hash);
|
||||
var hex = sjcl.codec.hex.fromBits(sig).toUpperCase();
|
||||
|
||||
this.tx_json.TxnSignature = hex;
|
||||
@@ -494,7 +502,7 @@ Transaction.prototype.addId = function(id) {
|
||||
Transaction.prototype.findId = function(cache) {
|
||||
var result;
|
||||
|
||||
for (var i=0; i<this.submittedIDs.length; i++) {
|
||||
for (var i = 0; i < this.submittedIDs.length; i++) {
|
||||
var hash = this.submittedIDs[i];
|
||||
if ((result = cache[hash])) {
|
||||
break;
|
||||
@@ -629,7 +637,7 @@ Transaction.prototype.maxFee = function(fee) {
|
||||
};
|
||||
|
||||
/*
|
||||
* Set the fee user will pay to the network for submitting this transaction.
|
||||
* Set the fee user will pay to the network for submitting this transaction.
|
||||
* Specified fee must be >= 0.
|
||||
*
|
||||
* @param {Number} fee The proposed fee
|
||||
@@ -716,7 +724,7 @@ Transaction.prototype.pathAdd = function(path) {
|
||||
Transaction.prototype.setPaths =
|
||||
Transaction.prototype.paths = function(paths) {
|
||||
if (Array.isArray(paths)) {
|
||||
for (var i=0, l=paths.length; i<l; i++) {
|
||||
for (var i = 0, l = paths.length; i < l; i++) {
|
||||
this.addPath(paths[i]);
|
||||
}
|
||||
}
|
||||
@@ -778,7 +786,7 @@ Transaction.prototype.transferRate = function(rate) {
|
||||
*/
|
||||
|
||||
Transaction.prototype.setFlags = function(flags) {
|
||||
if (flags === void(0)) {
|
||||
if (flags === undefined) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -790,7 +798,7 @@ Transaction.prototype.setFlags = function(flags) {
|
||||
var transaction_flags = Transaction.flags[this.getTransactionType()] || { };
|
||||
var flag_set = Array.isArray(flags) ? flags : [].slice.call(arguments);
|
||||
|
||||
for (var i=0, l=flag_set.length; i<l; i++) {
|
||||
for (var i = 0, l = flag_set.length; i < l; i++) {
|
||||
var flag = flag_set[i];
|
||||
|
||||
if (transaction_flags.hasOwnProperty(flag)) {
|
||||
@@ -845,8 +853,8 @@ Transaction.prototype.addMemo = function(memoType, memoFormat, memoData) {
|
||||
|
||||
if (memoType) {
|
||||
if (Transaction.MEMO_TYPES[memoType]) {
|
||||
//XXX Maybe in the future we want a schema validator for
|
||||
//memo types
|
||||
// XXX Maybe in the future we want a schema validator for
|
||||
// memo types
|
||||
memoType = Transaction.MEMO_TYPES[memoType];
|
||||
}
|
||||
memo.MemoType = convertStringToHex(memoType);
|
||||
@@ -862,17 +870,19 @@ Transaction.prototype.addMemo = function(memoType, memoFormat, memoData) {
|
||||
try {
|
||||
memoData = JSON.stringify(memoData);
|
||||
} catch (e) {
|
||||
throw new Error('MemoFormat json with invalid JSON in MemoData field');
|
||||
throw new Error(
|
||||
'MemoFormat json with invalid JSON in MemoData field');
|
||||
}
|
||||
} else {
|
||||
throw new Error('MemoData can only be a JSON object with a valid json MemoFormat');
|
||||
throw new Error(
|
||||
'MemoData can only be a JSON object with a valid json MemoFormat');
|
||||
}
|
||||
}
|
||||
|
||||
memo.MemoData = convertStringToHex(memoData);
|
||||
}
|
||||
|
||||
this.tx_json.Memos = (this.tx_json.Memos || []).concat({ Memo: memo });
|
||||
this.tx_json.Memos = (this.tx_json.Memos || []).concat({Memo: memo});
|
||||
|
||||
return this;
|
||||
};
|
||||
@@ -917,23 +927,33 @@ Transaction.prototype.accountSet = function(src, set_flag, clear_flag) {
|
||||
throw new Error('Source address invalid');
|
||||
}
|
||||
|
||||
this.tx_json.TransactionType= 'AccountSet';
|
||||
this.tx_json.TransactionType = 'AccountSet';
|
||||
this.tx_json.Account = UInt160.json_rewrite(src);
|
||||
|
||||
var SetClearFlags = Transaction.set_clear_flags.AccountSet;
|
||||
|
||||
function prepareFlag(flag) {
|
||||
return (typeof flag === 'number')
|
||||
? flag
|
||||
? flag
|
||||
: (SetClearFlags[flag] || SetClearFlags['asf' + flag]);
|
||||
};
|
||||
|
||||
if (set_flag && (set_flag = prepareFlag(set_flag))) {
|
||||
this.tx_json.SetFlag = set_flag;
|
||||
}
|
||||
|
||||
if (clear_flag && (clear_flag = prepareFlag(clear_flag))) {
|
||||
this.tx_json.ClearFlag = clear_flag;
|
||||
var prepared;
|
||||
|
||||
if (set_flag) {
|
||||
prepared = prepareFlag(set_flag);
|
||||
|
||||
if (prepared) {
|
||||
this.tx_json.SetFlag = prepared;
|
||||
}
|
||||
}
|
||||
|
||||
if (clear_flag) {
|
||||
prepared = prepareFlag(clear_flag);
|
||||
|
||||
if (prepared) {
|
||||
this.tx_json.ClearFlag = prepared;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -995,7 +1015,8 @@ Transaction.prototype.offerCancel = function(src, sequence) {
|
||||
* @param [Number] sequence of an existing offer to replace
|
||||
*/
|
||||
|
||||
Transaction.prototype.offerCreate = function(src, taker_pays, taker_gets, expiration, cancel_sequence) {
|
||||
Transaction.prototype.offerCreate = function(src, taker_pays, taker_gets,
|
||||
expiration, cancel_sequence) {
|
||||
if (typeof src === 'object') {
|
||||
var options = src;
|
||||
cancel_sequence = options.cancel_sequence || options.sequence;
|
||||
@@ -1111,7 +1132,10 @@ Transaction.prototype.payment = function(src, dst, amount) {
|
||||
*/
|
||||
|
||||
Transaction.prototype.trustSet =
|
||||
Transaction.prototype.rippleLineSet = function(src, limit, quality_in, quality_out) {
|
||||
Transaction.prototype.rippleLineSet = function(src,
|
||||
limit,
|
||||
quality_in,
|
||||
quality_out) {
|
||||
if (typeof src === 'object') {
|
||||
var options = src;
|
||||
quality_out = options.quality_out;
|
||||
@@ -1127,7 +1151,7 @@ Transaction.prototype.rippleLineSet = function(src, limit, quality_in, quality_o
|
||||
this.tx_json.TransactionType = 'TrustSet';
|
||||
this.tx_json.Account = UInt160.json_rewrite(src);
|
||||
|
||||
if (limit !== void(0)) {
|
||||
if (limit !== undefined) {
|
||||
this.tx_json.LimitAmount = Amount.json_rewrite(limit);
|
||||
}
|
||||
|
||||
@@ -1153,7 +1177,7 @@ Transaction.prototype.rippleLineSet = function(src, limit, quality_in, quality_o
|
||||
Transaction.prototype.submit = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.callback = (typeof callback === 'function') ? callback : function(){};
|
||||
this.callback = (typeof callback === 'function') ? callback : function() {};
|
||||
|
||||
this._errorHandler = function transactionError(error, message) {
|
||||
if (!(error instanceof RippleError)) {
|
||||
@@ -1168,7 +1192,7 @@ Transaction.prototype.submit = function(callback) {
|
||||
|
||||
if (!this.remote) {
|
||||
this.emit('error', new Error('No remote found'));
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.getManager().submit(this);
|
||||
@@ -1198,7 +1222,7 @@ Transaction.prototype.summary = function() {
|
||||
initialSubmitIndex: this.initialSubmitIndex,
|
||||
lastLedgerSequence: this.lastLedgerSequence,
|
||||
state: this.state,
|
||||
server: this._server ? this._server._opts.url : void(0),
|
||||
server: this._server ? this._server._opts.url : undefined,
|
||||
finalized: this.finalized
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
var utils = require('./utils');
|
||||
var sjcl = utils.sjcl;
|
||||
var config = require('./config');
|
||||
'use strict';
|
||||
|
||||
/*eslint new-cap: 1*/
|
||||
|
||||
var utils = require('./utils');
|
||||
var sjcl = utils.sjcl;
|
||||
var config = require('./config');
|
||||
|
||||
//
|
||||
// Abstract UInt class
|
||||
@@ -8,11 +12,11 @@ var config = require('./config');
|
||||
// Base class for UInt classes
|
||||
//
|
||||
|
||||
var UInt = function() {
|
||||
function UInt() {
|
||||
// Internal form: NaN or sjcl.bn
|
||||
this._value = NaN;
|
||||
this._value = NaN;
|
||||
this._update();
|
||||
};
|
||||
}
|
||||
|
||||
UInt.json_rewrite = function(j, opts) {
|
||||
return this.from_json(j).to_json(opts);
|
||||
@@ -22,63 +26,56 @@ UInt.json_rewrite = function(j, opts) {
|
||||
UInt.from_generic = function(j) {
|
||||
if (j instanceof this) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return (new this()).parse_generic(j);
|
||||
}
|
||||
return (new this()).parse_generic(j);
|
||||
};
|
||||
|
||||
// Return a new UInt from j.
|
||||
UInt.from_hex = function(j) {
|
||||
if (j instanceof this) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return (new this()).parse_hex(j);
|
||||
}
|
||||
return (new this()).parse_hex(j);
|
||||
};
|
||||
|
||||
// Return a new UInt from j.
|
||||
UInt.from_json = function(j) {
|
||||
if (j instanceof this) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return (new this()).parse_json(j);
|
||||
}
|
||||
return (new this()).parse_json(j);
|
||||
};
|
||||
|
||||
// Return a new UInt from j.
|
||||
UInt.from_bits = function(j) {
|
||||
if (j instanceof this) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return (new this()).parse_bits(j);
|
||||
}
|
||||
return (new this()).parse_bits(j);
|
||||
};
|
||||
|
||||
// Return a new UInt from j.
|
||||
UInt.from_bytes = function(j) {
|
||||
if (j instanceof this) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return (new this()).parse_bytes(j);
|
||||
}
|
||||
return (new this()).parse_bytes(j);
|
||||
};
|
||||
|
||||
// Return a new UInt from j.
|
||||
UInt.from_bn = function(j) {
|
||||
if (j instanceof this) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return (new this()).parse_bn(j);
|
||||
}
|
||||
return (new this()).parse_bn(j);
|
||||
};
|
||||
|
||||
// Return a new UInt from j.
|
||||
UInt.from_number = function(j) {
|
||||
if (j instanceof this) {
|
||||
return j.clone();
|
||||
} else {
|
||||
return (new this()).parse_number(j);
|
||||
}
|
||||
return (new this()).parse_number(j);
|
||||
};
|
||||
|
||||
UInt.is_valid = function(j) {
|
||||
@@ -93,7 +90,7 @@ UInt.prototype.clone = function() {
|
||||
UInt.prototype.copyTo = function(d) {
|
||||
d._value = this._value;
|
||||
|
||||
if (this._version_byte !== void(0)) {
|
||||
if (this._version_byte !== undefined) {
|
||||
d._version_byte = this._version_byte;
|
||||
}
|
||||
|
||||
@@ -125,6 +122,8 @@ UInt.prototype.is_zero = function() {
|
||||
*
|
||||
* The reason for keeping this mechanism in this class is so every subclass can
|
||||
* call it whenever it modifies the internal state.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
UInt.prototype._update = function() {
|
||||
// Nothing to do by default. Subclasses will override this.
|
||||
@@ -137,33 +136,34 @@ UInt.prototype.parse_generic = function(j) {
|
||||
j = config.accounts[j].account;
|
||||
}
|
||||
|
||||
|
||||
switch (j) {
|
||||
case undefined:
|
||||
case '0':
|
||||
case this.constructor.STR_ZERO:
|
||||
case this.constructor.ACCOUNT_ZERO:
|
||||
case this.constructor.HEX_ZERO:
|
||||
this._value = new sjcl.bn(0);
|
||||
case '0':
|
||||
case this.constructor.STR_ZERO:
|
||||
case this.constructor.ACCOUNT_ZERO:
|
||||
case this.constructor.HEX_ZERO:
|
||||
this._value = new sjcl.bn(0);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
case this.constructor.STR_ONE:
|
||||
case this.constructor.ACCOUNT_ONE:
|
||||
case this.constructor.HEX_ONE:
|
||||
this._value = new sjcl.bn(1);
|
||||
case this.constructor.STR_ONE:
|
||||
case this.constructor.ACCOUNT_ONE:
|
||||
case this.constructor.HEX_ONE:
|
||||
this._value = new sjcl.bn(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (typeof j !== 'string') {
|
||||
this._value = NaN;
|
||||
this._value = NaN;
|
||||
} else if (this.constructor.width === j.length) {
|
||||
var hex = utils.arrayToHex(utils.stringToArray(j));
|
||||
this._value = new sjcl.bn(hex, 16);
|
||||
this._value = new sjcl.bn(hex, 16);
|
||||
} else if ((this.constructor.width * 2) === j.length) {
|
||||
// XXX Check char set!
|
||||
this._value = new sjcl.bn(j, 16);
|
||||
this._value = new sjcl.bn(j, 16);
|
||||
} else {
|
||||
this._value = NaN;
|
||||
this._value = NaN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ UInt.prototype.parse_bytes = function(j) {
|
||||
this._value = NaN;
|
||||
} else {
|
||||
var bits = sjcl.codec.bytes.toBits(j);
|
||||
this._value = sjcl.bn.fromBits(bits);
|
||||
this._value = sjcl.bn.fromBits(bits);
|
||||
}
|
||||
|
||||
this._update();
|
||||
@@ -216,9 +216,8 @@ UInt.prototype.parse_bytes = function(j) {
|
||||
UInt.prototype.parse_json = UInt.prototype.parse_hex;
|
||||
|
||||
UInt.prototype.parse_bn = function(j) {
|
||||
if ((j instanceof sjcl.bn) && j.bitLength() <= this.constructor.width * 8) {
|
||||
// var bytes = sjcl.codec.bytes.fromBits(j.toBits());
|
||||
// this._value = new sjcl.bn(utils.arrayToHex(bytes), 16);
|
||||
if ((j instanceof sjcl.bn) &&
|
||||
j.bitLength() <= this.constructor.width * 8) {
|
||||
this._value = new sjcl.bn(j);
|
||||
} else {
|
||||
this._value = NaN;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
var utils = require('./utils');
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var extend = require('extend');
|
||||
var UInt = require('./uint').UInt;
|
||||
var UInt = require('./uint').UInt;
|
||||
|
||||
//
|
||||
// UInt128 support
|
||||
//
|
||||
|
||||
var UInt128 = extend(function () {
|
||||
this._value = NaN;
|
||||
var UInt128 = extend(function() {
|
||||
this._value = NaN;
|
||||
}, UInt);
|
||||
|
||||
UInt128.width = 16;
|
||||
@@ -15,8 +17,9 @@ UInt128.prototype = extend({}, UInt.prototype);
|
||||
UInt128.prototype.constructor = UInt128;
|
||||
|
||||
var HEX_ZERO = UInt128.HEX_ZERO = '00000000000000000000000000000000';
|
||||
var HEX_ONE = UInt128.HEX_ONE = '00000000000000000000000000000000';
|
||||
var STR_ZERO = UInt128.STR_ZERO = utils.hexToString(HEX_ZERO);
|
||||
var STR_ONE = UInt128.STR_ONE = utils.hexToString(HEX_ONE);
|
||||
var HEX_ONE = UInt128.HEX_ONE = '00000000000000000000000000000000';
|
||||
|
||||
UInt128.STR_ZERO = utils.hexToString(HEX_ZERO);
|
||||
UInt128.STR_ONE = utils.hexToString(HEX_ONE);
|
||||
|
||||
exports.UInt128 = UInt128;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
var utils = require('./utils');
|
||||
var config = require('./config');
|
||||
var extend = require('extend');
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var config = require('./config');
|
||||
var extend = require('extend');
|
||||
|
||||
var UInt = require('./uint').UInt;
|
||||
var Base = require('./base').Base;
|
||||
@@ -10,8 +12,8 @@ var Base = require('./base').Base;
|
||||
//
|
||||
|
||||
var UInt160 = extend(function() {
|
||||
this._value = NaN;
|
||||
this._version_byte = void(0);
|
||||
this._value = NaN;
|
||||
this._version_byte = undefined;
|
||||
this._update();
|
||||
}, UInt);
|
||||
|
||||
@@ -19,12 +21,13 @@ UInt160.width = 20;
|
||||
UInt160.prototype = extend({}, UInt.prototype);
|
||||
UInt160.prototype.constructor = UInt160;
|
||||
|
||||
var ACCOUNT_ZERO = UInt160.ACCOUNT_ZERO = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp';
|
||||
var ACCOUNT_ONE = UInt160.ACCOUNT_ONE = 'rrrrrrrrrrrrrrrrrrrrBZbvji';
|
||||
var HEX_ZERO = UInt160.HEX_ZERO = '0000000000000000000000000000000000000000';
|
||||
var HEX_ONE = UInt160.HEX_ONE = '0000000000000000000000000000000000000001';
|
||||
var STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO);
|
||||
var STR_ONE = UInt160.STR_ONE = utils.hexToString(HEX_ONE);
|
||||
var HEX_ZERO = UInt160.HEX_ZERO = '0000000000000000000000000000000000000000';
|
||||
var 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;
|
||||
@@ -78,7 +81,7 @@ UInt160.prototype.parse_generic = function(j) {
|
||||
|
||||
// XXX Json form should allow 0 and 1, C++ doesn't currently allow it.
|
||||
UInt160.prototype.to_json = function(opts) {
|
||||
opts = opts || {};
|
||||
opts = opts || {};
|
||||
|
||||
if (this.is_valid()) {
|
||||
// If this value has a type, return a Base58 encoded string.
|
||||
@@ -90,9 +93,8 @@ UInt160.prototype.to_json = function(opts) {
|
||||
}
|
||||
|
||||
return output;
|
||||
} else {
|
||||
return this.to_hex();
|
||||
}
|
||||
return this.to_hex();
|
||||
}
|
||||
return NaN;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
var utils = require('./utils');
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var extend = require('extend');
|
||||
var UInt = require('./uint').UInt;
|
||||
var UInt = require('./uint').UInt;
|
||||
|
||||
//
|
||||
// UInt256 support
|
||||
@@ -14,9 +16,13 @@ UInt256.width = 32;
|
||||
UInt256.prototype = extend({}, UInt.prototype);
|
||||
UInt256.prototype.constructor = UInt256;
|
||||
|
||||
var HEX_ZERO = UInt256.HEX_ZERO = '00000000000000000000000000000000' + '00000000000000000000000000000000';
|
||||
var HEX_ONE = UInt256.HEX_ONE = '00000000000000000000000000000000' + '00000000000000000000000000000001';
|
||||
var STR_ZERO = UInt256.STR_ZERO = utils.hexToString(HEX_ZERO);
|
||||
var STR_ONE = UInt256.STR_ONE = utils.hexToString(HEX_ONE);
|
||||
var HEX_ZERO = UInt256.HEX_ZERO = '00000000000000000000000000000000' +
|
||||
'00000000000000000000000000000000';
|
||||
|
||||
var HEX_ONE = UInt256.HEX_ONE = '00000000000000000000000000000000' +
|
||||
'00000000000000000000000000000001';
|
||||
|
||||
UInt256.STR_ZERO = utils.hexToString(HEX_ZERO);
|
||||
UInt256.STR_ONE = utils.hexToString(HEX_ONE);
|
||||
|
||||
exports.UInt256 = UInt256;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
function getMantissaDecimalString(bignum) {
|
||||
var mantissa = bignum.toPrecision(16)
|
||||
@@ -10,37 +11,22 @@ function getMantissaDecimalString(bignum) {
|
||||
return mantissa;
|
||||
}
|
||||
|
||||
function filterErr(code, done) {
|
||||
return function(e) {
|
||||
done(e.code !== code ? e : void(0));
|
||||
};
|
||||
};
|
||||
|
||||
function throwErr(done) {
|
||||
return function(e) {
|
||||
if (e) {
|
||||
throw e;
|
||||
}
|
||||
done();
|
||||
};
|
||||
};
|
||||
|
||||
function trace(comment, func) {
|
||||
return function() {
|
||||
console.log('%s: %s', trace, arguments.toString);
|
||||
func(arguments);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function arraySet(count, value) {
|
||||
var a = new Array(count);
|
||||
|
||||
for (var i=0; i<count; i++) {
|
||||
for (var i = 0; i < count; i++) {
|
||||
a[i] = value;
|
||||
}
|
||||
|
||||
return a;
|
||||
};
|
||||
}
|
||||
|
||||
function hexToString(h) {
|
||||
var a = [];
|
||||
@@ -51,35 +37,35 @@ function hexToString(h) {
|
||||
i = 1;
|
||||
}
|
||||
|
||||
for (; i<h.length; i+=2) {
|
||||
a.push(String.fromCharCode(parseInt(h.substring(i, i+2), 16)));
|
||||
for (; i < h.length; i += 2) {
|
||||
a.push(String.fromCharCode(parseInt(h.substring(i, i + 2), 16)));
|
||||
}
|
||||
|
||||
return a.join('');
|
||||
};
|
||||
}
|
||||
|
||||
function stringToHex(s) {
|
||||
var result = '';
|
||||
for (var i=0; i<s.length; i++) {
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
var b = s.charCodeAt(i);
|
||||
result += b < 16 ? '0' + b.toString(16) : b.toString(16);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function stringToArray(s) {
|
||||
var a = new Array(s.length);
|
||||
|
||||
for (var i=0; i<a.length; i+=1) {
|
||||
for (var i = 0; i < a.length; i += 1) {
|
||||
a[i] = s.charCodeAt(i);
|
||||
}
|
||||
|
||||
return a;
|
||||
};
|
||||
}
|
||||
|
||||
function hexToArray(h) {
|
||||
return stringToArray(hexToString(h));
|
||||
};
|
||||
}
|
||||
|
||||
function arrayToHex(a) {
|
||||
return a.map(function(byteValue) {
|
||||
@@ -90,7 +76,7 @@ function arrayToHex(a) {
|
||||
|
||||
function chunkString(str, n, leftAlign) {
|
||||
var ret = [];
|
||||
var i=0, len=str.length;
|
||||
var i = 0, len = str.length;
|
||||
|
||||
if (leftAlign) {
|
||||
i = str.length % n;
|
||||
@@ -99,26 +85,27 @@ function chunkString(str, n, leftAlign) {
|
||||
}
|
||||
}
|
||||
|
||||
for(; i<len; i+=n) {
|
||||
for (; i < len; i += n) {
|
||||
ret.push(str.slice(i, n + i));
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
function assert(assertion, msg) {
|
||||
if (!assertion) {
|
||||
throw new Error('Assertion failed' + (msg ? ': ' + msg : '.'));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return unique values in array.
|
||||
* @param {Array} arr (values)
|
||||
* @return {Array} unique values (for string representation of value) in `arr`
|
||||
*/
|
||||
function arrayUnique(arr) {
|
||||
var u = {}, a = [];
|
||||
|
||||
for (var i=0, l=arr.length; i<l; i++){
|
||||
for (var i = 0, l = arr.length; i < l; i++) {
|
||||
var k = arr[i];
|
||||
if (u[k]) {
|
||||
continue;
|
||||
@@ -128,46 +115,45 @@ function arrayUnique(arr) {
|
||||
}
|
||||
|
||||
return a;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a ripple epoch to a JavaScript timestamp.
|
||||
* @param {Number} rpepoch (seconds since 1/1/2000 GMT)
|
||||
* @return {Number} ms since unix epoch
|
||||
*
|
||||
* JavaScript timestamps are unix epoch in milliseconds.
|
||||
*/
|
||||
function toTimestamp(rpepoch) {
|
||||
return (rpepoch + 0x386D4380) * 1000;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a JavaScript timestamp or Date to a Ripple epoch.
|
||||
*
|
||||
* JavaScript timestamps are unix epoch in milliseconds.
|
||||
* @param {Number|Date} timestamp (ms since unix epoch)
|
||||
* @return {Number} seconds since ripple epoch ( 1/1/2000 GMT)
|
||||
*/
|
||||
function fromTimestamp(rpepoch) {
|
||||
if (rpepoch instanceof Date) {
|
||||
rpepoch = rpepoch.getTime();
|
||||
function fromTimestamp(timestamp) {
|
||||
if (timestamp instanceof Date) {
|
||||
timestamp = timestamp.getTime();
|
||||
}
|
||||
|
||||
return Math.round(rpepoch / 1000) - 0x386D4380;
|
||||
};
|
||||
return Math.round(timestamp / 1000) - 0x386D4380;
|
||||
}
|
||||
|
||||
exports.time = {
|
||||
fromRipple: toTimestamp,
|
||||
toRipple: fromTimestamp
|
||||
};
|
||||
|
||||
exports.trace = trace;
|
||||
exports.arraySet = arraySet;
|
||||
exports.hexToString = hexToString;
|
||||
exports.hexToArray = hexToArray;
|
||||
exports.trace = trace;
|
||||
exports.arraySet = arraySet;
|
||||
exports.hexToString = hexToString;
|
||||
exports.hexToArray = hexToArray;
|
||||
exports.stringToArray = stringToArray;
|
||||
exports.stringToHex = stringToHex;
|
||||
exports.arrayToHex = arrayToHex;
|
||||
exports.chunkString = chunkString;
|
||||
exports.assert = assert;
|
||||
exports.arrayUnique = arrayUnique;
|
||||
exports.toTimestamp = toTimestamp;
|
||||
exports.stringToHex = stringToHex;
|
||||
exports.arrayToHex = arrayToHex;
|
||||
exports.chunkString = chunkString;
|
||||
exports.assert = assert;
|
||||
exports.arrayUnique = arrayUnique;
|
||||
exports.toTimestamp = toTimestamp;
|
||||
exports.fromTimestamp = fromTimestamp;
|
||||
exports.getMantissaDecimalString = getMantissaDecimalString;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
var ws = require('ws');
|
||||
var lodash = require('lodash');
|
||||
var assert = require('assert-diff');
|
||||
var sjcl = require('ripple-lib').sjcl;
|
||||
var Remote = require('ripple-lib').Remote;
|
||||
var SerializedObject = require('ripple-lib').SerializedObject;
|
||||
var Transaction = require('ripple-lib').Transaction;
|
||||
@@ -42,6 +43,11 @@ describe('TransactionManager', function() {
|
||||
var account;
|
||||
var transactionManager;
|
||||
|
||||
before(function() {
|
||||
sjcl.random.addEntropy(
|
||||
'3045022100A58B0460BC5092CB4F96155C19125A4E079C870663F1D5E8BBC9BD', 256);
|
||||
});
|
||||
|
||||
beforeEach(function(done) {
|
||||
rippled = new ws.Server({port: 5763});
|
||||
|
||||
@@ -51,6 +57,7 @@ describe('TransactionManager', function() {
|
||||
try {
|
||||
c.send(JSON.stringify(v));
|
||||
} catch (e) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
c.sendResponse = function(baseResponse, ext) {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
var assert = require('assert');
|
||||
var Amount = require('ripple-lib').Amount;
|
||||
var Transaction = require('ripple-lib').Transaction;
|
||||
/* eslint-disable max-len */
|
||||
'use strict';
|
||||
var assert = require('assert');
|
||||
var Transaction = require('ripple-lib').Transaction;
|
||||
var TransactionQueue = require('ripple-lib').TransactionQueue;
|
||||
var Remote = require('ripple-lib').Remote;
|
||||
var Server = require('ripple-lib').Server;
|
||||
var Remote = require('ripple-lib').Remote;
|
||||
var Server = require('ripple-lib').Server;
|
||||
var sjcl = require('ripple-lib').sjcl;
|
||||
|
||||
var transactionResult = {
|
||||
engine_result: 'tesSUCCESS',
|
||||
@@ -17,24 +19,30 @@ var transactionResult = {
|
||||
metadata: {
|
||||
AffectedNodes: [ ],
|
||||
TransactionIndex: 0,
|
||||
TransactionResult: 'tesSUCCESS' },
|
||||
tx_json: {
|
||||
Account: 'rHPotLj3CNKaP4bQANcecEuT8hai3VpxfB',
|
||||
Amount: '1000000',
|
||||
Destination: 'rYtn3D1VGQyf1MTqcwLDepUKm22YEGXGJA',
|
||||
Fee: '10',
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 7106151,
|
||||
Sequence: 2973,
|
||||
SigningPubKey: '0306E9F38DF11402953A5B030C1AE8A88C47E348170C3B8EC6C8D775E797168462',
|
||||
TransactionType: 'Payment',
|
||||
TxnSignature: '3045022100A58B0460BC5092CB4F96155C19125A4E079C870663F1D5E8BBC9BDEE06D51F530220408A3AA26988ABF18E16BE77B016F25018A2AA7C99FFE723FC8598471357DBCF',
|
||||
date: 455660500,
|
||||
hash: '61D60378AB70ACE630B20A81B50708A3DB5E7CEE35914292FF3761913DA61DEA'
|
||||
}
|
||||
TransactionResult: 'tesSUCCESS'
|
||||
},
|
||||
tx_json: {
|
||||
Account: 'rHPotLj3CNKaP4bQANcecEuT8hai3VpxfB',
|
||||
Amount: '1000000',
|
||||
Destination: 'rYtn3D1VGQyf1MTqcwLDepUKm22YEGXGJA',
|
||||
Fee: '10',
|
||||
Flags: 0,
|
||||
LastLedgerSequence: 7106151,
|
||||
Sequence: 2973,
|
||||
SigningPubKey: '0306E9F38DF11402953A5B030C1AE8A88C47E348170C3B8EC6C8D775E797168462',
|
||||
TransactionType: 'Payment',
|
||||
TxnSignature: '3045022100A58B0460BC5092CB4F96155C19125A4E079C870663F1D5E8BBC9BDEE06D51F530220408A3AA26988ABF18E16BE77B016F25018A2AA7C99FFE723FC8598471357DBCF',
|
||||
date: 455660500,
|
||||
hash: '61D60378AB70ACE630B20A81B50708A3DB5E7CEE35914292FF3761913DA61DEA'
|
||||
}
|
||||
};
|
||||
|
||||
describe('Transaction', function() {
|
||||
before(function() {
|
||||
sjcl.random.addEntropy(
|
||||
'3045022100A58B0460BC5092CB4F96155C19125A4E079C870663F1D5E8BBC9BD', 256);
|
||||
});
|
||||
|
||||
it('Success listener', function(done) {
|
||||
var transaction = new Transaction();
|
||||
|
||||
@@ -189,7 +197,7 @@ describe('Transaction', function() {
|
||||
|
||||
assert.strictEqual(transaction._accountSecret('rpzT237Ctpaa58KieifoK8RyBmmRwEcfhK'), 'shY1njzHAXp8Qt3bpxYW6RpoZtMKP');
|
||||
assert.strictEqual(transaction._accountSecret('rpdxPs9CR93eLAc5DTvAgv4S9XJ1CzKj1a'), 'ssboTJezioTq8obyvDU9tVo95NGGQ');
|
||||
assert.strictEqual(transaction._accountSecret('rExistNot'), void(0));
|
||||
assert.strictEqual(transaction._accountSecret('rExistNot'), undefined);
|
||||
});
|
||||
|
||||
it('Get fee units', function() {
|
||||
@@ -220,7 +228,7 @@ describe('Transaction', function() {
|
||||
s5._connected = true;
|
||||
s5._load_factor = 256 * 7;
|
||||
|
||||
remote._servers = [ s2, s3, s1, s4 ];
|
||||
remote._servers = [s2, s3, s1, s4];
|
||||
|
||||
assert.strictEqual(s1._computeFee(10), '12');
|
||||
assert.strictEqual(s2._computeFee(10), '48');
|
||||
@@ -235,7 +243,7 @@ describe('Transaction', function() {
|
||||
|
||||
it('Compute fee, no remote', function() {
|
||||
var transaction = new Transaction();
|
||||
assert.strictEqual(transaction._computeFee(10), void(0));
|
||||
assert.strictEqual(transaction._computeFee(10), undefined);
|
||||
});
|
||||
|
||||
it('Compute fee - no connected server', function() {
|
||||
@@ -252,7 +260,7 @@ describe('Transaction', function() {
|
||||
s3._connected = false;
|
||||
s3._load_factor = 256 * 8;
|
||||
|
||||
remote._servers = [ s1, s2, s3 ];
|
||||
remote._servers = [s1, s2, s3];
|
||||
|
||||
assert.strictEqual(s1._computeFee(10), '12');
|
||||
assert.strictEqual(s2._computeFee(10), '48');
|
||||
@@ -260,7 +268,7 @@ describe('Transaction', function() {
|
||||
|
||||
var transaction = new Transaction(remote);
|
||||
|
||||
assert.strictEqual(transaction._computeFee(), void(0));
|
||||
assert.strictEqual(transaction._computeFee(), undefined);
|
||||
});
|
||||
|
||||
it('Compute fee - one connected server', function() {
|
||||
@@ -277,7 +285,7 @@ describe('Transaction', function() {
|
||||
s3._connected = true;
|
||||
s3._load_factor = 256 * 8;
|
||||
|
||||
remote._servers = [ s1, s2, s3 ];
|
||||
remote._servers = [s1, s2, s3];
|
||||
|
||||
assert.strictEqual(s1._computeFee(10), '12');
|
||||
assert.strictEqual(s2._computeFee(10), '48');
|
||||
@@ -307,7 +315,7 @@ describe('Transaction', function() {
|
||||
s4._connected = true;
|
||||
s4._load_factor = 256 * 16;
|
||||
|
||||
remote._servers = [ s1, s2, s3, s4 ];
|
||||
remote._servers = [s1, s2, s3, s4];
|
||||
|
||||
assert.strictEqual(s1._computeFee(10), '12');
|
||||
assert.strictEqual(s2._computeFee(10), '48');
|
||||
@@ -319,7 +327,7 @@ describe('Transaction', function() {
|
||||
transaction.tx_json.Sequence = 1;
|
||||
var src = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh';
|
||||
var dst = 'rGihwhaqU8g7ahwAvTq6iX5rvsfcbgZw6v';
|
||||
|
||||
|
||||
transaction.payment(src, dst, '100');
|
||||
remote.set_secret(src, 'masterpassphrase');
|
||||
|
||||
@@ -347,7 +355,7 @@ describe('Transaction', function() {
|
||||
s4._connected = true;
|
||||
s4._load_factor = 256 * 16;
|
||||
|
||||
remote._servers = [ s1, s2, s3, s4 ];
|
||||
remote._servers = [s1, s2, s3, s4];
|
||||
|
||||
assert.strictEqual(s1._computeFee(10), '12');
|
||||
assert.strictEqual(s2._computeFee(10), '48');
|
||||
@@ -366,7 +374,7 @@ describe('Transaction', function() {
|
||||
var s1 = new Server(remote, 'wss://s-west.ripple.com:443');
|
||||
s1._connected = true;
|
||||
|
||||
remote._servers = [ s1 ];
|
||||
remote._servers = [s1];
|
||||
remote.trusted = true;
|
||||
remote.local_signing = true;
|
||||
|
||||
@@ -427,7 +435,7 @@ describe('Transaction', function() {
|
||||
remote.trusted = true;
|
||||
remote.local_signing = true;
|
||||
|
||||
transaction.SigningPubKey = void(0);
|
||||
transaction.SigningPubKey = undefined;
|
||||
transaction.tx_json.Account = 'rMWwx3Ma16HnqSd4H6saPisihX9aKpXxHJ';
|
||||
transaction._secret = 'sh2pTicynUEG46jjR4EoexHcQEoijX';
|
||||
|
||||
@@ -465,7 +473,7 @@ describe('Transaction', function() {
|
||||
var s1 = new Server(remote, 'wss://s-west.ripple.com:443');
|
||||
s1._connected = true;
|
||||
|
||||
remote._servers = [ s1 ];
|
||||
remote._servers = [s1];
|
||||
remote.trusted = true;
|
||||
remote.local_signing = true;
|
||||
|
||||
@@ -473,7 +481,7 @@ describe('Transaction', function() {
|
||||
transaction.tx_json.Account = 'rMWwx3Ma16HnqSd4H6saPisihX9aKpXxHJ';
|
||||
transaction._secret = 'sh2pTicynUEG46jjR4EoexHcQEoij';
|
||||
|
||||
assert.strictEqual(transaction.tx_json.Fee, void(0));
|
||||
assert.strictEqual(transaction.tx_json.Fee, undefined);
|
||||
|
||||
assert(transaction.complete());
|
||||
|
||||
@@ -483,13 +491,13 @@ describe('Transaction', function() {
|
||||
});
|
||||
|
||||
it('Complete transaction - compute fee exceeds max fee', function(done) {
|
||||
var remote = new Remote({ max_fee: 10 });
|
||||
var remote = new Remote({max_fee: 10});
|
||||
|
||||
var s1 = new Server(remote, 'wss://s-west.ripple.com:443');
|
||||
s1._connected = true;
|
||||
s1._load_factor = 256 * 16;
|
||||
|
||||
remote._servers = [ s1 ];
|
||||
remote._servers = [s1];
|
||||
remote.trusted = true;
|
||||
remote.local_signing = true;
|
||||
|
||||
@@ -513,7 +521,7 @@ describe('Transaction', function() {
|
||||
s1._connected = true;
|
||||
s1._load_factor = 256;
|
||||
|
||||
remote._servers = [ s1 ];
|
||||
remote._servers = [s1];
|
||||
remote.trusted = true;
|
||||
remote.local_signing = true;
|
||||
|
||||
@@ -539,7 +547,7 @@ describe('Transaction', function() {
|
||||
transaction.tx_json.Sequence = 1;
|
||||
transaction.tx_json.TransactionType = 'AccountSet';
|
||||
|
||||
assert.strictEqual(transaction.signingHash(), 'D1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE')
|
||||
assert.strictEqual(transaction.signingHash(), 'D1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE');
|
||||
|
||||
done();
|
||||
});
|
||||
@@ -554,7 +562,7 @@ describe('Transaction', function() {
|
||||
transaction.tx_json.Sequence = 1;
|
||||
transaction.tx_json.TransactionType = 'AccountSet';
|
||||
|
||||
assert.strictEqual(transaction.hash(), '1A860FC46D1DD9200560C64002418A4E8BBDE939957AC82D7B14D80A1C0E2EB5')
|
||||
assert.strictEqual(transaction.hash(), '1A860FC46D1DD9200560C64002418A4E8BBDE939957AC82D7B14D80A1C0E2EB5');
|
||||
|
||||
done();
|
||||
});
|
||||
@@ -569,7 +577,7 @@ describe('Transaction', function() {
|
||||
transaction.tx_json.Sequence = 1;
|
||||
transaction.tx_json.TransactionType = 'AccountSet';
|
||||
|
||||
assert.strictEqual(transaction.hash('HASH_TX_SIGN'), 'D1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE')
|
||||
assert.strictEqual(transaction.hash('HASH_TX_SIGN'), 'D1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE');
|
||||
assert.strictEqual(transaction.hash('HASH_TX_SIGN_TESTNET'), '9FE7D27FC5B9891076B66591F99A683E01E0912986A629235459A3BD1961F341');
|
||||
|
||||
done();
|
||||
@@ -594,51 +602,51 @@ describe('Transaction', function() {
|
||||
|
||||
it('Get hash - complex transaction', function() {
|
||||
var input_json = {
|
||||
Account : 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Amount : {
|
||||
currency : 'LTC',
|
||||
issuer : 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
value : '9.985'
|
||||
Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Amount: {
|
||||
currency: 'LTC',
|
||||
issuer: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
value: '9.985'
|
||||
},
|
||||
Destination : 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Fee : '15',
|
||||
Flags : 0,
|
||||
Paths : [
|
||||
Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Fee: '15',
|
||||
Flags: 0,
|
||||
Paths: [
|
||||
[
|
||||
{
|
||||
account : 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q',
|
||||
currency : 'USD',
|
||||
issuer : 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q',
|
||||
type : 49,
|
||||
type_hex : '0000000000000031'
|
||||
account: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q',
|
||||
currency: 'USD',
|
||||
issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q',
|
||||
type: 49,
|
||||
type_hex: '0000000000000031'
|
||||
},
|
||||
{
|
||||
currency : 'LTC',
|
||||
issuer : 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
type : 48,
|
||||
type_hex : '0000000000000030'
|
||||
currency: 'LTC',
|
||||
issuer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
type: 48,
|
||||
type_hex: '0000000000000030'
|
||||
},
|
||||
{
|
||||
account : 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
currency : 'LTC',
|
||||
issuer : 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
type : 49,
|
||||
type_hex : '0000000000000031'
|
||||
account: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
currency: 'LTC',
|
||||
issuer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
type: 49,
|
||||
type_hex: '0000000000000031'
|
||||
}
|
||||
]
|
||||
],
|
||||
SendMax : {
|
||||
currency : 'USD',
|
||||
issuer : 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
value : '30.30993068'
|
||||
SendMax: {
|
||||
currency: 'USD',
|
||||
issuer: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
value: '30.30993068'
|
||||
},
|
||||
Sequence : 415,
|
||||
SigningPubKey : '02854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A',
|
||||
TransactionType : 'Payment',
|
||||
TxnSignature : '304602210096C2F385530587DE573936CA51CB86B801A28F777C944E268212BE7341440B7F022100EBF0508A9145A56CDA7FAF314DF3BBE51C6EE450BA7E74D88516891A3608644E'
|
||||
Sequence: 415,
|
||||
SigningPubKey: '02854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A',
|
||||
TransactionType: 'Payment',
|
||||
TxnSignature: '304602210096C2F385530587DE573936CA51CB86B801A28F777C944E268212BE7341440B7F022100EBF0508A9145A56CDA7FAF314DF3BBE51C6EE450BA7E74D88516891A3608644E'
|
||||
};
|
||||
|
||||
var expected_hash = "87366146D381AD971B97DD41CFAC1AE4670B0E996AB574B0CE18CE6467811868";
|
||||
var expected_hash = '87366146D381AD971B97DD41CFAC1AE4670B0E996AB574B0CE18CE6467811868';
|
||||
var transaction = Transaction.from_json(input_json);
|
||||
|
||||
assert.deepEqual(transaction.hash(), expected_hash);
|
||||
@@ -723,48 +731,48 @@ describe('Transaction', function() {
|
||||
|
||||
it('Serialize transaction', function() {
|
||||
var input_json = {
|
||||
Account : 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Amount : {
|
||||
currency : 'LTC',
|
||||
issuer : 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
value : '9.985'
|
||||
Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Amount: {
|
||||
currency: 'LTC',
|
||||
issuer: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
value: '9.985'
|
||||
},
|
||||
Destination : 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Fee : '15',
|
||||
Flags : 0,
|
||||
Paths : [
|
||||
Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
Fee: '15',
|
||||
Flags: 0,
|
||||
Paths: [
|
||||
[
|
||||
{
|
||||
account : 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q',
|
||||
currency : 'USD',
|
||||
issuer : 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q',
|
||||
type : 49,
|
||||
type_hex : '0000000000000031'
|
||||
account: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q',
|
||||
currency: 'USD',
|
||||
issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q',
|
||||
type: 49,
|
||||
type_hex: '0000000000000031'
|
||||
},
|
||||
{
|
||||
currency : 'LTC',
|
||||
issuer : 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
type : 48,
|
||||
type_hex : '0000000000000030'
|
||||
currency: 'LTC',
|
||||
issuer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
type: 48,
|
||||
type_hex: '0000000000000030'
|
||||
},
|
||||
{
|
||||
account : 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
currency : 'LTC',
|
||||
issuer : 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
type : 49,
|
||||
type_hex : '0000000000000031'
|
||||
account: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
currency: 'LTC',
|
||||
issuer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX',
|
||||
type: 49,
|
||||
type_hex: '0000000000000031'
|
||||
}
|
||||
]
|
||||
],
|
||||
SendMax : {
|
||||
currency : 'USD',
|
||||
issuer : 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
value : '30.30993068'
|
||||
SendMax: {
|
||||
currency: 'USD',
|
||||
issuer: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS',
|
||||
value: '30.30993068'
|
||||
},
|
||||
Sequence : 415,
|
||||
SigningPubKey : '02854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A',
|
||||
TransactionType : 'Payment',
|
||||
TxnSignature : '304602210096C2F385530587DE573936CA51CB86B801A28F777C944E268212BE7341440B7F022100EBF0508A9145A56CDA7FAF314DF3BBE51C6EE450BA7E74D88516891A3608644E'
|
||||
Sequence: 415,
|
||||
SigningPubKey: '02854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A',
|
||||
TransactionType: 'Payment',
|
||||
TxnSignature: '304602210096C2F385530587DE573936CA51CB86B801A28F777C944E268212BE7341440B7F022100EBF0508A9145A56CDA7FAF314DF3BBE51C6EE450BA7E74D88516891A3608644E'
|
||||
};
|
||||
|
||||
var expected_hex = '1200002200000000240000019F61D4A3794DFA1510000000000000000000000000004C54430000000000EF7ED76B77750D79EC92A59389952E0E8054407668400000000000000F69D4CAC4AC112283000000000000000000000000005553440000000000EF7ED76B77750D79EC92A59389952E0E80544076732102854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A7448304602210096C2F385530587DE573936CA51CB86B801A28F777C944E268212BE7341440B7F022100EBF0508A9145A56CDA7FAF314DF3BBE51C6EE450BA7E74D88516891A3608644E8114EF7ED76B77750D79EC92A59389952E0E805440768314EF7ED76B77750D79EC92A59389952E0E80544076011231DD39C650A96EDA48334E70CC4A85B8B2E8502CD30000000000000000000000005553440000000000DD39C650A96EDA48334E70CC4A85B8B2E8502CD3300000000000000000000000004C5443000000000047DA9E2E00ECF224A52329793F1BB20FB1B5EA643147DA9E2E00ECF224A52329793F1BB20FB1B5EA640000000000000000000000004C5443000000000047DA9E2E00ECF224A52329793F1BB20FB1B5EA6400';
|
||||
@@ -810,8 +818,8 @@ describe('Transaction', function() {
|
||||
|
||||
assert.deepEqual(
|
||||
transaction.submittedIDs,
|
||||
[ 'F1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE',
|
||||
'D1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE' ]
|
||||
['F1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE',
|
||||
'D1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE']
|
||||
);
|
||||
|
||||
done();
|
||||
@@ -822,7 +830,7 @@ describe('Transaction', function() {
|
||||
|
||||
assert.deepEqual(transaction.findId({
|
||||
F1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE: transaction
|
||||
}), void(0));
|
||||
}), undefined);
|
||||
|
||||
transaction.addId('F1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE');
|
||||
|
||||
@@ -832,7 +840,7 @@ describe('Transaction', function() {
|
||||
|
||||
assert.strictEqual(transaction.findId({
|
||||
Z1C15200CF532175F1890B6440AD223D3676140522BC11D2784E56760AE3B4FE: transaction
|
||||
}), void(0));
|
||||
}), undefined);
|
||||
|
||||
done();
|
||||
});
|
||||
@@ -846,7 +854,7 @@ describe('Transaction', function() {
|
||||
it('Set DestinationTag', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.destinationTag('tag');
|
||||
assert.strictEqual(transaction.tx_json.DestinationTag, void(0));
|
||||
assert.strictEqual(transaction.tx_json.DestinationTag, undefined);
|
||||
transaction.destinationTag(1);
|
||||
assert.strictEqual(transaction.tx_json.DestinationTag, 1);
|
||||
});
|
||||
@@ -855,7 +863,7 @@ describe('Transaction', function() {
|
||||
var transaction = new Transaction();
|
||||
|
||||
transaction.invoiceID(1);
|
||||
assert.strictEqual(transaction.tx_json.InvoiceID, void(0));
|
||||
assert.strictEqual(transaction.tx_json.InvoiceID, undefined);
|
||||
|
||||
transaction.invoiceID('DEADBEEF');
|
||||
assert.strictEqual(transaction.tx_json.InvoiceID, 'DEADBEEF00000000000000000000000000000000000000000000000000000000');
|
||||
@@ -868,7 +876,7 @@ describe('Transaction', function() {
|
||||
var transaction = new Transaction();
|
||||
|
||||
transaction.clientID(1);
|
||||
assert.strictEqual(transaction._clientID, void(0));
|
||||
assert.strictEqual(transaction._clientID, undefined);
|
||||
|
||||
transaction.clientID('DEADBEEF');
|
||||
assert.strictEqual(transaction._clientID, 'DEADBEEF');
|
||||
@@ -878,11 +886,11 @@ describe('Transaction', function() {
|
||||
var transaction = new Transaction();
|
||||
|
||||
transaction.lastLedger('a');
|
||||
assert.strictEqual(transaction.tx_json.LastLedgerSequence, void(0));
|
||||
assert.strictEqual(transaction.tx_json.LastLedgerSequence, undefined);
|
||||
assert(!transaction._setLastLedger);
|
||||
|
||||
transaction.lastLedger(NaN);
|
||||
assert.strictEqual(transaction.tx_json.LastLedgerSequence, void(0));
|
||||
assert.strictEqual(transaction.tx_json.LastLedgerSequence, undefined);
|
||||
assert(!transaction._setLastLedger);
|
||||
|
||||
transaction.lastLedger(12);
|
||||
@@ -922,8 +930,6 @@ describe('Transaction', function() {
|
||||
});
|
||||
|
||||
it('Rewrite transaction path', function() {
|
||||
var transaction = new Transaction();
|
||||
|
||||
var path = [
|
||||
{
|
||||
account: 'rP51ycDJw5ZhgvdKiRjBYZKYjsyoCcHmnY',
|
||||
@@ -965,7 +971,7 @@ describe('Transaction', function() {
|
||||
|
||||
it('Rewrite transaction path - invalid path', function() {
|
||||
assert.throws(function() {
|
||||
assert.strictEqual(Transaction._rewritePath(1), void(0));
|
||||
assert.strictEqual(Transaction._rewritePath(1), undefined);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -974,7 +980,7 @@ describe('Transaction', function() {
|
||||
|
||||
transaction.pathAdd(1);
|
||||
|
||||
assert.strictEqual(transaction.tx_json.Paths, void(0));
|
||||
assert.strictEqual(transaction.tx_json.Paths, undefined);
|
||||
|
||||
var path = [
|
||||
{
|
||||
@@ -1025,7 +1031,7 @@ describe('Transaction', function() {
|
||||
|
||||
transaction.paths(1);
|
||||
|
||||
assert.strictEqual(transaction.tx_json.Paths, void(0));
|
||||
assert.strictEqual(transaction.tx_json.Paths, undefined);
|
||||
|
||||
transaction.paths([
|
||||
[{
|
||||
@@ -1075,7 +1081,7 @@ describe('Transaction', function() {
|
||||
it('Set SourceTag', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.sourceTag('tag');
|
||||
assert.strictEqual(transaction.tx_json.SourceTag, void(0));
|
||||
assert.strictEqual(transaction.tx_json.SourceTag, undefined);
|
||||
transaction.sourceTag(1);
|
||||
assert.strictEqual(transaction.tx_json.SourceTag, 1);
|
||||
});
|
||||
@@ -1083,7 +1089,7 @@ describe('Transaction', function() {
|
||||
it('Set TransferRate', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.transferRate(1);
|
||||
assert.strictEqual(transaction.tx_json.TransferRate, void(0));
|
||||
assert.strictEqual(transaction.tx_json.TransferRate, undefined);
|
||||
transaction.transferRate(1.5 * 1e9);
|
||||
assert.strictEqual(transaction.tx_json.TransferRate, 1.5 * 1e9);
|
||||
});
|
||||
@@ -1094,33 +1100,33 @@ describe('Transaction', function() {
|
||||
transaction.setFlags();
|
||||
assert.strictEqual(transaction.tx_json.Flags, 0);
|
||||
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
transaction.setFlags(Transaction.flags.Payment.PartialPayment);
|
||||
assert.strictEqual(transaction.tx_json.Flags, 131072);
|
||||
var transaction2 = new Transaction();
|
||||
transaction2.tx_json.TransactionType = 'Payment';
|
||||
transaction2.setFlags(Transaction.flags.Payment.PartialPayment);
|
||||
assert.strictEqual(transaction2.tx_json.Flags, 131072);
|
||||
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
transaction.setFlags('NoRippleDirect');
|
||||
assert.strictEqual(transaction.tx_json.Flags, 65536);
|
||||
var transaction3 = new Transaction();
|
||||
transaction3.tx_json.TransactionType = 'Payment';
|
||||
transaction3.setFlags('NoRippleDirect');
|
||||
assert.strictEqual(transaction3.tx_json.Flags, 65536);
|
||||
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
transaction.setFlags('PartialPayment', 'NoRippleDirect');
|
||||
assert.strictEqual(transaction.tx_json.Flags, 196608);
|
||||
var transaction4 = new Transaction();
|
||||
transaction4.tx_json.TransactionType = 'Payment';
|
||||
transaction4.setFlags('PartialPayment', 'NoRippleDirect');
|
||||
assert.strictEqual(transaction4.tx_json.Flags, 196608);
|
||||
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
transaction.setFlags([ 'LimitQuality', 'PartialPayment' ]);
|
||||
assert.strictEqual(transaction.tx_json.Flags, 393216);
|
||||
var transaction5 = new Transaction();
|
||||
transaction5.tx_json.TransactionType = 'Payment';
|
||||
transaction5.setFlags(['LimitQuality', 'PartialPayment']);
|
||||
assert.strictEqual(transaction5.tx_json.Flags, 393216);
|
||||
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
transaction.once('error', function(err) {
|
||||
var transaction6 = new Transaction();
|
||||
transaction6.tx_json.TransactionType = 'Payment';
|
||||
transaction6.once('error', function(err) {
|
||||
assert.strictEqual(err.result, 'tejInvalidFlag');
|
||||
done();
|
||||
});
|
||||
transaction.setFlags('asdf');
|
||||
transaction6.setFlags('asdf');
|
||||
});
|
||||
|
||||
it('Add Memo', function() {
|
||||
@@ -1179,10 +1185,10 @@ describe('Transaction', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
transaction.addMemo('testkey', void(0), 'testvalue');
|
||||
transaction.addMemo('testkey2', void(0), 'testvalue2');
|
||||
transaction.addMemo('testkey', undefined, 'testvalue');
|
||||
transaction.addMemo('testkey2', undefined, 'testvalue2');
|
||||
transaction.addMemo('testkey3', 'text/html');
|
||||
transaction.addMemo(void(0), void(0), 'testvalue4');
|
||||
transaction.addMemo(undefined, undefined, 'testvalue4');
|
||||
transaction.addMemo('testkey4', 'text/html', '<html>');
|
||||
|
||||
var expected = [
|
||||
@@ -1244,7 +1250,7 @@ describe('Transaction', function() {
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
assert.throws(function() {
|
||||
transaction.addMemo(void(0), 1);
|
||||
transaction.addMemo(undefined, 1);
|
||||
}, /^Error: MemoFormat must be a string$/);
|
||||
});
|
||||
|
||||
@@ -1253,7 +1259,7 @@ describe('Transaction', function() {
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
assert.throws(function() {
|
||||
transaction.addMemo(void(0), 'России');
|
||||
transaction.addMemo(undefined, 'России');
|
||||
}, /^Error: MemoFormat must be valid ASCII$/);
|
||||
});
|
||||
|
||||
@@ -1261,7 +1267,7 @@ describe('Transaction', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
transaction.addMemo({memoData:'some_string'});
|
||||
transaction.addMemo({memoData: 'some_string'});
|
||||
|
||||
assert.deepEqual(transaction.tx_json.Memos, [
|
||||
{
|
||||
@@ -1360,7 +1366,7 @@ describe('Transaction', function() {
|
||||
|
||||
it('Construct AccountSet transaction - invalid account', function() {
|
||||
assert.throws(function() {
|
||||
var transaction = new Transaction().accountSet('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm');
|
||||
new Transaction().accountSet('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1393,7 +1399,7 @@ describe('Transaction', function() {
|
||||
|
||||
it('Construct OfferCancel transaction - invalid account', function() {
|
||||
assert.throws(function() {
|
||||
var transaction = new Transaction().offerCancel('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', 1);
|
||||
new Transaction().offerCancel('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', 1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1595,7 +1601,7 @@ describe('Transaction', function() {
|
||||
|
||||
it('Construct Payment transaction - invalid account', function() {
|
||||
assert.throws(function() {
|
||||
var transaction = new Transaction().payment(
|
||||
new Transaction().payment(
|
||||
'xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm',
|
||||
'r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe',
|
||||
'1/USD/r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe'
|
||||
@@ -1605,7 +1611,7 @@ describe('Transaction', function() {
|
||||
|
||||
it('Construct Payment transaction - invalid destination', function() {
|
||||
assert.throws(function() {
|
||||
var transaction = new Transaction().payment(
|
||||
new Transaction().payment(
|
||||
'rsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm',
|
||||
'xr36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe',
|
||||
'1/USD/r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe'
|
||||
@@ -1674,7 +1680,7 @@ describe('Transaction', function() {
|
||||
it('Construct TrustSet transaction - invalid account', function() {
|
||||
assert.throws(function() {
|
||||
var limit = '1/USD/r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe';
|
||||
var transaction = new Transaction().trustSet('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', limit, 1.0, 1.0);
|
||||
new Transaction().trustSet('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', limit, 1.0, 1.0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1682,9 +1688,9 @@ describe('Transaction', function() {
|
||||
var remote = new Remote();
|
||||
var transaction = new Transaction(remote).accountSet('r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
|
||||
assert.strictEqual(transaction.callback, void(0));
|
||||
assert.strictEqual(transaction._errorHandler, void(0));
|
||||
assert.strictEqual(transaction._successHandler, void(0));
|
||||
assert.strictEqual(transaction.callback, undefined);
|
||||
assert.strictEqual(transaction._errorHandler, undefined);
|
||||
assert.strictEqual(transaction._successHandler, undefined);
|
||||
assert.strictEqual(transaction.listeners('error').length, 1);
|
||||
|
||||
var account = remote.addAccount('r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
@@ -1705,13 +1711,13 @@ describe('Transaction', function() {
|
||||
receivedSuccess = true;
|
||||
});
|
||||
|
||||
function submitCallback(err, res) {
|
||||
function submitCallback(err) {
|
||||
setImmediate(function() {
|
||||
assert.ifError(err);
|
||||
assert(receivedSuccess);
|
||||
done();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
transaction.submit(submitCallback);
|
||||
|
||||
@@ -1744,14 +1750,14 @@ describe('Transaction', function() {
|
||||
receivedError = true;
|
||||
});
|
||||
|
||||
function submitCallback(err, res) {
|
||||
function submitCallback(err) {
|
||||
setImmediate(function() {
|
||||
assert(err);
|
||||
assert.strictEqual(err.constructor.name, 'RippleError');
|
||||
assert(receivedError);
|
||||
done();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
transaction.submit(submitCallback);
|
||||
});
|
||||
@@ -1771,7 +1777,7 @@ describe('Transaction', function() {
|
||||
it('Submit transaction - invalid account', function(done) {
|
||||
var remote = new Remote();
|
||||
assert.throws(function() {
|
||||
var transaction = new Transaction(remote).accountSet('r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWeZ');
|
||||
new Transaction(remote).accountSet('r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWeZ');
|
||||
});
|
||||
done();
|
||||
});
|
||||
@@ -1781,7 +1787,9 @@ describe('Transaction', function() {
|
||||
remote.setSecret('rJaT8TafQfYJqDm8aC5n3Yx5yWEL2Ery79', 'snPwFATthTkKnGjEW73q3TL4yci1Q');
|
||||
|
||||
var server = new Server(remote, 'wss://s1.ripple.com:443');
|
||||
server._computeFee = function() { return '12'; };
|
||||
server._computeFee = function() {
|
||||
return '12';
|
||||
};
|
||||
server._connected = true;
|
||||
|
||||
remote._servers.push(server);
|
||||
@@ -1797,7 +1805,7 @@ describe('Transaction', function() {
|
||||
transaction.abort();
|
||||
});
|
||||
|
||||
transaction.submit(function(err, res) {
|
||||
transaction.submit(function(err) {
|
||||
setImmediate(function() {
|
||||
assert(err);
|
||||
assert.strictEqual(err.result, 'tejAbort');
|
||||
@@ -1822,7 +1830,7 @@ describe('Transaction', function() {
|
||||
872298,
|
||||
543305
|
||||
]
|
||||
.forEach(function(index){
|
||||
.forEach(function(index) {
|
||||
var tx = new Transaction();
|
||||
tx.initialSubmitIndex = index;
|
||||
queue.push(tx);
|
||||
@@ -1833,11 +1841,9 @@ describe('Transaction', function() {
|
||||
return a.initialSubmitIndex - b.initialSubmitIndex;
|
||||
});
|
||||
|
||||
sorted.forEach(function(tx){
|
||||
sorted.forEach(function(tx) {
|
||||
assert.strictEqual(queue.getMinLedger(), tx.initialSubmitIndex);
|
||||
queue.remove(tx);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
//vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
Reference in New Issue
Block a user