Compare commits

..

29 Commits

Author SHA1 Message Date
Geert Weening
66d21b24cd [TASK] bump ripple-lib to 0.9.2-rc5 2014-11-07 18:22:23 -08:00
Geert Weening
5a084ea3cc [TEST] fix broken tests
as a result of updating account_info request in account.js
2014-11-07 18:22:05 -08:00
Geert Weening
486944fa4c [FIX] request account info in account.js 2014-11-07 18:04:04 -08:00
Geert Weening
b63a76d298 [TASK] bump version to 0.9.2-rc4 2014-11-07 17:45:17 -08:00
Geert Weening
31045039c0 [DOC] update release notes 2014-11-07 17:44:30 -08:00
Geert Weening
6f5d1104aa [TASK] change accountRequest method signature
`(type, options, callback)` where the last argument will be considered for callback if it's a function
2014-11-07 17:08:01 -08:00
Geert Weening
3c9660203b Merge pull request #203 from geertweening/feature/marker_valid_ledger
[FEATURE] check for valid ledger when using marker
2014-11-07 12:57:57 -08:00
Geert Weening
29e1423f84 [FEATURE] check for valid ledger when using marker
when using a marker on an account request, a valid ledger_index or ledger_hash is required, otherwise the results can't be guaranteed to be reliable

consolidated test values for addresses, indexes and hashes
2014-11-07 11:18:24 -08:00
Geert Weening
e42e67e259 [TASK] consolidate accountRequest and pagingAccountRequest
update `requestAccountCurrencies` and  `requestAccountInfo`
2014-11-07 09:52:17 -08:00
Geert Weening
ed018282c4 [TASK] remove clone in favor of copy and update
see 'object' case in `parse_json`
2014-11-06 22:58:04 -08:00
Geert Weening
fbe015758c [TASK] bump version to 0.9.2-rc3 2014-11-06 21:48:01 -08:00
Geert Weening
7e24a81764 [DOC] update release notes 2014-11-06 21:47:44 -08:00
Geert Weening
9ab77e90fe Merge pull request #202 from geertweening/feature/paging_account_request
[FEATURE] add paging account request
2014-11-06 21:41:44 -08:00
Geert Weening
ae3ed699db Merge pull request #201 from geertweening/fix/from_human_full_name_native
[FIX] from_human 'XRP' with full name
2014-11-06 21:41:30 -08:00
Geert Weening
0c22a9753e Merge pull request #199 from geertweening/fix/amount_cap
[FIX] cap IOU Amounts to their max and min value
2014-11-06 21:41:08 -08:00
Geert Weening
a447f6b723 [TEST] add missing testcases for interest bearing currencies
- `get_interest_at` by providing a Date object
- `get_interest_at` for a Currency without interest
2014-11-06 21:38:00 -08:00
Geert Weening
a8ef614b81 [FIX] Currency constructor with Currency object
clone the given Currency instance in `parse_json`
2014-11-06 21:36:57 -08:00
Geert Weening
9025e8bfa8 [FIX] get interest for currency without interest
- `get_interest_at` for a currency without interest would not hit the intended check since the function was used as variable instead of calling the method
2014-11-06 21:35:41 -08:00
Geert Weening
722f4e175d [FEATURE] add paging account request
some requests return results that can be paged through, e.g. `account_lines`
use `limit` and `marker` options to specify results per response and position

change `requestAccountLines` and `requestAccountOffers` to use the `pagingAccountRequest`
2014-11-06 18:40:45 -08:00
Geert Weening
1ad6e5a15f [FIX] from_human 'XRP' with full name
from_human 'XRP - Ripples' should result in native XRP
2014-11-05 16:54:45 -08:00
Geert Weening
3554572db7 [TASK] bump version to 0.9.2-rc2 2014-11-05 16:32:37 -08:00
Geert Weening
f1abff962f Merge pull request #200 from boxbag/fix-max-fee
[FIX] fix test and do not set tx_json.Fee in maxFee method
2014-11-05 16:07:01 -08:00
Geert Weening
f05941fbc4 [FIX] cap IOU Amounts to their max and min value
respect rippled's limits
2014-11-05 16:04:02 -08:00
Bo Chen
237c46d5a0 [FIX] fix test and do not set tx_json.Fee in maxFee method 2014-11-05 15:59:57 -08:00
Geert Weening
76cfb69d9f [TASK] bump version to 0.9.2-rc1 2014-11-05 14:38:47 -08:00
Geert Weening
7610df0fbb [DOC] update release notes 2014-11-05 14:38:35 -08:00
Geert Weening
8bc935aa62 Merge pull request #198 from boxbag/transaction-max-fee
[FEATURE] set max fee the submitter of a transaction is willing to pay
2014-11-05 09:27:26 -08:00
Bo Chen
24587fab9c [FEATURE] set max fee the submitter of a transaction is willing to pay 2014-11-04 14:13:42 -08:00
Geert Weening
0248475473 [DOC] update description in package.json 2014-10-31 18:52:09 -07:00
15 changed files with 564 additions and 86 deletions

View File

