Compare commits

...

26 Commits

Author SHA1 Message Date
Geert Weening
ef51490a1a Bump version to 0.12.3 2015-04-13 16:27:52 -07:00
Geert Weening
c40d643238 Bump version to 0.12.3-rc2 2015-04-10 14:36:47 -07:00
Geert Weening
6f23c88567 Update release notes 2015-04-10 14:36:15 -07:00
Geert Weening
56958a6242 Merge pull request #324 from clark800/develop
Add Amount.scale
2015-04-10 13:25:57 -07:00
Chris Clark
74dac97b36 Add Amount.scale 2015-04-10 12:56:50 -07:00
Geert Weening
2f2e41c781 Bump version to 0.12.3-rc1 2015-04-08 13:36:23 -07:00
Geert Weening
8c872f71c6 Update release notes 2015-04-08 13:36:01 -07:00
wltsmrz
b40b496866 Merge pull request #322 from clark800/rest1.7
Add getLedgerSequence method
2015-04-08 11:20:46 -07:00
Geert Weening
569fec296e Merge pull request #321 from clark800/paranoia
[FIX] Fail if PRNG has not been seeded with at least 256 bits of entr…
2015-04-08 11:16:47 -07:00
Chris Clark
56d8aa797a Fix lint errors in transaction-test.js and transaction-manager-test.js 2015-04-07 18:08:07 -07:00
Chris Clark
fe7e30b737 [FIX] Fail if PRNG has not been seeded with at least 256 bits of entropy before generating ECDSA signatures 2015-04-07 18:08:02 -07:00
Chris Clark
a114281c60 Update comment about the fee base reference constant 2015-04-07 14:34:26 -07:00
Chris Clark
d09548d04d Add getLedgerSequence 2015-04-07 14:34:22 -07:00
Geert Weening
a02b8e3e5c Merge branch 'release' into develop 2015-04-06 13:00:36 -07:00
Geert Weening
2c3f9ca202 bump version to 0.12.2 2015-04-06 12:57:47 -07:00
Geert Weening
587782820d Merge pull request #318 from sublimator/serial-offender
Fix SerializedObject.append performance issue
2015-04-06 12:54:48 -07:00
Nicholas Dudfield
8fad048569 Update verify_ledger_json.js script:
* Set `Amount.strict_mode = false` in verify_ledger_json.js script
* Don't try and calculate hash of non present accountState
* Fix lint issues
2015-04-04 14:51:35 +07:00
Nicholas Dudfield
f7c35b118e Fix SerializedObject.append perf issue:
* Replace array.concat(array2) with Array.prototype.push.apply
2015-04-04 14:51:12 +07:00
Geert Weening
65a669bbb2 Merge pull request #319 from sublimator/lints
eslint fixes
2015-04-04 00:35:57 -07:00
Nicholas Dudfield
9985acc539 Fix linting issues:
* Fix lint violations in various files
* Use per-file comment directives to make new-cap a warning instead of error
  * sjcl.* don't conform to our standards and eslint exemptions are unweildy
2015-04-04 14:23:41 +07:00
Geert Weening
f1f0a43f21 Bump version to 0.12.1-rc1 2015-03-27 16:56:27 -07:00
Geert Weening
6b856c3cc5 Update release notes 2015-03-27 16:55:44 -07:00
Geert Weening
d92888ed73 Merge pull request #317 from ripple/fix-browser-log
Check that Error.stack is available, fixes logging in browser
2015-03-27 16:52:18 -07:00
wltsmrz
0357840654 Lint 2015-03-27 15:54:26 -07:00
wltsmrz
53cae3a66d Check that stack trace is available, fixes logging in browser 2015-03-27 15:49:13 -07:00
Geert Weening
949a1ca4ae Bump version to 0.12.1 2015-03-26 15:12:14 -07:00
19 changed files with 614 additions and 487 deletions

View File

@@ -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 amounts 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
View File

