Add blockchain

This commit is contained in:
eordano 2015-04-06 15:44:31 -03:00
parent 13b4f41f80
commit 9c7fa5cfaf
3 changed files with 77 additions and 10 deletions

45
lib/blockchain.js Normal file
View File

@ -0,0 +1,45 @@
'use strict';
var bitcore = require('bitcore');
var $ = bitcore.util.preconditions;
var _ = bitcore.deps._;
function BlockChain() {
this.tip = null;
this.headers = {};
this.next = {};
this.prev = {};
}
BlockChain.fromObject = function(obj) {
var blockchain = new BlockChain();
blockchain.tip = obj.tip;
blockchain.headers = obj.headers;
blockchain.next = obj.next;
blockchain.prev = obj.prev;
return blockchain;
};
BlockChain.prototype.setTip = function(block) {
$.checkArgument(block instanceof bitcore.Block, 'Argument is not a Block instance');
this.tip = block.hash;
this.headers[block.hash] = block.header;
var prevHash = bitcore.util.buffer.reverse(block.header.prevHash).toString('hex');
this.next[prevHash] = block.hash;
this.prev[block.hash] = prevHash;
};
BlockChain.prototype.toObject = function() {
return {
tip: this.tip,
headers: _.map(this.headers, function(header) { return header.toObject(); }),
next: this.next,
prev: this.prev
};
};
BlockChain.prototype.toJSON = function() {
return JSON.stringify(this.toObject());
};
module.exports = BlockChain;

View File

@ -19,6 +19,7 @@ var BlockService = require('./services/block');
var TransactionService = require('./services/transaction');
var AddressService = require('./services/address');
var BlockChain = require('./blockchain');
var genesisBlocks = require('./data/genesis');
var BitcoreNode = function(bus, networkMonitor, blockService, transactionService, addressService) {
@ -89,16 +90,14 @@ BitcoreNode.prototype.sync = function() {
var genesis = bitcore.Block.fromBuffer(genesisBlocks[bitcore.Networks.defaultNetwork.name]);
var self = this;
this.networkMonitor.on('ready', function() {
console.log('ready');
self.blockService.getLatest().then(function(latest) {
var start = genesis.hash;
console.log('latest', latest);
if (latest) {
start = latest.hash;
self.blockService.getBlockchain().then(function(blockchain) {
if (blockchain) {
self.blockchain = blockchain;
} else {
self.blockchain = new BlockChain();
self.blockchain.setTip(genesis);
}
console.log('Starting sync from', start);
self.tip = latest;
self.networkMonitor.requestBlocks(start);
self.networkMonitor.requestBlocks(self.blockchain.tip);
})
.catch(function(err) {
self.networkMonitor.stop();

View File

@ -39,7 +39,8 @@ var Index = {
prev: 'prev-', // prev-<hash> -> parent hash
next: 'nxt-', // nxt-<hash> -> hash for the next block in the main chain that is a child
height: 'bh-', // bh-<hash> -> height (-1 means disconnected)
tip: 'tip' // tip -> { hash: hex, height: int }, the latest tip
tip: 'tip', // tip -> { hash: hex, height: int }, the latest tip
blockchain: 'chain'
};
_.extend(Index, {
getNextBlock: helper(Index.next),
@ -381,4 +382,26 @@ BlockService.prototype.getBlockForTransaction = function(transaction) {
});
};
BlockService.prototype.getBlockchain = function() {
var self = this;
return new Promise(function(resolve, reject) {
self.database.getAsync(Index.blockchain).then(function(blockchain) {
blockchain = BlockChain.fromObject(JSON.parse(blockchain));
return resolve(blockchain);
}).catch(function(arg) {
if (arg.message.indexOf('Key not found in database') !== -1) {
return resolve();
}
return reject(arg);
});
});
};
BlockService.prototype.saveBlockchain = function(blockchain) {
return this.database.putAsync({
key: Index.blockchain,
value: blockchain.toJSON()
});
};
module.exports = BlockService;