Update name to Bitcore Node
This commit is contained in:
parent
47219a745a
commit
f4061037b6
@ -1,7 +1,7 @@
|
|||||||
sudo: false
|
sudo: false
|
||||||
language: node_js
|
language: node_js
|
||||||
env:
|
env:
|
||||||
- BITCOINDJS_ENV=test BITCOINDJS_ASSUME_YES=true
|
- BITCORENODE_ENV=test BITCORENODE_ASSUME_YES=true
|
||||||
node_js:
|
node_js:
|
||||||
- "0.12"
|
- "0.12"
|
||||||
before_install:
|
before_install:
|
||||||
|
|||||||
31
README.md
31
README.md
@ -1,15 +1,13 @@
|
|||||||
bitcoind.js
|
Bitcore Node
|
||||||
=======
|
=======
|
||||||
[](https://travis-ci.org/bitpay/bitcoind.js)
|
|
||||||
[](https://coveralls.io/r/bitpay/bitcoind.js)
|
|
||||||
|
|
||||||
A Node.js module that adds a native interface to Bitcoin Core for querying information about the Bitcoin blockchain. Bindings are linked to Bitcore Core compiled as a shared library.
|
A Node.js module that adds a native interface to Bitcoin Core for querying information about the Bitcoin blockchain. Bindings are linked to Bitcore Core compiled as a shared library.
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/bitpay/bitcoind.js.git
|
git clone https://github.com/bitpay/bitcore-node.git
|
||||||
cd bitcoind.js
|
cd bitcore-node
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -17,7 +15,7 @@ npm install
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
||||||
var BitcoinNode = require('bitcoind.js');
|
var BitcoinNode = require('bitcore-node');
|
||||||
|
|
||||||
var configuration = {
|
var configuration = {
|
||||||
datadir: '~/.bitcoin',
|
datadir: '~/.bitcoin',
|
||||||
@ -101,22 +99,22 @@ $ tail -f ~/.bitcoin/debug.log
|
|||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
Bitcoind.js has a module system where additional information can be indexed and queried from
|
Bitcore Node has a module system where additional information can be indexed and queried from
|
||||||
the blockchain. One built-in module is the address module which exposes the API methods for getting balances and outputs.
|
the blockchain. One built-in module is the address module which exposes the API methods for getting balances and outputs.
|
||||||
|
|
||||||
### Writing a Module
|
### Writing a Module
|
||||||
|
|
||||||
A new module can be created by inheriting from `BitcoindJS.Module`, implementing the methods `blockHandler()`, `getAPIMethods()`, `getPublishEvents()` and any additional methods for querying the data. Here is an example:
|
A new module can be created by inheriting from `Node.Module`, implementing the methods `blockHandler()`, `getAPIMethods()`, `getPublishEvents()` and any additional methods for querying the data. Here is an example:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var inherits = require('util').inherits;
|
var inherits = require('util').inherits;
|
||||||
var BitcoindJS = require('bitcoind.js');
|
var Node = require('bitcore-node').Node;
|
||||||
|
|
||||||
var MyModule = function(options) {
|
var MyModule = function(options) {
|
||||||
BitcoindJS.Module.call(this, options);
|
Node.Module.call(this, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
inherits(MyModule, BitcoindJS.Module);
|
inherits(MyModule, Node.Module);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* blockHandler
|
* blockHandler
|
||||||
@ -195,13 +193,13 @@ The module can then be used when running a node:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
var configuration = {
|
var configuration = {
|
||||||
datadir: process.env.BITCOINDJS_DIR || '~/.bitcoin',
|
datadir: process.env.BITCORENODE_DIR || '~/.bitcoin',
|
||||||
db: {
|
db: {
|
||||||
modules: [MyModule]
|
modules: [MyModule]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var node = new BitcoindJS.Node(configuration);
|
var node = new Node(configuration);
|
||||||
|
|
||||||
node.on('ready', function() {
|
node.on('ready', function() {
|
||||||
node.getData('key', function(err, value) {
|
node.getData('key', function(err, value) {
|
||||||
@ -210,7 +208,7 @@ node.on('ready', function() {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that if you already have a bitcoind.js database, and you want to query data from previous blocks in the blockchain, you will need to reindex. Reindexing right now means deleting your bitcoind.js database and resyncing.
|
Note that if you already have a bitcore-node database, and you want to query data from previous blocks in the blockchain, you will need to reindex. Reindexing right now means deleting your bitcore-node database and resyncing.
|
||||||
|
|
||||||
## Daemon Documentation
|
## Daemon Documentation
|
||||||
|
|
||||||
@ -290,7 +288,7 @@ Every effort will be made to ensure that this patch stays up-to-date with the la
|
|||||||
There is a build script that will download Bitcoin Core v0.10.2 and apply the necessary patch, compile `libbitcoind.{so|dylib}` and copy the artifact into `platform/<os_dir>`. Unix/Linux uses the file extension "so" whereas Mac OSX uses "dylib" *(bitcoind compiled as a shared library)*.
|
There is a build script that will download Bitcoin Core v0.10.2 and apply the necessary patch, compile `libbitcoind.{so|dylib}` and copy the artifact into `platform/<os_dir>`. Unix/Linux uses the file extension "so" whereas Mac OSX uses "dylib" *(bitcoind compiled as a shared library)*.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cd /path/to/bitcoind.js
|
$ cd /path/to/bitcore-node
|
||||||
$ ./bin/build-libbitcoind
|
$ ./bin/build-libbitcoind
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -327,10 +325,9 @@ $ cp -R libbitcoind/src/.libs/libbitcoind.*dylib platform/osx/lib
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Code released under [the MIT license](https://github.com/bitpay/bitcoind.js/blob/master/LICENSE).
|
Code released under [the MIT license](https://github.com/bitpay/bitcore-node/blob/master/LICENSE).
|
||||||
|
|
||||||
Copyright 2013-2015 BitPay, Inc.
|
Copyright 2013-2015 BitPay, Inc.
|
||||||
|
|
||||||
- bitcoin: Copyright (c) 2009-2015 Bitcoin Core Developers (MIT License)
|
- bitcoin: Copyright (c) 2009-2015 Bitcoin Core Developers (MIT License)
|
||||||
- bcoin (some code borrowed temporarily): Copyright Fedor Indutny, 2014.
|
- bcoin (some code borrowed temporarily): Copyright Fedor Indutny, 2014.
|
||||||
|
|
||||||
|
|||||||
@ -64,12 +64,12 @@ compare_patch () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug=
|
debug=
|
||||||
if [ "${BITCOINDJS_ENV}" == "debug" ]; then
|
if [ "${BITCORENODE_ENV}" == "debug" ]; then
|
||||||
options=`cat ${root_dir}/bin/config_options_debug.sh`
|
options=`cat ${root_dir}/bin/config_options_debug.sh`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test=false
|
test=false
|
||||||
if [ "${BITCOINDJS_ENV}" == "test" ]; then
|
if [ "${BITCORENODE_ENV}" == "test" ]; then
|
||||||
test=true
|
test=true
|
||||||
options=`cat ${root_dir}/bin/config_options_test.sh`
|
options=`cat ${root_dir}/bin/config_options_test.sh`
|
||||||
fi
|
fi
|
||||||
@ -96,7 +96,7 @@ if [ "${shared_file_built}" = false ]; then
|
|||||||
${root_dir}/etc/bitcoin.patch."
|
${root_dir}/etc/bitcoin.patch."
|
||||||
echo -n "Would you like to remove the current patch, checkout the tag: ${tag} and \
|
echo -n "Would you like to remove the current patch, checkout the tag: ${tag} and \
|
||||||
apply the current patch from "${root_dir}"/etc/bitcoin.patch? (y/N): "
|
apply the current patch from "${root_dir}"/etc/bitcoin.patch? (y/N): "
|
||||||
if [ "${BITCOINDJS_ASSUME_YES}" = true ]; then
|
if [ "${BITCORENODE_ASSUME_YES}" = true ]; then
|
||||||
input=y
|
input=y
|
||||||
echo ""
|
echo ""
|
||||||
else
|
else
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
'targets': [{
|
'targets': [{
|
||||||
'target_name': 'bitcoindjs',
|
'target_name': 'libbitcoind',
|
||||||
'include_dirs' : [
|
'include_dirs' : [
|
||||||
'<!(node -e "require(\'nan\')")',
|
'<!(node -e "require(\'nan\')")',
|
||||||
'<!(./platform/os.sh artifacts_dir)/include/libbitcoind/src',
|
'<!(./platform/os.sh artifacts_dir)/include/libbitcoind/src',
|
||||||
@ -8,7 +8,7 @@
|
|||||||
'<!(./platform/os.sh artifacts_dir)/include/libbitcoind/src/leveldb/include'
|
'<!(./platform/os.sh artifacts_dir)/include/libbitcoind/src/leveldb/include'
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'./src/bitcoindjs.cc',
|
'./src/libbitcoind.cc',
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
['OS=="mac"', {
|
['OS=="mac"', {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ process.title = 'bitcoind.js';
|
|||||||
* daemon
|
* daemon
|
||||||
*/
|
*/
|
||||||
var daemon = require('../').daemon({
|
var daemon = require('../').daemon({
|
||||||
datadir: process.env.BITCOINDJS_DIR || '~/.bitcoin',
|
datadir: process.env.BITCORENODE_DIR || '~/.bitcoin',
|
||||||
});
|
});
|
||||||
|
|
||||||
daemon.on('ready', function() {
|
daemon.on('ready', function() {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ var log = chainlib.log;
|
|||||||
log.debug = function() {};
|
log.debug = function() {};
|
||||||
|
|
||||||
var configuration = {
|
var configuration = {
|
||||||
datadir: process.env.BITCOINDJS_DIR || '~/.bitcoin'
|
datadir: process.env.BITCORENODE_DIR || '~/.bitcoin'
|
||||||
};
|
};
|
||||||
|
|
||||||
var node = new BitcoinNode(configuration);
|
var node = new BitcoinNode(configuration);
|
||||||
|
|||||||
4
index.js
4
index.js
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {};
|
module.exports = require('./lib/node');
|
||||||
module.exports.daemon = require('./lib/daemon');
|
module.exports.daemon = require('./lib/daemon');
|
||||||
module.exports.Node = require('./lib/node');
|
module.exports.Node = require('./lib/node');
|
||||||
module.exports.Block = require('./lib/block');
|
module.exports.Block = require('./lib/block');
|
||||||
@ -14,4 +14,4 @@ module.exports.modules = {};
|
|||||||
module.exports.modules.AddressModule = require('./lib/modules/address');
|
module.exports.modules.AddressModule = require('./lib/modules/address');
|
||||||
|
|
||||||
module.exports.deps = {};
|
module.exports.deps = {};
|
||||||
module.exports.deps.chainlib = require('chainlib');
|
module.exports.deps.chainlib = require('chainlib');
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
module.exports = require('./lib/bitcoind_stripped.js');
|
|
||||||
@ -5,8 +5,8 @@
|
|||||||
// functionality by including the wallet in the build.
|
// functionality by including the wallet in the build.
|
||||||
// To run the tests: $ mocha -R spec integration/regtest.js
|
// To run the tests: $ mocha -R spec integration/regtest.js
|
||||||
|
|
||||||
if (process.env.BITCOINDJS_ENV !== 'test') {
|
if (process.env.BITCORENODE_ENV !== 'test') {
|
||||||
console.log('Please set the environment variable BITCOINDJS_ENV=test and make sure bindings are compiled for testing');
|
console.log('Please set the environment variable BITCORENODE_ENV=test and make sure bindings are compiled for testing');
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
110
lib/daemon.js
110
lib/daemon.js
@ -1,6 +1,6 @@
|
|||||||
var net = require('net');
|
var net = require('net');
|
||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var bitcoindjs = require('bindings')('bitcoindjs.node');
|
var bitcoind = require('bindings')('bitcoind.node');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var mkdirp = require('mkdirp');
|
var mkdirp = require('mkdirp');
|
||||||
@ -106,7 +106,7 @@ tiny.error = function() {};
|
|||||||
tiny.prototype.error = function() {};
|
tiny.prototype.error = function() {};
|
||||||
|
|
||||||
Daemon.db = tiny({
|
Daemon.db = tiny({
|
||||||
file: process.env.HOME + '/.bitcoindjs.db',
|
file: process.env.HOME + '/.bitcoind.db',
|
||||||
saveIndex: false,
|
saveIndex: false,
|
||||||
initialCache: false
|
initialCache: false
|
||||||
});
|
});
|
||||||
@ -146,7 +146,7 @@ Daemon.prototype.start = function(options, callback) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
bitcoindjs.start(options, function(err, status) {
|
bitcoind.start(options, function(err, status) {
|
||||||
self._started = true;
|
self._started = true;
|
||||||
|
|
||||||
// Poll for queued packet
|
// Poll for queued packet
|
||||||
@ -199,22 +199,22 @@ Daemon.prototype.start = function(options, callback) {
|
|||||||
self.stop();
|
self.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
bitcoindjs.onBlocksReady(function(err, result) {
|
bitcoind.onBlocksReady(function(err, result) {
|
||||||
|
|
||||||
function onTipUpdateListener(result) {
|
function onTipUpdateListener(result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
// Emit and event that the tip was updated
|
// Emit and event that the tip was updated
|
||||||
self.emit('tip', result);
|
self.emit('tip', result);
|
||||||
// Recursively wait until the next update
|
// Recursively wait until the next update
|
||||||
bitcoindjs.onTipUpdate(onTipUpdateListener);
|
bitcoind.onTipUpdate(onTipUpdateListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitcoindjs.onTipUpdate(onTipUpdateListener);
|
bitcoind.onTipUpdate(onTipUpdateListener);
|
||||||
|
|
||||||
self.emit('ready', result);
|
self.emit('ready', result);
|
||||||
|
|
||||||
bitcoindjs.startTxMon(function(txs) {
|
bitcoind.startTxMon(function(txs) {
|
||||||
for(var i = 0; i < txs.length; i++) {
|
for(var i = 0; i < txs.length; i++) {
|
||||||
self.emit('tx', txs[i]);
|
self.emit('tx', txs[i]);
|
||||||
}
|
}
|
||||||
@ -247,12 +247,12 @@ Daemon.prototype.start = function(options, callback) {
|
|||||||
// bitcoind's boost threads aren't in the thread pool
|
// bitcoind's boost threads aren't in the thread pool
|
||||||
// or on node's event loop, so we need to keep node open.
|
// or on node's event loop, so we need to keep node open.
|
||||||
this._shutdown = setInterval(function() {
|
this._shutdown = setInterval(function() {
|
||||||
if (!self._stoppingSaid && bitcoindjs.stopping()) {
|
if (!self._stoppingSaid && bitcoind.stopping()) {
|
||||||
self._stoppingSaid = true;
|
self._stoppingSaid = true;
|
||||||
self.log('shutting down...');
|
self.log('shutting down...');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitcoindjs.stopped()) {
|
if (bitcoind.stopped()) {
|
||||||
self.log('shut down.');
|
self.log('shut down.');
|
||||||
|
|
||||||
clearInterval(self._shutdown);
|
clearInterval(self._shutdown);
|
||||||
@ -281,7 +281,7 @@ Daemon.prototype.start = function(options, callback) {
|
|||||||
|
|
||||||
Daemon.prototype.getBlock = function(blockhash, callback) {
|
Daemon.prototype.getBlock = function(blockhash, callback) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getBlock(blockhash, function(err, block) {
|
return bitcoind.getBlock(blockhash, function(err, block) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
return callback(null, block);
|
return callback(null, block);
|
||||||
});
|
});
|
||||||
@ -289,30 +289,30 @@ Daemon.prototype.getBlock = function(blockhash, callback) {
|
|||||||
|
|
||||||
Daemon.prototype.getBlockHeight = function(height, callback) {
|
Daemon.prototype.getBlockHeight = function(height, callback) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getBlock(+height, function(err, block) {
|
return bitcoind.getBlock(+height, function(err, block) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
return callback(null, daemon.block(block));
|
return callback(null, daemon.block(block));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.isSpent = function(txid, outputIndex) {
|
Daemon.prototype.isSpent = function(txid, outputIndex) {
|
||||||
return bitcoindjs.isSpent(txid, outputIndex);
|
return bitcoind.isSpent(txid, outputIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getBlockIndex = function(blockHash) {
|
Daemon.prototype.getBlockIndex = function(blockHash) {
|
||||||
return bitcoindjs.getBlockIndex(blockHash);
|
return bitcoind.getBlockIndex(blockHash);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.estimateFee = function(blocks) {
|
Daemon.prototype.estimateFee = function(blocks) {
|
||||||
return bitcoindjs.estimateFee(blocks);
|
return bitcoind.estimateFee(blocks);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.sendTransaction = function(transaction, allowAbsurdFees) {
|
Daemon.prototype.sendTransaction = function(transaction, allowAbsurdFees) {
|
||||||
return bitcoindjs.sendTransaction(transaction, allowAbsurdFees);
|
return bitcoind.sendTransaction(transaction, allowAbsurdFees);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getTransaction = function(txid, queryMempool, callback) {
|
Daemon.prototype.getTransaction = function(txid, queryMempool, callback) {
|
||||||
return bitcoindjs.getTransaction(txid, queryMempool, callback);
|
return bitcoind.getTransaction(txid, queryMempool, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getTransactionWithBlock = function(txid, blockhash, callback) {
|
Daemon.prototype.getTransactionWithBlock = function(txid, blockhash, callback) {
|
||||||
@ -345,7 +345,7 @@ Daemon.prototype.getTransactionWithBlock = function(txid, blockhash, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bitcoindjs.getTransaction(txid, blockhash, function(err, tx) {
|
return bitcoind.getTransaction(txid, blockhash, function(err, tx) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
||||||
if (slow && !tx.blockhash) {
|
if (slow && !tx.blockhash) {
|
||||||
@ -355,7 +355,7 @@ Daemon.prototype.getTransactionWithBlock = function(txid, blockhash, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return bitcoindjs.getBlock(tx.blockhash, function(err, block) {
|
return bitcoind.getBlock(tx.blockhash, function(err, block) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
return callback(null, daemon.tx(tx), daemon.block(block));
|
return callback(null, daemon.tx(tx), daemon.block(block));
|
||||||
});
|
});
|
||||||
@ -363,49 +363,49 @@ Daemon.prototype.getTransactionWithBlock = function(txid, blockhash, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getTransactionWithBlockInfo = function(txid, queryMempool, callback) {
|
Daemon.prototype.getTransactionWithBlockInfo = function(txid, queryMempool, callback) {
|
||||||
return bitcoindjs.getTransactionWithBlockInfo(txid, queryMempool, callback);
|
return bitcoind.getTransactionWithBlockInfo(txid, queryMempool, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getMempoolOutputs = function(address) {
|
Daemon.prototype.getMempoolOutputs = function(address) {
|
||||||
return bitcoindjs.getMempoolOutputs(address);
|
return bitcoind.getMempoolOutputs(address);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.addMempoolUncheckedTransaction = function(txBuffer) {
|
Daemon.prototype.addMempoolUncheckedTransaction = function(txBuffer) {
|
||||||
return bitcoindjs.addMempoolUncheckedTransaction(txBuffer);
|
return bitcoind.addMempoolUncheckedTransaction(txBuffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getInfo = function() {
|
Daemon.prototype.getInfo = function() {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getInfo();
|
return bitcoind.getInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getPeerInfo = function() {
|
Daemon.prototype.getPeerInfo = function() {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getPeerInfo();
|
return bitcoind.getPeerInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getAddresses = function() {
|
Daemon.prototype.getAddresses = function() {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getAddresses();
|
return bitcoind.getAddresses();
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getProgress = function(callback) {
|
Daemon.prototype.getProgress = function(callback) {
|
||||||
return bitcoindjs.getProgress(callback);
|
return bitcoind.getProgress(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.setGenerate = function(options) {
|
Daemon.prototype.setGenerate = function(options) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.setGenerate(options || {});
|
return bitcoind.setGenerate(options || {});
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getGenerate = function(options) {
|
Daemon.prototype.getGenerate = function(options) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getGenerate(options || {});
|
return bitcoind.getGenerate(options || {});
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getMiningInfo = function() {
|
Daemon.prototype.getMiningInfo = function() {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getMiningInfo();
|
return bitcoind.getMiningInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getAddrTransactions = function(address, callback) {
|
Daemon.prototype.getAddrTransactions = function(address, callback) {
|
||||||
@ -424,7 +424,7 @@ Daemon.prototype.getAddrTransactions = function(address, callback) {
|
|||||||
: out;
|
: out;
|
||||||
}, -1)
|
}, -1)
|
||||||
};
|
};
|
||||||
return bitcoindjs.getAddrTransactions(options, function(err, addr) {
|
return bitcoind.getAddrTransactions(options, function(err, addr) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
addr = daemon.addr(addr);
|
addr = daemon.addr(addr);
|
||||||
if (addr.tx[0] && !addr.tx[0].vout[0]) {
|
if (addr.tx[0] && !addr.tx[0].vout[0]) {
|
||||||
@ -461,13 +461,13 @@ Daemon.prototype.getAddrTransactions = function(address, callback) {
|
|||||||
|
|
||||||
Daemon.prototype.getBestBlock = function(callback) {
|
Daemon.prototype.getBestBlock = function(callback) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
var hash = bitcoindjs.getBestBlock();
|
var hash = bitcoind.getBestBlock();
|
||||||
return bitcoindjs.getBlock(hash, callback);
|
return bitcoind.getBlock(hash, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.getChainHeight = function() {
|
Daemon.prototype.getChainHeight = function() {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getChainHeight();
|
return bitcoind.getChainHeight();
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.__defineGetter__('chainHeight', function() {
|
Daemon.prototype.__defineGetter__('chainHeight', function() {
|
||||||
@ -488,7 +488,7 @@ Daemon.prototype.getBlockByTx = function(txid, callback) {
|
|||||||
return callback(null, block, tx_);
|
return callback(null, block, tx_);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return bitcoindjs.getBlockByTx(txid, function(err, block, tx_) {
|
return bitcoind.getBlockByTx(txid, function(err, block, tx_) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
daemon.db.set('block-tx/' + txid, { hash: block.hash }, utils.NOOP);
|
daemon.db.set('block-tx/' + txid, { hash: block.hash }, utils.NOOP);
|
||||||
return callback(null, daemon.block(block), daemon.tx(tx_));
|
return callback(null, daemon.block(block), daemon.tx(tx_));
|
||||||
@ -499,7 +499,7 @@ Daemon.prototype.getBlockByTx = function(txid, callback) {
|
|||||||
Daemon.prototype.getBlocksByDate =
|
Daemon.prototype.getBlocksByDate =
|
||||||
Daemon.prototype.getBlocksByTime = function(options, callback) {
|
Daemon.prototype.getBlocksByTime = function(options, callback) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getBlocksByTime(options, function(err, blocks) {
|
return bitcoind.getBlocksByTime(options, function(err, blocks) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
return callback(null, blocks.map(function(block) {
|
return callback(null, blocks.map(function(block) {
|
||||||
return daemon.block(block);
|
return daemon.block(block);
|
||||||
@ -509,7 +509,7 @@ Daemon.prototype.getBlocksByTime = function(options, callback) {
|
|||||||
|
|
||||||
Daemon.prototype.getFromTx = function(txid, callback) {
|
Daemon.prototype.getFromTx = function(txid, callback) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getFromTx(txid, function(err, txs) {
|
return bitcoind.getFromTx(txid, function(err, txs) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
return callback(null, txs.map(function(tx) {
|
return callback(null, txs.map(function(tx) {
|
||||||
return daemon.tx(tx)
|
return daemon.tx(tx)
|
||||||
@ -519,7 +519,7 @@ Daemon.prototype.getFromTx = function(txid, callback) {
|
|||||||
|
|
||||||
Daemon.prototype.getLastFileIndex = function() {
|
Daemon.prototype.getLastFileIndex = function() {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return bitcoindjs.getLastFileIndex();
|
return bitcoind.getLastFileIndex();
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.log =
|
Daemon.prototype.log =
|
||||||
@ -549,7 +549,7 @@ Daemon.prototype.stop =
|
|||||||
Daemon.prototype.close = function(callback) {
|
Daemon.prototype.close = function(callback) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
var self = this;
|
var self = this;
|
||||||
return bitcoindjs.stop(function(err, status) {
|
return bitcoind.stop(function(err, status) {
|
||||||
if (err) {
|
if (err) {
|
||||||
self.error(err.message);
|
self.error(err.message);
|
||||||
} else {
|
} else {
|
||||||
@ -561,19 +561,19 @@ Daemon.prototype.close = function(callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Daemon.prototype.__defineGetter__('stopping', function() {
|
Daemon.prototype.__defineGetter__('stopping', function() {
|
||||||
return bitcoindjs.stopping() || bitcoindjs.stopped();
|
return bitcoind.stopping() || bitcoind.stopped();
|
||||||
});
|
});
|
||||||
|
|
||||||
Daemon.prototype.__defineGetter__('stopped', function() {
|
Daemon.prototype.__defineGetter__('stopped', function() {
|
||||||
return bitcoindjs.stopped();
|
return bitcoind.stopped();
|
||||||
});
|
});
|
||||||
|
|
||||||
Daemon.__defineGetter__('stopping', function() {
|
Daemon.__defineGetter__('stopping', function() {
|
||||||
return bitcoindjs.stopping() || bitcoindjs.stopped();
|
return bitcoind.stopping() || bitcoind.stopped();
|
||||||
});
|
});
|
||||||
|
|
||||||
Daemon.__defineGetter__('stopped', function() {
|
Daemon.__defineGetter__('stopped', function() {
|
||||||
return bitcoindjs.stopped();
|
return bitcoind.stopped();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -627,12 +627,12 @@ Block.isBlock = function(block) {
|
|||||||
|
|
||||||
Block.fromHex = function(hex) {
|
Block.fromHex = function(hex) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return daemon.block(bitcoindjs.blockFromHex(hex));
|
return daemon.block(bitcoind.blockFromHex(hex));
|
||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.getHash = function(enc) {
|
Block.prototype.getHash = function(enc) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
var data = bitcoindjs.getBlockHex(this);
|
var data = bitcoind.getBlockHex(this);
|
||||||
if (!this.hash || this.hash !== data.hash) {
|
if (!this.hash || this.hash !== data.hash) {
|
||||||
this.hash = data.hash;
|
this.hash = data.hash;
|
||||||
}
|
}
|
||||||
@ -644,7 +644,7 @@ Block.prototype.getHash = function(enc) {
|
|||||||
|
|
||||||
Block.prototype.verify = function() {
|
Block.prototype.verify = function() {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return this.verified = this.verified || bitcoindjs.verifyBlock(this);
|
return this.verified = this.verified || bitcoind.verifyBlock(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.toHex = function() {
|
Block.prototype.toHex = function() {
|
||||||
@ -658,7 +658,7 @@ Block.prototype.toHex = function() {
|
|||||||
|
|
||||||
Block.toHex = function(block) {
|
Block.toHex = function(block) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
var data = bitcoindjs.getBlockHex(block);
|
var data = bitcoind.getBlockHex(block);
|
||||||
return data.hex;
|
return data.hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -669,7 +669,7 @@ Block.prototype.toBinary = function() {
|
|||||||
|
|
||||||
Block.toBinary = function(block) {
|
Block.toBinary = function(block) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
var data = bitcoindjs.getBlockHex(block);
|
var data = bitcoind.getBlockHex(block);
|
||||||
return new Buffer(data.hex, 'hex');
|
return new Buffer(data.hex, 'hex');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -721,12 +721,12 @@ Transaction.isTx = function(tx) {
|
|||||||
|
|
||||||
Transaction.fromHex = function(hex) {
|
Transaction.fromHex = function(hex) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return daemon.tx(bitcoindjs.txFromHex(hex));
|
return daemon.tx(bitcoind.txFromHex(hex));
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction.prototype.verify = function() {
|
Transaction.prototype.verify = function() {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
return this.verified = this.verified || bitcoindjs.verifyTransaction(this);
|
return this.verified = this.verified || bitcoind.verifyTransaction(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction.prototype.sign =
|
Transaction.prototype.sign =
|
||||||
@ -746,7 +746,7 @@ Transaction.fill = function(tx, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
newTx = bitcoindjs.fillTransaction(tx, options || {});
|
newTx = bitcoind.fillTransaction(tx, options || {});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -760,7 +760,7 @@ Transaction.fill = function(tx, options) {
|
|||||||
|
|
||||||
Transaction.prototype.getHash = function(enc) {
|
Transaction.prototype.getHash = function(enc) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
var data = bitcoindjs.getTxHex(this);
|
var data = bitcoind.getTxHex(this);
|
||||||
if (!this.txid || this.txid !== data.hash) {
|
if (!this.txid || this.txid !== data.hash) {
|
||||||
this.txid = data.hash;
|
this.txid = data.hash;
|
||||||
}
|
}
|
||||||
@ -786,7 +786,7 @@ Transaction.prototype.toHex = function() {
|
|||||||
|
|
||||||
Transaction.toHex = function(tx) {
|
Transaction.toHex = function(tx) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
var data = bitcoindjs.getTxHex(tx);
|
var data = bitcoind.getTxHex(tx);
|
||||||
return data.hex;
|
return data.hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -797,7 +797,7 @@ Transaction.prototype.toBinary = function() {
|
|||||||
|
|
||||||
Transaction.toBinary = function(tx) {
|
Transaction.toBinary = function(tx) {
|
||||||
if (daemon.stopping) return [];
|
if (daemon.stopping) return [];
|
||||||
var data = bitcoindjs.getTxHex(tx);
|
var data = bitcoind.getTxHex(tx);
|
||||||
return new Buffer(data.hex, 'hex');
|
return new Buffer(data.hex, 'hex');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -827,7 +827,7 @@ Transaction.broadcast = function(tx, options, callback) {
|
|||||||
tx = daemon.tx(tx);
|
tx = daemon.tx(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bitcoindjs.broadcastTx(tx, fee, own, function(err, hash, tx) {
|
return bitcoind.broadcastTx(tx, fee, own, function(err, hash, tx) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (callback === utils.NOOP) {
|
if (callback === utils.NOOP) {
|
||||||
daemon.global.emit('error', err);
|
daemon.global.emit('error', err);
|
||||||
@ -917,8 +917,8 @@ exports.Daemon = daemon;
|
|||||||
exports.daemon = daemon;
|
exports.daemon = daemon;
|
||||||
exports.bitcoind = daemon;
|
exports.bitcoind = daemon;
|
||||||
|
|
||||||
exports.native = bitcoindjs;
|
exports.native = bitcoind;
|
||||||
exports.bitcoindjs = bitcoindjs;
|
exports.bitcoind = bitcoind;
|
||||||
|
|
||||||
exports.Block = Block;
|
exports.Block = Block;
|
||||||
exports.block = Block;
|
exports.block = Block;
|
||||||
|
|||||||
12
package.json
12
package.json
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "bitcoind.js",
|
"name": "bitcore-node",
|
||||||
"description": "Node binding for bitcoind",
|
"description": "Full node with extended capabilities using Bitcore and Bitcoin Core",
|
||||||
"author": "BitPay <dev@bitpay.com>",
|
"author": "BitPay <dev@bitpay.com>",
|
||||||
"version": "0.0.8",
|
"version": "0.2.0",
|
||||||
"main": "./index.js",
|
"main": "./index.js",
|
||||||
"repository": "git://github.com/bitpay/bitcoind.js.git",
|
"repository": "git://github.com/bitpay/bitcore-node.git",
|
||||||
"homepage": "https://github.com/bitpay/bitcoind.js",
|
"homepage": "https://github.com/bitpay/bitcore-node.js",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/bitpay/bitcoind.js/issues"
|
"url": "https://github.com/bitpay/bitcore-node/issues"
|
||||||
},
|
},
|
||||||
"contributors": [
|
"contributors": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,517 +0,0 @@
|
|||||||
/**
|
|
||||||
* bitcoind.js - a binding for node.js which links to libbitcoind.so/dylib.
|
|
||||||
* Copyright (c) 2015, BitPay (MIT License)
|
|
||||||
*
|
|
||||||
* bitcoindjs.cc:
|
|
||||||
* A bitcoind node.js binding.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bitcoindjs_stripped.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace boost;
|
|
||||||
using namespace node;
|
|
||||||
using namespace v8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bitcoin Globals
|
|
||||||
*/
|
|
||||||
|
|
||||||
// These global functions and variables are
|
|
||||||
// required to be defined/exposed here.
|
|
||||||
|
|
||||||
extern void DetectShutdownThread(boost::thread_group*);
|
|
||||||
extern int nScriptCheckThreads;
|
|
||||||
static termios orig_termios;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Node.js Internal Function Templates
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_start_node(uv_work_t *req);
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_start_node_after(uv_work_t *req);
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_stop_node(uv_work_t *req);
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_stop_node_after(uv_work_t *req);
|
|
||||||
|
|
||||||
static int
|
|
||||||
start_node(void);
|
|
||||||
|
|
||||||
static void
|
|
||||||
start_node_thread(void);
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
init(Handle<Object>);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private Global Variables
|
|
||||||
* Used only by bitcoindjs functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static volatile bool shutdown_complete = false;
|
|
||||||
static char *g_data_dir = NULL;
|
|
||||||
static bool g_rpc = false;
|
|
||||||
static bool g_testnet = false;
|
|
||||||
static bool g_txindex = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private Structs
|
|
||||||
* Used for async functions and necessary linked lists at points.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* async_node_data
|
|
||||||
* Where the uv async request data resides.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct async_node_data {
|
|
||||||
std::string err_msg;
|
|
||||||
std::string result;
|
|
||||||
std::string datadir;
|
|
||||||
bool rpc;
|
|
||||||
bool testnet;
|
|
||||||
bool txindex;
|
|
||||||
Eternal<Function> callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helpers
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool
|
|
||||||
set_cooked(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* StartBitcoind()
|
|
||||||
* bitcoind.start(callback)
|
|
||||||
* Start the bitcoind node with AppInit2() on a separate thread.
|
|
||||||
*/
|
|
||||||
|
|
||||||
NAN_METHOD(StartBitcoind) {
|
|
||||||
Isolate* isolate = Isolate::GetCurrent();
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
|
|
||||||
Local<Function> callback;
|
|
||||||
std::string datadir = std::string("");
|
|
||||||
bool rpc = false;
|
|
||||||
bool testnet = false;
|
|
||||||
bool txindex = false;
|
|
||||||
|
|
||||||
if (args.Length() >= 2 && args[0]->IsObject() && args[1]->IsFunction()) {
|
|
||||||
Local<Object> options = Local<Object>::Cast(args[0]);
|
|
||||||
if (options->Get(NanNew<String>("datadir"))->IsString()) {
|
|
||||||
String::Utf8Value datadir_(options->Get(NanNew<String>("datadir"))->ToString());
|
|
||||||
datadir = std::string(*datadir_);
|
|
||||||
}
|
|
||||||
if (options->Get(NanNew<String>("rpc"))->IsBoolean()) {
|
|
||||||
rpc = options->Get(NanNew<String>("rpc"))->ToBoolean()->IsTrue();
|
|
||||||
}
|
|
||||||
if (options->Get(NanNew<String>("testnet"))->IsBoolean()) {
|
|
||||||
testnet = options->Get(NanNew<String>("testnet"))->ToBoolean()->IsTrue();
|
|
||||||
}
|
|
||||||
if (options->Get(NanNew<String>("txindex"))->IsBoolean()) {
|
|
||||||
txindex = options->Get(NanNew<String>("txindex"))->ToBoolean()->IsTrue();
|
|
||||||
}
|
|
||||||
callback = Local<Function>::Cast(args[1]);
|
|
||||||
} else if (args.Length() >= 2
|
|
||||||
&& (args[0]->IsUndefined() || args[0]->IsNull())
|
|
||||||
&& args[1]->IsFunction()) {
|
|
||||||
callback = Local<Function>::Cast(args[1]);
|
|
||||||
} else if (args.Length() >= 1 && args[0]->IsFunction()) {
|
|
||||||
callback = Local<Function>::Cast(args[0]);
|
|
||||||
} else {
|
|
||||||
return NanThrowError(
|
|
||||||
"Usage: bitcoind.start(callback)");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Run bitcoind's StartNode() on a separate thread.
|
|
||||||
//
|
|
||||||
|
|
||||||
async_node_data *data = new async_node_data();
|
|
||||||
data->err_msg = std::string("");
|
|
||||||
data->result = std::string("");
|
|
||||||
data->datadir = datadir;
|
|
||||||
data->rpc = rpc;
|
|
||||||
data->testnet = testnet;
|
|
||||||
data->txindex = txindex;
|
|
||||||
|
|
||||||
Eternal<Function> eternal(isolate, callback);
|
|
||||||
|
|
||||||
data->callback = eternal;
|
|
||||||
uv_work_t *req = new uv_work_t();
|
|
||||||
req->data = data;
|
|
||||||
|
|
||||||
int status = uv_queue_work(uv_default_loop(),
|
|
||||||
req, async_start_node,
|
|
||||||
(uv_after_work_cb)async_start_node_after);
|
|
||||||
|
|
||||||
assert(status == 0);
|
|
||||||
|
|
||||||
NanReturnValue(Undefined(isolate));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* async_start_node()
|
|
||||||
* Call start_node() and start all our boost threads.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_start_node(uv_work_t *req) {
|
|
||||||
async_node_data *data = static_cast<async_node_data*>(req->data);
|
|
||||||
if (data->datadir != "") {
|
|
||||||
g_data_dir = (char *)data->datadir.c_str();
|
|
||||||
} else {
|
|
||||||
g_data_dir = (char *)malloc(sizeof(char) * 512);
|
|
||||||
snprintf(g_data_dir, sizeof(char) * 512, "%s/.bitcoind.js", getenv("HOME"));
|
|
||||||
}
|
|
||||||
g_rpc = (bool)data->rpc;
|
|
||||||
g_testnet = (bool)data->testnet;
|
|
||||||
g_txindex = (bool)data->txindex;
|
|
||||||
tcgetattr(STDIN_FILENO, &orig_termios);
|
|
||||||
start_node();
|
|
||||||
data->result = std::string("bitcoind opened.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* async_start_node_after()
|
|
||||||
* Execute our callback.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_start_node_after(uv_work_t *req) {
|
|
||||||
Isolate* isolate = Isolate::GetCurrent();
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
async_node_data *data = static_cast<async_node_data*>(req->data);
|
|
||||||
|
|
||||||
Local<Function> cb = data->callback.Get(isolate);
|
|
||||||
if (data->err_msg != "") {
|
|
||||||
Local<Value> err = Exception::Error(NanNew<String>(data->err_msg));
|
|
||||||
const unsigned argc = 1;
|
|
||||||
Local<Value> argv[argc] = { err };
|
|
||||||
TryCatch try_catch;
|
|
||||||
cb->Call(isolate->GetCurrentContext()->Global(), argc, argv);
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
node::FatalException(try_catch);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const unsigned argc = 2;
|
|
||||||
Local<Value> argv[argc] = {
|
|
||||||
v8::Null(isolate),
|
|
||||||
Local<Value>::New(isolate, NanNew<String>(data->result))
|
|
||||||
};
|
|
||||||
TryCatch try_catch;
|
|
||||||
cb->Call(isolate->GetCurrentContext()->Global(), argc, argv);
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
node::FatalException(try_catch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
delete req;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* start_node(void)
|
|
||||||
* Start AppInit2() on a separate thread, wait for
|
|
||||||
* Unfortunately, we need to wait for the initialization
|
|
||||||
* to unhook the signal handlers so we can use them
|
|
||||||
* from node.js in javascript.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
start_node(void) {
|
|
||||||
SetupEnvironment();
|
|
||||||
|
|
||||||
noui_connect();
|
|
||||||
|
|
||||||
new boost::thread(boost::bind(&start_node_thread));
|
|
||||||
|
|
||||||
// Drop the bitcoind signal handlers: we want our own.
|
|
||||||
signal(SIGINT, SIG_DFL);
|
|
||||||
signal(SIGHUP, SIG_DFL);
|
|
||||||
signal(SIGQUIT, SIG_DFL);
|
|
||||||
|
|
||||||
// Hook into packet handling
|
|
||||||
//new boost::thread(boost::bind(&hook_packets));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
start_node_thread(void) {
|
|
||||||
boost::thread_group threadGroup;
|
|
||||||
boost::thread* detectShutdownThread = NULL;
|
|
||||||
|
|
||||||
// Workaround for AppInit2() arg parsing. Not ideal, but it works.
|
|
||||||
int argc = 0;
|
|
||||||
char **argv = (char **)malloc((4 + 1) * sizeof(char **));
|
|
||||||
|
|
||||||
argv[argc] = (char *)"bitcoind";
|
|
||||||
argc++;
|
|
||||||
|
|
||||||
if (g_data_dir) {
|
|
||||||
const int argl = 9 + strlen(g_data_dir) + 1;
|
|
||||||
char *arg = (char *)malloc(sizeof(char) * argl);
|
|
||||||
int w = snprintf(arg, argl, "-datadir=%s", g_data_dir);
|
|
||||||
if (w >= 10 && w <= argl) {
|
|
||||||
arg[w] = '\0';
|
|
||||||
argv[argc] = arg;
|
|
||||||
argc++;
|
|
||||||
} else {
|
|
||||||
if (set_cooked()) {
|
|
||||||
fprintf(stderr, "bitcoind.js: Bad -datadir value.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_rpc) {
|
|
||||||
argv[argc] = (char *)"-server";
|
|
||||||
argc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_testnet) {
|
|
||||||
argv[argc] = (char *)"-testnet";
|
|
||||||
argc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_txindex) {
|
|
||||||
argv[argc] = (char *)"-txindex";
|
|
||||||
argc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv[argc] = NULL;
|
|
||||||
|
|
||||||
bool fRet = false;
|
|
||||||
try {
|
|
||||||
ParseParameters((const int)argc, (const char **)argv);
|
|
||||||
|
|
||||||
if (!boost::filesystem::is_directory(GetDataDir(false))) {
|
|
||||||
if (set_cooked()) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"bitcoind.js: Specified data directory \"%s\" does not exist.\n",
|
|
||||||
mapArgs["-datadir"].c_str());
|
|
||||||
}
|
|
||||||
shutdown_complete = true;
|
|
||||||
_exit(1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
|
||||||
} catch(std::exception &e) {
|
|
||||||
if (set_cooked()) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"bitcoind.js: Error reading configuration file: %s\n", e.what());
|
|
||||||
}
|
|
||||||
shutdown_complete = true;
|
|
||||||
_exit(1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SelectParamsFromCommandLine()) {
|
|
||||||
if (set_cooked()) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"bitcoind.js: Invalid combination of -regtest and -testnet.\n");
|
|
||||||
}
|
|
||||||
shutdown_complete = true;
|
|
||||||
_exit(1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CreatePidFile(GetPidFile(), getpid());
|
|
||||||
|
|
||||||
detectShutdownThread = new boost::thread(
|
|
||||||
boost::bind(&DetectShutdownThread, &threadGroup));
|
|
||||||
|
|
||||||
fRet = AppInit2(threadGroup);
|
|
||||||
|
|
||||||
} catch (std::exception& e) {
|
|
||||||
if (set_cooked()) {
|
|
||||||
fprintf(stderr, "bitcoind.js: AppInit(): std::exception\n");
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
if (set_cooked()) {
|
|
||||||
fprintf(stderr, "bitcoind.js: AppInit(): other exception\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fRet) {
|
|
||||||
if (detectShutdownThread) {
|
|
||||||
detectShutdownThread->interrupt();
|
|
||||||
}
|
|
||||||
threadGroup.interrupt_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (detectShutdownThread) {
|
|
||||||
detectShutdownThread->join();
|
|
||||||
delete detectShutdownThread;
|
|
||||||
detectShutdownThread = NULL;
|
|
||||||
}
|
|
||||||
Shutdown();
|
|
||||||
|
|
||||||
// bitcoind is shutdown. Notify the main thread
|
|
||||||
// which is polling this variable:
|
|
||||||
shutdown_complete = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* StopBitcoind()
|
|
||||||
* bitcoind.stop(callback)
|
|
||||||
*/
|
|
||||||
|
|
||||||
NAN_METHOD(StopBitcoind) {
|
|
||||||
fprintf(stderr, "Stopping Bitcoind please wait!");
|
|
||||||
Isolate* isolate = Isolate::GetCurrent();
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsFunction()) {
|
|
||||||
return NanThrowError(
|
|
||||||
"Usage: bitcoind.stop(callback)");
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Function> callback = Local<Function>::Cast(args[0]);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Run bitcoind's StartShutdown() on a separate thread.
|
|
||||||
//
|
|
||||||
|
|
||||||
async_node_data *data = new async_node_data();
|
|
||||||
data->err_msg = std::string("");
|
|
||||||
data->result = std::string("");
|
|
||||||
Eternal<Function> eternal(isolate, callback);
|
|
||||||
data->callback = eternal;
|
|
||||||
|
|
||||||
uv_work_t *req = new uv_work_t();
|
|
||||||
req->data = data;
|
|
||||||
|
|
||||||
int status = uv_queue_work(uv_default_loop(),
|
|
||||||
req, async_stop_node,
|
|
||||||
(uv_after_work_cb)async_stop_node_after);
|
|
||||||
|
|
||||||
assert(status == 0);
|
|
||||||
NanReturnValue(Undefined(isolate));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* async_stop_node()
|
|
||||||
* Call StartShutdown() to join the boost threads, which will call Shutdown()
|
|
||||||
* and set shutdown_complete to true to notify the main node.js thread.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_stop_node(uv_work_t *req) {
|
|
||||||
async_node_data *data = static_cast<async_node_data*>(req->data);
|
|
||||||
StartShutdown();
|
|
||||||
data->result = std::string("bitcoind shutdown.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* async_stop_node_after()
|
|
||||||
* Execute our callback.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_stop_node_after(uv_work_t *req) {
|
|
||||||
Isolate* isolate = Isolate::GetCurrent();
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
async_node_data* data = static_cast<async_node_data*>(req->data);
|
|
||||||
|
|
||||||
Local<Function> cb = data->callback.Get(isolate);
|
|
||||||
if (data->err_msg != "") {
|
|
||||||
Local<Value> err = Exception::Error(NanNew<String>(data->err_msg));
|
|
||||||
const unsigned argc = 1;
|
|
||||||
Local<Value> argv[argc] = { err };
|
|
||||||
TryCatch try_catch;
|
|
||||||
cb->Call(isolate->GetCurrentContext()->Global(), argc, argv);
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
node::FatalException(try_catch);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const unsigned argc = 2;
|
|
||||||
Local<Value> argv[argc] = {
|
|
||||||
Local<Value>::New(isolate, NanNull()),
|
|
||||||
Local<Value>::New(isolate, NanNew<String>(data->result))
|
|
||||||
};
|
|
||||||
TryCatch try_catch;
|
|
||||||
cb->Call(isolate->GetCurrentContext()->Global(), argc, argv);
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
node::FatalException(try_catch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
delete req;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IsStopping()
|
|
||||||
* bitcoind.stopping()
|
|
||||||
* Check whether bitcoind is in the process of shutting down. This is polled
|
|
||||||
* from javascript.
|
|
||||||
*/
|
|
||||||
|
|
||||||
NAN_METHOD(IsStopping) {
|
|
||||||
NanScope();
|
|
||||||
NanReturnValue(NanNew<Boolean>(ShutdownRequested()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IsStopped()
|
|
||||||
* bitcoind.stopped()
|
|
||||||
* Check whether bitcoind has shutdown completely. This will be polled by
|
|
||||||
* javascript to check whether the libuv event loop is safe to stop.
|
|
||||||
*/
|
|
||||||
|
|
||||||
NAN_METHOD(IsStopped) {
|
|
||||||
NanScope();
|
|
||||||
NanReturnValue(NanNew<Boolean>(shutdown_complete));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helpers
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool
|
|
||||||
set_cooked(void) {
|
|
||||||
uv_tty_t tty;
|
|
||||||
tty.mode = 1;
|
|
||||||
tty.orig_termios = orig_termios;
|
|
||||||
|
|
||||||
if (!uv_tty_set_mode(&tty, 0)) {
|
|
||||||
printf("\x1b[H\x1b[J");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init()
|
|
||||||
* Initialize the singleton object known as bitcoindjs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
init(Handle<Object> target) {
|
|
||||||
NanScope();
|
|
||||||
|
|
||||||
NODE_SET_METHOD(target, "start", StartBitcoind);
|
|
||||||
NODE_SET_METHOD(target, "stop", StopBitcoind);
|
|
||||||
NODE_SET_METHOD(target, "stopping", IsStopping);
|
|
||||||
NODE_SET_METHOD(target, "stopped", IsStopped);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
NODE_MODULE(bitcoindjs, init)
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
/**
|
|
||||||
* bitcoind.js
|
|
||||||
* Copyright (c) 2014, BitPay (MIT License)
|
|
||||||
*
|
|
||||||
* bitcoindjs.h:
|
|
||||||
* A bitcoind node.js binding header file.
|
|
||||||
*/
|
|
||||||
#include "nan.h"
|
|
||||||
#include "addrman.h"
|
|
||||||
#include "base58.h"
|
|
||||||
#include "init.h"
|
|
||||||
#include "noui.h"
|
|
||||||
#include <boost/thread.hpp>
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
NAN_METHOD(StartBitcoind);
|
|
||||||
NAN_METHOD(IsStopping);
|
|
||||||
NAN_METHOD(IsStopped);
|
|
||||||
NAN_METHOD(StopBitcoind);
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
* A bitcoind node.js binding.
|
* A bitcoind node.js binding.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bitcoindjs.h"
|
#include "libbitcoind.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
@ -1634,4 +1634,4 @@ init(Handle<Object> target) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NODE_MODULE(bitcoindjs, init)
|
NODE_MODULE(libbitcoind, init)
|
||||||
Loading…
Reference in New Issue
Block a user