diff --git a/src/js/ripple/orderbook.js b/src/js/ripple/orderbook.js index 2516642d..6cde6acf 100644 --- a/src/js/ripple/orderbook.js +++ b/src/js/ripple/orderbook.js @@ -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, + { + ledger: 'validated', + peer: self._issuerGets + } ); request.request(function(err, res) { diff --git a/src/js/ripple/remote.js b/src/js/ripple/remote.js index ea048133..85104b73 100644 --- a/src/js/ripple/remote.js +++ b/src/js/ripple/remote.js @@ -1234,6 +1234,70 @@ Remote.accountRequest = function(type, account, ledger, peer, callback) { return request; }; +/** + * Account Request for paging request + * + * @param {String} type - request name, e.g. 'account_lines' + * @param {String} account - ripple address + * @param {Object} options + * @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.pagingAccountRequest = function(type, account, options, callback) { + var ledger, peer, limit, marker; + + if (typeof options === 'object') { + ledger = options.ledger; + peer = options.peer; + limit = options.limit; + marker = options.marker; + } + + var lastArg = arguments[arguments.length - 1]; + + if (typeof lastArg === 'function') { + callback = lastArg; + } + + var request = new Request(this, type); + var account = UInt160.json_rewrite(account); + + request.message.account = account; + request.ledgerSelect(ledger); + + if (UInt160.is_valid(peer)) { + request.message.peer = UInt160.json_rewrite(peer); + } + + 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 * @@ -1265,32 +1329,38 @@ Remote.prototype.requestAccountCurrencies = function(account, callback) { /** * Request account_lines * - * @param {String} ripple address - * @param [String|Number] ledger identifier - * @param [String] peer + * @param {String} account - ripple address + * @param {Object} options + * @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(account, options, callback) { // XXX Does this require the server to be trusted? //utils.assert(this.trusted); var args = Array.prototype.concat.apply(['account_lines'], arguments); - return Remote.accountRequest.apply(this, args); + return Remote.pagingAccountRequest.apply(this, args); }; /** * Request account_offers * - * @param {String} ripple address - * @param [String|Number] ledger identifier + * @param {String} account - ripple address + * @param {Object} options + * @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(account, options, callback) { var args = Array.prototype.concat.apply(['account_offers'], arguments); - return Remote.accountRequest.apply(this, args); + return Remote.pagingAccountRequest.apply(this, args); }; /** diff --git a/src/js/ripple/server.js b/src/js/ripple/server.js index b80f0da9..23ab705e 100644 --- a/src/js/ripple/server.js +++ b/src/js/ripple/server.js @@ -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; diff --git a/test/remote-test.js b/test/remote-test.js index a2365b47..72e31c44 100644 --- a/test/remote-test.js +++ b/test/remote-test.js @@ -28,10 +28,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({ @@ -222,7 +222,155 @@ describe('Remote', function () { assert.strictEqual(request.message.account_root, 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS'); assert.strictEqual(request.message.ledger_index, 'validated'); }); - }) + }); + + it('pagingAccountRequest', function() { + var request = Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS'); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS' + }); + }); + + it('pagingAccountRequest - limit', function() { + var request = Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: 100}); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + limit: 100 + }); + }); + + it('pagingAccountRequest - limit, marker', function() { + var request = Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: 100, marker: '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73'}); + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + limit: 100, + marker: '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73' + }); + + assert(!request.requested); + }); + + it('pagingAccountRequest - limit min', function() { + assert.strictEqual(Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: 0}).message.limit, 0); + assert.strictEqual(Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: -1}).message.limit, 0); + assert.strictEqual(Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: -1e9}).message.limit, 0); + assert.strictEqual(Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: -1e24}).message.limit, 0); + }); + + it('pagingAccountRequest - limit max', function() { + assert.strictEqual(Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: 1e9}).message.limit, 1e9); + assert.strictEqual(Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: 1e9+1}).message.limit, 1e9); + assert.strictEqual(Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: 1e10}).message.limit, 1e9); + assert.strictEqual(Remote.pagingAccountRequest('account_lines', 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', {limit: 1e24}).message.limit, 1e9); + }); + + 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( + 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + callback + ); + + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS' + }); + + 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( + 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + { + ledger: 'validated', + peer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX' + }, + callback + ); + + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + ledger_index: 'validated', + peer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX' + }); + + 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( + 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + { + ledger: 'validated', + peer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX', + limit: 200, + marker: '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73' + }, + callback + ); + + assert.deepEqual(request.message, { + command: 'account_lines', + id: undefined, + account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + ledger_index: 'validated', + peer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX', + limit: 200, + marker: '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73' + }); + + 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( + 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + { + ledger: 'validated', + peer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX', + limit: 32, + marker: '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73' + }, + callback + ); + + assert.deepEqual(request.message, { + command: 'account_offers', + id: undefined, + account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + ledger_index: 'validated', + peer: 'rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX', + limit: 32, + marker: '29F992CC252056BF690107D1E8F2D9FBAFF29FF107B62B1D1F4E4E11ADF2CC73' + }); + + assert(request.requested); + }); it('create remote and get pending transactions', function() { before(function() { @@ -282,7 +430,7 @@ describe('Remote', function () { callback(null, tx); } } - }) + }); it('should set transaction members correct ', function(done) { remote = new Remote(options);