WIP short address cache

This commit is contained in:
Matias Alejo Garcia 2017-11-02 10:35:34 -03:00
parent cc9e0ba403
commit bf2e281787
No known key found for this signature in database
GPG Key ID: 02470DB551277AB3
3 changed files with 80 additions and 2 deletions

View File

@ -96,6 +96,12 @@ Defaults.CONFIRMATIONS_TO_START_CACHING = 6 * 6; // ~ 6hrs
// Number of addresses from which tx history is enabled in a wallet
Defaults.HISTORY_CACHE_ADDRESS_THRESOLD = 100;
// Number of addresses from which balance in cache for a few seconds
Defaults.BALANCE_CACHE_ADDRESS_THRESOLD = Defaults.HISTORY_CACHE_ADDRESS_THRESOLD;
// Duration in seconds of the balance cache
Defaults.BALANCE_CACHE_DURATION = 5
// Cache time for blockchain height (in seconds)
Defaults.BLOCKHEIGHT_CACHE_TIME = 10 * 60;

View File

@ -1243,11 +1243,18 @@ WalletService.prototype._totalizeUtxos = function(utxos) {
WalletService.prototype._getBalanceFromAddresses = function(opts, cb, i) {
var self = this;
var opts = opts || {};
var isBig = opts.addresses.length > Default.BALANCE_CACHE_ADDRESS_THRESOLD;
// This lock is to prevent server starvation on big wallets
self._runLocked(cb, function(cb) {
if (isBig && self.storage.checkAndUseBalanceCache(addresses,cb))
log.info('Using UTXO Cache');
return;
}
self._getUtxosForCurrentWallet({
coin: opts.coin,
addresses: opts.addresses
@ -1271,7 +1278,12 @@ WalletService.prototype._getBalanceFromAddresses = function(opts, cb, i) {
});
balance.byAddress = _.values(byAddress);
return cb(null, balance);
if (isBig) {
return self.storage.storeBalanceCache(addresses, balance, cb);
} else {
return cb(null, balance);
}
});
});
};

View File

@ -7,6 +7,7 @@ var log = require('npmlog');
log.debug = log.verbose;
log.disableColor();
var util = require('util');
var Bitcore = require('bitcore-lib');
var mongodb = require('mongodb');
@ -1065,5 +1066,64 @@ Storage.prototype._dump = function(cb, fn) {
});
};
Storage.prototype._addressHash = function(addresses) {
var all = addresses.join();
return Bitcore.crypto.Hash.ripemd160(new Buffer(all)).toString('hex');
};
Storage.prototype.checkAndUseBalanceCache = function(addresses, cb) {
var key = ths._addressHash(addresses);
var now = Date.now();
self.db.collection(collections.CACHE).findOne({
walletId: walletId,
type: 'balanceCache',
key: key,
}, function(err, ret) {
if (err) return cb(err);
if (!ret) return cb();
var validFor = ret.ts + Defauls.BALANCE_CACHE_DURATION * 1000 - now;
if (validFor > 0) {
log.debug('','Using Balance Cache valid for %d ms more', validFor);
return cb(null, ret.result);
}
return cb();
log.debug('','Balance cache expired, deleting');
self.db.collection(collections.CACHE).remove({
walletId: walletId,
type: 'balanceCache',
key: key,
}, {}, function() {
});
});
});
Storage.prototype.storeBalanceCache = function (addresses, balance, cb) {
var key = ths._addressHash(addresses);
var now = Date.now();
self.db.collection(collections.CACHE).update( {
walletId: walletId,
type: 'balanceCache',
key: key,
}, {
"$set":
{
ts: now,
result: balance,
}
}, {
w: 1,
upsert: true,
}, cb);
};
Storage.collections = collections;
module.exports = Storage;