bitcoind: get blocks and transactions as buffers
This commit is contained in:
parent
d11d0300de
commit
b4b560aa45
@ -63,9 +63,11 @@ Bitcoin.prototype._initCaches = function() {
|
||||
|
||||
// caches valid indefinitely
|
||||
this.transactionCache = LRU(100000);
|
||||
this.rawTransactionCache = LRU(50000);
|
||||
this.transactionInfoCache = LRU(100000);
|
||||
this.transactionInfoCacheConfirmations = 6;
|
||||
this.blockCache = LRU(144);
|
||||
this.rawBlockCache = LRU(72);
|
||||
this.blockHeaderCache = LRU(288);
|
||||
this.zmqKnownTransactions = LRU(50);
|
||||
this.zmqLastBlock = 0;
|
||||
@ -93,12 +95,14 @@ Bitcoin.prototype._initClients = function() {
|
||||
Bitcoin.prototype.getAPIMethods = function() {
|
||||
var methods = [
|
||||
['getBlock', this, this.getBlock, 1],
|
||||
['getRawBlock', this, this.getRawBlock, 1],
|
||||
['getBlockHeader', this, this.getBlockHeader, 1],
|
||||
['getBlockHashesByTimestamp', this, this.getBlockHashesByTimestamp, 2],
|
||||
['getBestBlockHash', this, this.getBestBlockHash, 0],
|
||||
['getInfo', this, this.getInfo, 0],
|
||||
['syncPercentage', this, this.syncPercentage, 0],
|
||||
['isSynced', this, this.isSynced, 0],
|
||||
['getRawTransaction', this, this.getRawTransaction, 1],
|
||||
['getTransaction', this, this.getTransaction, 2],
|
||||
['getTransactionWithBlockInfo', this, this.getTransactionWithBlockInfo, 2],
|
||||
['sendTransaction', this, this.sendTransaction, 1],
|
||||
@ -791,11 +795,9 @@ Bitcoin.prototype._getAddressDetailsForTransaction = function(transaction, addre
|
||||
*/
|
||||
Bitcoin.prototype._getDetailedTransaction = function(txid, options, next) {
|
||||
var self = this;
|
||||
var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool;
|
||||
|
||||
self.getTransactionWithBlockInfo(
|
||||
txid,
|
||||
queryMempool,
|
||||
function(err, transaction) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
@ -980,6 +982,46 @@ Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Will retrieve a block as a Node.js Buffer
|
||||
* @param {String|Number} block - A block hash or block height number
|
||||
* @param {Function} callback
|
||||
*/
|
||||
Bitcoin.prototype.getRawBlock = function(blockArg, callback) {
|
||||
// TODO apply performance patch to the RPC method for raw data
|
||||
var self = this;
|
||||
|
||||
function queryBlock(blockhash) {
|
||||
self.client.getBlock(blockhash, false, function(err, response) {
|
||||
if (err) {
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var buffer = new Buffer(response.result, 'hex');
|
||||
self.rawBlockCache.set(blockhash, buffer);
|
||||
callback(null, buffer);
|
||||
});
|
||||
}
|
||||
|
||||
var cachedBlock = self.rawBlockCache.get(blockArg);
|
||||
if (cachedBlock) {
|
||||
return setImmediate(function() {
|
||||
callback(null, cachedBlock);
|
||||
});
|
||||
} else {
|
||||
if (_.isNumber(blockArg)) {
|
||||
self.client.getBlockHash(blockArg, function(err, response) {
|
||||
if (err) {
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var blockhash = response.result;
|
||||
queryBlock(blockhash);
|
||||
});
|
||||
} else {
|
||||
queryBlock(blockArg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Will retrieve a block as a Bitcore object
|
||||
* @param {String|Number} block - A block hash or block height number
|
||||
@ -995,7 +1037,7 @@ Bitcoin.prototype.getBlock = function(blockArg, callback) {
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var blockObj = bitcore.Block.fromString(response.result);
|
||||
self.blockCache.set(blockArg, blockObj);
|
||||
self.blockCache.set(blockhash, blockObj);
|
||||
callback(null, blockObj);
|
||||
});
|
||||
}
|
||||
@ -1122,13 +1164,39 @@ Bitcoin.prototype.sendTransaction = function(tx, allowAbsurdFees, callback) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Will get a transaction as a Node.js Buffer. Results include the mempool.
|
||||
* @param {String} txid - The transaction hash
|
||||
* @param {Function} callback
|
||||
*/
|
||||
Bitcoin.prototype.getRawTransaction = function(txid, callback) {
|
||||
var self = this;
|
||||
var tx = self.rawTransactionCache.get(txid);
|
||||
if (tx) {
|
||||
return setImmediate(function() {
|
||||
callback(null, tx);
|
||||
});
|
||||
} else {
|
||||
self.client.getRawTransaction(txid, function(err, response) {
|
||||
if (err && response.error.code === -5) {
|
||||
return callback(null, null);
|
||||
} else if (err) {
|
||||
return callback(self._wrapRPCError(err));
|
||||
}
|
||||
var buffer = new Buffer(response.result, 'hex');
|
||||
self.rawTransactionCache.set(txid, buffer);
|
||||
callback(null, buffer);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Will get a transaction as a Bitcore Transaction. Results include the mempool.
|
||||
* @param {String} txid - The transaction hash
|
||||
* @param {Boolean} queryMempool - Include the mempool
|
||||
* @param {Function} callback
|
||||
*/
|
||||
Bitcoin.prototype.getTransaction = function(txid, queryMempool, callback) {
|
||||
Bitcoin.prototype.getTransaction = function(txid, callback) {
|
||||
var self = this;
|
||||
var tx = self.transactionCache.get(txid);
|
||||
if (tx) {
|
||||
@ -1158,10 +1226,9 @@ Bitcoin.prototype.getTransaction = function(txid, queryMempool, callback) {
|
||||
* __timestamp: 1442951110, // in seconds
|
||||
* }
|
||||
* @param {String} txid - The transaction hash
|
||||
* @param {Boolean} queryMempool - Include the mempool
|
||||
* @param {Function} callback
|
||||
*/
|
||||
Bitcoin.prototype.getTransactionWithBlockInfo = function(txid, queryMempool, callback) {
|
||||
Bitcoin.prototype.getTransactionWithBlockInfo = function(txid, callback) {
|
||||
var self = this;
|
||||
var tx = self.transactionInfoCache.get(txid);
|
||||
if (tx) {
|
||||
|
||||
@ -149,6 +149,21 @@ describe('Bitcoind Functionality', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('get blocks as buffers', function() {
|
||||
[0,1,2,3,5,6,7,8,9].forEach(function(i) {
|
||||
it('generated block ' + i, function(done) {
|
||||
bitcoind.getRawBlock(blockHashes[i], function(err, block) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
should.exist(block);
|
||||
(block instanceof Buffer).should.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('get errors as error instances', function() {
|
||||
it('will wrap an rpc into a javascript error', function(done) {
|
||||
bitcoind.client.getBlock(1000000000, function(err, response) {
|
||||
@ -194,7 +209,7 @@ describe('Bitcoind Functionality', function() {
|
||||
var txhex = transactionData[i];
|
||||
var tx = new bitcore.Transaction();
|
||||
tx.fromString(txhex);
|
||||
bitcoind.getTransaction(tx.hash, true, function(err, response) {
|
||||
bitcoind.getTransaction(tx.hash, function(err, response) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
@ -206,7 +221,7 @@ describe('Bitcoind Functionality', function() {
|
||||
|
||||
it('will return null if the transaction does not exist', function(done) {
|
||||
var txid = '6226c407d0e9705bdd7158e60983e37d0f5d23529086d6672b07d9238d5aa618';
|
||||
bitcoind.getTransaction(txid, true, function(err, response) {
|
||||
bitcoind.getTransaction(txid, function(err, response) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
@ -214,7 +229,34 @@ describe('Bitcoind Functionality', function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('get transactions as buffers', function() {
|
||||
[0,1,2,3,4,5,6,7,8,9].forEach(function(i) {
|
||||
it('for tx ' + i, function(done) {
|
||||
var txhex = transactionData[i];
|
||||
var tx = new bitcore.Transaction();
|
||||
tx.fromString(txhex);
|
||||
bitcoind.getRawTransaction(tx.hash, function(err, response) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
assert(response.toString('hex') === txhex, 'incorrect tx data result');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('will return null if the transaction does not exist', function(done) {
|
||||
var txid = '6226c407d0e9705bdd7158e60983e37d0f5d23529086d6672b07d9238d5aa618';
|
||||
bitcoind.getRawTransaction(txid, function(err, response) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
should.not.exist(response);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('get block header', function() {
|
||||
@ -390,7 +432,7 @@ describe('Bitcoind Functionality', function() {
|
||||
|
||||
describe('get transaction with block info', function() {
|
||||
it('should include tx buffer, height and timestamp', function(done) {
|
||||
bitcoind.getTransactionWithBlockInfo(utxos[0].txid, true, function(err, tx) {
|
||||
bitcoind.getTransactionWithBlockInfo(utxos[0].txid, function(err, tx) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user