From 9f290649e6ca816be101a973b9c4a1af62a4ac97 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 8 Apr 2015 16:04:16 -0300 Subject: [PATCH] p2p sync algorithm working --- lib/networkmonitor.js | 9 +++++---- lib/node.js | 36 ++++++++++++++++-------------------- lib/services/block.js | 16 +--------------- lib/services/transaction.js | 2 ++ 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/lib/networkmonitor.js b/lib/networkmonitor.js index 5c5f7312..7fbd83c4 100644 --- a/lib/networkmonitor.js +++ b/lib/networkmonitor.js @@ -65,10 +65,11 @@ NetworkMonitor.prototype.setupPeer = function(peer) { }; -NetworkMonitor.prototype.requestBlocks = function(start) { - $.checkArgument(_.isArray(start) || - _.isString(start), 'start must be a block hash string or array'); - this.peer.sendMessage(messages.GetBlocks(_.isArray(start) ? start : [start])); +NetworkMonitor.prototype.requestBlocks = function(locator) { + $.checkArgument(_.isArray(locator) && _.isString(locator[0]), 'start must be a block hash string array'); + this.peer.sendMessage(messages.GetBlocks({ + starts: locator + })); }; NetworkMonitor.prototype.start = function() { diff --git a/lib/node.js b/lib/node.js index a4f020b9..78a01eee 100644 --- a/lib/node.js +++ b/lib/node.js @@ -6,8 +6,6 @@ var EventEmitter = require('eventemitter2').EventEmitter2; var bitcore = require('bitcore'); var _ = bitcore.deps._; var config = require('config'); -var p2p = require('bitcore-p2p'); -var messages = new p2p.Messages(); var $ = bitcore.util.preconditions; var Promise = require('bluebird'); var RPC = require('bitcoind-rpc'); @@ -39,30 +37,27 @@ var BitcoreNode = function(bus, networkMonitor, blockService, transactionService this.blockCache = {}; this.inventory = {}; // blockHash -> bool (has data) - + /* this.networkMonitor.on('inv', function(inventory) { _.each(inventory, function(info) { var hash = bitcore.util.buffer.reverse(info.hash).toString('hex'); - $.checkState(_.isUndefined(self.inventory[hash])); - if (info.type === 2) { // TODO: use static field from bitcore-p2p + $.checkState(_.isUndefined(self.inventory[hash]), hash); + if (self.inventory[hash] && info.type === 2) { // TODO: use static field from bitcore-p2p self.inventory[hash] = false; } }); }); - + */ this.bus.register(bitcore.Block, function(block) { - console.log('Block', block.id); var prevHash = bitcore.util.buffer.reverse(block.header.prevHash).toString('hex'); self.blockCache[block.hash] = block; self.inventory[block.hash] = true; - console.log('prevHash', prevHash); - console.log('height', self.blockchain.height[self.blockchain.tip]); - if (!self.blockchain.hasData(prevHash)) { - self.networkMonitor.requestBlocks(self.blockchain.getBlockLocator()); + self.requestFromTip(); return; } + console.log('block', block.id, 'height', self.blockchain.height[self.blockchain.tip] + 1); var blockchainChanges = self.blockchain.proposeNewBlock(block); Promise.each(blockchainChanges.unconfirmed, function(hash) { @@ -70,14 +65,15 @@ var BitcoreNode = function(bus, networkMonitor, blockService, transactionService }) .then(function() { return Promise.all(blockchainChanges.confirmed.map(function(hash) { + self.blockCache[hash].height = self.blockchain.height[hash]; return self.blockService.confirm(self.blockCache[hash]); })); }) .then(function() { - if (_.size(self.inventory) && _.all(_.values(self.inventory))) { + // TODO: include this + if (false && _.size(self.inventory) && _.all(_.values(self.inventory))) { self.inventory = {}; - console.log('requesting ...', self.blockchain.getBlockLocator().length); - self.networkMonitor.requestBlocks(self.blockchain.getBlockLocator()); + self.requestFromTip(); } }) .catch(function(error) { @@ -98,6 +94,11 @@ var BitcoreNode = function(bus, networkMonitor, blockService, transactionService }; util.inherits(BitcoreNode, EventEmitter); +BitcoreNode.prototype.requestFromTip = function() { + var locator = this.blockchain.getBlockLocator(); + this.networkMonitor.requestBlocks(locator); +}; + BitcoreNode.create = function(opts) { opts = opts || {}; @@ -152,12 +153,7 @@ BitcoreNode.prototype.stop = function(reason) { BitcoreNode.prototype.sync = function() { var self = this; this.networkMonitor.on('ready', function() { - self.blockService.getBlockchain().then(function(blockchain) { - self.networkMonitor.requestBlocks(self.blockchain.getBlockLocator()); - }).catch(function(err) { - self.networkMonitor.stop(); - throw err; - }); + self.networkMonitor.requestBlocks(self.blockchain.getBlockLocator()); }); }; diff --git a/lib/services/block.js b/lib/services/block.js index 9a6a0680..38d833e9 100644 --- a/lib/services/block.js +++ b/lib/services/block.js @@ -249,22 +249,9 @@ BlockService.prototype.confirm = function(block) { return self._setNextBlock(ops, block.header.prevHash, block); }).then(function() { - //console.log(2); - - if (block.header.prevHash.toString('hex') !== NULLBLOCKHASH) { - //console.log(2.1); - return self.getBlock(block.header.prevHash, { - withoutTransactions: true - }); - } else { - //console.log(2.2); - return GENESISPARENT; - } - - }).then(function(parent) { //console.log(3); - return self._setBlockHeight(ops, block, parent.height + 1); + return self._setBlockHeight(ops, block, block.height); }).then(function() { //console.log(4); @@ -310,7 +297,6 @@ BlockService.prototype._setNextBlock = function(ops, prevBlockHash, block) { }; BlockService.prototype._setBlockHeight = function(ops, block, height) { - block.height = height; return Promise.try(function() { ops.push({ type: 'put', diff --git a/lib/services/transaction.js b/lib/services/transaction.js index 375b5d85..22c2ea96 100644 --- a/lib/services/transaction.js +++ b/lib/services/transaction.js @@ -179,6 +179,7 @@ TransactionService.prototype._getAddressForInput = function(input) { hash, bitcore.Networks.defaultNetwork, bitcore.Address.PayToPublicKeyHash ); } else if (script.isPublicKeyIn()) { + /* return self.getTransaction(input.prevTxId.toString('hex')).then(function(transaction) { var outputScript = transaction.outputs[input.outputIndex].script; if (outputScript.isPublicKeyOut()) { @@ -189,6 +190,7 @@ TransactionService.prototype._getAddressForInput = function(input) { } return; }); + */ } else { return new bitcore.Script(script.chunks[script.chunks.length - 1]).toAddress(); }