From 12d5c1cffd265b10a2397105a35fb4af67467b6e Mon Sep 17 00:00:00 2001 From: eordano Date: Thu, 9 Apr 2015 19:07:48 -0300 Subject: [PATCH] Blockchain retrieval and sync --- lib/blockchain.js | 6 ++- lib/node.js | 6 ++- lib/services/block.js | 99 +++++++++++++++++++++++-------------------- 3 files changed, 63 insertions(+), 48 deletions(-) diff --git a/lib/blockchain.js b/lib/blockchain.js index 4bd822dc..c40de043 100644 --- a/lib/blockchain.js +++ b/lib/blockchain.js @@ -8,8 +8,10 @@ var NULL = '0000000000000000000000000000000000000000000000000000000000000000'; function BlockChain() { this.tip = NULL; - this.work = { NULL: 0 }; - this.height = { NULL: -1 }; + this.work = {}; + this.work[NULL] = 0; + this.height = {}; + this.height[NULL] = -1; this.hashByHeight = { '-1': NULL }; this.next = {}; this.prev = {}; diff --git a/lib/node.js b/lib/node.js index 75deaed6..ac644419 100644 --- a/lib/node.js +++ b/lib/node.js @@ -86,7 +86,7 @@ var BitcoreNode = function(bus, networkMonitor, blockService, transactionService } }) .catch(function(error) { - self.stop(error); + self.abort(error); }); }); @@ -136,10 +136,14 @@ BitcoreNode.create = function(opts) { BitcoreNode.prototype.start = function() { var self = this; var genesis = bitcore.Block.fromBuffer(genesisBlocks[bitcore.Networks.defaultNetwork.name]); + this.blockService.getBlockchain().then(function(blockchain) { if (!blockchain) { + console.log('nothing'); self.blockchain = new BlockChain(); self.bus.process(genesis); + } else { + self.blockchain = blockchain; } self.sync(); self.networkMonitor.start(); diff --git a/lib/services/block.js b/lib/services/block.js index f0480b8f..6906a20f 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -47,6 +47,7 @@ _.extend(Index, { getNextBlock: helper(Index.next), getPreviousBlock: helper(Index.prev), getBlockHeight: helper(Index.height), + getBlockWork: helper(Index.work), getBlockByTs: function(block) { return Index.timestamp + block.header.time; } @@ -250,6 +251,8 @@ BlockService.prototype.confirm = function(block, ops) { //console.log(4); self._setBlockByTs(ops, block); + self._setTip(ops, block); + //console.log(5); return Promise.all(block.transactions.map(function(transaction) { return self.transactionService._confirmTransaction(ops, block, transaction); @@ -290,6 +293,14 @@ BlockService.prototype._setBlockHeight = function(ops, block) { }); }; +BlockService.prototype._setTip = function(ops, block) { + ops.push({ + type: 'put', + key: Index.tip, + value: block.hash + }); +}; + BlockService.prototype._setBlockWork = function(ops, block) { ops.push({ type: 'put', @@ -402,54 +413,52 @@ BlockService.prototype.getBlockForTransaction = function(transaction) { BlockService.prototype.getBlockchain = function() { var self = this; - return new Promise(function(resolve, reject) { + var blockchain = new BlockChain(); - var blockchain = new BlockChain(); + var fetchBlock = function(blockHash) { + return Promise.all([ + self.database.getAsync(Index.getPreviousBlock(blockHash)).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; + }); + }; - var fetchBlock = function(blockHash) { - return Promise.all([ - function() { - return self.database.getAsync(Index.getPreviousBlock(blockHash)).then(function(prevHash) { - blockchain.prev[blockHash] = prevHash; - blockchain.next[prevHash] = blockHash; - }); - }, - function() { - return self.database.getAsync(Index.getBlockHeight(blockHash)).then(function(height) { - blockchain.height[blockHash] = height; - blockchain.hashByHeight[height] = blockHash; - }); - }, - function() { - return self.database.getAsync(Index.getWork(blockHash)).then(function(work) { - blockchain.work[blockHash] = work; - }); - } - ]).then(function() { - return 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; + var fetchUnlessGenesis = function(blockHash) { + return fetchBlock(blockHash).then(function() { + if (blockchain.prev[blockHash] === BlockChain.NULL) { + return; + } else { + return fetchUnlessGenesis(blockchain.prev[blockHash]); } - throw err; - }) - .then(function(tip) { - blockchain.tip = tip; - return fetchUnlessGenesis(tip); + }); + }; + + return self.database.getAsync(Index.tip) + .catch(function(err) { + if (err.notFound) { + return undefined; + } + throw err; + }) + .then(function(tip) { + if (!tip) { + console.log('No tip found'); + return; + } + console.log('Tip is', tip); + blockchain.tip = tip; + return fetchUnlessGenesis(tip).then(function() { + return blockchain; }); }); };