@@ -1,6 +1,6 @@
{
"name": "ripple-lib",
"version": "0.12.1-rc6",
"version": "0.12.3",
"dependencies": {
"async": {
"version": "0.9.0",

View File

@@ -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",

View File

@@ -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 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');
}

View File

@@ -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()) {

View File

@@ -1,3 +1,7 @@
'use strict';
/*eslint new-cap: 1*/
var sjcl = require('./utils').sjcl;
var UInt160 = require('./uint160').UInt160;
@@ -8,7 +12,7 @@ function KeyPair() {
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);
};

View File

@@ -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);
}

View File

@@ -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
*

View File

@@ -1,3 +1,5 @@
'use strict';
//
// Seed support
//
@@ -8,7 +10,6 @@ var sjcl = utils.sjcl;
var Base = require('./base').Base;
var UInt = require('./uint').UInt;
var UInt256 = require('./uint256').UInt256;
var UInt160 = require('./uint160').UInt160;
var KeyPair = require('./keypair').KeyPair;
@@ -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,8 +91,9 @@ 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) {
var account_number = 0, address;
@@ -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));
@@ -146,6 +153,7 @@ Seed.prototype.get_key = function (account, maxLoops) {
}
} while (address && !key_pair.get_address().equals(address));
return key_pair;
};

View File

@@ -1,3 +1,5 @@
'use strict';
var _ = require('lodash');
var assert = require('assert');
var extend = require('extend');
@@ -29,7 +31,9 @@ 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';
}
@@ -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;
}
// 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,7 +230,10 @@ 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
output = new structure.constructor();
@@ -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);
}
@@ -274,15 +291,9 @@ SerializedObject.prototype.signing_hash = SerializedObject.prototype.hash;
SerializedObject.prototype.serialize_field = function(spec, obj) {
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

View File

@@ -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,7 +56,9 @@ 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) {
var depth = this.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,7 +111,6 @@ SHAMapTreeNodeInner.prototype.hash = function() {
}
var hash_buffer = new SerializedObject();
var buffer = [ ];
for (var i = 0; i < 16; i++) {
var leafHash = UInt256.from_hex(UInt256.HEX_ZERO);
@@ -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,7 +146,7 @@ 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);
@@ -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;

View File

@@ -1,5 +1,6 @@
'use strict';
var util = require('util');
var assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var utils = require('./utils');
var sjcl = require('./utils').sjcl;
@@ -36,13 +37,13 @@ function Transaction(remote) {
this.remote = remote;
this.tx_json = {Flags: 0};
this._secret = void(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
};
@@ -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) {
@@ -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,7 +321,7 @@ Transaction.prototype.feeUnits = function() {
Transaction.prototype._computeFee = function() {
if (!this.remote) {
return void(0);
return undefined;
}
var servers = this.remote._servers;
@@ -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;
}
@@ -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;
@@ -778,7 +786,7 @@ Transaction.prototype.transferRate = function(rate) {
*/
Transaction.prototype.setFlags = function(flags) {
if (flags === void(0)) {
if (flags === undefined) {
return this;
}
@@ -862,10 +870,12 @@ 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');
}
}
@@ -926,14 +936,24 @@ Transaction.prototype.accountSet = function(src, set_flag, clear_flag) {
return (typeof flag === 'number')
? 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);
}
@@ -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
};

View File

@@ -1,3 +1,7 @@
'use strict';
/*eslint new-cap: 1*/
var utils = require('./utils');
var sjcl = utils.sjcl;
var config = require('./config');
@@ -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._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,6 +136,7 @@ UInt.prototype.parse_generic = function(j) {
j = config.accounts[j].account;
}
switch (j) {
case undefined:
case '0':
@@ -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;

View File

@@ -1,3 +1,5 @@
'use strict';
var utils = require('./utils');
var extend = require('extend');
var UInt = require('./uint').UInt;
@@ -16,7 +18,8 @@ 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);
UInt128.STR_ZERO = utils.hexToString(HEX_ZERO);
UInt128.STR_ONE = utils.hexToString(HEX_ONE);
exports.UInt128 = UInt128;

View File

@@ -1,3 +1,5 @@
'use strict';
var utils = require('./utils');
var config = require('./config');
var extend = require('extend');
@@ -11,7 +13,7 @@ var Base = require('./base').Base;
var UInt160 = extend(function() {
this._value = NaN;
this._version_byte = void(0);
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);
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;
@@ -90,9 +93,8 @@ UInt160.prototype.to_json = function(opts) {
}
return output;
} else {
return this.to_hex();
}
return this.to_hex();
}
return NaN;
};

