readme. bitcoindjs.stop. building.
This commit is contained in:
parent
ea706e329b
commit
2de298bbc3
75
README.md
75
README.md
@ -4,39 +4,58 @@ Bitcoind as a node.js module.
|
||||
|
||||
## Building
|
||||
|
||||
### bitcoind:
|
||||
### bitcoind
|
||||
|
||||
- NOTE (to self): Arch is using bitcoin-daemon 0.9.2.1, the latest boost headers
|
||||
in Arch should be correct.
|
||||
|
||||
Cloning libbitcoind:
|
||||
|
||||
``` bash
|
||||
$ cd ~/bitcoin
|
||||
$ git clean -xdf
|
||||
$ cd ~
|
||||
$ git clone git@github.com:bitpay/libbitcoind.git bitcoin
|
||||
$ cd bitcoin
|
||||
```
|
||||
|
||||
...
|
||||
This is a fork of bitcoin v0.9.0 right now, but it has the ability to compile
|
||||
bitcoind as a shared object. This may not be ideal yet.
|
||||
|
||||
$ git checkout v0.9.2.1
|
||||
OR:
|
||||
$ git checkout v0.9.0
|
||||
#### Compiling bticoind as a library
|
||||
|
||||
...
|
||||
``` bash
|
||||
# ensure clean up
|
||||
$ make clean
|
||||
$ find ~/bitcoin -type f -name '*.o' -or -name '*.so' -print0 | xargs -0 rm -f
|
||||
|
||||
# create configure file
|
||||
$ ./autogen.sh
|
||||
|
||||
...
|
||||
# configure as a library with -fPIC on all object files
|
||||
# use --with-incompatible-bdb if necessary
|
||||
# use --prefix=/usr if necessary
|
||||
$ ./configure --enable-library --with-incompatible-bdb
|
||||
|
||||
$ ./configure --with-incompatible-bdb --prefix=/usr
|
||||
OR:
|
||||
$ ./configure --prefix=/usr
|
||||
|
||||
...
|
||||
|
||||
$ time make
|
||||
# build libbitcoind.so
|
||||
$ time make library
|
||||
real 31m33.128s
|
||||
user 16m23.930s
|
||||
sys 2m52.310s
|
||||
```
|
||||
|
||||
`--enable-library` will compile all object files with `-fPIC` (Position
|
||||
Independent Code - needed to create a shared object).
|
||||
|
||||
`make library` will then compile `./src/libbitcoind.so` (with `-shared -fPIC`),
|
||||
linking to all the freshly compiled PIC object files.
|
||||
|
||||
Without `--enable-library`, the Makefile with compile bitcoind with -fPIE
|
||||
(Position Independent for Executable), this allows compiling of bitcoind.
|
||||
|
||||
#### Todo
|
||||
|
||||
- Find a way to compile bitcoind and libbitcoind.so at the same time without
|
||||
recompiling object files each time?
|
||||
|
||||
### bitcoind.js:
|
||||
|
||||
- NOTE: This will eventually try to include our included version of boost.
|
||||
@ -47,6 +66,30 @@ $ cd ~/work/node_modules/bitcoind.js
|
||||
$ PYTHON=/usr/bin/python2.7 make gyp
|
||||
```
|
||||
|
||||
#### Running bitcoind.js
|
||||
|
||||
You can run bitcoind.js to start downloading the blockchain by doing:
|
||||
|
||||
``` bash
|
||||
$ node example/ &
|
||||
bitcoind: log pipe opened: 12
|
||||
bitcoind: status="start_node(): bitcoind opened."
|
||||
```
|
||||
|
||||
However, if you look at the bitcoind log files:
|
||||
|
||||
``` bash
|
||||
$ tail -f ~/.bitcoin/debug.log
|
||||
connect() to [2001:470:c1f2:3::201]:8333 failed: 101
|
||||
connect() to [2001:470:6c:778::2]:8333 failed: 101
|
||||
connect() to [2001:470:c1f2:3::201]:8333 failed: 101
|
||||
```
|
||||
|
||||
Right now, the `connect(3)` call is failing due to some conflict with node or
|
||||
libuv I'm guessing. This is being investigated.
|
||||
|
||||
^C (SIGINT) will call `StartShutdown()` in bitcoind on the node thread pool.
|
||||
|
||||
## Contribution and License Agreement
|
||||
|
||||
If you contribute code to this project, you are implicitly allowing your code
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
'defines': [
|
||||
'HAVE_WORKING_BOOST_SLEEP',
|
||||
#'HAVE_WORKING_BOOST_SLEEP_FOR',
|
||||
'ENABLE_WALLET',
|
||||
],
|
||||
'cflags_cc': [
|
||||
'-fexceptions',
|
||||
|
||||
@ -2,10 +2,18 @@
|
||||
|
||||
var bitcoind = require('../')();
|
||||
|
||||
bitcoind.on('error', function(err) {
|
||||
console.log('bitcoind: error="%s"', err.message);
|
||||
bitcoind.start(function(err) {
|
||||
bitcoind.on('error', function(err) {
|
||||
console.log('bitcoind: error="%s"', err.message);
|
||||
});
|
||||
bitcoind.on('open', function(status) {
|
||||
console.log('bitcoind: status="%s"', status);
|
||||
});
|
||||
});
|
||||
|
||||
bitcoind.on('open', function(status) {
|
||||
console.log('bitcoind: status="%s"', status);
|
||||
process.on('SIGINT', function() {
|
||||
return bitcoind.stop(function(err) {
|
||||
if (err) throw err;
|
||||
return process.exit(0);
|
||||
});
|
||||
});
|
||||
|
||||
@ -23,13 +23,23 @@ function Bitcoin(options) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
Bitcoin.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
Bitcoin.prototype.start = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.log_pipe = bitcoindjs.start(function(err, status) {
|
||||
if (callback) {
|
||||
callback(err);
|
||||
callback = null;
|
||||
}
|
||||
if (err) {
|
||||
self.emit('error', err);
|
||||
return;
|
||||
} else {
|
||||
self.emit('open', status);
|
||||
}
|
||||
self.emit('open', status);
|
||||
});
|
||||
|
||||
// bitcoind's boost threads aren't in the thread pool
|
||||
@ -38,10 +48,8 @@ function Bitcoin(options) {
|
||||
;
|
||||
}, 10000);
|
||||
|
||||
this.log('log pipe opened: %d', this.log_pipe);
|
||||
}
|
||||
|
||||
Bitcoin.prototype.__proto__ = EventEmitter.prototype;
|
||||
return this.log('log pipe opened: %d', this.log_pipe);
|
||||
};
|
||||
|
||||
Bitcoin.prototype.log =
|
||||
Bitcoin.prototype.info = function() {
|
||||
@ -62,10 +70,20 @@ Bitcoin.prototype.error = function() {
|
||||
return process.stderr.write('bitcoind: ' + out + '\n');
|
||||
};
|
||||
|
||||
Bitcoin.prototype.close = function() {
|
||||
Bitcoin.prototype.stop =
|
||||
Bitcoin.prototype.close = function(callback) {
|
||||
var self = this;
|
||||
clearInterval(this._interval);
|
||||
delete this._interval;
|
||||
// XXX Call bitcoind's shutdown here
|
||||
return bitcoindjs.stop(function(err, status) {
|
||||
if (err) {
|
||||
self.error(err.message);
|
||||
} else {
|
||||
self.log(status);
|
||||
}
|
||||
if (!callback) return;
|
||||
return callback(err, status);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -78,8 +78,8 @@ extern void (ThreadImport)(std::vector<boost::filesystem::path>);
|
||||
extern void (DetectShutdownThread)(boost::thread_group*);
|
||||
extern void (StartNode)(boost::thread_group&);
|
||||
extern void (ThreadScriptCheck)();
|
||||
extern void (StartShutdown)();
|
||||
extern int nScriptCheckThreads;
|
||||
// extern const int DEFAULT_SCRIPTCHECK_THREADS; // static!!
|
||||
#ifdef ENABLE_WALLET
|
||||
extern std::string strWalletFile;
|
||||
extern CWallet *pwalletMain;
|
||||
@ -108,6 +108,12 @@ async_start_node_work(uv_work_t *req);
|
||||
static void
|
||||
async_start_node_after(uv_work_t *req);
|
||||
|
||||
static void
|
||||
async_stop_node_work(uv_work_t *req);
|
||||
|
||||
static void
|
||||
async_stop_node_after(uv_work_t *req);
|
||||
|
||||
static int
|
||||
start_node(void);
|
||||
|
||||
@ -275,6 +281,8 @@ async_start_node_after(uv_work_t *req) {
|
||||
static int
|
||||
start_node(void) {
|
||||
boost::thread_group threadGroup;
|
||||
|
||||
// XXX Run this in a node thread instead to keep the event loop open:
|
||||
boost::thread *detectShutdownThread = NULL;
|
||||
detectShutdownThread = new boost::thread(
|
||||
boost::bind(&DetectShutdownThread, &threadGroup));
|
||||
@ -451,6 +459,97 @@ async_parse_logs_after(uv_work_t *req) {
|
||||
delete req;
|
||||
}
|
||||
|
||||
/**
|
||||
* StopBitcoind
|
||||
* bitcoind.stop(callback)
|
||||
*/
|
||||
|
||||
NAN_METHOD(StopBitcoind) {
|
||||
NanScope();
|
||||
|
||||
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_stop_node = new async_node_data();
|
||||
data_stop_node->err_msg = NULL;
|
||||
data_stop_node->result = NULL;
|
||||
data_stop_node->callback = Persistent<Function>::New(callback);
|
||||
|
||||
uv_work_t *req_stop_node = new uv_work_t();
|
||||
req_stop_node->data = data_stop_node;
|
||||
|
||||
int status_stop_node = uv_queue_work(uv_default_loop(),
|
||||
req_stop_node, async_stop_node_work,
|
||||
(uv_after_work_cb)async_stop_node_after);
|
||||
|
||||
assert(status_stop_node == 0);
|
||||
|
||||
NanReturnValue(Undefined());
|
||||
}
|
||||
|
||||
/**
|
||||
* async_stop_node_work()
|
||||
* Call StartShutdown() to join the boost threads, which will call Shutdown().
|
||||
*/
|
||||
|
||||
static void
|
||||
async_stop_node_work(uv_work_t *req) {
|
||||
async_node_data* node_data = static_cast<async_node_data*>(req->data);
|
||||
StartShutdown();
|
||||
node_data->result = (char *)strdup("stop_node(): bitcoind shutdown.");
|
||||
}
|
||||
|
||||
/**
|
||||
* async_stop_node_after()
|
||||
* Execute our callback.
|
||||
*/
|
||||
|
||||
static void
|
||||
async_stop_node_after(uv_work_t *req) {
|
||||
NanScope();
|
||||
async_node_data* node_data = static_cast<async_node_data*>(req->data);
|
||||
|
||||
if (node_data->err_msg != NULL) {
|
||||
Local<Value> err = Exception::Error(String::New(node_data->err_msg));
|
||||
free(node_data->err_msg);
|
||||
const unsigned argc = 1;
|
||||
Local<Value> argv[argc] = { err };
|
||||
TryCatch try_catch;
|
||||
node_data->callback->Call(Context::GetCurrent()->Global(), argc, argv);
|
||||
if (try_catch.HasCaught()) {
|
||||
node::FatalException(try_catch);
|
||||
}
|
||||
} else {
|
||||
const unsigned argc = 2;
|
||||
Local<Value> argv[argc] = {
|
||||
Local<Value>::New(Null()),
|
||||
Local<Value>::New(String::New(node_data->result))
|
||||
};
|
||||
TryCatch try_catch;
|
||||
node_data->callback->Call(Context::GetCurrent()->Global(), argc, argv);
|
||||
if (try_catch.HasCaught()) {
|
||||
node::FatalException(try_catch);
|
||||
}
|
||||
}
|
||||
|
||||
node_data->callback.Dispose();
|
||||
|
||||
if (node_data->result != NULL) {
|
||||
free(node_data->result);
|
||||
}
|
||||
|
||||
delete node_data;
|
||||
delete req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init
|
||||
*/
|
||||
@ -459,6 +558,7 @@ extern "C" void
|
||||
init(Handle<Object> target) {
|
||||
NanScope();
|
||||
NODE_SET_METHOD(target, "start", StartBitcoind);
|
||||
NODE_SET_METHOD(target, "stop", StopBitcoind);
|
||||
}
|
||||
|
||||
NODE_MODULE(bitcoindjs, init)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user