flocore-node/lib/services/block.js
2015-03-11 12:33:08 -03:00

113 lines
2.8 KiB
JavaScript

'use strict';
var LevelUp = require('levelup');
var Promise = require('bluebird');
var RPC = require('bitcoind-rpc');
var TransactionService = require('./transaction');
var bitcore = require('bitcore');
var config = require('config');
var BitcoreNode = require('../../');
var $ = bitcore.util.preconditions;
var JSUtil = bitcore.util.js;
var _ = bitcore.deps._;
var LATEST_BLOCK = 'latest-block';
function BlockService (opts) {
opts = _.extend({}, opts);
this.database = opts.database || Promise.promisifyAll(new LevelUp(config.get('LevelUp')));
this.rpc = opts.rpc || Promise.promisifyAll(new RPC(config.get('RPC')));
this.transactionService = opts.transactionService || new TransactionService({
database: this.database,
rpc: this.rpc
});
}
BlockService.blockRPCtoBitcore = function(blockData, transactions) {
$.checkArgument(_.all(transactions, function(transaction) {
return transaction instanceof bitcore.Transaction;
}), 'All transactions must be instances of bitcore.Transaction');
return new bitcore.Block({
header: new bitcore.BlockHeader({
version: blockData.version,
prevHash: bitcore.util.buffer.reverse(
new bitcore.deps.Buffer(blockData.previousblockhash, 'hex')
),
time: blockData.time,
nonce: blockData.nonce,
bits: new bitcore.deps.bnjs(
new bitcore.deps.Buffer(blockData.bits, 'hex')
),
merkleRoot: bitcore.util.buffer.reverse(
new bitcore.deps.Buffer(blockData.merkleRoot, 'hex')
)
}),
transactions: transactions
});
};
var blockNotFound = function(err) {
console.log(err);
return Promise.reject(new BitcoreNode.errors.Blocks.NotFound());
};
BlockService.prototype.getBlock = function(blockHash) {
$.checkArgument(JSUtil.isHexa(blockHash), 'Block hash must be hexa');
var blockData;
var self = this;
return Promise.try(function() {
return self.rpc.getBlockAsync(blockHash);
}).then(function(block) {
blockData = block.result;
return Promise.all(blockData.tx.map(function(txId) {
return self.transactionService.getTransaction(txId);
}));
}).then(function(transactions) {
blockData.transactions = transactions;
return BlockService.blockRPCtoBitcore(blockData);
}).catch(blockNotFound);
};
BlockService.prototype.getBlockByHeight = function(height) {
$.checkArgument(_.isNumber(height), 'Block height must be a number');
var self = this;
return Promise.try(function() {
return this.rpc.getBlockHash(height);
}).then(function(blockHash) {
return self.getBlock(blockHash);
}).catch(blockNotFound);
};
BlockService.prototype.getLatest = function() {
var self = this;
return Promise.try(function() {
return self.database.getAsync(LATEST_BLOCK);
}).then(function(blockHash) {
return self.getBlock(blockHash);
}).catch(blockNotFound);
};
module.exports = BlockService;