Merge pull request #344 from clark800/babel

Setup babel transpiler
This commit is contained in:
Chris Clark
2015-05-15 16:59:32 -07:00
22 changed files with 991 additions and 879 deletions

2
.gitignore vendored
View File

@@ -17,7 +17,7 @@
# Ignore object files.
*.o
build/*.js
build/
tags
bin/rippled
Debug/*.*

View File

@@ -1,2 +1,4 @@
lib-cov
coverage.html
src
dist/bower

View File

@@ -1,9 +1,9 @@
language: node_js
node_js:
- "0.10"
- "0.12"
before_script:
- npm install -g eslint
- curl 'https://raw.githubusercontent.com/ripple/javascript-style-guide/master/eslintrc' > ./eslintrc
- curl 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc' > ./eslintrc
- eslint --reset -c ./eslintrc $(git --no-pager diff --name-only -M100% --diff-filter=AM --relative $(git merge-base FETCH_HEAD origin/HEAD) FETCH_HEAD | grep "\.js$")
script: MOCHA_REPORTER=tap npm test --coverage
after_success:

View File

@@ -1,4 +1,7 @@
/* eslint-disable no-var, no-param-reassign */
/* these eslint rules are disabled because gulp does not support babel yet */
'use strict';
var _ = require('lodash');
var gulp = require('gulp');
var gutil = require('gulp-util');
var watch = require('gulp-watch');
@@ -15,20 +18,33 @@ var argv = require('yargs').argv;
var pkg = require('./package.json');
function logPluginError(error) {
gutil.log(error.toString());
}
gulp.task('build', function(callback) {
webpack({
function webpackConfig(extension, overrides) {
overrides = overrides || {};
var defaults = {
cache: true,
entry: './src/index.js',
output: {
library: 'ripple',
path: './build/',
filename: ['ripple-', '.js'].join(pkg.version)
filename: ['ripple-', extension].join(pkg.version)
},
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader?optional=runtime'
}]
}
}, callback);
};
return _.assign({}, defaults, overrides);
}
function logPluginError(error) {
gutil.log(error.toString());
}
gulp.task('build', function(callback) {
webpack(webpackConfig('.js'), callback);
});
gulp.task('build-min', ['build'], function() {
@@ -39,17 +55,8 @@ gulp.task('build-min', ['build'], function() {
});
gulp.task('build-debug', function(callback) {
webpack({
cache: true,
entry: './src/index.js',
output: {
library: 'ripple',
path: './build/',
filename: ['ripple-', '-debug.js'].join(pkg.version)
},
debug: true,
devtool: 'eval'
}, callback);
var configOverrides = {debug: true, devtool: 'eval'};
webpack(webpackConfig('-debug.js', configOverrides), callback);
});
/**
@@ -64,51 +71,44 @@ function buildUseError(cons) {
}
gulp.task('build-core', function(callback) {
webpack({
entry: [
'./src/remote.js'
],
externals: [
{
'./transaction': buildUseError('Transaction'),
'./orderbook': buildUseError('OrderBook'),
'./account': buildUseError('Account'),
'./serializedobject': buildUseError('SerializedObject')
}
],
output: {
library: 'ripple',
path: './build/',
filename: ['ripple-', '-core.js'].join(pkg.version)
},
var configOverrides = {
cache: false,
entry: './src/remote.js',
externals: [{
'./transaction': buildUseError('Transaction'),
'./orderbook': buildUseError('OrderBook'),
'./account': buildUseError('Account'),
'./serializedobject': buildUseError('SerializedObject')
}],
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
}, callback);
};
webpack(webpackConfig('-core.js', configOverrides), callback);
});
gulp.task('bower-build', ['build'], function() {
return gulp.src(['./build/ripple-', '.js'].join(pkg.version))
.pipe(rename('ripple.js'))
.pipe(gulp.dest('./dist/'));
.pipe(gulp.dest('./dist/bower'));
});
gulp.task('bower-build-min', ['build-min'], function() {
return gulp.src(['./build/ripple-', '-min.js'].join(pkg.version))
.pipe(rename('ripple-min.js'))
.pipe(gulp.dest('./dist/'));
.pipe(gulp.dest('./dist/bower'));
});
gulp.task('bower-build-debug', ['build-debug'], function() {
return gulp.src(['./build/ripple-', '-debug.js'].join(pkg.version))
.pipe(rename('ripple-debug.js'))
.pipe(gulp.dest('./dist/'));
.pipe(gulp.dest('./dist/bower'));
});
gulp.task('bower-version', function() {
gulp.src('./dist/bower.json')
gulp.src('./dist/bower/bower.json')
.pipe(bump({version: pkg.version}))
.pipe(gulp.dest('./dist/'));
.pipe(gulp.dest('./dist/bower'));
});
gulp.task('bower', ['bower-build', 'bower-build-min', 'bower-build-debug',

View File

@@ -1,47 +1,52 @@
#!/usr/bin/env node
/* eslint-disable no-var */
'use strict';
var SerializedObject = require('..').SerializedObject;
var SerializedObject = require('../src/js/ripple/serializedobject').SerializedObject;
function main() {
var argv = process.argv.slice(2);
var blob = argv.shift();
var argv = process.argv.slice(2);
var blob;
blob = argv.shift();
if (blob === '-') {
read_input(ready);
} else {
ready();
if (blob === '-') {
read_input(ready);
} else {
ready(blob);
}
}
function read_input(callback) {
tx_json = '';
process.stdin.on('data', function(data) { tx_json += data; });
var tx_json = '';
process.stdin.on('data', function(data) {
tx_json += data;
});
process.stdin.on('end', callback);
process.stdin.resume();
}
function ready() {
function ready(blob) {
var valid_arguments = blob;
if (!valid_arguments) {
console.error('Invalid arguments\n');
print_usage();
} else {
decode();
}
decode(blob);
}
}
function print_usage() {
/* eslint-disable max-len */
console.log(
'Usage: decode_binary.js <hex_blob>\n\n',
'Example: decode_binary.js 120000240000000161D6871AFD498D00000000000000000000000000005553440000000000550FC62003E785DC231A1058A05E56E3F09CF4E668400000000000000A732102AE75B908F0A95F740A7BFA96057637E5C2170BC8DAD13B2F7B52AE75FAEBEFCF811450F97A072F1C4357F1AD84566A609479D927C9428314550FC62003E785DC231A1058A05E56E3F09CF4E6'
);
};
/* eslint-enable max-len */
}
function decode() {
buffer = new SerializedObject(blob);
function decode(blob) {
var buffer = new SerializedObject(blob);
console.log(buffer.to_json());
};
}
main();
// vim:sw=2:sts=2:ts=8:et

View File

@@ -1,62 +1,23 @@
#!/usr/bin/env node
var Transaction = require('../src/js/ripple/transaction').Transaction;
var argv = process.argv.slice(2);
var verbose;
var secret;
var tx_json;
if (~argv.indexOf('-v')){
argv.splice(argv.indexOf('-v'), 1);
verbose = true;
}
secret = argv.shift();
tx_json = argv.shift();
if (tx_json === '-') {
read_input(ready);
} else {
ready();
}
/* eslint-disable no-var */
'use strict';
var Transaction = require('..').Transaction;
function read_input(callback) {
tx_json = '';
process.stdin.on('data', function(data) { tx_json += data; });
process.stdin.on('end', callback);
var stdin = '';
process.stdin.on('data', function(data) {
stdin += data;
});
process.stdin.on('end', function() {
callback(stdin);
});
process.stdin.resume();
}
function ready() {
var valid_arguments = secret && tx_json;
if (!valid_arguments) {
console.error('Invalid arguments\n');
print_usage();
} else {
var valid_json = true;
try {
tx_json = JSON.parse(tx_json);
} catch(exception) {
valid_json = false;
}
if (!valid_json) {
console.error('Invalid JSON\n');
print_usage();
} else {
sign_transaction();
}
}
}
function print_usage() {
console.log(
'Usage: rsign.js <secret> <json>\n\n',
'Example: rsign.js ssq55ueDob4yV3kPVnNQLHB6icwpC','\''+
'Example: rsign.js ssq55ueDob4yV3kPVnNQLHB6icwpC', '\'' +
JSON.stringify({
TransactionType: 'Payment',
Account: 'r3P9vH81KBayazSTrQj6S25jW6kDb779Gi',
@@ -64,14 +25,14 @@ function print_usage() {
Amount: '200000000',
Fee: '10',
Sequence: 1
})+'\''
);
};
}) + '\''
);
}
function sign_transaction() {
function sign_transaction(tx_json_object, secret, verbose) {
var tx = new Transaction();
tx.tx_json = tx_json;
tx.tx_json = tx_json_object;
tx._secret = secret;
tx.complete();
@@ -81,16 +42,56 @@ function sign_transaction() {
if (verbose) {
var sim = { };
sim.tx_blob = tx.serialize().to_hex();
sim.tx_json = tx.tx_json;
sim.tx_blob = tx.serialize().to_hex();
sim.tx_json = tx.tx_json;
sim.tx_signing_hash = unsigned_hash;
sim.tx_unsigned = unsigned_blob;
sim.tx_unsigned = unsigned_blob;
console.log(JSON.stringify(sim, null, 2));
} else {
console.log(tx.serialize().to_hex());
}
};
}
function ready(tx_json, secret, verbose) {
if (!(tx_json && secret)) {
console.error('Invalid arguments\n');
print_usage();
return;
}
var tx_json_object;
try {
tx_json_object = JSON.parse(tx_json);
} catch(exception) {
console.error('Invalid JSON\n');
print_usage();
return;
}
sign_transaction(tx_json_object, secret, verbose);
}
function main() {
var argv = process.argv.slice(2);
var verbose;
var secret;
var tx_json;
if (~argv.indexOf('-v')) {
argv.splice(argv.indexOf('-v'), 1);
verbose = true;
}
secret = argv.shift();
tx_json = argv.shift();
if (tx_json === '-') {
read_input(function(stdin) {
ready(stdin, secret, verbose);
});
} else {
ready(tx_json, secret, verbose);
}
}
main();
// vim:sw=2:sts=2:ts=8:et

View File

@@ -1,12 +1,16 @@
#!/usr/bin/env node
/* eslint-disable no-var */
'use strict';
var UInt160 = require('..').UInt160;
var UInt160 = require('../').UInt160;
var address = process.argv[2];
function main() {
var address = process.argv[2];
if (address === '-') {
readInput(validateAddress);
} else {
validateAddress(address);
if (address === '-') {
readInput(validateAddress);
} else {
validateAddress(address);
}
}
function readInput(callback) {
@@ -19,8 +23,10 @@ function readInput(callback) {
process.stdin.on('end', function() {
callback(result);
});
};
}
function validateAddress(address) {
process.stdout.write((UInt160.is_valid(address.trim()) ? '0' : '1') + '\r\n');
};
}
main();

16
npm-shrinkwrap.json generated
View File

@@ -2,12 +2,22 @@
"name": "ripple-lib",
"version": "0.12.5-rc2",
"npm-shrinkwrap-version": "5.4.0",
"node-version": "v0.10.38",
"node-version": "v0.12.3",
"dependencies": {
"async": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
},
"babel-runtime": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.3.3.tgz",
"dependencies": {
"core-js": {
"version": "0.9.9",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-0.9.9.tgz"
}
}
},
"bignumber.js": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.0.7.tgz"
@@ -17,8 +27,8 @@
"resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz"
},
"lodash": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz"
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.8.0.tgz"
},
"lru-cache": {
"version": "2.5.2",

View File

@@ -3,19 +3,19 @@
"version": "0.12.5-rc2",
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
"files": [
"src/js/*",
"dist/npm/*",
"bin/*",
"build/*",
"test/*",
"Makefile",
"Gulpfile.js"
],
"main": "src/",
"main": "dist/npm/",
"directories": {
"test": "test"
},
"dependencies": {
"async": "~0.9.0",
"babel-runtime": "^5.3.2",
"bignumber.js": "^2.0.3",
"extend": "~1.2.1",
"lodash": "^3.1.0",
@@ -26,6 +26,9 @@
},
"devDependencies": {
"assert-diff": "^1.0.1",
"babel": "^5.3.3",
"babel-core": "^5.3.2",
"babel-loader": "^5.0.0",
"coveralls": "~2.10.0",
"eslint": "^0.18.0",
"gulp": "~3.8.10",
@@ -48,10 +51,13 @@
},
"scripts": {
"build": "gulp",
"compile": "babel -i runtime -d dist/npm/ src/",
"compile-with-source-maps": "babel -i runtime -s -t -d dist/npm/ src/",
"prepublish": "npm run compile",
"postinstall": "cd node_modules/sjcl; ./configure --with-all --compress=none; make",
"test": "istanbul test _mocha",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"lint": "if ! [ -f eslintrc ]; then curl -o eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/master/eslintrc'; fi; eslint --reset -c eslintrc src/*.js",
"lint": "if ! [ -f eslintrc ]; then curl -o eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc'; fi; eslint --reset -c eslintrc src/*.js",
"perf": "./scripts/perf_test.sh"
},
"repository": {

View File

@@ -8,4 +8,4 @@ then
mkdir -p "$DIR/cache"
curl -L "$URL" > "$DEST"
fi
time node "$DIR/verify_ledger_json.js" "$DEST"
npm run compile && time node "$DIR/verify_ledger_json.js" "$DEST"

View File

@@ -17,15 +17,15 @@ echo "publish to npm"
npm publish
exit_on_error
rm -rf dist
rm -rf dist/bower
echo ""
echo "publish to bower"
git clone git@github.com:ripple/bower-ripple.git dist
git clone git@github.com:ripple/bower-ripple.git dist/bower
gulp bower
exit_on_error
cd dist
cd dist/bower
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc[0-9])?')
echo "version: $version"
git add ripple.js ripple-debug.js ripple-min.js bower.json
@@ -40,4 +40,4 @@ exit_on_error
git push origin master
git push --tags origin master
cd ..
cd ..

View File

@@ -17,15 +17,15 @@ echo "publish rc to npm"
npm publish --tag beta
exit_on_error
rm -rf dist
rm -rf dist/bower
echo ""
echo "publish to bower"
git clone git@github.com:ripple/bower-ripple.git dist
git clone git@github.com:ripple/bower-ripple.git dist/bower
gulp bower
exit_on_error
cd dist
cd dist/bower
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc[0-9])?')
echo "version: $version"
git add ripple.js ripple-debug.js ripple-min.js bower.json
@@ -40,4 +40,4 @@ exit_on_error
git push origin master
git push --tags origin master
cd ..
cd ..

