diff --git a/lib/services/bitcoind.js b/lib/services/bitcoind.js index e989a8fc..433c950d 100644 --- a/lib/services/bitcoind.js +++ b/lib/services/bitcoind.js @@ -15,25 +15,41 @@ var _ = bitcore.deps._; var index = require('../'); var log = index.log; -var errors = index.errors; var Service = require('../service'); var Transaction = require('../transaction'); /** - * Provides an interface to native bindings to [Bitcoin Core](https://github.com/bitcoin/bitcoin) - * compiled as a static library. The C++ bindings can be found at `src/libbitcoind.cc` + * Provides a friendly event driven API to bitcoind in Node.js. Manages starting and + * stopping bitcoind as a child process for application support, as well as connecting + * to multiple bitcoind processes for server infrastructure. Results are cached in an + * LRU cache for improved performance and methods added for common queries. + * * @param {Object} options * @param {Node} options.node - A reference to the node */ function Bitcoin(options) { - /* jshint maxstatements: 20 */ - var self = this; if (!(this instanceof Bitcoin)) { return new Bitcoin(options); } Service.call(this, options); + this.options = options; + this._initCaches(); + + // bitcoind child process + this.spawn = false; + + // available bitcoind nodes + this._initClients(); +} +util.inherits(Bitcoin, Service); + +Bitcoin.dependencies = []; + +Bitcoin.DEFAULT_CONFIG = 'whitelist=127.0.0.1\n' + 'txindex=1\n' + 'addressindex=1\n' + 'server=1\n'; + +Bitcoin.prototype._initCaches = function() { // caches valid until there is a new block this.utxosCache = LRU(50000); this.txidsCache = LRU(50000); @@ -49,13 +65,10 @@ function Bitcoin(options) { this.zmqKnownTransactions = LRU(50); this.zmqLastBlock = 0; this.zmqUpdateTipTimeout = false; +}; - this.options = options; - - // bitcoind child process - this.spawn = false; - - // available bitcoind nodes +Bitcoin.prototype._initClients = function() { + var self = this; this.nodes = []; this.nodesIndex = 0; Object.defineProperty(this, 'client', { @@ -67,13 +80,7 @@ function Bitcoin(options) { enumerable: true, configurable: false }); - -} -util.inherits(Bitcoin, Service); - -Bitcoin.dependencies = []; - -Bitcoin.DEFAULT_CONFIG = 'whitelist=127.0.0.1\n' + 'txindex=1\n' + 'addressindex=1\n' + 'server=1\n'; +}; /** * Called by Node to determine the available API methods. @@ -507,7 +514,6 @@ Bitcoin.prototype.start = function(callback) { /** * Helper to determine the state of the database. * @param {Function} callback - * @returns {Boolean} If the database is fully synced */ Bitcoin.prototype.isSynced = function(callback) { this.syncPercentage(function(err, percentage) { @@ -525,7 +531,6 @@ Bitcoin.prototype.isSynced = function(callback) { /** * Helper to determine the progress of the database. * @param {Function} callback - * @returns {Number} An estimated percentage of the syncronization status */ Bitcoin.prototype.syncPercentage = function(callback) { var self = this; @@ -538,6 +543,12 @@ Bitcoin.prototype.syncPercentage = function(callback) { }); }; +/** + * Will get the balance for an address or multiple addresses + * @param {String|Address|Array} addressArg - An address string, bitcore address, or array of addresses + * @param {Object} options + * @param {Function} callback + */ Bitcoin.prototype.getAddressBalance = function(addressArg, options, callback) { var self = this; var addresses = [addressArg]; @@ -561,6 +572,12 @@ Bitcoin.prototype.getAddressBalance = function(addressArg, options, callback) { } }; +/** + * Will get the unspent outputs for an address or multiple addresses + * @param {String|Address|Array} addressArg - An address string, bitcore address, or array of addresses + * @param {Object} options + * @param {Function} callback + */ Bitcoin.prototype.getAddressUnspentOutputs = function(addressArg, options, callback) { var self = this; var addresses = [addressArg]; @@ -605,6 +622,12 @@ Bitcoin.prototype._getTxidsFromMempool = function(deltas) { return mempoolTxids; }; +/** + * Will get the txids for an address or multiple addresses + * @param {String|Address|Array} addressArg - An address string, bitcore address, or array of addresses + * @param {Object} options + * @param {Function} callback + */ Bitcoin.prototype.getAddressTxids = function(addressArg, options, callback) { var self = this; var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool; @@ -776,6 +799,12 @@ Bitcoin.prototype._paginateTxids = function(fullTxids, from, to) { return txids; }; +/** + * Will detailed transaction history for an address or multiple addresses + * @param {String|Address|Array} addressArg - An address string, bitcore address, or array of addresses + * @param {Object} options + * @param {Function} callback + */ Bitcoin.prototype.getAddressHistory = function(addressArg, options, callback) { var self = this; var addresses = [addressArg]; @@ -818,6 +847,12 @@ Bitcoin.prototype.getAddressHistory = function(addressArg, options, callback) { }); }; +/** + * Will get the summary including txids and balance for an address or multiple addresses + * @param {String|Address|Array} addressArg - An address string, bitcore address, or array of addresses + * @param {Object} options + * @param {Function} callback + */ Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) { var self = this; var summary = {}; @@ -896,8 +931,9 @@ Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) { }; /** - * Will retrieve a block as a Node.js Buffer from disk. + * Will retrieve a block as a Bitcore object * @param {String|Number} block - A block hash or block height number + * @param {Function} callback */ Bitcoin.prototype.getBlock = function(blockArg, callback) { // TODO apply performance patch to the RPC method for raw data @@ -935,6 +971,12 @@ Bitcoin.prototype.getBlock = function(blockArg, callback) { }; +/** + * Will retrieve an array of block hashes within a range of timestamps + * @param {Number} high - The more recent timestamp in seconds + * @param {Number} low - The older timestamp in seconds + * @param {Function} callback + */ Bitcoin.prototype.getBlockHashesByTimestamp = function(high, low, callback) { var self = this; self.client.getBlockHashes(high, low, function(err, response) { @@ -955,7 +997,7 @@ Bitcoin.prototype.getBlockHashesByTimestamp = function(high, low, callback) { * height: 10 * } * @param {String|Number} block - A block hash or block height - * @returns {Object} + * @param {Function} callback */ Bitcoin.prototype.getBlockHeader = function(block, callback) { var self = this; @@ -990,7 +1032,7 @@ Bitcoin.prototype.getBlockHeader = function(block, callback) { /** * Will estimate the fee per kilobyte. * @param {Number} blocks - The number of blocks for the transaction to be confirmed. - * @returns {Number} + * @param {Function} callback */ Bitcoin.prototype.estimateFee = function(blocks, callback) { var self = this; @@ -1003,10 +1045,10 @@ Bitcoin.prototype.estimateFee = function(blocks, callback) { }; /** - * Will add a transaction to the mempool and relay to connected peers, the function - * will throw an error if there were validation problems. - * @param {String} transaction - The hex string of the transaction - * @param {Boolean} allowAbsurdFees - Enable large fees + * Will add a transaction to the mempool and relay to connected peers + * @param {String|Transaction} transaction - The hex string of the transaction + * @param {Boolean=} allowAbsurdFees - Enable large fees + * @param {Function} callback */ Bitcoin.prototype.sendTransaction = function(tx, allowAbsurdFees, callback) { var self = this; @@ -1031,7 +1073,7 @@ Bitcoin.prototype.sendTransaction = function(tx, allowAbsurdFees, callback) { }; /** - * Will get a transaction as a Node.js Buffer from disk and the mempool. + * 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 @@ -1059,12 +1101,11 @@ Bitcoin.prototype.getTransaction = function(txid, queryMempool, callback) { }; /** - * Will get a transaction with additional information about the block, in the format: + * Will get a transaction as Bitcore Transaction with additional fields: * { - * blockHash: '2725743288feae6bdaa976590af7cb12d7b535b5a242787de6d2789c73682ed1', - * height: 48, - * timestamp: 1442951110, // in seconds - * buffer: // transaction buffer + * __blockHash: '2725743288feae6bdaa976590af7cb12d7b535b5a242787de6d2789c73682ed1', + * __height: 48, + * __timestamp: 1442951110, // in seconds * } * @param {String} txid - The transaction hash * @param {Boolean} queryMempool - Include the mempool @@ -1100,7 +1141,7 @@ Bitcoin.prototype.getTransactionWithBlockInfo = function(txid, queryMempool, cal /** * Will get the best block hash for the chain. - * @returns {String} + * @param {Function} callback */ Bitcoin.prototype.getBestBlockHash = function(callback) { var self = this; @@ -1127,9 +1168,11 @@ Bitcoin.prototype.getInputForOutput = function(txid, index, options, callback) { * connections: 0, * difficulty: 4.6565423739069247e-10, * testnet: false, + * network: 'testnet' * relayfee: 1000, * errors: '' * } + * @param {Function} callback */ Bitcoin.prototype.getInfo = function(callback) { var self = this;