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() {
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 = {};

View File

@ -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();

View File

@ -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;
});
});
};