Blockchain retrieval and sync

This commit is contained in:
eordano 2015-04-09 19:07:48 -03:00
parent 7102e63933
commit 12d5c1cffd
3 changed files with 63 additions and 48 deletions

View File

@ -8,8 +8,10 @@ var NULL = '0000000000000000000000000000000000000000000000000000000000000000';
function BlockChain() { function BlockChain() {
this.tip = NULL; this.tip = NULL;
this.work = { NULL: 0 }; this.work = {};
this.height = { NULL: -1 }; this.work[NULL] = 0;
this.height = {};
this.height[NULL] = -1;
this.hashByHeight = { '-1': NULL }; this.hashByHeight = { '-1': NULL };
this.next = {}; this.next = {};
this.prev = {}; this.prev = {};

View File

@ -86,7 +86,7 @@ var BitcoreNode = function(bus, networkMonitor, blockService, transactionService
} }
}) })
.catch(function(error) { .catch(function(error) {
self.stop(error); self.abort(error);
}); });
}); });
@ -136,10 +136,14 @@ BitcoreNode.create = function(opts) {
BitcoreNode.prototype.start = function() { BitcoreNode.prototype.start = function() {
var self = this; var self = this;
var genesis = bitcore.Block.fromBuffer(genesisBlocks[bitcore.Networks.defaultNetwork.name]); var genesis = bitcore.Block.fromBuffer(genesisBlocks[bitcore.Networks.defaultNetwork.name]);
this.blockService.getBlockchain().then(function(blockchain) { this.blockService.getBlockchain().then(function(blockchain) {
if (!blockchain) { if (!blockchain) {
console.log('nothing');
self.blockchain = new BlockChain(); self.blockchain = new BlockChain();
self.bus.process(genesis); self.bus.process(genesis);
} else {
self.blockchain = blockchain;
} }
self.sync(); self.sync();
self.networkMonitor.start(); self.networkMonitor.start();

View File

@ -47,6 +47,7 @@ _.extend(Index, {
getNextBlock: helper(Index.next), getNextBlock: helper(Index.next),
getPreviousBlock: helper(Index.prev), getPreviousBlock: helper(Index.prev),
getBlockHeight: helper(Index.height), getBlockHeight: helper(Index.height),
getBlockWork: helper(Index.work),
getBlockByTs: function(block) { getBlockByTs: function(block) {
return Index.timestamp + block.header.time; return Index.timestamp + block.header.time;
} }
@ -250,6 +251,8 @@ BlockService.prototype.confirm = function(block, ops) {
//console.log(4); //console.log(4);
self._setBlockByTs(ops, block); self._setBlockByTs(ops, block);
self._setTip(ops, block);
//console.log(5); //console.log(5);
return Promise.all(block.transactions.map(function(transaction) { return Promise.all(block.transactions.map(function(transaction) {
return self.transactionService._confirmTransaction(ops, block, 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) { BlockService.prototype._setBlockWork = function(ops, block) {
ops.push({ ops.push({
type: 'put', type: 'put',
@ -402,54 +413,52 @@ BlockService.prototype.getBlockForTransaction = function(transaction) {
BlockService.prototype.getBlockchain = function() { BlockService.prototype.getBlockchain = function() {
var self = this; 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) { var fetchUnlessGenesis = function(blockHash) {
return Promise.all([ return fetchBlock(blockHash).then(function() {
function() { if (blockchain.prev[blockHash] === BlockChain.NULL) {
return self.database.getAsync(Index.getPreviousBlock(blockHash)).then(function(prevHash) { return;
blockchain.prev[blockHash] = prevHash; } else {
blockchain.next[prevHash] = blockHash; return fetchUnlessGenesis(blockchain.prev[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;
} }
throw err; });
}) };
.then(function(tip) {
blockchain.tip = tip; return self.database.getAsync(Index.tip)
return fetchUnlessGenesis(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;
}); });
}); });
}; };