1. Changed build script libbitcoind to support debug builds as well as release builds

2. Added node binding.gyp build script
3. Adjust authors and removed unneeded npm modules
4. Removed unneeded polling of hook packets every 50ms in bitcoind.js
5. Removed hard-coded path to --prefix
This commit is contained in:
Chris Kleeschulte 2015-07-08 14:24:26 -04:00
parent 0a3337933e
commit 36c9f44050
7 changed files with 120 additions and 297 deletions

14
bin/build-bindings Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
set -e
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.."
cd "${root_dir}"
debug=
if test x"$1" = x'debug'; then
debug=--d
fi
node-gyp ${debug} rebuild

View File

@ -1,5 +1,5 @@
#!/bin/bash
set -e
set -e
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.."
cd "${root_dir}"
@ -9,60 +9,70 @@ os_dir=$(./platform/os.sh osdir)
#set the LD_LIBRARY_PATH for the linux clients.
export LD_LIBRARY_PATH="${root_dir}/libbitcoind/src/leveldb":"${os_dir}":$LD_LIBRARY_PATH
if test -e "${os_dir}/libbitcoind.so" || test -e "${os_dir}/libbitcoind.dylib"; then
read -r -p 'libbitcoind already built. Rebuild? (Y/n): ' choice
if test x"$choice" != x'y' -a x"$choice" != x'Y'; then
debug=
if test x"$1" = x'debug'; then
debug=--enable-debug
fi
only_make=false
libbitcoind=`find "${os_dir}" -iname "libbitcoind*"`
if [ "$libbitcoind" != "" ]; then
read -r -p 'libbitcoind already built. Remove and reinstall/Re-make only/Do Nothing? (r/m/D): ' choice
if test x"$choice" = x'r' -o x"$choice" = x'R'; then
echo "Removing libbitcoind and recloning, patching, and building..."
rm -rf "${root_dir}/libbitcoind"
rm -f "${os_dir}/libbitcoind.*"
elif test x"$choice" = x'm' -o x"$choice" = x'M'; then
echo "Running make inside libbitcoind..."
rm -f "${os_dir}/libbitcoind.*"
if [ -d "${root_dir}/libbitcoind" ]; then
only_make=true
else
echo "can not seem to find the build directory, we must do the whole shebang, bummer..."
fi
else
echo 'libbitcoind ready.'
exit 0
fi
rm -rf libbitcoind
rm -f "${os_dir}/libbitcoind.*"
fi
if [ -d "${root_dir}/libbitcoind" ]; then
read -r -p "libbitcoind (bitcoind repo) exists, would you like to remove it? (Y/n): " choice
if [ "$choice" = "y" -o "$choice" = "Y" ]; then
rm -rf "${root_dir}/libbitcoind"
else
echo "ok you chose not to remove the bitcoin repo, exiting...bu bye!"
fi
fi
#read the PATCH VERSION
if test -e "${root_dir/PATCH_VERSION}"; then
tag=`cat "$root_dir/PATCH_VERSION" | xargs`
else
echo "no tag file found, please create it in the root of the project as so: 'echo \"v0.10.2\" > PATCH_VERSION'"
exit 0
fi
echo "attempting to checkout tag: $tag of bitcoin from github..."
git clone --depth 1 --branch "${tag}" git://github.com/bitcoin/bitcoin.git libbitcoind
btc_dir="${root_dir}/libbitcoind"
echo "Found BTC directory: ${btc_dir}"
cd "${btc_dir}"
echo "Found BTC directory: $btc_dir"
if [ "${only_make}" = false ]; then
if test -e "${root_dir/PATCH_VERSION}"; then
tag=`cat "${root_dir}/PATCH_VERSION" | xargs`
else
echo "no tag file found, please create it in the root of the project as so: 'echo \"v0.10.2\" > PATCH_VERSION'"
exit 0
fi
echo './patch-bitcoin.sh' "$btc_dir"
./bin/patch-bitcoin "$btc_dir"
echo "attempting to checkout tag: ${tag} of bitcoin from github..."
git clone --depth 1 --branch "${tag}" git://github.com/bitcoin/bitcoin.git libbitcoind
cd "$btc_dir"
echo './patch-bitcoin.sh' "${btc_dir}"
./bin/patch-bitcoin "${btc_dir}"
if ! test -d .git; then
echo 'Please point this script to an upstream bitcoin git repo.'
exit 1
if ! test -d .git; then
echo 'Please point this script to an upstream bitcoin git repo.'
exit 1
fi
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
echo './autogen.sh'
./autogen.sh
options=`cat ${root_dir}/bin/config_options.sh`
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
make V=1
ext=$($root_dir/platform/os.sh ext)
echo 'Copying libbitcoind.{so|dylib} to its appropriate location.'
if test -e "${root_dir}/libbitcoind/src/.libs/libbitcoind.${ext}"; then
if test -e "${root_dir}/libbitcoind/src/.libs/libbitcoind.${ext}"; then
if [ "$ext" = "dylib" ]; then
cp "${root_dir}/libbitcoind/src/.libs/libbitcoind.0.dylib" "${os_dir}/"
cp "${root_dir}/libbitcoind/src/.libs/libbitcoind.dylib" "${os_dir}/"

