Regtest testing

- Removed config option for build scripts, replaced with env variable
- Updated README
- Added regtest option under test build, wallet built-in
- added network key to bindings
- datadir for the bitcoind object instead of directory
- added new config_options scripts for test and debug
This commit is contained in:
Chris Kleeschulte 2015-07-20 17:55:49 -04:00 committed by Braydon Fuller
parent cda1e2a438
commit cf6225c495
9 changed files with 81 additions and 24 deletions

View File

@ -21,7 +21,7 @@ var BitcoinNode = require('bitcoind.js');
var configuration = {
datadir: '~/.bitcoin',
testnet: true
network: 'testnet'
};
var node = new BitcoinNode(configuration);
@ -110,7 +110,7 @@ $ tail -f ~/.bitcoin/debug.log
## Building
There are two main parts of the build, compiling Bitcoin Core and the Node.js bindings. You can run both by using `npm install` and `npm run debug_install`.
There are two main parts of the build, compiling Bitcoin Core and the Node.js bindings. You can run both by using `npm install` and set environment variable, $BITCOINDJS_ENV to 'test' or 'debug'. Both 'test' and 'debug' build libbitcoind with debug symbols whereas 'test' adds wallet capability so that regtest can be used.
### Node.js Bindings
@ -130,6 +130,11 @@ To be able to debug you'll need to have `gdb` and `node` compiled for debugging
$ gdb --args node_g path/to/example.js
```
To run mocha from within gdb (notice _mocha and not mocha so that the tests run in the same process):
```bash
$ gdb --args node /path/to/_mocha -R spec integration/index.js
```
To run integration tests against testnet or livenet data:
```bash
@ -161,7 +166,7 @@ Most of all the dependencies for building Bitcoin Core are needed, for more info
#### Shared Library Patch
To provide native bindings to JavaScript *(or any other language for that matter)*, Bitcoin code, itself, must be linkable. Currently, Bitcoin Core provides a JSON RPC interface to bitcoind as well as a shared library for script validation *(and hopefully more)* called libbitcoinconsensus. There is a node module, [node-libbitcoinconsensus](https://github.com/bitpay/node-libbitcoinconsensus), that exposes these methods. While these interfaces are useful for several use cases, there are additional use cases that are not fulfilled, and being able to implement customized interfaces is necessary. To be able to do this a few simple changes need to be made to Bitcoin Core to compile as a shared library.
To provide native bindings to JavaScript *(or any other language for that matter)*, Bitcoin code, itself, must be linkable. Currently, Bitcoin Core provides a JSON RPC interface to bitcoind as well as a shared library for script validation *(and hopefully more)* called libbitcoinconsensus. There is a node module, [node-libbitcoinconsensus](https://github.com/bitpay/node-libbitcoinconsensus), that exposes these methods. While these interfaces are useful for several use cases, there are additional use cases that are not fulfilled, and being able to implement customized interfaces is necessary. To be able to do this a few simple changes need to be made to Bitcoin Core to compile as a shared library.
The patch is located at `etc/bitcoin.patch` and adds a configure option `--enable-daemonlib` to compile all object files with `-fPIC` (Position Independent Code - needed to create a shared object), exposes leveldb variables and objects, exposes the threadpool to the bindings, and conditionally includes the main function.
@ -176,7 +181,7 @@ $ cd /path/to/bitcoind.js
$ ./bin/build-libbitcoind
```
The first argument is 'debug', this will compile node bindings and bitcoind with debug flags. The `PATCH_VERSION` file dictates what version/tag the patch goes clean against.
The `PATCH_VERSION` file dictates what version/tag the patch goes clean against.
There is a config_options.sh that has the configure options used to build libbitcoind. `make` will then compile `libbitcoind/src/.libs/libbitcoind.{so|dylib}`. This will completely ignore compiling tests, QT object files and the wallet features in `bitcoind/libbitcoind.{so|dylib}`.

View File

@ -28,7 +28,7 @@ var fixtureData = {
var bitcoind = require('../').daemon({
datadir: process.env.BITCOINDJS_DIR || '~/.bitcoin',
testnet: true
network: 'testnet'
});
bitcoind.on('error', function(err) {

View File

@ -3,6 +3,7 @@ set -e
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.."
cd "${root_dir}"
options=`cat ${root_dir}/bin/config_options.sh`
os_dir=$(./platform/os.sh osdir)
@ -10,8 +11,13 @@ os_dir=$(./platform/os.sh osdir)
export LD_LIBRARY_PATH="${root_dir}/libbitcoind/src/leveldb":"${os_dir}":$LD_LIBRARY_PATH
debug=
if test x"$1" = x'debug'; then
debug=--enable-debug
if [ "${BITCOINDJS_ENV}" == "debug" ]; then
options=`cat ${root_dir}/bin/config_options_debug.sh`
fi
test=
if [ "${BITCOINDJS_ENV}" == "test" ]; then
options=`cat ${root_dir}/bin/config_options_test.sh`
fi
btc_dir="${root_dir}/libbitcoind"
@ -50,12 +56,11 @@ if [ "${only_make}" = false ]; then
echo './autogen.sh'
./autogen.sh
options=`cat ${root_dir}/bin/config_options.sh`
full_options="${options}${os_dir} ${debug}"
echo "running the configure script with the following options:\n :::[\"${full_options}\"]:::"
${full_options}
fi
full_options="${options}${os_dir}"
echo "running the configure script with the following options:\n :::[\"${full_options}\"]:::"
${full_options}
echo 'make V=1'
make V=1

View File

@ -0,0 +1,2 @@
./configure --enable_debug --enable-tests=no --enable-daemonlib --with-gui=no --without-qt --without-miniupnpc --without-bdb --disable-wallet --without-utils --prefix=

View File

@ -0,0 +1,2 @@
./configure --enable-tests=no --enable-daemonlib --with-gui=no --without-qt --without-miniupnpc --prefix=

15
example/daemon.js Normal file
View File

@ -0,0 +1,15 @@
'use strict';
process.title = 'bitcoind.js';
var daemon = require('../').daemon({
directory: process.env.BITCOINDJS_DIR || '~/.bitcoin'
});
daemon.on('error', function(err) {
daemon.log('error="%s"', err.message);
});
daemon.on('open', function(status) {
daemon.log('status="%s"', status);
});

View File

@ -37,14 +37,6 @@ function Daemon(options) {
this.options = options || {};
if (typeof this.options === 'string') {
this.options = { datadir: this.options };
}
if (this.options.directory) {
this.options.datadir = this.options.directory;
delete this.options.directory;
}
if (!this.options.datadir) {
this.options.datadir = '~/.bitcoind.js';
@ -54,7 +46,13 @@ function Daemon(options) {
this.datadir = this.options.datadir;
this.config = this.datadir + '/bitcoin.conf';
this.network = Daemon[this.options.testnet ? 'testnet' : 'livenet'];
this.network = Daemon['livenet'];
if (this.options.network === 'testnet') {
this.network = Daemon['testnet'];
} else if(this.options.network === 'regtest') {
this.network = Daemon['regtest'];
}
if (!fs.existsSync(this.datadir)) {
mkdirp.sync(this.datadir);
@ -83,7 +81,6 @@ function Daemon(options) {
fs.writeFileSync(data + peers);
}
// Copy config into testnet dir
if (this.network.name === 'testnet') {
if (!fs.existsSync(this.datadir + '/testnet3')) {
fs.mkdirSync(this.datadir + '/testnet3');
@ -93,6 +90,15 @@ function Daemon(options) {
fs.readFileSync(this.config));
}
if (this.network.name === 'regtest') {
if (!fs.existsSync(this.datadir + '/regtest')) {
fs.mkdirSync(this.datadir + '/regtest');
}
fs.writeFileSync(
this.datadir + '/regtest/bitcoin.conf',
fs.readFileSync(this.config));
}
Object.keys(exports).forEach(function(key) {
self[key] = exports[key];
});
@ -120,6 +126,13 @@ Daemon.testnet = {
]
};
Bitcoin.regtest = {
name: 'regtest',
peers: [
// hardcoded peers
]
};
// Make sure signal handlers are not overwritten
Daemon._signalQueue = [];
Daemon._processOn = process.on;

View File

@ -30,7 +30,6 @@
"preinstall": "./bin/build-libbitcoind",
"install": "./bin/build-bindings",
"start": "node example",
"debug_install": "./bin/build-libbitcoind debug && ./bin/build-bindings debug",
"test": "NODE_ENV=test mocha --recursive",
"coverage": "istanbul cover _mocha -- --recursive"
},

View File

@ -76,6 +76,7 @@ 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_regtest = false;
static bool g_txindex = false;
/**
@ -105,6 +106,7 @@ struct async_node_data {
std::string datadir;
bool rpc;
bool testnet;
bool regtest;
bool txindex;
Eternal<Function> callback;
};
@ -298,6 +300,7 @@ NAN_METHOD(StartBitcoind) {
std::string datadir = std::string("");
bool rpc = false;
bool testnet = false;
bool regtest = false;
bool txindex = false;
if (args.Length() >= 2 && args[0]->IsObject() && args[1]->IsFunction()) {
@ -309,8 +312,14 @@ NAN_METHOD(StartBitcoind) {
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>("network"))->IsString()) {
String::Utf8Value network_(options->Get(NanNew<String>("network"))->ToString());
std::string network = std::string(*network_);
if (network == "testnet") {
testnet = true;
} else if (network == "regtest") {
regtest = true;
}
}
if (options->Get(NanNew<String>("txindex"))->IsBoolean()) {
txindex = options->Get(NanNew<String>("txindex"))->ToBoolean()->IsTrue();
@ -337,6 +346,7 @@ NAN_METHOD(StartBitcoind) {
data->datadir = datadir;
data->rpc = rpc;
data->testnet = testnet;
data->regtest = regtest;
data->txindex = txindex;
Eternal<Function> eternal(isolate, callback);
@ -370,6 +380,7 @@ async_start_node(uv_work_t *req) {
}
g_rpc = (bool)data->rpc;
g_testnet = (bool)data->testnet;
g_regtest = (bool)data->regtest;
g_txindex = (bool)data->txindex;
tcgetattr(STDIN_FILENO, &orig_termios);
start_node();
@ -475,6 +486,11 @@ start_node_thread(void) {
argc++;
}
if (g_regtest) {
argv[argc] = (char *)"-regtest";
argc++;
}
argv[argc] = (char *)"-txindex";
argc++;