@@ -1,3 +1,35 @@
##0.9.2
+ [**Breaking change**: Change accountRequest method signature](https://github.com/ripple/ripple-lib/commit/6f5d1104aa3eb440c518ec4f39e264fdce15fa15)
+ [Add paging behavior for account requests, `account_lines` and `account_offers`](https://github.com/ripple/ripple-lib/commit/722f4e175dbbf378e51b49142d0285f87acb22d7)
+ [Add max_fee setter to transactions to set max fee the submitter is willing to pay] (https://github.com/ripple/ripple-lib/commit/24587fab9c8ad3840d7aa345a7037b48839e09d7)
+ [Fix: cap IOU Amounts to their max and min value] (https://github.com/ripple/ripple-lib/commit/f05941fbc46fdb7c6fe7ad72927af02d527ffeed)
Example on how to use paging with `account_offers`:
```
// A valid `ledger_index` or `ledger_hash` is required to provide a reliable result.
// Results can change between ledger closes, so the provided ledger will be used as base.
var options = {
account: < rippleAccount >,
limit: < Number between 10 and 400 >,
ledger: < valid ledger_index or ledger_hash >
}
// The `marker` comes back in an account request if there are more results than are returned
// in the current response. The amount of results per response are determined by the `limit`.
if (marker) {
options.marker = < marker >;
}
var request = remote.requestAccountOffers(options);
```
[Full working example](https://github.com/geertweening/ripple-lib-scripts/blob/master/account_offers_paging.js)
##0.9.1
+ Switch account requests to use ledgerSelect rather than ledgerChoose ([278df90](https://github.com/ripple/ripple-lib/commit/278df9025a20228de22379a53c76ca12d40fa591))

View File

@@ -1,7 +1,7 @@
{
"name": "ripple-lib",
"version": "0.9.1",
"description": "Ripple JavaScript client library",
"version": "0.9.2-rc5",
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
"files": [
"src/js/*",
"bin/*",

View File

@@ -132,7 +132,7 @@ Account.prototype.isValid = function() {
*/
Account.prototype.getInfo = function(callback) {
return this._remote.request_account_info(this._account_id, callback);
return this._remote.requestAccountInfo({account: this._account_id}, callback);
};
/**
@@ -211,7 +211,7 @@ Account.prototype.lines = function(callback) {
}
}
this._remote.requestAccountLines(this._account_id, accountLines);
this._remote.requestAccountLines({account: this._account_id}, accountLines);
return this;
};

View File

@@ -54,7 +54,9 @@ var consts = {
// Maximum possible amount for non-XRP currencies using the maximum mantissa
// with maximum exponent. Corresponds to hex 0xEC6386F26FC0FFFF.
max_value: '9999999999999999e80'
max_value: '9999999999999999e80',
// Minimum possible amount for non-XRP currencies.
min_value: '-1000000000000000e-96'
};
// Add constants to Amount class
@@ -424,6 +426,33 @@ Amount.prototype.invert = function() {
return this.copy()._invert();
};
/**
* Canonicalize amount value
*
* Mirrors rippled's internal Amount representation
* From https://github.com/ripple/rippled/blob/develop/src/ripple/data/protocol/STAmount.h#L31-L40
*
* Internal form:
* 1: If amount is zero, then value is zero and offset is -100
* 2: Otherwise:
* legal offset range is -96 to +80 inclusive
* value range is 10^15 to (10^16 - 1) inclusive
* amount = value * [10 ^ offset]
*
* -------------------
*
* The amount can be epxresses as A x 10^B
* Where:
* - A must be an integer between 10^15 and (10^16)-1 inclusive
* - B must be between -96 and 80 inclusive
*
* This results
* - minumum: 10^15 x 10^-96 -> 10^-81 -> -1e-81
* - maximum: (10^16)-1 x 10^80 -> 9999999999999999e80
*
* @returns {Amount}
* @throws {Error} if offset exceeds legal ranges, meaning the amount value is bigger than supported
*/
Amount.prototype.canonicalize = function() {
if (!(this._value instanceof BigInteger)) {
// NaN.
@@ -447,9 +476,8 @@ Amount.prototype.canonicalize = function() {
}
}
// XXX Make sure not bigger than supported. Throw if so.
} else if (this.is_zero()) {
this._offset = -100;
this._offset = Amount.cMinOffset;
this._is_negative = false;
} else {
// Normalize mantissa to valid range.
@@ -465,6 +493,16 @@ Amount.prototype.canonicalize = function() {
}
}
// Make sure not bigger than supported. Throw if so.
if (this.is_negative() && this._offset < Amount.cMinOffset) {
throw new Error('Exceeding min value of ' + Amount.min_value);
}
// Make sure not smaller than supported. Throw if so.
if (!this.is_negative() && this._offset > Amount.cMaxOffset) {
throw new Error('Exceeding max value of ' + Amount.max_value);
}
return this;
};
@@ -539,9 +577,7 @@ Amount.prototype.equals = function(d, ignore_issuer) {
return this.equals(Amount.from_json(d));
}
var result = true;
result = !((!this.is_valid() || !d.is_valid())
var result = !((!this.is_valid() || !d.is_valid())
|| (this._is_native !== d._is_native)
|| (!this._value.equals(d._value) || this._offset !== d._offset)
|| (this._is_negative !== d._is_negative)

View File

@@ -53,11 +53,7 @@ Currency.HEX_CURRENCY_BAD = '0000000000000000000000005852500000000000';
Currency.prototype.human_RE = /^\s*([a-zA-Z0-9]{3})(\s*-\s*[- \w]+)?(\s*\(-?\d+\.?\d*%pa\))?\s*$/;
Currency.from_json = function(j, shouldInterpretXrpAsIou) {
if (j instanceof this) {
return j.clone();
} else {
return (new this()).parse_json(j, shouldInterpretXrpAsIou);
}
return (new Currency()).parse_json(j, shouldInterpretXrpAsIou);
};
Currency.from_human = function(j, opts) {
@@ -71,12 +67,9 @@ Currency.prototype.parse_json = function(j, shouldInterpretXrpAsIou) {
switch (typeof j) {
case 'string':
if (!j || /^(0|XRP)$/.test(j)) {
if (shouldInterpretXrpAsIou) {
this.parse_hex(Currency.HEX_CURRENCY_BAD);
} else {
this.parse_hex(Currency.HEX_ZERO);
}
// if an empty string is given, fall back to XRP
if (!j) {
this.parse_hex(shouldInterpretXrpAsIou ? Currency.HEX_CURRENCY_BAD : Currency.HEX_ZERO);
break;
}
@@ -86,6 +79,17 @@ Currency.prototype.parse_json = function(j, shouldInterpretXrpAsIou) {
if (matches) {
var currencyCode = matches[1];
// for the currency 'XRP' case
// we drop everything else that could have been provided
// e.g. 'XRP - Ripple'
if (!currencyCode || /^(0|XRP)$/.test(currencyCode)) {
this.parse_hex(shouldInterpretXrpAsIou ? Currency.HEX_CURRENCY_BAD : Currency.HEX_ZERO);
// early break, we can't have interest on XRP
break;
}
// the full currency is matched as it is part of the valid currency format, but not stored
// var full_currency = matches[2] || '';
var interest = matches[3] || '';
@@ -270,7 +274,7 @@ Currency.prototype.has_interest = function() {
* @returns {number} - interest for provided interval, can be negative for demurred currencies
*/
Currency.prototype.get_interest_at = function(referenceDate, decimals) {
if (!this.has_interest) {
if (!this.has_interest()) {
return 0;
}

View File

@@ -344,7 +344,7 @@ OrderBook.prototype.requestTransferRate = function(callback) {
return this.emit('transfer_rate', this._issuerTransferRate);
}
this._remote.requestAccountInfo(issuer, function(err, info) {
this._remote.requestAccountInfo({account: issuer}, function(err, info) {
if (err) {
// XXX What now?
return callback(err);
@@ -447,7 +447,7 @@ OrderBook.prototype.requestFundedAmount = function(account, callback) {
}
function requestNativeBalance(callback) {
self._remote.requestAccountInfo(account, function(err, info) {
self._remote.requestAccountInfo({account: account}, function(err, info) {
if (err) {
callback(err);
} else {
@@ -458,10 +458,11 @@ OrderBook.prototype.requestFundedAmount = function(account, callback) {
function requestLineBalance(callback) {
var request = self._remote.requestAccountLines(
account, // account
void(0), // account index
'VALIDATED', // ledger
self._issuerGets //peer
{
account: account,
ledger: 'validated',
peer: self._issuerGets
}
);
request.request(function(err, res) {

View File

@@ -23,6 +23,7 @@ var Server = require('./server').Server;
var Amount = require('./amount').Amount;
var Currency = require('./currency').Currency;
var UInt160 = require('./uint160').UInt160;
var UInt256 = require('./uint256').UInt256;
var Transaction = require('./transaction').Transaction;
var Account = require('./account').Account;
var Meta = require('./meta').Meta;
@@ -1198,19 +1199,42 @@ Remote.prototype.requestTx = function(hash, callback) {
};
/**
* Account request abstraction
* Account Request
*
* @this Remote
* @api private
* Optional paging with limit and marker options
* supported in rippled for 'account_lines' and 'account_offers'
*
* The paged responses aren't guaranteed to be reliable between
* ledger closes. You have to supply a ledger_index or ledger_hash
* when paging to ensure a complete response
*
* @param {String} type - request name, e.g. 'account_lines'
* @param {String} account - ripple address
* @param {Object} options - all optional
* @param {String} peer - ripple address
* @param [String|Number] ledger identifier
* @param [Number] limit - max results per response
* @param {String} marker - start position in response paging
* @param [Function] callback
* @return {Request}
*/
Remote.accountRequest = function(type, options, callback) {
var account, ledger, peer, limit, marker;
Remote.accountRequest = function(type, account, ledger, peer, callback) {
if (typeof account === 'object') {
var options = account;
callback = ledger;
ledger = options.ledger;
account = options.account || options.accountID;
peer = options.peer;
if (typeof options === 'object') {
account = options.account;
ledger = options.ledger;
peer = options.peer;
limit = options.limit;
marker = options.marker;
}
// if a marker is given, we need a ledger
// check if a valid ledger_index or ledger_hash is provided
if (marker) {
if (!(Number(ledger) > 0) && !UInt256.is_valid(ledger)) {
throw new Error('A ledger_index or ledger_hash must be provided when using a marker');
}
}
var lastArg = arguments[arguments.length - 1];
@@ -1220,30 +1244,55 @@ Remote.accountRequest = function(type, account, ledger, peer, callback) {
}
var request = new Request(this, type);
var account = UInt160.json_rewrite(account);
request.message.account = account;
if (account) {
account = UInt160.json_rewrite(account);
request.message.account = account;
}
request.ledgerSelect(ledger);
if (UInt160.is_valid(peer)) {
request.message.peer = UInt160.json_rewrite(peer);
}
request.callback(callback);
if (!isNaN(Number(limit))) {
limit = Number(limit);
// max for 32-bit unsigned int is 4294967295
// we'll clamp to 1e9
if (limit > 1e9) {
limit = 1e9;
}
// min for 32-bit unsigned int is 0
// we'll clamp to 0
if (limit < 0) {
limit = 0;
}
request.message.limit = limit;
}
if (marker) {
request.message.marker = marker;
}
request.callback(callback);
return request;
};
/**
* Request account_info
*
* @param {String} ripple address
* @param [String|Number] ledger identifier
* @param {Object} options
* @param {String} account - ripple address
* @param {String} peer - ripple address
* @param [String|Number] ledger identifier
* @param [Function] callback
* @return {Request}
*/
Remote.prototype.requestAccountInfo = function(account, callback) {
Remote.prototype.requestAccountInfo = function(options, callback) {
var args = Array.prototype.concat.apply(['account_info'], arguments);
return Remote.accountRequest.apply(this, args);
};
@@ -1251,13 +1300,15 @@ Remote.prototype.requestAccountInfo = function(account, callback) {
/**
* Request account_currencies
*
* @param {String} ripple address
* @param [String|Number] ledger identifier
* @param {Object} options
* @param {String} account - ripple address
* @param {String} peer - ripple address
* @param [String|Number] ledger identifier
* @param [Function] callback
* @return {Request}
*/
Remote.prototype.requestAccountCurrencies = function(account, callback) {
Remote.prototype.requestAccountCurrencies = function(options, callback) {
var args = Array.prototype.concat.apply(['account_currencies'], arguments);
return Remote.accountRequest.apply(this, args);
};
@@ -1265,14 +1316,24 @@ Remote.prototype.requestAccountCurrencies = function(account, callback) {
/**
* Request account_lines
*
* @param {String} ripple address
* @param [String|Number] ledger identifier
* @param [String] peer
* Requests for account_lines support paging, provide a limit and marker
* to page through responses.
*
* The paged responses aren't guaranteed to be reliable between
* ledger closes. You have to supply a ledger_index or ledger_hash
* when paging to ensure a complete response
*
* @param {Object} options
* @param {String} account - ripple address
* @param {String} peer - ripple address
* @param [String|Number] ledger identifier
* @param [Number] limit - max results per response
* @param {String} marker - start position in response paging
* @param [Function] callback
* @return {Request}
*/
Remote.prototype.requestAccountLines = function(account, peer, callback) {
Remote.prototype.requestAccountLines = function(options, callback) {
// XXX Does this require the server to be trusted?
//utils.assert(this.trusted);
var args = Array.prototype.concat.apply(['account_lines'], arguments);
@@ -1282,13 +1343,23 @@ Remote.prototype.requestAccountLines = function(account, peer, callback) {
/**
* Request account_offers
*
* @param {String} ripple address
* @param [String|Number] ledger identifier
* Requests for account_offers support paging, provide a limit and marker
* to page through responses.
*
* The paged responses aren't guaranteed to be reliable between
* ledger closes. You have to supply a ledger_index or ledger_hash
* when paging to ensure a complete response
*
* @param {Object} options
* @param {String} account - ripple address
* @param [String|Number] ledger identifier
* @param [Number] limit - max results per response
* @param {String} marker - start position in response paging
* @param [Function] callback
* @return {Request}
*/
Remote.prototype.requestAccountOffers = function(account, callback) {
Remote.prototype.requestAccountOffers = function(options, callback) {
var args = Array.prototype.concat.apply(['account_offers'], arguments);
return Remote.accountRequest.apply(this, args);
};

View File

@@ -564,7 +564,7 @@ Server.prototype._handleServerStatus = function(message) {
this._remote.emit('load', message, this);
var loadChanged = message.load_base !== this._load_base
|| message.load_factor !== this._load_factor
|| message.load_factor !== this._load_factor;
if (loadChanged) {
this._load_base = message.load_base;

View File

@@ -491,6 +491,23 @@ Transaction.prototype.lastLedger = function(sequence) {
return this;
};
/*
* Set the transaction's proposed fee. No op when fee parameter
* is not 0 or a positive number
*
* @param {Number} fee The proposed fee
*
* @returns {Transaction} calling instance for chaining
*/
Transaction.prototype.maxFee = function(fee) {
if (typeof fee === 'number' && fee >= 0) {
this._setMaxFee = true;
this._maxFee = fee;
}
return this;
};
Transaction._pathRewrite = function(path) {
if (!Array.isArray(path)) {
return;

View File

@@ -29,13 +29,15 @@ describe('Account', function(){
});
// XXX: clean up the stubbed out remote methods
describe('#publicKeyIsActive()', function(){
it('should respond true if the public key corresponds to the account address and the master key IS NOT disabled', function(){
var account = new Account({
on: function(){},
request_account_info: function(address, callback) {
requestAccountInfo: function(address, callback) {
if (address === 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz') {
callback(null, { account_data: {
Account: 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz',
@@ -56,7 +58,7 @@ describe('Account', function(){
var account = new Account({
on: function(){},
request_account_info: function(address, callback) {
requestAccountInfo: function(address, callback) {
if (address === 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz') {
callback(null, { account_data: {
Account: 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz',
@@ -77,7 +79,7 @@ describe('Account', function(){
var account = new Account({
on: function(){},
request_account_info: function(address, callback) {
requestAccountInfo: function(address, callback) {
if (address === 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz') {
callback(null, { account_data: {
Account: 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz',
@@ -99,7 +101,7 @@ describe('Account', function(){
var account = new Account({
on: function(){},
request_account_info: function(address, callback) {
requestAccountInfo: function(address, callback) {
if (address === 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz') {
callback(null, { account_data: {
Account: 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz',
@@ -121,7 +123,7 @@ describe('Account', function(){
var account = new Account({
on: function(){},
request_account_info: function(address, callback) {
requestAccountInfo: function(address, callback) {
if (address === 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz') {
callback(null, { account_data: {
Account: 'rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz',
@@ -142,7 +144,7 @@ describe('Account', function(){
var account = new Account({
on: function(){},
request_account_info: function(address, callback) {
requestAccountInfo: function(address, callback) {
if (address === 'rLdfp6eoR948KVxfn6EpaaNTKwfwXhzSeQ') {
callback({ error: 'remoteError',
error_message: 'Remote reported an error.',

View File

@@ -1162,4 +1162,80 @@ describe('Amount', function() {
assert.strictEqual(demAmount.to_human_full(), '10.75853086191915/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
});
});
describe('amount limits', function() {
it ('max JSON wire limite', function() {
assert.strictEqual(Amount.bi_xns_max.toString(), '9000000000000000000');
});
it ('max JSON wire limite', function() {
assert.strictEqual(Amount.bi_xns_min.toString(), '-9000000000000000000');
});
it('max mantissa value', function() {
assert.strictEqual(Amount.bi_man_max_value.toString(), '9999999999999999');
});
it('min mantissa value', function() {
assert.strictEqual(Amount.bi_man_min_value.toString(), '1000000000000000');
});
it ('from_json minimum XRP', function() {
console.log('max', Amount.bi_xns_max.toString());
var amt = Amount.from_json('-9000000000000000000');
assert.strictEqual(amt.to_json(), '-9000000000000000000');
});
it ('from_json maximum XRP', function() {
var amt = Amount.from_json('-9000000000000000000');
assert.strictEqual(amt.to_json(), '-9000000000000000000');
});
it ('from_json less than minimum XRP', function() {
var amt = Amount.from_json('-9000000000000000001');
assert.strictEqual(amt.to_json(), '0');
});
it ('from_json more than maximum XRP', function() {
var amt = Amount.from_json('9000000000000000001');
assert.strictEqual(amt.to_json(), '0');
});
it ('from_json minimum IOU', function() {
var amt = Amount.from_json('-1e-81/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(amt._value.toString(), Amount.bi_man_min_value.toString());
assert.strictEqual(amt.to_text(), '-1000000000000000e-96');
assert.strictEqual(amt.to_text(), Amount.min_value);
});
it('from_json exceed minimum IOU', function() {
assert.throws(function() {
Amount.from_json('-1e-82/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh')
}, 'Exceeding min value of ' + Amount.min_value);
});
it ('from_json maximum IOU', function() {
var amt = Amount.from_json('9999999999999999e80/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(amt._value.toString(), Amount.bi_man_max_value.toString());
assert.strictEqual(amt.to_text(), '9999999999999999e80');
});
it ('from_json exceed maximum IOU', function() {
assert.throws(function() {
Amount.from_json('9999999999999999e81/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh')
}, 'Exceeding max value of ' + Amount.max_value);
});
it ('from_json normalize mantissa to valid max range, lost significant digits', function() {
var amt = Amount.from_json('99999999999999999999999999999999/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
assert.strictEqual(amt._value.toString(), Amount.bi_man_max_value.toString());
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');
assert.strictEqual(amt._value.toString(), Amount.bi_man_min_value.toString());
assert.strictEqual(amt.to_text(), '-1000000000000000e-40');
});
});
});

View File

@@ -1,6 +1,7 @@
var assert = require('assert');
var utils = require('./testutils');
var currency = utils.load_module('currency').Currency;
var timeUtil = utils.load_module('utils').time;
describe('Currency', function() {
describe('json_rewrite', function() {
@@ -16,11 +17,22 @@ describe('Currency', function() {
});
});
describe('from_json', function() {
it('from_json().to_json() == "XRP"', function() {
var r = currency.from_json();
assert(!r.is_valid());
assert.strictEqual('XRP', r.to_json());
});
it('from_json(NaN).to_json() == "XRP"', function() {
var r = currency.from_json(NaN);
assert(!r.is_valid());
assert.strictEqual('XRP', r.to_json());
});
it('from_json().to_json("") == "XRP"', function() {
var r = currency.from_json('');
assert(r.is_valid());
assert(r.is_native());
assert.strictEqual('XRP', r.to_json());
});
it('from_json("XRP").to_json() == "XRP"', function() {
var r = currency.from_json('XRP');
assert(r.is_valid());
@@ -103,6 +115,16 @@ describe('Currency', function() {
var cur = currency.from_human('INR - 30 Indian Rupees');
assert.strictEqual(cur.to_json(), 'INR');
});
it('From human "XRP"', function() {
var cur = currency.from_human('XRP');
assert.strictEqual(cur.to_json(), 'XRP');
assert(cur.is_native(), true);
});
it('From human "XRP - Ripples"', function() {
var cur = currency.from_human('XRP - Ripples');
assert.strictEqual(cur.to_json(), 'XRP');
assert(cur.is_native(), true);
});
});
@@ -162,10 +184,20 @@ describe('Currency', function() {
assert.strictEqual(cur.to_json(), cur.to_human());
});
});
describe('parse_json(currency obj)', function() {
assert.strictEqual('USD', new currency().parse_json(currency.from_json('USD')).to_json());
describe('parse_json', function() {
it('should parse a currency object', function() {
assert.strictEqual('USD', new currency().parse_json(currency.from_json('USD')).to_json());
assert.strictEqual('USD (0.5%pa)', new currency().parse_json(currency.from_json('USD (0.5%pa)')).to_json());
});
it('should clone for parse_json on itself', function() {
var cur = currency.from_json('USD');
var cur2 = currency.from_json(cur);
assert.strictEqual(cur.to_json(), cur2.to_json());
assert.strictEqual('USD (0.5%pa)', new currency().parse_json(currency.from_json('USD (0.5%pa)')).to_json());
cur = currency.from_hex('015841551A748AD2C1F76FF6ECB0CCCD00000000');
cur2 = currency.from_json(cur);
assert.strictEqual(cur.to_json(), cur2.to_json());
});
});
describe('is_valid', function() {
@@ -207,14 +239,16 @@ describe('Currency', function() {
return +(Math.round(num + "e+"+precision) + "e-"+precision);
}
describe('get_interest_at', function() {
it('returns demurred value for demurrage currency', function() {
it('should return demurred value for demurrage currency', function() {
var cur = currency.from_json('015841551A748AD2C1F76FF6ECB0CCCD00000000');
// At start, no demurrage should occur
assert.equal(1, cur.get_interest_at(443845330));
assert.equal(1, precision(cur.get_interest_at(new Date(timeUtil.fromRipple(443845330))), 14));
// After one year, 0.5% should have occurred
assert.equal(0.995, precision(cur.get_interest_at(443845330 + 31536000), 14));
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));
@@ -225,6 +259,11 @@ describe('Currency', function() {
// One demurrage period before start, rate should be e
assert.equal(Math.E, cur.get_interest_at(443845330 - 6291418827.05));
});
it('should return 0 for currency without interest', function() {
var cur = currency.from_json('USD - US Dollar');
assert.equal(0, cur.get_interest_at(443845330));
assert.equal(0, cur.get_interest_at(443845330 + 31536000));
});
});
describe('get_iso', function() {
it('should get "XRP" iso_code', function() {

View File

@@ -270,7 +270,8 @@ describe('Message', function(){
//Remote.prototype.addServer = function(){};
var test_remote = new Remote();
test_remote.state = 'online';
test_remote.request_account_info = function(account, callback) {
test_remote.requestAccountInfo = function(options, callback) {
var account = options.account;
if (account === data.account) {
callback(null, {
"account_data": {
@@ -306,7 +307,8 @@ describe('Message', function(){
//Remote.prototype.addServer = function(){};
var test_remote = new Remote();
test_remote.state = 'online';
test_remote.request_account_info = function(account, callback) {
test_remote.requestAccountInfo = function(options, callback) {
var account = options.account;
if (account === data.account) {
callback(null, {
"account_data": {

View File

@@ -5,7 +5,14 @@ var Remote = utils.load_module('remote').Remote;
var Server = utils.load_module('server').Server;
var Request = utils.load_module('request').Request;
var options, spy, mock, stub, remote, callback, database, tx;
var options, remote, callback, database, tx;
var ADDRESS = 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS';
var PEER_ADDRESS = 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX';
var LEDGER_INDEX = 9592219;
var LEDGER_HASH = 'B4FD84A73DBD8F0DA9E320D137176EBFED969691DC0AAC7882B76B595A0841AE';
var PAGING_MARKER = '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73';
describe('Remote', function () {
beforeEach(function () {
@@ -28,10 +35,10 @@ describe('Remote', function () {
// 'bitcoin': 'localhost:3000'
// 'bitcoin': 'https://www.bitstamp.net/ripple/bridge/out/bitcoin/'
}
},
}
};
})
});
it('remote server initialization - url object', function() {
var remote = new Remote({
@@ -185,44 +192,221 @@ describe('Remote', function () {
assert(request instanceof Request);
});
it('request account currencies with ledger index', function() {
var request = remote.requestAccountCurrencies({account: ADDRESS});
assert.strictEqual(request.message.command, 'account_currencies');
assert.strictEqual(request.message.account, ADDRESS);
});
it('request account info with ledger index', function() {
var request = remote.requestAccountInfo('r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', 9592219);
var request = remote.requestAccountInfo({account: ADDRESS, ledger: 9592219});
assert.strictEqual(request.message.command, 'account_info');
assert.strictEqual(request.message.account, 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS');
assert.strictEqual(request.message.account, ADDRESS);
assert.strictEqual(request.message.ledger_index, 9592219);
});
it('request account info with ledger hash', function() {
var request = remote.requestAccountInfo('r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', 'B4FD84A73DBD8F0DA9E320D137176EBFED969691DC0AAC7882B76B595A0841AE');
var request = remote.requestAccountInfo({account: ADDRESS, ledger: LEDGER_HASH});
assert.strictEqual(request.message.command, 'account_info');
assert.strictEqual(request.message.account, 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS');
assert.strictEqual(request.message.ledger_hash, 'B4FD84A73DBD8F0DA9E320D137176EBFED969691DC0AAC7882B76B595A0841AE');
assert.strictEqual(request.message.account, ADDRESS);
assert.strictEqual(request.message.ledger_hash, LEDGER_HASH);
});
it('request account info with ledger identifier', function() {
var request = remote.requestAccountInfo('r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', 'validated');
var request = remote.requestAccountInfo({account: ADDRESS, ledger: 'validated'});
assert.strictEqual(request.message.command, 'account_info');
assert.strictEqual(request.message.account, 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS');
assert.strictEqual(request.message.account, ADDRESS);
assert.strictEqual(request.message.ledger_index, 'validated');
});
it('request account balance with ledger index', function() {
var request = remote.requestAccountBalance('r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', 9592219);
var request = remote.requestAccountBalance(ADDRESS, 9592219);
assert.strictEqual(request.message.command, 'ledger_entry');
assert.strictEqual(request.message.account_root, 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS');
assert.strictEqual(request.message.account_root, ADDRESS);
assert.strictEqual(request.message.ledger_index, 9592219);
});
it('request account balance with ledger hash', function() {
var request = remote.requestAccountBalance('r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', 'B4FD84A73DBD8F0DA9E320D137176EBFED969691DC0AAC7882B76B595A0841AE');
var request = remote.requestAccountBalance(ADDRESS, LEDGER_HASH);
assert.strictEqual(request.message.command, 'ledger_entry');
assert.strictEqual(request.message.account_root, 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS');
assert.strictEqual(request.message.ledger_hash, 'B4FD84A73DBD8F0DA9E320D137176EBFED969691DC0AAC7882B76B595A0841AE');
assert.strictEqual(request.message.account_root, ADDRESS);
assert.strictEqual(request.message.ledger_hash, LEDGER_HASH);
});
it('request account balance with ledger identifier', function() {
var request = remote.requestAccountBalance('r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', 'validated');
var request = remote.requestAccountBalance(ADDRESS, 'validated');
assert.strictEqual(request.message.command, 'ledger_entry');
assert.strictEqual(request.message.account_root, 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS');
assert.strictEqual(request.message.account_root, ADDRESS);
assert.strictEqual(request.message.ledger_index, 'validated');
});
})
});
it('pagingAccountRequest', function() {
var request = Remote.accountRequest('account_lines', {account: ADDRESS});
assert.deepEqual(request.message, {
command: 'account_lines',
id: undefined,
account: ADDRESS
});
});
it('pagingAccountRequest - limit', function() {
var request = Remote.accountRequest('account_lines', {account: ADDRESS, limit: 100});
assert.deepEqual(request.message, {
command: 'account_lines',
id: undefined,
account: ADDRESS,
limit: 100
});
});
it('pagingAccountRequest - limit, marker', function() {
var request = Remote.accountRequest('account_lines', {account: ADDRESS, limit: 100, marker: PAGING_MARKER, ledger: 9592219});
assert.deepEqual(request.message, {
command: 'account_lines',
id: undefined,
account: ADDRESS,
limit: 100,
marker: PAGING_MARKER,
ledger_index: 9592219
});
assert(!request.requested);
});
it('accountRequest - limit min', function() {
assert.strictEqual(Remote.accountRequest('account_lines', {account: ADDRESS, limit: 0}).message.limit, 0);
assert.strictEqual(Remote.accountRequest('account_lines', {account: ADDRESS, limit: -1}).message.limit, 0);
assert.strictEqual(Remote.accountRequest('account_lines', {account: ADDRESS, limit: -1e9}).message.limit, 0);
assert.strictEqual(Remote.accountRequest('account_lines', {account: ADDRESS, limit: -1e24}).message.limit, 0);
});
it('accountRequest - limit max', function() {
assert.strictEqual(Remote.accountRequest('account_lines', {account: ADDRESS, limit: 1e9}).message.limit, 1e9);
assert.strictEqual(Remote.accountRequest('account_lines', {account: ADDRESS, limit: 1e9+1}).message.limit, 1e9);
assert.strictEqual(Remote.accountRequest('account_lines', {account: ADDRESS, limit: 1e10}).message.limit, 1e9);
assert.strictEqual(Remote.accountRequest('account_lines', {account: ADDRESS, limit: 1e24}).message.limit, 1e9);
});
it('accountRequest - a valid ledger is required when using a marker', function() {
assert.throws(function() {
Remote.accountRequest('account_lines', {account: ADDRESS, marker: PAGING_MARKER})
},'A ledger_index or ledger_hash must be provided when using a marker');
assert.throws(function() {
Remote.accountRequest('account_lines', {account: ADDRESS, marker: PAGING_MARKER, ledger:'validated'})
},'A ledger_index or ledger_hash must be provided when using a marker');
assert.throws(function() {
Remote.accountRequest('account_lines', {account: ADDRESS, marker: PAGING_MARKER, ledger:NaN})
},'A ledger_index or ledger_hash must be provided when using a marker');
assert.throws(function() {
Remote.accountRequest('account_lines', {account: ADDRESS, marker: PAGING_MARKER, ledger:LEDGER_HASH.substr(0,63)})
},'A ledger_index or ledger_hash must be provided when using a marker');
assert.throws(function() {
Remote.accountRequest('account_lines', {account: ADDRESS, marker: PAGING_MARKER, ledger:LEDGER_HASH+'F'})
},'A ledger_index or ledger_hash must be provided when using a marker');
});
it('requestAccountLines, account and callback', function() {
var callback = function() {};
var remote = new Remote({
servers: [ { host: 's-west.ripple.com', port: 443, secure: true } ]
});
var request = remote.requestAccountLines(
{account: ADDRESS},
callback
);
assert.deepEqual(request.message, {
command: 'account_lines',
id: undefined,
account: ADDRESS
});
assert(request.requested);
});
it('requestAccountLines, ledger, peer', function() {
var callback = function() {};
var remote = new Remote({
servers: [ { host: 's-west.ripple.com', port: 443, secure: true } ]
});
var request = remote.requestAccountLines(
{
account: ADDRESS,
ledger: LEDGER_HASH,
peer: PEER_ADDRESS
},
callback
);
assert.deepEqual(request.message, {
command: 'account_lines',
id: undefined,
account: ADDRESS,
ledger_hash: LEDGER_HASH,
peer: PEER_ADDRESS
});
assert(request.requested);
});
it('requestAccountLines, ledger, peer, limit and marker', function() {
var callback = function() {};
var remote = new Remote({
servers: [ { host: 's-west.ripple.com', port: 443, secure: true } ]
});
var request = remote.requestAccountLines(
{
account: ADDRESS,
ledger: LEDGER_INDEX,
peer: PEER_ADDRESS,
limit: 200,
marker: PAGING_MARKER
},
callback
);
assert.deepEqual(request.message, {
command: 'account_lines',
id: undefined,
account: ADDRESS,
ledger_index: LEDGER_INDEX,
peer: PEER_ADDRESS,
limit: 200,
marker: PAGING_MARKER
});
assert(request.requested);
});
it('requestAccountOffers, ledger, peer, limit and marker', function() {
var callback = function() {};
var remote = new Remote({
servers: [ { host: 's-west.ripple.com', port: 443, secure: true } ]
});
var request = remote.requestAccountOffers(
{
account: ADDRESS,
ledger: LEDGER_HASH,
peer: PEER_ADDRESS,
limit: 32,
marker: PAGING_MARKER
},
callback
);
assert.deepEqual(request.message, {
command: 'account_offers',
id: undefined,
account: ADDRESS,
ledger_hash: LEDGER_HASH,
peer: PEER_ADDRESS,
limit: 32,
marker: PAGING_MARKER
});
assert(request.requested);
});
it('create remote and get pending transactions', function() {
before(function() {
@@ -282,7 +466,7 @@ describe('Remote', function () {
callback(null, tx);
}
}
})
});
it('should set transaction members correct ', function(done) {
remote = new Remote(options);

View File

@@ -835,6 +835,20 @@ describe('Transaction', function() {
assert(transaction._setLastLedger);
});
it('Set Max Fee', function() {
var transaction = new Transaction();
transaction.maxFee('a');
assert(!transaction._setMaxFee);
transaction.maxFee(NaN);
assert(!transaction._setMaxFee);
transaction.maxFee(1000);
assert.strictEqual(transaction._maxFee, 1000);
assert.strictEqual(transaction._setMaxFee, true);
});
it('Rewrite transaction path', function() {
var transaction = new Transaction();