View File

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

View File

@ -20,7 +20,7 @@ index 0000000..9623c59
--- /dev/null
+++ b/config_me.sh
@@ -0,0 +1 @@
+./configure --enable-tests=no --enable-daemonlib --with-gui=no --without-qt --without-miniupnpc --without-bdb --enable-debug --disable-wallet --without-utils --prefix=/home/k/source/bitcoind.js/platform/debian
+./configure --enable-tests=no --enable-daemonlib --with-gui=no --without-qt --without-miniupnpc --without-bdb --enable-debug --disable-wallet --without-utils
diff --git a/configure.ac b/configure.ac
index 579035f..cd20489 100644
--- a/configure.ac
@ -28,7 +28,7 @@ index 579035f..cd20489 100644
@@ -126,6 +126,12 @@ AC_ARG_ENABLE([reduce-exports],
[use_reduce_exports=$enableval],
[use_reduce_exports=auto])
+AC_ARG_ENABLE([daemonlib],
+ [AS_HELP_STRING([--enable-daemonlib],
+ [compile all of bitcoind as a library (default is no)])],
@ -45,13 +45,13 @@ index 579035f..cd20489 100644
+ if test x$use_daemonlib = xno; then
+ AX_CHECK_COMPILE_FLAG([-fPIE],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fPIE"])
+ fi
AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[
AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[
@@ -422,7 +431,7 @@ if test x$use_hardening != xno; then
AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"])
AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"])
- if test x$TARGET_OS != xwindows; then
+ if test x$TARGET_OS != xwindows -a x$use_daemonlib = xno; then
# All windows code is PIC, forcing it on just adds useless compile warnings
@ -60,7 +60,7 @@ index 579035f..cd20489 100644
@@ -440,6 +449,17 @@ if test x$use_hardening != xno; then
OBJCXXFLAGS="$CXXFLAGS"
fi
+AC_DEFINE([ENABLE_DAEMONLIB],[0],[Enable daemonlib.])
+AM_CONDITIONAL([ENABLE_DAEMONLIB],[false])
+if test x$use_daemonlib != xno; then
@ -78,7 +78,7 @@ index 579035f..cd20489 100644
@@ -485,7 +505,7 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([
]
)
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports != xno -a x$use_daemonlib = xno; then
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"],
@ -87,7 +87,7 @@ index 579035f..cd20489 100644
@@ -496,6 +516,13 @@ if test x$use_reduce_exports != xno; then
])
fi
+AC_MSG_CHECKING([whether to compile as daemonlib])
+if test x$use_daemonlib != xno; then
+ AC_MSG_RESULT([yes])
@ -105,9 +105,9 @@ index 81b16d1..d05c91a 100644
@@ -1,6 +1,7 @@
DIST_SUBDIRS = secp256k1
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS)
+lib_LTLIBRARIES =
if EMBEDDED_LEVELDB
LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include
@@ -15,6 +16,10 @@ $(LIBLEVELDB) $(LIBMEMENV):
@ -119,12 +119,12 @@ index 81b16d1..d05c91a 100644
+ @echo "Building the LevelDB shared library..." && $(MAKE) -C ./leveldb
+
endif
BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
@@ -49,16 +54,16 @@ BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
EXTRA_LIBRARIES += libbitcoin_wallet.a
endif
-if BUILD_BITCOIN_LIBS
-lib_LTLIBRARIES = libbitcoinconsensus.la
-LIBBITCOIN_CONSENSUS=libbitcoinconsensus.la
@ -135,7 +135,7 @@ index 81b16d1..d05c91a 100644
+LIBBITCOIN_CONSENSUS =
bin_PROGRAMS =
TESTS =
+if BUILD_BITCOIN_LIBS
+lib_LTLIBRARIES += libbitcoinconsensus.la
+LIBBITCOIN_CONSENSUS += libbitcoinconsensus.la
@ -152,7 +152,7 @@ index 81b16d1..d05c91a 100644
+else
+lib_LTLIBRARIES += libbitcoind.la
+endif
.PHONY: FORCE
# bitcoin core #
@@ -156,8 +164,9 @@ obj/build.h: FORCE
@ -160,7 +160,7 @@ index 81b16d1..d05c91a 100644
@$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \
$(abs_top_srcdir)
-libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
+libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
+clientversion.cpp: obj/build.h
# server: shared between bitcoind and bitcoin-qt
@ -184,12 +184,12 @@ index 81b16d1..d05c91a 100644
+libbitcoind_la_SOURCES += $(libbitcoin_server_a_SOURCES)
+libbitcoind_la_SOURCES += $(crypto_libbitcoin_crypto_a_SOURCES)
+libbitcoind_la_SOURCES += $(univalue_libbitcoin_univalue_a_SOURCES)
if TARGET_WINDOWS
bitcoind_SOURCES += bitcoind-res.rc
+libbitcoind_la_SOURCES += bitcoind-res.rc
endif
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
@ -197,7 +197,7 @@ index 81b16d1..d05c91a 100644
+libbitcoind_la_CPPFLAGS = $(BITCOIN_INCLUDES)
+libbitcoind_la_LDFLAGS = -lleveldb -L./leveldb $(RELDFLAGS) -no-undefined
+libbitcoind_la_DEPENDENCIES = $(LIBSECP256K1) LIBLEVELDB_SHARED $(MEMOBJ)
# bitcoin-cli binary #
bitcoin_cli_LDADD = \
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
@ -207,23 +207,23 @@ index be7757b..0eb62d8 100644
@@ -15,6 +15,9 @@
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
+#if ENABLE_DAEMONLIB
+extern void DetectShutdownThread(boost::thread_group* threadGroup);
+#endif
/* Introduction text for doxygen: */
/*! \mainpage Developer documentation
@@ -175,6 +178,7 @@ bool AppInit(int argc, char* argv[])
return fRet;
}
+#if !ENABLE_DAEMONLIB
int main(int argc, char* argv[])
{
SetupEnvironment();
@@ -184,3 +188,4 @@ int main(int argc, char* argv[])
return (AppInit(argc, argv) ? 0 : 1);
}
+#endif
@ -232,9 +232,9 @@ index f2f7ac6..9106580 100644
--- a/src/init.h
+++ b/src/init.h
@@ -17,6 +17,11 @@ class thread_group;
extern CWallet* pwalletMain;
+#if ENABLE_DAEMONLIB
+#include <boost/filesystem/path.hpp>
+#include <boost/thread/mutex.hpp>
@ -249,24 +249,24 @@ index 2bd2cad..490ba66 100644
+++ b/src/leveldb/Makefile
@@ -103,7 +103,7 @@ check: all $(PROGRAMS) $(TESTS)
for t in $(TESTS); do echo "***** Running $$t"; ./$$t || exit 1; done
clean:
- -rm -f $(PROGRAMS) $(BENCHMARKS) $(LIBRARY) $(SHARED) $(MEMENVLIBRARY) */*.o */*/*.o ios-x86/*/*.o ios-arm/*/*.o build_config.mk
+ -rm -f $(PROGRAMS) $(BENCHMARKS) $(LIBRARY) $(SHARED) $(MEMENVLIBRARY) */*.o */*/*.lo helpers/memenv/.deps/*.Plo helpers/memenv/.deps/*.Tpo */*/*.o ios-x86/*/*.o ios-arm/*/*.o build_config.mk
-rm -rf ios-x86/* ios-arm/*
$(LIBRARY): $(LIBOBJECTS)
@@ -192,6 +192,10 @@ $(MEMENVLIBRARY) : $(MEMENVOBJECTS)
rm -f $@
$(AR) -rs $@ $(MEMENVOBJECTS)
+helpers/memenv/memenv.lo: helpers/memenv/memenv.cc
+ -mkdir -p helpers/memenv/.deps
+ /bin/bash ../../libtool --tag=CXX --mode=compile $(CXX) $(CXXFLAGS) $(CFLAGS) -fPIC -MT $@ -MD -MP -MF helpers/memenv/.deps/memenv.Tpo -c -o $@ $<
+
memenv_test : helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS)
$(CXX) $(LDFLAGS) helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHARNESS) -o $@ $(LIBS)
diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h
index 4247920..c75c63c 100644
--- a/src/leveldbwrapper.h
@ -274,14 +274,14 @@ index 4247920..c75c63c 100644
@@ -29,10 +29,16 @@ class CLevelDBBatch
{
friend class CLevelDBWrapper;
+#if ENABLE_DAEMONLIB
+public:
+#else
private:
+#endif
leveldb::WriteBatch batch;
+#if !ENABLE_DAEMONLIB
public:
+#endif
@ -289,7 +289,7 @@ index 4247920..c75c63c 100644
void Write(const K& key, const V& value)
{
@@ -63,7 +69,11 @@ public:
class CLevelDBWrapper
{
+#if ENABLE_DAEMONLIB
@ -299,17 +299,17 @@ index 4247920..c75c63c 100644
+#endif
//! custom environment this database is using (may be NULL in case of default environment)
leveldb::Env* penv;
@@ -85,7 +95,9 @@ private:
//! the database itself
leveldb::DB* pdb;
+#if !ENABLE_DAEMONLIB
public:
+#endif
CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
~CLevelDBWrapper();
--
--
2.3.2 (Apple Git-55)

View File

@ -6,19 +6,10 @@
process.title = 'bitcoind.js';
var util = require('util');
var fs = require('fs');
var argv = require('optimist').argv;
var rimraf = require('rimraf');
var assert = require('assert');
/**
* bitcoind
*/
if (fs.existsSync(process.env.HOME + '/.libbitcoind-example')) {
rimraf.sync(process.env.HOME + '/.libbitcoind-example');
}
var bitcoindjsConf = process.env('BITCOINDJS_DIR');
var bitcoind = require('../')({
directory: '~/.libbitcoind-example'
@ -30,149 +21,4 @@ bitcoind.on('error', function(err) {
bitcoind.on('open', function(status) {
bitcoind.log('status="%s"', status);
if (argv.list) {
return;
}
if (argv.blocks) {
return getBlocks(bitcoind);
}
function assertHex(obj) {
// Hash
if (obj.txid) {
assert.equal(obj.hash, obj.getHash('hex'));
} else {
assert.equal(obj.hash, obj.getHash('hex'));
}
// Hex
if (obj.txid) {
assert.equal(obj.hex, obj.toHex());
} else {
assert.equal(obj.hex, obj.toHex());
}
}
if (argv['on-block']) {
return bitcoind.on('block', function callee(block) {
if (block.tx.length === 1) return;
bitcoind.log('Found Block:');
bitcoind.log(block);
return assertHex(block);
});
}
if (argv['on-tx']) {
bitcoind.on('tx', function(tx) {
bitcoind.log('Found TX:');
bitcoind.log(tx);
return assertHex(tx);
});
bitcoind.on('mptx', function(mptx) {
bitcoind.log('Found mempool TX:');
bitcoind.log(mptx);
return assertHex(mptx);
});
return;
}
if (argv.broadcast) {
// Help propagate transactions
return bitcoind.once('tx', function(tx) {
bitcoind.log('Broadcasting TX...');
return tx.broadcast(function(err, hash, tx) {
if (err) throw err;
bitcoind.log('TX Hash: %s', hash);
return bitcoind.log(tx);
});
});
}
// Test fromHex:
if (argv['from-hex']) {
var block = bitcoind.block(testBlock);
assert.equal(block.hash, '0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af');
assert.equal(block.merkleroot, '2fda58e5959b0ee53c5253da9b9f3c0c739422ae04946966991cf55895287552');
bitcoind.log('Block:');
bitcoind.log(block);
var tx = bitcoind.tx(testTx);
assert.equal(tx.txid, 'b4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b');
bitcoind.log('Transaction:');
bitcoind.log(tx);
return;
}
// Test all digest packets:
if (argv['packets']) {
bitcoind.on('digest', function(packet) {
return bitcoind.log(packet);
});
return;
}
argv['on-block'] = true;
setTimeout(function() {
bitcoind.on('block', function callee(block) {
if (!argv['on-block']) {
return bitcoind.removeListener('block', callee);
}
bitcoind.log('Found Block:');
bitcoind.log(block);
return assertHex(block);
});
bitcoind.once('block', function(block) {
setTimeout(function() {
argv['on-block'] = false;
bitcoind.log(bitcoind.getInfo());
bitcoind.log(bitcoind.getPeerInfo());
bitcoind.once('version', function(version) {
bitcoind.log('VERSION packet:');
bitcoind.log(version);
});
bitcoind.once('addr', function(addr) {
bitcoind.log('ADDR packet:');
bitcoind.log(addr);
});
}, 8000);
});
}, 2000);
return;
});
/**
* Helpers
*/
function getBlocks(bitcoind) {
return setTimeout(function() {
return (function next(hash) {
return bitcoind.getBlock(hash, function(err, block) {
if (err) return bitcoind.log(err.message);
bitcoind.log(block);
if (argv['get-tx'] && block.tx.length && block.tx[0].txid) {
var txid = block.tx[0].txid;
// XXX Dies with a segfault
// bitcoind.getTx(txid, hash, function(err, tx) {
bitcoind.getTx(txid, function(err, tx) {
if (err) return bitcoind.log(err.message);
bitcoind.log('TX -----------------------------------------------------');
bitcoind.log(tx);
bitcoind.log('/TX ----------------------------------------------------');
});
}
if (block.nextblockhash) {
setTimeout(next.bind(null, block.nextblockhash), 500);
}
});
})(genesisBlock);
}, 1000);
}

View File

@ -196,66 +196,7 @@ Bitcoin.prototype.start = function(options, callback) {
bitcoindjs.start(options, function(err, status) {
self._started = true;
// Poll for queued packets
setInterval(function() {
var packets = bitcoindjs.hookPackets();
if (!packets) {
if (self.debug) {
self.error('Error polling packet queue.');
}
return;
}
if (!packets.length) {
return;
}
self.emit('_packets', packets);
packets.forEach(function(packet) {
setImmediate(function() {
self.emit('raw:' + packet.name, packet);
self.emit('raw', packet);
if (packet.name === 'addr') {
self.emit(packet.name, packet.addresses);
self.emit('digest', packet.addresses);
return;
}
if (packet.name === 'block') {
var block = self.block(packet.block);
self.emit(packet.name, block);
self.emit('digest', block);
block.tx.forEach(function(tx) {
setImmediate(function() {
tx = self.tx(tx);
self.emit('tx', tx);
self.emit('digest', tx);
});
});
return;
}
if (packet.name === 'tx') {
var tx = self.tx(packet.tx);
var name = packet.name;
if (!packet.tx.blockhash) {
name = 'mptx';
}
self.emit(name, tx);
self.emit('digest', tx);
return;
}
self.emit(packet.name, packet);
self.emit('digest', packet);
});
});
}, 50);
[sigint, sighup, sigquit].forEach(function(signal) {
// Poll for queued packet [sigint, sighup, sigquit].forEach(function(signal) {
process.on(signal.name, signal.listener = function() {
if (process.listeners(signal.name).length > 1) {
return;

View File

@ -1,17 +1,31 @@
{
"name": "bitcoind.js",
"description": "Node binding for bitcoind",
"author": "Christopher Jeffrey",
"author": "BitPay <dev@bitpay.com>",
"version": "0.0.8",
"main": "./index.js",
"repository": "git://github.com/chjj/bitcoind.js.git",
"homepage": "https://github.com/chjj/bitcoind.js",
"repository": "git://github.com/bitpay/bitcoind.js.git",
"homepage": "https://github.com/bitpay/bitcoind.js",
"bugs": {
"url": "https://github.com/chjj/bitcoind.js/issues"
"url": "https://github.com/bitpay/bitcoind.js/issues"
},
"contributors": [
{
"name": "Christopher Jeffrey"
},
{
"name": "Braydon Fuller",
"email": "braydon@bitpay.com"
},
{
"name": "Chris Kleeschulte",
"email": "chrisk@bitpay.com"
}
],
"scripts": {
"preinstall": "./bin/build-libbitcoind remote",
"start": "export LD_LIBRARY_PATH=`./platform/os.sh osdir` && node example"
"preinstall": "./bin/build-libbitcoind && ./bin/build-bindings",
"start": "export LD_LIBRARY_PATH=`./platform/os.sh osdir` && node example",
"debug_install": "./bin/build-libbitcoind debug && ./bin/build-bindings debug"
},
"tags": [
"bitcoin",
@ -24,8 +38,6 @@
},
"devDependencies": {
"mocha": "~1.16.2",
"optimist": "0.6.0",
"rimraf": "2.2.8",
"async": "1.2.1",
"benchmark": "1.0.0"
}