View File

@@ -1,3 +1,5 @@
'use strict';
var utils = require('./utils');
var extend = require('extend');
var UInt = require('./uint').UInt;
@@ -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;

View File

@@ -1,3 +1,4 @@
'use strict';
function getMantissaDecimalString(bignum) {
var mantissa = bignum.toPrecision(16)
@@ -10,27 +11,12 @@ 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);
@@ -40,7 +26,7 @@ function arraySet(count, value) {
}
return a;
};
}
function hexToString(h) {
var a = [];
@@ -56,7 +42,7 @@ function hexToString(h) {
}
return a.join('');
};
}
function stringToHex(s) {
var result = '';
@@ -65,7 +51,7 @@ function stringToHex(s) {
result += b < 16 ? '0' + b.toString(16) : b.toString(16);
}
return result;
};
}
function stringToArray(s) {
var a = new Array(s.length);
@@ -75,11 +61,11 @@ function stringToArray(s) {
}
return a;
};
}
function hexToArray(h) {
return stringToArray(hexToString(h));
};
}
function arrayToHex(a) {
return a.map(function(byteValue) {
@@ -104,16 +90,17 @@ function chunkString(str, n, leftAlign) {
}
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 = [];
@@ -128,29 +115,28 @@ 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.
*/
function fromTimestamp(rpepoch) {
if (rpepoch instanceof Date) {
rpepoch = rpepoch.getTime();
}
return Math.round(rpepoch / 1000) - 0x386D4380;
};
/**
* @param {Number|Date} timestamp (ms since unix epoch)
* @return {Number} seconds since ripple epoch ( 1/1/2000 GMT)
*/
function fromTimestamp(timestamp) {
if (timestamp instanceof Date) {
timestamp = timestamp.getTime();
}
return Math.round(timestamp / 1000) - 0x386D4380;
}
exports.time = {
fromRipple: toTimestamp,

View File

@@ -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) {

View File

@@ -1,9 +1,11 @@
/* eslint-disable max-len */
'use strict';
var assert = require('assert');
var Amount = require('ripple-lib').Amount;
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 sjcl = require('ripple-lib').sjcl;
var transactionResult = {
engine_result: 'tesSUCCESS',
@@ -17,7 +19,8 @@ var transactionResult = {
metadata: {
AffectedNodes: [ ],
TransactionIndex: 0,
TransactionResult: 'tesSUCCESS' },
TransactionResult: 'tesSUCCESS'
},
tx_json: {
Account: 'rHPotLj3CNKaP4bQANcecEuT8hai3VpxfB',
Amount: '1000000',
@@ -35,6 +38,11 @@ var transactionResult = {
};
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() {
@@ -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() {
@@ -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() {
@@ -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';
@@ -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());
@@ -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();
@@ -638,7 +646,7 @@ describe('Transaction', function() {
TxnSignature: '304602210096C2F385530587DE573936CA51CB86B801A28F777C944E268212BE7341440B7F022100EBF0508A9145A56CDA7FAF314DF3BBE51C6EE450BA7E74D88516891A3608644E'
};
var expected_hash = "87366146D381AD971B97DD41CFAC1AE4670B0E996AB574B0CE18CE6467811868";
var expected_hash = '87366146D381AD971B97DD41CFAC1AE4670B0E996AB574B0CE18CE6467811868';
var transaction = Transaction.from_json(input_json);
assert.deepEqual(transaction.hash(), expected_hash);
@@ -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$/);
});
@@ -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');
@@ -1839,5 +1847,3 @@ describe('Transaction', function() {
});
});
});
//vim:sw=2:sts=2:ts=8:et