View File

@@ -1,7 +1,7 @@
rm -rf dist
git clone git@github.com:ripple/bower-ripple.git dist
rm -rf dist/bower
git clone git@github.com:ripple/bower-ripple.git dist/bower
gulp bower
cd dist
cd dist/bower
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc[0-9])?')
echo "version: $version"
git add ripple.js ripple-debug.js ripple-min.js bower.json
@@ -9,4 +9,4 @@ git commit -m "[TASK] add v$version"
git tag "v$version"
git push origin master
git push --tags origin master
cd ..
cd ..

View File

@@ -1,8 +1,9 @@
/* eslint-disable no-var */
'use strict';
var fs = require('fs');
var Amount = require('../src/js/ripple').Amount;
var Ledger = require('../src/js/ripple/ledger').Ledger;
var Amount = require('../dist/npm').Amount;
var Ledger = require('../dist/npm/ledger').Ledger;
function parse_options(from, flags) {
var argv = from.slice(),
@@ -12,10 +13,10 @@ function parse_options(from, flags) {
// Do we have the flag?
var flag_index = argv.indexOf('--' + f);
// normalize the name of the flag
f = f.replace('-', '_');
var flag = f.replace('-', '_');
// opts_ has Boolean value for normalized flag key
opts_[f] = flag_index !== -1;
if (opts_[f]) {
opts_[flag] = flag_index !== -1;
if (opts_[flag]) {
// remove the flag from the argv
argv.splice(flag_index, 1);
}

View File

@@ -1,10 +1,11 @@
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var async = require('async');
var UInt160 = require('./uint160').UInt160;
var Currency = require('./currency').Currency;
var RippleError = require('./rippleerror').RippleError;
var Server = require('./server').Server;
'use strict';
const EventEmitter = require('events').EventEmitter;
const util = require('util');
const async = require('async');
const UInt160 = require('./uint160').UInt160;
const Currency = require('./currency').Currency;
const RippleError = require('./rippleerror').RippleError;
// Request events emitted:
// 'success' : Request successful.
@@ -30,20 +31,15 @@ function Request(remote, command) {
this.errorEvent = 'error';
this.message = {
command: command,
id: void(0)
id: undefined
};
};
}
util.inherits(Request, EventEmitter);
// Send the request to a remote.
Request.prototype.request = function(servers, callback) {
this.emit('before');
if (typeof servers === 'function') {
callback = servers;
}
this.callback(callback);
if (this.requested) {
@@ -51,7 +47,7 @@ Request.prototype.request = function(servers, callback) {
}
this.requested = true;
this.on('error', function(){});
this.on('error', function() {});
this.emit('request', this.remote);
if (Array.isArray(servers)) {
@@ -79,8 +75,8 @@ Request.prototype.request = function(servers, callback) {
Request.prototype.filter =
Request.prototype.addFilter =
Request.prototype.broadcast = function(filterFn) {
var self = this;
Request.prototype.broadcast = function(filterFn=Boolean) {
const self = this;
if (!this.requested) {
// Defer until requested, and prevent the normal request() from executing
@@ -91,10 +87,9 @@ Request.prototype.broadcast = function(filterFn) {
return this;
}
var filterFn = typeof filterFn === 'function' ? filterFn : Boolean;
var lastResponse = new Error('No servers available');
var connectTimeouts = { };
var emit = this.emit;
let lastResponse = new Error('No servers available');
let connectTimeouts = { };
const emit = this.emit;
this.emit = function(event, a, b) {
// Proxy success/error events
@@ -123,13 +118,13 @@ Request.prototype.broadcast = function(filterFn) {
// Server is disconnected but should reconnect. Wait for it to reconnect,
// and abort after a timeout
var serverID = server.getServerID();
const serverID = server.getServerID();
function serverReconnected() {
clearTimeout(connectTimeouts[serverID]);
connectTimeouts[serverID] = null;
iterator(server, callback);
};
}
connectTimeouts[serverID] = setTimeout(function() {
server.removeListener('connect', serverReconnected);
@@ -137,27 +132,27 @@ Request.prototype.broadcast = function(filterFn) {
}, self.reconnectTimeout);
server.once('connect', serverReconnected);
};
}
function complete(success) {
// Emit success if the filter is satisfied by any server
// Emit error if the filter is not satisfied by any server
// Include the last response
emit.call(self, success ? 'success' : 'error', lastResponse);
};
}
var servers = this.remote._servers.filter(function(server) {
const servers = this.remote._servers.filter(function(server) {
// Pre-filter servers that are disconnected and should not reconnect
return (server.isConnected() || server._shouldConnect)
// Pre-filter servers that do not contain the ledger in request
&& (!self.message.hasOwnProperty('ledger_index')
|| server.hasLedger(self.message.ledger_index))
&& (!self.message.hasOwnProperty('ledger_index_min')
// Pre-filter servers that do not contain the ledger in request
&& (!self.message.hasOwnProperty('ledger_index')
|| server.hasLedger(self.message.ledger_index))
&& (!self.message.hasOwnProperty('ledger_index_min')
|| self.message.ledger_index_min === -1
|| server.hasLedger(self.message.ledger_index_min))
&& (!self.message.hasOwnProperty('ledger_index_max')
&& (!self.message.hasOwnProperty('ledger_index_max')
|| self.message.ledger_index_max === -1
|| server.hasLedger(self.message.ledger_index_max))
|| server.hasLedger(self.message.ledger_index_max));
});
// Apply iterator in parallel to connected servers, complete when the
@@ -169,7 +164,7 @@ Request.prototype.broadcast = function(filterFn) {
Request.prototype.cancel = function() {
this.removeAllListeners();
this.on('error', function(){});
this.on('error', function() {});
return this;
};
@@ -191,7 +186,7 @@ Request.prototype.setReconnectTimeout = function(timeout) {
};
Request.prototype.callback = function(callback, successEvent, errorEvent) {
var self = this;
const self = this;
if (typeof callback !== 'function') {
return this;
@@ -204,26 +199,26 @@ Request.prototype.callback = function(callback, successEvent, errorEvent) {
this.errorEvent = errorEvent;
}
var called = false;
let called = false;
function requestSuccess(message) {
if (!called) {
called = true;
callback.call(self, null, message);
}
};
}
function requestError(error) {
if (!called) {
called = true;
if (!(error instanceof RippleError)) {
error = new RippleError(error);
callback.call(self, new RippleError(error));
} else {
callback.call(self, error);
}
callback.call(self, error);
}
};
}
this.once(this.successEvent, requestSuccess);
this.once(this.errorEvent, requestError);
@@ -233,21 +228,21 @@ Request.prototype.callback = function(callback, successEvent, errorEvent) {
};
Request.prototype.timeout = function(duration, callback) {
var self = this;
const self = this;
function requested() {
self.timeout(duration, callback);
};
}
if (!this.requested) {
// Defer until requested
return this.once('request', requested);
}
var emit = this.emit;
var timed_out = false;
const emit = this.emit;
let timed_out = false;
var timeout = setTimeout(function() {
const timeout = setTimeout(function() {
timed_out = true;
if (typeof callback === 'function') {
@@ -269,7 +264,7 @@ Request.prototype.timeout = function(duration, callback) {
};
Request.prototype.setServer = function(server) {
var selected = null;
let selected = null;
switch (typeof server) {
case 'object':
@@ -278,16 +273,16 @@ Request.prototype.setServer = function(server) {
case 'string':
// Find server by URL
var servers = this.remote._servers;
const servers = this.remote._servers;
for (var i=0, s; (s=servers[i]); i++) {
for (let i = 0, s; (s = servers[i]); i++) {
if (s._url === server) {
selected = s;
break;
}
}
break;
};
}
this.server = selected;
@@ -299,7 +294,7 @@ Request.prototype.buildPath = function(build) {
throw new Error(
'`build_path` is completely ignored when doing local signing as '
+ '`Paths` is a component of the signed blob. The `tx_blob` is signed,'
+ 'sealed and delivered, and the txn unmodified after' );
+ 'sealed and delivered, and the txn unmodified after');
}
if (build) {
@@ -317,7 +312,7 @@ Request.prototype.ledgerChoose = function(current) {
if (current) {
this.message.ledger_index = this.remote._ledger_current_index;
} else {
this.message.ledger_hash = this.remote._ledger_hash;
this.message.ledger_hash = this.remote._ledger_hash;
}
return this;
@@ -425,13 +420,11 @@ Request.prototype.rippleState = function(account, issuer, currency) {
};
Request.prototype.setAccounts =
Request.prototype.accounts = function(accounts, proposed) {
if (!Array.isArray(accounts)) {
accounts = [ accounts ];
}
Request.prototype.accounts = function(accountsIn, proposed) {
const accounts = Array.isArray(accountsIn) ? accountsIn : [accountsIn];
// Process accounts parameters
var processedAccounts = accounts.map(function(account) {
const processedAccounts = accounts.map(function(account) {
return UInt160.json_rewrite(account);
});
@@ -450,8 +443,8 @@ Request.prototype.addAccount = function(account, proposed) {
return this;
}
var processedAccount = UInt160.json_rewrite(account);
var prop = proposed === true ? 'accounts_proposed' : 'accounts';
const processedAccount = UInt160.json_rewrite(account);
const prop = proposed === true ? 'accounts_proposed' : 'accounts';
this.message[prop] = (this.message[prop] || []).concat(processedAccount);
return this;
@@ -475,10 +468,10 @@ Request.prototype.addAccountProposed = function(account) {
Request.prototype.setBooks =
Request.prototype.books = function(books, snapshot) {
// Reset list of books (this method overwrites the current list)
this.message.books = [ ];
this.message.books = [];
for (var i=0, l=books.length; i<l; i++) {
var book = books[i];
for (let i = 0, l = books.length; i < l; i++) {
const book = books[i];
this.addBook(book, snapshot);
}
@@ -491,15 +484,17 @@ Request.prototype.addBook = function(book, snapshot) {
return this;
}
var json = { };
const json = { };
function processSide(side) {
if (!book[side]) {
throw new Error('Missing ' + side);
}
var obj = json[side] = {
currency: Currency.json_rewrite(book[side].currency, { force_hex: true })
const obj = json[side] = {
currency: Currency.json_rewrite(book[side].currency, {
force_hex: true
})
};
if (!Currency.from_json(obj.currency).is_native()) {
@@ -507,7 +502,7 @@ Request.prototype.addBook = function(book, snapshot) {
}
}
[ 'taker_gets', 'taker_pays' ].forEach(processSide);
['taker_gets', 'taker_pays'].forEach(processSide);
if (typeof snapshot !== 'boolean') {
json.snapshot = true;
@@ -527,8 +522,6 @@ Request.prototype.addBook = function(book, snapshot) {
};
Request.prototype.addStream = function(stream, values) {
var self = this;
if (Array.isArray(values)) {
switch (stream) {
case 'accounts':
@@ -542,14 +535,14 @@ Request.prototype.addStream = function(stream, values) {
break;
}
} else if (arguments.length > 1) {
for (arg in arguments) {
for (let arg in arguments) {
this.addStream(arguments[arg]);
}
return;
return this;
}
if (!Array.isArray(this.message.streams)) {
this.message.streams = [ ];
this.message.streams = [];
}
if (this.message.streams.indexOf(stream) === -1) {

View File

@@ -1,10 +1,13 @@
var util = require('util');
var url = require('url');
var LRU = require('lru-cache');
var EventEmitter = require('events').EventEmitter;
var Amount = require('./amount').Amount;
var RangeSet = require('./rangeset').RangeSet;
var log = require('./log').internal.sub('server');
'use strict';
const _ = require('lodash');
const util = require('util');
const url = require('url');
const LRU = require('lru-cache');
const EventEmitter = require('events').EventEmitter;
const Amount = require('./amount').Amount;
const RangeSet = require('./rangeset').RangeSet;
const log = require('./log').internal.sub('server');
/**
* @constructor Server
@@ -16,18 +19,20 @@ var log = require('./log').internal.sub('server');
* @param [Boolean] securec
*/
function Server(remote, opts) {
function Server(remote, _opts) {
EventEmitter.call(this);
var self = this;
if (typeof opts === 'string') {
var parsedUrl = url.parse(opts);
const self = this;
let opts;
if (typeof _opts === 'string') {
const parsedUrl = url.parse(_opts);
opts = {
host: parsedUrl.hostname,
port: parsedUrl.port,
secure: (parsedUrl.protocol === 'ws:') ? false : true
};
} else {
opts = _opts;
}
if (typeof opts !== 'object') {
@@ -35,11 +40,14 @@ function Server(remote, opts) {
}
if (!Server.DOMAIN_RE.test(opts.host)) {
throw new Error('Server host is malformed, use "host" and "port" server configuration');
throw new Error(
'Server host is malformed, use "host" and "port" server configuration');
}
// We want to allow integer strings as valid port numbers for backward compatibility
if (!(opts.port = Number(opts.port))) {
// We want to allow integer strings as valid port numbers
// for backward compatibility
opts.port = Number(opts.port);
if (!opts.port) {
throw new TypeError('Server port must be a number');
}
@@ -53,13 +61,15 @@ function Server(remote, opts) {
this._remote = remote;
this._opts = opts;
this._ws = void(0);
this._ws = undefined;
this._connected = false;
this._shouldConnect = false;
this._state = 'offline';
this._ledgerRanges = new RangeSet();
this._ledgerMap = LRU({ max: 200 });
this._ledgerMap = new LRU({
max: 200
});
this._id = 0; // request ID
this._retry = 0;
@@ -71,8 +81,8 @@ function Server(remote, opts) {
this._fee = 10;
this._fee_ref = 10;
this._fee_base = 10;
this._reserve_base = void(0);
this._reserve_inc = void(0);
this._reserve_base = undefined;
this._reserve_inc = undefined;
this._fee_cushion = this._remote.fee_cushion;
this._lastLedgerIndex = NaN;
@@ -87,7 +97,7 @@ function Server(remote, opts) {
this._pubkey_node = '';
this._url = this._opts.url = (this._opts.secure ? 'wss://' : 'ws://')
+ this._opts.host + ':' + this._opts.port;
+ this._opts.host + ':' + this._opts.port;
this.on('message', function onMessage(message) {
self._handleMessage(message);
@@ -98,9 +108,9 @@ function Server(remote, opts) {
});
function setActivityInterval() {
var interval = self._checkActivity.bind(self);
const interval = self._checkActivity.bind(self);
self._activityInterval = setInterval(interval, 1000);
};
}
this.on('disconnect', function onDisconnect() {
clearInterval(self._activityInterval);
@@ -124,11 +134,13 @@ function Server(remote, opts) {
this.on('connect', function() {
self.requestServerID();
});
};
}
util.inherits(Server, EventEmitter);
/* eslint-disable max-len */
Server.DOMAIN_RE = /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?)*\.?$/;
/* eslint-enable max-len */
Server.TLS_ERRORS = [
'UNABLE_TO_GET_ISSUER_CERT', 'UNABLE_TO_GET_CRL',
@@ -227,7 +239,7 @@ Server.prototype._checkActivity = function() {
return;
}
var delta = (Date.now() - this._lastLedgerClose);
const delta = (Date.now() - this._lastLedgerClose);
if (delta > (1000 * 25)) {
if (this._remote.trace) {
@@ -244,7 +256,7 @@ Server.prototype._checkActivity = function() {
*/
Server.prototype.requestServerID = function() {
var self = this;
const self = this;
if (this._pubkey_node) {
return;
@@ -254,11 +266,12 @@ Server.prototype.requestServerID = function() {
try {
self._pubkey_node = message.info.pubkey_node;
} catch (e) {
// empty
}
});
var serverInfoRequest = this._remote.requestServerInfo();
serverInfoRequest.on('error', function() { });
const serverInfoRequest = this._remote.requestServerInfo();
serverInfoRequest.on('error', function() {});
this._request(serverInfoRequest);
};
@@ -279,19 +292,20 @@ Server.prototype._updateScore = function(type, data) {
return;
}
var weight = this._scoreWeights[type] || 1;
const weight = this._scoreWeights[type] || 1;
let delta;
switch (type) {
case 'ledgerclose':
// Ledger lag
var delta = data.ledger_index - this._lastLedgerIndex;
delta = data.ledger_index - this._lastLedgerIndex;
if (delta > 0) {
this._score += weight * delta;
}
break;
case 'response':
// Ping lag
var delta = Math.floor((Date.now() - data.time) / 200);
delta = Math.floor((Date.now() - data.time) / 200);
this._score += weight * delta;
break;
case 'loadchange':
@@ -316,20 +330,18 @@ Server.prototype._updateScore = function(type, data) {
Server.prototype.getRemoteAddress =
Server.prototype._remoteAddress = function() {
var address;
try {
address = this._ws._socket.remoteAddress;
return this._ws._socket.remoteAddress;
} catch (e) {
// empty
}
return address;
};
/**
* Get the server's hostid
*/
Server.prototype.getHostID =
Server.prototype.getServerID = function() {
Server.prototype.getHostID = Server.prototype.getServerID = function() {
return this._url + ' (' + (this._pubkey_node ? this._pubkey_node : '') + ')';
};
@@ -340,7 +352,7 @@ Server.prototype.getServerID = function() {
*/
Server.prototype.disconnect = function() {
var self = this;
const self = this;
if (!this.isConnected()) {
this.once('socket_open', function() {
@@ -349,8 +361,8 @@ Server.prototype.disconnect = function() {
return;
}
//these need to be reset so that updateScore
//and checkActivity do not trigger reconnect
// these need to be reset so that updateScore
// and checkActivity do not trigger reconnect
this._lastLedgerIndex = NaN;
this._lastLedgerClose = NaN;
this._score = 0;
@@ -371,13 +383,13 @@ Server.prototype.disconnect = function() {
*/
Server.prototype.reconnect = function() {
var self = this;
const self = this;
function reconnect() {
self._shouldConnect = true;
self._retry = 0;
self.connect();
};
}
if (this._ws && this._shouldConnect) {
if (this.isConnected()) {
@@ -398,9 +410,9 @@ Server.prototype.reconnect = function() {
*/
Server.prototype.connect = function() {
var self = this;
const self = this;
var WebSocket = Server.websocketConstructor();
const WebSocket = Server.websocketConstructor();
if (!WebSocket) {
throw new Error('No websocket support detected!');
@@ -423,7 +435,7 @@ Server.prototype.connect = function() {
log.info(this.getServerID(), 'connect');
}
var ws = this._ws = new WebSocket(this._opts.url);
const ws = this._ws = new WebSocket(this._opts.url);
this._shouldConnect = true;
@@ -446,7 +458,7 @@ Server.prototype.connect = function() {
self.emit('socket_error');
if (self._remote.trace) {
log.info(self.getServerID(), 'onerror:', e.data || e);
log.info(self.getServerID(), 'onerror:', e.data || e);
}
if (Server.TLS_ERRORS.indexOf(e.message) !== -1) {
@@ -454,11 +466,13 @@ Server.prototype.connect = function() {
throw e;
}
// Most connection errors for WebSockets are conveyed as 'close' events with
// Most connection errors for WebSockets are conveyed as 'close'
// events with
// code 1006. This is done for security purposes and therefore unlikely to
// ever change.
// This means that this handler is hardly ever called in practice. If it is,
// This means that this handler is hardly ever called in practice.
// If it is,
// it probably means the server's WebSocket implementation is corrupt, or
// the connection is somehow producing corrupt data.
@@ -489,21 +503,21 @@ Server.prototype.connect = function() {
*/
Server.prototype._retryConnect = function() {
var self = this;
const self = this;
this._retry += 1;
var retryTimeout = (this._retry < 40)
// First, for 2 seconds: 20 times per second
? (1000 / 20)
: (this._retry < 40 + 60)
// Then, for 1 minute: once per second
? (1000)
: (this._retry < 40 + 60 + 60)
// Then, for 10 minutes: once every 10 seconds
? (10 * 1000)
// Then: once every 30 seconds
: (30 * 1000);
const retryTimeout = (this._retry < 40)
// First, for 2 seconds: 20 times per second
? (1000 / 20)
: (this._retry < 40 + 60)
// Then, for 1 minute: once per second
? (1000)
: (this._retry < 40 + 60 + 60)
// Then, for 10 minutes: once every 10 seconds
? (10 * 1000)
// Then: once every 30 seconds
: (30 * 1000);
function connectionRetry() {
if (self._shouldConnect) {
@@ -512,7 +526,7 @@ Server.prototype._retryConnect = function() {
}
self.connect();
}
};
}
this._retryTimer = setTimeout(connectionRetry, retryTimeout);
};
@@ -524,13 +538,10 @@ Server.prototype._retryConnect = function() {
*/
Server.prototype._handleClose = function() {
var self = this;
var ws = this._ws;
function noOp(){};
const ws = this._ws;
// Prevent additional events from this socket
ws.onopen = ws.onerror = ws.onclose = ws.onmessage = noOp;
ws.onopen = ws.onerror = ws.onclose = ws.onmessage = _.noop;
this.emit('socket_close');
this._setState('offline');
@@ -548,11 +559,13 @@ Server.prototype._handleClose = function() {
*/
Server.prototype._handleMessage = function(message) {
var self = this;
try {
// this is fixed in Brandon's pull request
/* eslint-disable no-param-reassign */
message = JSON.parse(message);
} catch(e) {
/* eslint-enable no-param-reassign */
} catch (e) {
// empty
}
if (!Server.isValidMessage(message)) {
@@ -587,7 +600,7 @@ Server.prototype._handleLedgerClosed = function(message) {
Server.prototype._handleServerStatus = function(message) {
// This message is only received when online.
// As we are connected, it is the definitive final state.
var isOnline = ~Server.onlineStates.indexOf(message.server_status);
const isOnline = ~Server.onlineStates.indexOf(message.server_status);
this._setState(isOnline ? 'online' : 'offline');
@@ -598,8 +611,8 @@ Server.prototype._handleServerStatus = function(message) {
this.emit('load', message, this);
this._remote.emit('load', message, this);
var loadChanged = message.load_base !== this._load_base
|| message.load_factor !== this._load_factor;
const loadChanged = message.load_base !== this._load_base
|| message.load_factor !== this._load_factor;
if (loadChanged) {
this._load_base = message.load_base;
@@ -611,7 +624,7 @@ Server.prototype._handleServerStatus = function(message) {
Server.prototype._handleResponse = function(message) {
// A response to a request.
var request = this._requests[message.id];
const request = this._requests[message.id];
delete this._requests[message.id];
@@ -627,13 +640,13 @@ Server.prototype._handleResponse = function(message) {
log.info(this.getServerID(), 'response:', message);
}
var command = request.message.command;
var result = message.result;
var responseEvent = 'response_' + command;
const command = request.message.command;
const result = message.result;
const responseEvent = 'response_' + command;
request.emit('success', result);
[ this, this._remote ].forEach(function(emitter) {
[this, this._remote].forEach(function(emitter) {
emitter.emit(responseEvent, result, request, message);
});
} else if (message.error) {
@@ -672,10 +685,11 @@ Server.prototype._handleResponseSubscribe = function(message) {
}
if (!this._remote.allow_partial_history
&& !Server.hasFullLedgerHistory(message)) {
&& !Server.hasFullLedgerHistory(message)) {
// Server has partial history and Remote has been configured to disallow
// servers with incomplete history
return this.reconnect();
this.reconnect();
return;
}
if (message.pubkey_node) {
@@ -711,9 +725,9 @@ Server.prototype._handleResponseSubscribe = function(message) {
Server.hasFullLedgerHistory = function(message) {
return (typeof message === 'object')
&& (message.server_status === 'full')
&& (typeof message.validated_ledgers === 'string')
&& (message.validated_ledgers.split('-').length === 2);
&& (message.server_status === 'full')
&& (typeof message.validated_ledgers === 'string')
&& (message.validated_ledgers.split('-').length === 2);
};
/**
@@ -725,7 +739,7 @@ Server.hasFullLedgerHistory = function(message) {
Server.isValidMessage = function(message) {
return (typeof message === 'object')
&& (typeof message.type === 'string');
&& (typeof message.type === 'string');
};
/**
@@ -737,8 +751,8 @@ Server.isValidMessage = function(message) {
Server.isLoadStatus = function(message) {
return (typeof message === 'object')
&& (typeof message.load_base === 'number')
&& (typeof message.load_factor === 'number');
&& (typeof message.load_base === 'number')
&& (typeof message.load_factor === 'number');
};
/**
@@ -768,7 +782,7 @@ Server.prototype._sendMessage = function(message) {
*/
Server.prototype._request = function(request) {
var self = this;
const self = this;
// Only bother if we are still connected.
if (!this._ws) {
@@ -789,10 +803,10 @@ Server.prototype._request = function(request) {
function sendRequest() {
self._sendMessage(request.message);
};
}
var isOpen = this._ws.readyState === 1;
var isSubscribeRequest = request && request.message.command === 'subscribe';
const isOpen = this._ws.readyState === 1;
const isSubscribeRequest = request && request.message.command === 'subscribe';
if (this.isConnected() || (isOpen && isSubscribeRequest)) {
sendRequest();
@@ -807,8 +821,7 @@ Server.prototype._request = function(request) {
* @return boolean
*/
Server.prototype.isConnected =
Server.prototype._isConnected = function() {
Server.prototype.isConnected = Server.prototype._isConnected = function() {
return this._connected;
};
@@ -838,7 +851,7 @@ Server.prototype._computeFee = function(feeUnits) {
*/
Server.prototype._feeTx = function(units) {
var fee_unit = this._feeTxUnit();
const fee_unit = this._feeTxUnit();
return Amount.from_json(String(Math.ceil(units * fee_unit)));
};
@@ -852,12 +865,13 @@ Server.prototype._feeTx = function(units) {
*/
Server.prototype._feeTxUnit = function() {
var fee_unit = this._fee_base / this._fee_ref;
let fee_unit = this._fee_base / this._fee_ref;
// Apply load fees
fee_unit *= this._load_factor / this._load_base;
// Apply fee cushion (a safety margin in case fees rise since we were last updated)
// Apply fee cushion (a safety margin in case fees rise since
// we were last updated)
fee_unit *= this._fee_cushion;
return fee_unit;
@@ -870,9 +884,9 @@ Server.prototype._feeTxUnit = function() {
*/
Server.prototype._reserve = function(ownerCount) {
var reserve_base = Amount.from_json(String(this._reserve_base));
var reserve_inc = Amount.from_json(String(this._reserve_inc));
var owner_count = ownerCount || 0;
const reserve_base = Amount.from_json(String(this._reserve_base));
const reserve_inc = Amount.from_json(String(this._reserve_inc));
const owner_count = ownerCount || 0;
if (owner_count < 0) {
throw new Error('Owner count must not be negative.');
@@ -889,11 +903,11 @@ Server.prototype._reserve = function(ownerCount) {
*/
Server.prototype.hasLedger = function(ledger) {
var result = false;
let result = false;
if (typeof ledger === 'string' && /^[A-F0-9]{64}$/.test(ledger)) {
result = this._ledgerMap.has(ledger);
} else if (ledger != null && !isNaN(ledger)) {
} else if (ledger !== null && !isNaN(ledger)) {
result = this._ledgerRanges.has(ledger);
}

View File

@@ -1,8 +1,8 @@
/* eslint-disable max-len */
'use strict';
var assert = require('assert');
var Amount = require('ripple-lib').Amount;
var UInt160 = require('ripple-lib').UInt160;
const assert = require('assert');
const Amount = require('ripple-lib').Amount;
const UInt160 = require('ripple-lib').UInt160;
describe('Amount', function() {
@@ -444,17 +444,17 @@ describe('Amount', function() {
});
describe('Amount to_json', function() {
it('10 USD', function() {
var amount = Amount.from_human('10 USD').to_json();
const amount = Amount.from_human('10 USD').to_json();
assert.strictEqual('10', amount.value);
assert.strictEqual('USD', amount.currency);
});
it('10 0000000000000000000000005553440000000000', function() {
var amount = Amount.from_human('10 0000000000000000000000005553440000000000').to_json();
const amount = Amount.from_human('10 0000000000000000000000005553440000000000').to_json();
assert.strictEqual('10', amount.value);
assert.strictEqual('USD', amount.currency);
});
it('10 015841551A748AD2C1F76FF6ECB0CCCD00000000', function() {
var amount = Amount.from_human('10 015841551A748AD2C1F76FF6ECB0CCCD00000000').to_json();
const amount = Amount.from_human('10 015841551A748AD2C1F76FF6ECB0CCCD00000000').to_json();
assert.strictEqual('10', amount.value);
assert.strictEqual('015841551A748AD2C1F76FF6ECB0CCCD00000000', amount.currency);
});
@@ -766,135 +766,135 @@ describe('Amount', function() {
});
describe('Amount comparisons', function() {
it('0 USD == 0 USD amount.equals string argument', function() {
var a = '0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL';
const a = '0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL';
assert(Amount.from_json(a).equals(a));
});
it('0 USD == 0 USD', function() {
var a = Amount.from_json('0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(a.equals(b));
assert(!a.not_equals_why(b));
});
it('0 USD == -0 USD', function() {
var a = Amount.from_json('0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('-0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('-0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(a.equals(b));
assert(!a.not_equals_why(b));
});
it('0 XRP == 0 XRP', function() {
var a = Amount.from_json('0');
var b = Amount.from_json('0');
const a = Amount.from_json('0');
const b = Amount.from_json('0');
assert(a.equals(b));
assert(!a.not_equals_why(b));
});
it('0 XRP == -0 XRP', function() {
var a = Amount.from_json('0');
var b = Amount.from_json('-0');
const a = Amount.from_json('0');
const b = Amount.from_json('-0');
assert(a.equals(b));
assert(!a.not_equals_why(b));
});
it('10 USD == 10 USD', function() {
var a = Amount.from_json('10/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('10/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('10/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('10/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(a.equals(b));
assert(!a.not_equals_why(b));
});
it('123.4567 USD == 123.4567 USD', function() {
var a = Amount.from_json('123.4567/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('123.4567/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('123.4567/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('123.4567/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(a.equals(b));
assert(!a.not_equals_why(b));
});
it('10 XRP == 10 XRP', function() {
var a = Amount.from_json('10');
var b = Amount.from_json('10');
const a = Amount.from_json('10');
const b = Amount.from_json('10');
assert(a.equals(b));
assert(!a.not_equals_why(b));
});
it('1.1 XRP == 1.1 XRP', function() {
var a = Amount.from_json('1100000');
var b = Amount.from_json('11000000').ratio_human('10/XRP');
const a = Amount.from_json('1100000');
const b = Amount.from_json('11000000').ratio_human('10/XRP');
assert(a.equals(b));
assert(!a.not_equals_why(b));
});
it('0 USD == 0 USD (ignore issuer)', function() {
var a = Amount.from_json('0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('0/USD/rH5aWQJ4R7v4Mpyf4kDBUvDFT5cbpFq3XP');
const a = Amount.from_json('0/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('0/USD/rH5aWQJ4R7v4Mpyf4kDBUvDFT5cbpFq3XP');
assert(a.equals(b, true));
assert(!a.not_equals_why(b, true));
});
it('1.1 USD == 1.10 USD (ignore issuer)', function() {
var a = Amount.from_json('1.1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('1.10/USD/rH5aWQJ4R7v4Mpyf4kDBUvDFT5cbpFq3XP');
const a = Amount.from_json('1.1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('1.10/USD/rH5aWQJ4R7v4Mpyf4kDBUvDFT5cbpFq3XP');
assert(a.equals(b, true));
assert(!a.not_equals_why(b, true));
});
// Exponent mismatch
it('10 USD != 100 USD', function() {
var a = Amount.from_json('10/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('100/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('10/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('100/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'Non-XRP value differs.');
});
it('10 XRP != 100 XRP', function() {
var a = Amount.from_json('10');
var b = Amount.from_json('100');
const a = Amount.from_json('10');
const b = Amount.from_json('100');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'XRP value differs.');
});
// Mantissa mismatch
it('1 USD != 2 USD', function() {
var a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('2/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('2/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'Non-XRP value differs.');
});
it('1 XRP != 2 XRP', function() {
var a = Amount.from_json('1');
var b = Amount.from_json('2');
const a = Amount.from_json('1');
const b = Amount.from_json('2');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'XRP value differs.');
});
it('0.1 USD != 0.2 USD', function() {
var a = Amount.from_json('0.1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('0.2/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('0.1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('0.2/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'Non-XRP value differs.');
});
// Sign mismatch
it('1 USD != -1 USD', function() {
var a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('-1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('-1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'Non-XRP sign differs.');
});
it('1 XRP != -1 XRP', function() {
var a = Amount.from_json('1');
var b = Amount.from_json('-1');
const a = Amount.from_json('1');
const b = Amount.from_json('-1');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'XRP sign differs.');
});
it('1 USD != 1 USD (issuer mismatch)', function() {
var a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('1/USD/rH5aWQJ4R7v4Mpyf4kDBUvDFT5cbpFq3XP');
const a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('1/USD/rH5aWQJ4R7v4Mpyf4kDBUvDFT5cbpFq3XP');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'Non-XRP issuer differs: rH5aWQJ4R7v4Mpyf4kDBUvDFT5cbpFq3XP/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
});
it('1 USD != 1 EUR', function() {
var a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('1/EUR/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('1/EUR/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'Non-XRP currency differs.');
});
it('1 USD != 1 XRP', function() {
var a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
var b = Amount.from_json('1');
const a = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const b = Amount.from_json('1');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'Native mismatch.');
});
it('1 XRP != 1 USD', function() {
var a = Amount.from_json('1');
var b = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
const a = Amount.from_json('1');
const b = Amount.from_json('1/USD/rNDKeo9RrCiRdfsMG8AdoZvNZxHASGzbZL');
assert(!a.equals(b));
assert.strictEqual(a.not_equals_why(b), 'Native mismatch.');
});
@@ -1147,38 +1147,38 @@ describe('Amount', function() {
describe('apply interest', function() {
it('from_json apply interest 10 XAU', function() {
var demAmount = Amount.from_json('10/0158415500000000C1F76FF6ECB0BAC600000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
let demAmount = Amount.from_json('10/0158415500000000C1F76FF6ECB0BAC600000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(demAmount.to_text_full(), '10/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
demAmount = demAmount.applyInterest(459990264);
assert.strictEqual(demAmount.to_text_full(), '9.294949401870435/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(demAmount.to_text_full(), '9.294949401870436/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
});
it('from_json apply interest XAU', function() {
var demAmount = Amount.from_json('1235.5/0158415500000000C1F76FF6ECB0BAC600000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
let demAmount = Amount.from_json('1235.5/0158415500000000C1F76FF6ECB0BAC600000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(demAmount.to_text_full(), '1235.5/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
demAmount = demAmount.applyInterest(459990264);
assert.strictEqual(demAmount.to_text_full(), '1148.390998601092/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
});
it('from_human with reference date', function() {
var demAmount = Amount.from_human('10 0158415500000000C1F76FF6ECB0BAC600000000', {reference_date: 459990264});
const demAmount = Amount.from_human('10 0158415500000000C1F76FF6ECB0BAC600000000', {reference_date: 459990264});
demAmount.set_issuer('rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(demAmount.to_text_full(), '10.75853086191915/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
});
it('from_json apply interest 10 XAU human', function() {
var demAmount = Amount.from_json('10/0158415500000000C1F76FF6ECB0BAC600000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
let demAmount = Amount.from_json('10/0158415500000000C1F76FF6ECB0BAC600000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(demAmount.to_human_full(), '10/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
demAmount = demAmount.applyInterest(459990264);
assert.strictEqual(demAmount.to_human_full(), '9.294949401870435/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(demAmount.to_human_full(), '9.294949401870436/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
});
it('from_json apply interest XAU human', function() {
var demAmount = Amount.from_json('1235.5/0158415500000000C1F76FF6ECB0BAC600000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
let demAmount = Amount.from_json('1235.5/0158415500000000C1F76FF6ECB0BAC600000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(demAmount.to_human_full(), '1,235.5/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
demAmount = demAmount.applyInterest(459990264);
assert.strictEqual(demAmount.to_human_full(), '1,148.390998601092/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
});
it('from_human with reference date human', function() {
var demAmount = Amount.from_human('10 0158415500000000C1F76FF6ECB0BAC600000000', {reference_date: 459990264});
const demAmount = Amount.from_human('10 0158415500000000C1F76FF6ECB0BAC600000000', {reference_date: 459990264});
demAmount.set_issuer('rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(demAmount.to_human_full(), '10.75853086191915/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
});
@@ -1202,12 +1202,12 @@ describe('Amount', function() {
});
it('from_json minimum XRP', function() {
var amt = Amount.from_json('-100000000000000000');
const amt = Amount.from_json('-100000000000000000');
assert.strictEqual(amt.to_json(), '-100000000000000000');
});
it('from_json maximum XRP', function() {
var amt = Amount.from_json('100000000000000000');
const amt = Amount.from_json('100000000000000000');
assert.strictEqual(amt.to_json(), '100000000000000000');
});
@@ -1224,7 +1224,7 @@ describe('Amount', function() {
});
it('from_json minimum IOU', function() {
var amt = Amount.from_json('-1e-81/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
const amt = Amount.from_json('-1e-81/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(amt.to_text(), '-1000000000000000e-96');
assert.strictEqual(amt.to_text(), Amount.min_value);
});
@@ -1236,7 +1236,7 @@ describe('Amount', function() {
});
it('from_json maximum IOU', function() {
var amt = Amount.from_json('9999999999999999e80/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
const amt = Amount.from_json('9999999999999999e80/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(amt.to_text(), '9999999999999999e80');
});
@@ -1247,12 +1247,12 @@ describe('Amount', function() {
});
it('from_json normalize mantissa to valid max range, lost significant digits', function() {
var amt = Amount.from_json('99999999999999999999999999999999/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
const amt = Amount.from_json('99999999999999999999999999999999/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(amt.to_text(), '9999999999999999e16');
});
it('from_json normalize mantissa to min valid range, lost significant digits', function() {
var amt = Amount.from_json('-0.0000000000000000000000001/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
const amt = Amount.from_json('-0.0000000000000000000000001/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(amt.to_text(), '-1000000000000000e-40');
});
});

View File

@@ -272,7 +272,9 @@ describe('Currency', function() {
assert.equal(0.995, precision(cur.get_interest_at(new Date(timeUtil.fromRipple(443845330 + 31536000))), 14));
// After one demurrage period, 1/e should have occurred
assert.equal(1/Math.E, cur.get_interest_at(443845330 + 6291418827.05));
var epsilon = 1e-14;
assert(Math.abs(
1/Math.E - cur.get_interest_at(443845330 + 6291418827.05)) < epsilon);
// One year before start, it should be (roughly) 0.5% higher.
assert.equal(1.005, precision(cur.get_interest_at(443845330 - 31536000), 4));

View File

@@ -1,83 +1,88 @@
var assert = require('assert');
var fs = require('fs');
/* eslint-disable max-len */
'use strict';
var Ledger = require('ripple-lib').Ledger;
const assert = require('assert');
const fs = require('fs');
const Ledger = require('ripple-lib').Ledger;
/**
* @param ledger_index {Number}
* Expects a corresponding ledger dump in $repo/test/fixtures/ folder
*/
create_ledger_test = function (ledger_index) {
function create_ledger_test(ledger_index) {
describe(String(ledger_index), function() {
var path = __dirname + '/fixtures/ledger-full-'+ledger_index+'.json';
const path = __dirname + '/fixtures/ledger-full-' + ledger_index + '.json';
var ledger_raw = fs.readFileSync(path),
ledger_json = JSON.parse(ledger_raw),
ledger = Ledger.from_json(ledger_json);
const ledger_raw = fs.readFileSync(path);
const ledger_json = JSON.parse(ledger_raw);
const ledger = Ledger.from_json(ledger_json);
it('has account_hash of '+ ledger_json.account_hash, function() {
it('has account_hash of ' + ledger_json.account_hash, function() {
assert.equal(ledger_json.account_hash,
ledger.calc_account_hash({sanity_test:true}).to_hex());
})
it('has transaction_hash of '+ ledger_json.transaction_hash, function() {
ledger.calc_account_hash({
sanity_test: true
}).to_hex());
});
it('has transaction_hash of ' + ledger_json.transaction_hash, function() {
assert.equal(ledger_json.transaction_hash,
ledger.calc_tx_hash().to_hex());
})
})
ledger.calc_tx_hash().to_hex());
});
});
}
describe('Ledger', function() {
// This is the first recorded ledger with a non empty transaction set
create_ledger_test(38129);
// Because, why not.
create_ledger_test(40000);
describe('#calcAccountRootEntryHash', function () {
it('will calculate the AccountRoot entry hash for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function () {
var account = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh';
var expectedEntryHash = '2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8';
var actualEntryHash = Ledger.calcAccountRootEntryHash(account);
describe('#calcAccountRootEntryHash', function() {
it('will calculate the AccountRoot entry hash for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function() {
const account = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh';
const expectedEntryHash = '2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8';
const actualEntryHash = Ledger.calcAccountRootEntryHash(account);
assert.equal(actualEntryHash.to_hex(), expectedEntryHash);
});
});
describe('#calcRippleStateEntryHash', function () {
it('will calculate the RippleState entry hash for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh and rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY in USD', function () {
var account1 = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh';
var account2 = 'rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY';
var currency = 'USD';
describe('#calcRippleStateEntryHash', function() {
it('will calculate the RippleState entry hash for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh and rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY in USD', function() {
const account1 = 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh';
const account2 = 'rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY';
const currency = 'USD';
const expectedEntryHash = 'C683B5BB928F025F1E860D9D69D6C554C2202DE0D45877ADB3077DA4CB9E125C';
const actualEntryHash1 = Ledger.calcRippleStateEntryHash(account1, account2, currency);
const actualEntryHash2 = Ledger.calcRippleStateEntryHash(account2, account1, currency);
var expectedEntryHash = 'C683B5BB928F025F1E860D9D69D6C554C2202DE0D45877ADB3077DA4CB9E125C';
var actualEntryHash1 = Ledger.calcRippleStateEntryHash(account1, account2, currency);
var actualEntryHash2 = Ledger.calcRippleStateEntryHash(account2, account1, currency);
assert.equal(actualEntryHash1.to_hex(), expectedEntryHash);
assert.equal(actualEntryHash2.to_hex(), expectedEntryHash);
});
it('will calculate the RippleState entry hash for r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV and rUAMuQTfVhbfqUDuro7zzy4jj4Wq57MPTj in UAM', function () {
var account1 = 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV';
var account2 = 'rUAMuQTfVhbfqUDuro7zzy4jj4Wq57MPTj';
var currency = 'UAM';
var expectedEntryHash = 'AE9ADDC584358E5847ADFC971834E471436FC3E9DE6EA1773DF49F419DC0F65E';
var actualEntryHash1 = Ledger.calcRippleStateEntryHash(account1, account2, currency);
var actualEntryHash2 = Ledger.calcRippleStateEntryHash(account2, account1, currency);
it('will calculate the RippleState entry hash for r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV and rUAMuQTfVhbfqUDuro7zzy4jj4Wq57MPTj in UAM', function() {
const account1 = 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV';
const account2 = 'rUAMuQTfVhbfqUDuro7zzy4jj4Wq57MPTj';
const currency = 'UAM';
const expectedEntryHash = 'AE9ADDC584358E5847ADFC971834E471436FC3E9DE6EA1773DF49F419DC0F65E';
const actualEntryHash1 = Ledger.calcRippleStateEntryHash(account1, account2, currency);
const actualEntryHash2 = Ledger.calcRippleStateEntryHash(account2, account1, currency);
assert.equal(actualEntryHash1.to_hex(), expectedEntryHash);
assert.equal(actualEntryHash2.to_hex(), expectedEntryHash);
});
});
describe('#calcOfferEntryHash', function () {
it('will calculate the Offer entry hash for r32UufnaCGL82HubijgJGDmdE5hac7ZvLw, sequence 137', function () {
var account = 'r32UufnaCGL82HubijgJGDmdE5hac7ZvLw';
var sequence = 137
var expectedEntryHash = '03F0AED09DEEE74CEF85CD57A0429D6113507CF759C597BABB4ADB752F734CE3';
var actualEntryHash = Ledger.calcOfferEntryHash(account, sequence);
describe('#calcOfferEntryHash', function() {
it('will calculate the Offer entry hash for r32UufnaCGL82HubijgJGDmdE5hac7ZvLw, sequence 137', function() {
const account = 'r32UufnaCGL82HubijgJGDmdE5hac7ZvLw';
const sequence = 137;
const expectedEntryHash = '03F0AED09DEEE74CEF85CD57A0429D6113507CF759C597BABB4ADB752F734CE3';
const actualEntryHash = Ledger.calcOfferEntryHash(account, sequence);
assert.equal(actualEntryHash.to_hex(), expectedEntryHash);
});
});

View File

@@ -1 +1 @@
--reporter spec --timeout 10000 --slow 500
--reporter spec --timeout 10000 --slow 500 --compilers js:babel/register

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff