|
|
@ -1244,46 +1244,64 @@ 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; |
|
|
|
opts.addresses = opts.addresses || []; |
|
|
|
|
|
|
|
// 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; |
|
|
|
} |
|
|
|
function checkBalanceCache(cb) { |
|
|
|
if (opts.addresses.length < Defaults.BALANCE_CACHE_ADDRESS_THRESOLD) |
|
|
|
return cb(); |
|
|
|
|
|
|
|
self.storage.checkAndUseBalanceCache(self.walletId, opts.addresses, cb); |
|
|
|
}; |
|
|
|
|
|
|
|
self._getUtxosForCurrentWallet({ |
|
|
|
coin: opts.coin, |
|
|
|
addresses: opts.addresses |
|
|
|
}, function(err, utxos) { |
|
|
|
function storeBalanceCache(balance, cb) { |
|
|
|
if (opts.addresses.length < Defaults.BALANCE_CACHE_ADDRESS_THRESOLD) |
|
|
|
return cb(null, balance); |
|
|
|
|
|
|
|
self.storage.storeBalanceCache(self.walletId, opts.addresses, balance, function(err) { |
|
|
|
if (err) |
|
|
|
log.warn('Could not save cache:',err); |
|
|
|
|
|
|
|
return cb(null, balance); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// This lock is to prevent server starvation on big wallets
|
|
|
|
self._runLocked(cb, function(cb) { |
|
|
|
checkBalanceCache(function(err, cache) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
var balance = self._totalizeUtxos(utxos); |
|
|
|
if (cache) { |
|
|
|
log.info('Using UTXO Cache'); |
|
|
|
return cb(null, cache, true); |
|
|
|
} |
|
|
|
|
|
|
|
self._getUtxosForCurrentWallet({ |
|
|
|
coin: opts.coin, |
|
|
|
addresses: opts.addresses |
|
|
|
}, function(err, utxos) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
// Compute balance by address
|
|
|
|
var byAddress = {}; |
|
|
|
_.each(_.indexBy(_.sortBy(utxos, 'address'), 'address'), function(value, key) { |
|
|
|
byAddress[key] = { |
|
|
|
address: key, |
|
|
|
path: value.path, |
|
|
|
amount: 0, |
|
|
|
}; |
|
|
|
}); |
|
|
|
var balance = self._totalizeUtxos(utxos); |
|
|
|
|
|
|
|
_.each(utxos, function(utxo) { |
|
|
|
byAddress[utxo.address].amount += utxo.satoshis; |
|
|
|
}); |
|
|
|
// Compute balance by address
|
|
|
|
var byAddress = {}; |
|
|
|
_.each(_.indexBy(_.sortBy(utxos, 'address'), 'address'), function(value, key) { |
|
|
|
byAddress[key] = { |
|
|
|
address: key, |
|
|
|
path: value.path, |
|
|
|
amount: 0, |
|
|
|
}; |
|
|
|
}); |
|
|
|
|
|
|
|
balance.byAddress = _.values(byAddress); |
|
|
|
_.each(utxos, function(utxo) { |
|
|
|
byAddress[utxo.address].amount += utxo.satoshis; |
|
|
|
}); |
|
|
|
|
|
|
|
if (isBig) { |
|
|
|
return self.storage.storeBalanceCache(addresses, balance, cb); |
|
|
|
} else { |
|
|
|
return cb(null, balance); |
|
|
|
} |
|
|
|
balance.byAddress = _.values(byAddress); |
|
|
|
|
|
|
|
storeBalanceCache(balance, cb); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
@ -1296,7 +1314,7 @@ WalletService.prototype._getBalanceOneStep = function(opts, cb) { |
|
|
|
self._getBalanceFromAddresses({ |
|
|
|
coin: opts.coin, |
|
|
|
addresses: addresses |
|
|
|
}, function(err, balance) { |
|
|
|
}, function(err, balance, cacheUsed) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
// Update cache
|
|
|
@ -1305,7 +1323,7 @@ WalletService.prototype._getBalanceOneStep = function(opts, cb) { |
|
|
|
if (err) { |
|
|
|
log.warn('Could not update wallet cache', err); |
|
|
|
} |
|
|
|
return cb(null, balance); |
|
|
|
return cb(null, balance, cacheUsed); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -1382,7 +1400,6 @@ WalletService.prototype.getBalance = function(opts, cb, i) { |
|
|
|
return self._getBalanceOneStep(opts, cb); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
self.storage.getTwoStepCache(self.walletId, function(err, twoStepCache) { |
|
|
|
if (err) return cb(err); |
|
|
|
twoStepCache = twoStepCache || {}; |
|
|
@ -1404,9 +1421,9 @@ WalletService.prototype.getBalance = function(opts, cb, i) { |
|
|
|
self._getBalanceFromAddresses({ |
|
|
|
coin: opts.coin, |
|
|
|
addresses: activeAddresses |
|
|
|
}, function(err, partialBalance) { |
|
|
|
}, function(err, partialBalance, cacheUsed) { |
|
|
|
if (err) return cb(err); |
|
|
|
cb(null, partialBalance); |
|
|
|
cb(null, partialBalance, cacheUsed); |
|
|
|
|
|
|
|
var now = Math.floor(Date.now() / 1000); |
|
|
|
|
|
|
|