From 2dc2c4106c156e15367870837f47a229e981aa4e Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 29 Feb 2016 16:35:28 -0300 Subject: [PATCH] WIP --- app/controllers/addresses.js | 6 ++- app/models/Address.js | 89 ++++++++++++++++++++++++++++++++++-- lib/Sync.js | 11 ++++- 3 files changed, 99 insertions(+), 7 deletions(-) diff --git a/app/controllers/addresses.js b/app/controllers/addresses.js index ca2fc3a..1a660b9 100644 --- a/app/controllers/addresses.js +++ b/app/controllers/addresses.js @@ -47,8 +47,10 @@ var getAddrs = function(req, res, next) { var addrStrs = req.param('addrs'); var s = addrStrs.split(','); if (s.length === 0) return as; + var enableDeadAddresses = s.length > 100; +console.log('[addresses.js.50:enableDeadAddresses:]',enableDeadAddresses); //TODO for (var i = 0; i < s.length; i++) { - var a = new Address(s[i]); + var a = new Address(s[i], enableDeadAddresses); as.push(a); } } catch (e) { @@ -244,7 +246,7 @@ exports.multitxs = function(req, res, next) { cache[addrStrs] = txs; // 5 min. just to purge memory. Cache is overwritten in from=0 requests. setTimeout(function(){ - console.log('Deleting cache'); + console.log('Deleting cache:', addrStrs.substr(0,20)); delete cache[addrStrs]; }, 5 * 60 * 1000); } diff --git a/app/models/Address.js b/app/models/Address.js index 780daf7..305faf5 100644 --- a/app/models/Address.js +++ b/app/models/Address.js @@ -13,8 +13,19 @@ var TransactionDb = imports.TransactionDb || require('../../lib/TransactionDb'). var BlockDb = imports.BlockDb || require('../../lib/BlockDb').default(); var config = require('../../config/config'); var CONCURRENCY = 5; +var DAYS_TO_DEAD = 2; + +var deadCache = {}; + +function Address(addrStr, deadCacheEnable) { + + if (deadCacheEnable && deadCache[addrStr]) { + console.log('DEAD CACHE HIT:', addrStr, deadCache[addrStr].cached); + return deadCache[addrStr]; + } + + this.deadCacheEnable = deadCacheEnable; -function Address(addrStr) { this.balanceSat = 0; this.totalReceivedSat = 0; this.totalSentSat = 0; @@ -76,6 +87,26 @@ function Address(addrStr) { } + +Address.deleteDeadCache = function(addrStr) { + if (deadCache[addrStr]) { + console.log('Deleting Dead Address Cache', addrStr); + delete deadCache[addrStr]; + } +}; + + +Address.prototype.setCache = function() { + this.cached = true; + deadCache[this.addrStr] = this; + + console.log('%%%%%%%% setting DEAD cache for ', this.addrStr, this.unspent.length, this.transactions.length); //TODO + console.log('%%%%%%%% cache size:', _.keys(deadCache).length); //TODO + + // TODO expire it... +}; + + Address.prototype.getObj = function() { // Normalize json address return { @@ -165,8 +196,28 @@ Address.prototype.update = function(next, opts) { if (!('ignoreCache' in opts)) opts.ignoreCache = config.ignoreCache; + if (opts.onlyUnspent && opts.includeTxInfo) + return cb('Bad params'); + + if (!opts.ignoreCache && this.cached) { + +console.log('[Address.js.203] CACHED????', this.addrStr, opts.onlyUnspent, opts.includeTxInfo); //TODO + + + if (opts.onlyUnspent && this.unspent) { +console.log('[Address.js.206] YES (unspent)'); //TODO + return next(); + } + + if (opts.includeTxInfo && this.transactions.length) { +console.log('[Address.js.206] YES (TXS)'); //TODO + return next(); + } + } + // should collect txList from address? var txList = opts.txLimit === 0 ? null : []; + var lastUsage, now = Date.now() / 1000; var tDb = TransactionDb; var bDb = BlockDb; @@ -180,13 +231,15 @@ Address.prototype.update = function(next, opts) { // console.log('[Address.js.161:txOut:]',txOut); //TODO if (err) return next(err); if (opts.onlyUnspent) { - txOut = txOut.filter(function(x) { + + var unspent = _.filter(txOut,function(x) { return !x.spentTxId; }); - tDb.fillScriptPubKey(txOut, function() { + + tDb.fillScriptPubKey(unspent, function() { //_.filter will filterout unspend without scriptPubkey //(probably from double spends) - self.unspent = _.filter(txOut.map(function(x) { + self.unspent = _.filter(unspent.map(function(x) { return { address: self.addrStr, txid: x.txid, @@ -198,14 +251,42 @@ Address.prototype.update = function(next, opts) { confirmationsFromCache: !!x.isConfirmedCached, }; }), 'scriptPubKey');; + + if (self.deadCacheEnable && txOut.length && !self.unspent.length) { +// console.log('$$$$$$$$$$$$$$$$$$$$$$$$$$$ ',self.addrStr); //TODO +// console.log('[Address.js.242] NO UNSPENT:', self.addrStr, txOut.length); //TODO + // Asumes that addresses are ordered by Ts; + lastUsage = txOut[txOut.length-1].spentTs || now; + + var daysOld = (now-lastUsage) / (3600 * 24); +// console.log('[Address.js.253:dayOlds:]',daysOld); //TODO + var isOldEnough = daysOld > DAYS_TO_DEAD; + + // console.log('[Address.js.246:isOldEnough:]', isOldEnough, lastUsage, now); //TODO + + if (isOldEnough) { + self.setCache(); + } + } return next(); }); } else { + +console.log('[Address.js.273]'); //TODO txOut.forEach(function(txItem) { self._addTxItem(txItem, txList, opts.includeTxInfo); }); if (txList) self.transactions = txList; + + +console.log('[Address.js.279]', self.addrStr, self.deadCacheEnable , self.cached); //TODO + if (self.deadCacheEnable && self.cached) { + +console.log('[Address.js.281] WASS DEAD ALREADY! CACHING HISTORY'); //TODO + self.setCache(); + } + return next(); } }); diff --git a/lib/Sync.js b/lib/Sync.js index 36b0fa7..5795f4d 100644 --- a/lib/Sync.js +++ b/lib/Sync.js @@ -6,6 +6,8 @@ var config = imports.config || require('../config/config'); var bitcore = require('bitcore'); var networks = bitcore.networks; var async = require('async'); +var _ = require('lodash'); +var Address = require('../app/models/Address'); var logger = require('./logger').logger; var d = logger.log; @@ -293,7 +295,14 @@ Sync.prototype.setBranchConnectedBackwards = function(fromHash, cb) { //Store unconfirmed TXs Sync.prototype.storeTx = function(tx, cb) { - this.txDb.add(tx, cb); + this.txDb.add(tx, function(err, related) { + if (related) { + _.each(related, function(v,k){ + Address.deleteDeadCache(k); + }); + } + return cb(err, related); + }); };