From 1986cb40ef76ec4e068c9ca772fc9ab73a0dbda5 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 24 Apr 2015 10:45:53 -0300 Subject: [PATCH] moving towards removing memory leak --- lib/blockchain.js | 6 +-- lib/networkmonitor.js | 1 + lib/node.js | 14 +++++-- lib/services/block.js | 96 +++++++++++++++++++++++-------------------- 4 files changed, 65 insertions(+), 52 deletions(-) diff --git a/lib/blockchain.js b/lib/blockchain.js index c40de043..58a356e5 100644 --- a/lib/blockchain.js +++ b/lib/blockchain.js @@ -140,10 +140,10 @@ BlockChain.prototype.hasData = function(hash) { BlockChain.prototype.prune = function() { var self = this; - _.each(this.prev, function(key, value) { + _.each(this.prev, function(key) { if (!self.height[key]) { - delete this.prev[key]; - delete this.work[key]; + delete self.prev[key]; + delete self.work[key]; } }); }; diff --git a/lib/networkmonitor.js b/lib/networkmonitor.js index fd82714b..6d792b9c 100644 --- a/lib/networkmonitor.js +++ b/lib/networkmonitor.js @@ -78,6 +78,7 @@ NetworkMonitor.prototype.requestBlocks = function(locator) { }; NetworkMonitor.prototype.start = function() { + console.log('starting network monitor'); this.peer.connect(); }; diff --git a/lib/node.js b/lib/node.js index e1c6f8e3..0b181455 100644 --- a/lib/node.js +++ b/lib/node.js @@ -79,15 +79,22 @@ BitcoreNode.prototype.initialize = function() { var prevHeight = 0; var statTimer = 5 * 1000; setInterval(function() { + console.log(process.memoryUsage().heapTotal / 1024 / 1024, 'mb used'); if (!self.blockchain) { // not ready yet + console.log('No blockchain yet'); return; } var tipHash = self.blockchain.tip; var block = self.blockCache[tipHash]; + if (_.isUndefined(block)) { + console.log('No blocks yet'); + return; + } var delta = block.height - prevHeight; prevHeight = block.height; console.log(block.id, block.height, 'vel', delta * 1000 / statTimer, 'b/s'); + console.log('cache', Object.keys(self.blockCache).length); }, statTimer); this.bus.register(bitcore.Block, function(block) { @@ -149,7 +156,9 @@ BitcoreNode.prototype.start = function() { var self = this; var genesis = bitcore.Block.fromBuffer(genesisBlocks[bitcore.Networks.defaultNetwork.name]); + console.log('getting blockchain'); this.blockService.getBlockchain().then(function(blockchain) { + console.log('got blockchain', _.isUndefined(blockchain)); if (!blockchain) { self.blockchain = new BlockChain(); self.bus.process(genesis); @@ -159,9 +168,6 @@ BitcoreNode.prototype.start = function() { self.sync(); self.networkMonitor.start(); }); - this.networkMonitor.on('stop', function() { - self.blockService.saveBlockchain(self.blockchain); - }); }; BitcoreNode.prototype.stop = function(reason) { @@ -170,7 +176,7 @@ BitcoreNode.prototype.stop = function(reason) { BitcoreNode.prototype.requestFromTip = function() { var locator = this.blockchain.getBlockLocator(); - console.log('requesting blocks, locator size:', locator.length); + //console.log('requesting blocks, locator size:', locator.length); this.networkMonitor.requestBlocks(locator); }; diff --git a/lib/services/block.js b/lib/services/block.js index 0353685b..fdaa5941 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -182,27 +182,26 @@ BlockService.prototype.getBlockByHeight = function(height) { }); }; +BlockService.prototype._getLatestHash = function() { + var self = this; + return Promise.try(function() { + return self.database.getAsync(Index.tip); + }).catch(LevelUp.errors.NotFoundError, function() { + return null; + }); +}; /** * Fetch the block that is currently the tip of the blockchain * * @return {Promise} */ BlockService.prototype.getLatest = function() { - var self = this; - - return Promise.try(function() { - - return self.database.getAsync(Index.tip); - - }).then(function(blockHash) { - + return this._getLatestHash().then(function(blockHash) { + if (!blockHash) { + return null; + } return self.getBlock(blockHash); - - }).catch(LevelUp.errors.NotFoundError, function() { - - return null; - }); }; @@ -444,42 +443,48 @@ BlockService.prototype.getBlockchain = function() { var self = this; var blockchain = new BlockChain(); + console.log(process.memoryUsage().heapTotal / 1024 / 1024, 'mb used'); + var amount = 0; + var limit = 100; var fetchBlock = function(blockHash) { - return Promise.all([ - self.database.getAsync(Index.getPreviousBlock(blockHash)).then(function(prevHash) { + //console.log(process.memoryUsage().heapTotal / 1024 / 1024); + if (blockHash === BlockChain.NULL) { + console.log(process.memoryUsage().heapTotal / 1024 / 1024, 'mb used'); + return; + } + amount += 1; + var prevKey = Index.getPreviousBlock(blockHash); + var heightKey = Index.getBlockHeight(blockHash); + var workKey = Index.getBlockWork(blockHash); + + return self.database.getAsync(prevKey) + .then(function(prevHash) { blockchain.prev[blockHash] = prevHash; blockchain.next[prevHash] = blockHash; - }), - self.database.getAsync(Index.getBlockHeight(blockHash)).then(function(height) { - blockchain.height[blockHash] = +height; - blockchain.hashByHeight[height] = blockHash; - }), - self.database.getAsync(Index.getBlockWork(blockHash)).then(function(work) { - blockchain.work[blockHash] = work; }) - ]).then(function() { - return blockHash; - }); + .then(function() { + return self.database.getAsync(heightKey) + .then(function(height) { + blockchain.height[blockHash] = +height; + blockchain.hashByHeight[height] = blockHash; + }); + }) + .then(function() { + if (amount >= limit) { + return; + } + return self.database.getAsync(workKey) + .then(function(work) { + blockchain.work[blockHash] = work; + }); + }) + .then(function() { + return fetchBlock(blockchain.prev[blockHash]); + }); }; - var fetchUnlessGenesis = function(blockHash) { - return fetchBlock(blockHash).then(function() { - if (blockchain.prev[blockHash] === BlockChain.NULL) { - return; - } else { - return fetchUnlessGenesis(blockchain.prev[blockHash]); - } - }); - }; - - return self.database.getAsync(Index.tip) - .catch(function(err) { - if (err.notFound) { - return undefined; - } - throw err; - }) + return self._getLatestHash() .then(function(tip) { if (!tip) { console.log('No tip found'); @@ -487,9 +492,10 @@ BlockService.prototype.getBlockchain = function() { } console.log('Tip is', tip); blockchain.tip = tip; - return fetchUnlessGenesis(tip).then(function() { - return blockchain; - }); + return fetchBlock(tip) + .then(function() { + return blockchain; + }); }); };