diff --git a/lib/services/wallet-api/index.js b/lib/services/wallet-api/index.js index 1f4a3c34..d3b3c649 100644 --- a/lib/services/wallet-api/index.js +++ b/lib/services/wallet-api/index.js @@ -17,6 +17,7 @@ var validators = require('./validators'); var utils = require('./utils'); var _ = require('lodash'); var bodyParser = require('body-parser'); +var LRU = require('lru-cache'); var WalletService = function(options) { BaseService.call(this, options); @@ -25,6 +26,13 @@ var WalletService = function(options) { valueEncoding: 'json' }; this._db = levelup(options.dbPath, this._dbOptions); + this._cache = LRU({ + max: 500 * 1024 * 1024, + length: function(n, key) { + return Buffer.byteLength(n, 'utf8'); + }, + maxAge: 30 * 60 * 1000 + }); }; inherits(WalletService, BaseService); @@ -241,31 +249,54 @@ WalletService.prototype._chunkAdresses = function(addresses) { WalletService.prototype._getTransactions = function(walletId, options, callback) { var self = this; - self._getAddresses(walletId, function(err, addresses) { - if(err) { - return callback(err); - } - if (!addresses) { - return callback(new Error('wallet not found')); - } - var addressGroups = self._chunkAdresses(addresses); - var transactions = []; - async.eachSeries(addressGroups, function(addresses, next) { - self.node.services.bitcoind.getAddressHistory(addresses, options, function(err, history) { + var transactions = []; + var opts = { + start: options.start, + end: options.end + }; + var key = walletId + opts.start + opts.end; + if (!self._cache.peek(key)) { + self._getAddresses(walletId, function(err, addresses) { + if(err) { + return callback(err); + } + if (!addresses) { + return callback(new Error('wallet not found')); + } + var addressGroups = self._chunkAdresses(addresses); + async.eachSeries(addressGroups, function(addresses, next) { + self.node.services.bitcoind.getAddressHistory(addresses, opts, function(err, history) { + if(err) { + return next(err); + } + var groupTransactions = history.items.map(function(item) { + return item.tx; + }); + transactions = _.union(transactions, groupTransactions); + next(); + }); + }, function(err) { if(err) { return callback(err); } - var groupTransactions = history.items.map(function(item) { - return item.tx; - }); - transactions = _.union(transactions, groupTransactions); - next(); + self._cache.set(key, JSON.stringify(transactions)); + finish(); }); - - }, function(err) { - callback(null, transactions, transactions.length); }); - }); + } else { + try { + transactions = JSON.parse(self._cache.get(key)); + finish(); + } catch(e) { + self._cache.del(key); + return callback(e); + } + } + function finish() { + var from = options.from || 0; + var to = options.to || transactions.length; + callback(null, transactions.slice(from, to), transactions.length); + } }; WalletService.prototype._getAddresses = function(walletId, callback) { diff --git a/package.json b/package.json index 8f5d6136..6cfd90ea 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "levelup": "^1.3.3", "liftoff": "^2.2.0", "lodash": "^4.17.4", - "lru-cache": "^4.0.1", + "lru-cache": "^4.0.2", "mkdirp": "0.5.0", "multer": "^1.2.1", "path-is-absolute": "^1.0.0",