diff --git a/.travis.yml b/.travis.yml index e2df2e3b..5b0f5095 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,17 @@ sudo: false language: node_js env: -- BITCORENODE_ENV=test BITCORENODE_ASSUME_YES=true + - BITCORENODE_ENV=test BITCORENODE_ASSUME_YES=true CXX=g++-4.8 CC=gcc-4.8 +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-4.8 + - gcc-4.8 node_js: - "v0.12.7" + - "v4" before_install: - git config --global user.email "dev@bitpay.com" - git config --global user.name "BitPay, Inc." diff --git a/README.md b/README.md index 2f3f6212..2da202a5 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Note: For your convenience, we distribute binaries for x86_64 Linux and x86_64 M ## Prerequisites -- Node.js v0.12 +- Node.js v0.12 or v4.2 - ~100GB of disk storage - ~4GB of RAM - Mac OS X >= 10.9, Ubuntu >= 12.04 (libc >= 2.15 and libstdc++ >= 6.0.16) diff --git a/bin/get-tarball-name.js b/bin/get-tarball-name.js index 114916c9..e931904b 100644 --- a/bin/get-tarball-name.js +++ b/bin/get-tarball-name.js @@ -5,7 +5,8 @@ function getTarballName() { var version = require(packageRoot + '/package.json').version; var platform = process.platform; var arch = process.arch; - var tarballName = 'libbitcoind-' + version + '-' + platform + '-' + arch + '.tgz'; + var abi = process.versions.modules; + var tarballName = 'libbitcoind-' + version + '-node' + abi + '-' + platform + '-' + arch + '.tgz'; return tarballName; } diff --git a/binding.gyp b/binding.gyp index 99a5cab0..3db1adb1 100644 --- a/binding.gyp +++ b/binding.gyp @@ -48,8 +48,7 @@ "= 10.9, Ubuntu >= 12.04 (libc >= 2.15 and libstdc++ >= 6.0.16) diff --git a/etc/bitcoin.patch b/etc/bitcoin.patch index e1fe3b1b..e262753e 100644 --- a/etc/bitcoin.patch +++ b/etc/bitcoin.patch @@ -79,6 +79,30 @@ index fd74aef..9c79637 100644 LEVELDB_CPPFLAGS= LIBLEVELDB= LIBMEMENV= +diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk +index b13a0f1..0513394 100644 +--- a/depends/hosts/linux.mk ++++ b/depends/hosts/linux.mk +@@ -10,15 +10,15 @@ linux_debug_CXXFLAGS=$(linux_debug_CFLAGS) + linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC + + ifeq (86,$(findstring 86,$(build_arch))) +-i686_linux_CC=gcc -m32 +-i686_linux_CXX=g++ -m32 ++i686_linux_CC=${CC} -m32 ++i686_linux_CXX=${CXX} -m32 + i686_linux_AR=ar + i686_linux_RANLIB=ranlib + i686_linux_NM=nm + i686_linux_STRIP=strip + +-x86_64_linux_CC=gcc -m64 +-x86_64_linux_CXX=g++ -m64 ++x86_64_linux_CC=${CC} -m64 ++x86_64_linux_CXX=${CXX} -m64 + x86_64_linux_AR=ar + x86_64_linux_RANLIB=ranlib + x86_64_linux_NM=nm diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 68841af..65a105b 100644 --- a/depends/packages/bdb.mk diff --git a/package.json b/package.json index 02ff6bcd..a949da2f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "commander": "^2.8.1", "errno": "^0.1.4", "express": "^4.13.3", - "leveldown": "^1.4.1", + "leveldown": "^1.4.2", "levelup": "^1.2.1", "liftoff": "^2.2.0", "memdown": "^1.0.0", @@ -78,7 +78,7 @@ "bitcore-p2p": "~1.0.0" }, "engines": { - "node": "^0.12" + "node": "^0.12 || ^4.2" }, "os": [ "darwin", diff --git a/src/libbitcoind.cc b/src/libbitcoind.cc index 26eb7859..c3e27274 100644 --- a/src/libbitcoind.cc +++ b/src/libbitcoind.cc @@ -161,7 +161,7 @@ struct async_node_data { struct async_block_data { uv_work_t req; std::string err_msg; - std::string hash; + uint256 hash; int64_t height; char* buffer; uint32_t size; @@ -261,7 +261,7 @@ NAN_METHOD(StartTxMon) { static void tx_notifier(uv_async_t *handle) { - Isolate* isolate = GetCurrentContext()->GetIsolate(); + Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); Local results = Array::New(isolate); @@ -273,15 +273,15 @@ tx_notifier(uv_async_t *handle) { CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << tx; std::string stx = ssTx.str(); - Local txBuffer = node::Buffer::New(isolate, stx.c_str(), stx.size()); + Nan::MaybeLocal txBuffer = Nan::CopyBuffer((char *)stx.c_str(), stx.size()); uint256 hash = tx.GetHash(); Local obj = New(); - Set(obj, New("buffer").ToLocalChecked(), txBuffer); - Set(obj, New("hash").ToLocalChecked(), New(hash.GetHex()).ToLocalChecked()); - Set(obj, New("mempool").ToLocalChecked(), New(true)); + Nan::Set(obj, New("buffer").ToLocalChecked(), txBuffer.ToLocalChecked()); + Nan::Set(obj, New("hash").ToLocalChecked(), New(hash.GetHex()).ToLocalChecked()); + Nan::Set(obj, New("mempool").ToLocalChecked(), New(true)); results->Set(arrayIndex, obj); arrayIndex++; @@ -352,7 +352,7 @@ async_tip_update_after(uv_work_t *r) { HandleScope scope(isolate); Local cb = Local::New(isolate, req->callback); - TryCatch try_catch; + Nan::TryCatch try_catch; Local result = Undefined(isolate); if (!shutdown_complete) { @@ -363,11 +363,10 @@ async_tip_update_after(uv_work_t *r) { }; cb->Call(isolate->GetCurrentContext()->Global(), 1, argv); if (try_catch.HasCaught()) { - node::FatalException(try_catch); + Nan::FatalException(try_catch); } req->callback.Reset(); - delete req; } NAN_METHOD(OnBlocksReady) { @@ -443,7 +442,7 @@ async_blocks_ready_after(uv_work_t *r) { Isolate* isolate = req->isolate; HandleScope scope(isolate); - TryCatch try_catch; + Nan::TryCatch try_catch; Local cb = Local::New(isolate, req->callback); if (req->err_msg != "") { @@ -459,11 +458,10 @@ async_blocks_ready_after(uv_work_t *r) { } if (try_catch.HasCaught()) { - node::FatalException(try_catch); + Nan::FatalException(try_catch); } req->callback.Reset(); - delete req; } /** @@ -575,7 +573,7 @@ async_start_node_after(uv_work_t *r) { Isolate* isolate = req->isolate; HandleScope scope(isolate); - TryCatch try_catch; + Nan::TryCatch try_catch; Local cb = Local::New(isolate, req->callback); if (req->err_msg != "") { @@ -591,11 +589,10 @@ async_start_node_after(uv_work_t *r) { } if (try_catch.HasCaught()) { - node::FatalException(try_catch); + Nan::FatalException(try_catch); } req->callback.Reset(); - delete req; } /** @@ -789,7 +786,7 @@ async_stop_node_after(uv_work_t *r) { Isolate* isolate = req->isolate; HandleScope scope(isolate); - TryCatch try_catch; + Nan::TryCatch try_catch; Local cb = Local::New(isolate, req->callback); if (req->err_msg != "") { @@ -805,10 +802,9 @@ async_stop_node_after(uv_work_t *r) { } if (try_catch.HasCaught()) { - node::FatalException(try_catch); + Nan::FatalException(try_catch); } req->callback.Reset(); - delete req; } /** @@ -832,13 +828,11 @@ NAN_METHOD(GetBlock) { if (info[0]->IsNumber()) { int64_t height = info[0]->IntegerValue(); req->err_msg = std::string(""); - req->hash = std::string(""); req->height = height; } else { - String::Utf8Value hash_(info[0]->ToString()); - std::string hash = std::string(*hash_); + std::string hash = *Nan::Utf8String(info[0]); req->err_msg = std::string(""); - req->hash = hash; + req->hash = uint256S(hash); req->height = -1; } @@ -861,7 +855,6 @@ async_get_block(uv_work_t *req) { async_block_data* data = reinterpret_cast(req->data); CBlockIndex* pblockindex; - uint256 hash = uint256S(data->hash); if (data->height != -1) { pblockindex = chainActive[data->height]; @@ -870,11 +863,11 @@ async_get_block(uv_work_t *req) { return; } } else { - if (mapBlockIndex.count(hash) == 0) { + if (mapBlockIndex.count(data->hash) == 0) { data->err_msg = std::string("Block not found."); return; } else { - pblockindex = mapBlockIndex[hash]; + pblockindex = mapBlockIndex[data->hash]; } } @@ -917,7 +910,7 @@ async_get_block_after(uv_work_t *r) { Isolate *isolate = req->isolate; HandleScope scope(isolate); - TryCatch try_catch; + Nan::TryCatch try_catch; Local cb = Local::New(isolate, req->callback); if (req->err_msg != "") { @@ -926,24 +919,20 @@ async_get_block_after(uv_work_t *r) { cb->Call(isolate->GetCurrentContext()->Global(), 1, argv); } else { - Local rawNodeBuffer = node::Buffer::New(isolate, req->buffer, req->size); - - delete req->buffer; - req->buffer = NULL; + Nan::MaybeLocal rawNodeBuffer = Nan::NewBuffer(req->buffer, req->size); Local argv[2] = { Local::New(isolate, Null()), - rawNodeBuffer + rawNodeBuffer.ToLocalChecked() }; cb->Call(isolate->GetCurrentContext()->Global(), 2, argv); } if (try_catch.HasCaught()) { - node::FatalException(try_catch); + Nan::FatalException(try_catch); } req->callback.Reset(); - delete req; } /** @@ -963,17 +952,14 @@ NAN_METHOD(GetTransaction) { "Usage: daemon.getTransaction(txid, queryMempool, callback)"); } - String::Utf8Value txid_(info[0]->ToString()); + std::string txid = *Nan::Utf8String(info[0]); + bool queryMempool = info[1]->BooleanValue(); Local callback = Local::Cast(info[2]); async_tx_data *req = new async_tx_data(); req->err_msg = std::string(""); - req->txid = std::string(""); - - std::string txid = std::string(*txid_); - req->txid = txid; req->queryMempool = queryMempool; req->isolate = isolate; @@ -993,8 +979,8 @@ static void async_get_tx(uv_work_t *req) { async_tx_data* data = reinterpret_cast(req->data); - uint256 hash = uint256S(data->txid); uint256 blockhash; + uint256 hash = uint256S(data->txid); CTransaction ctx; if (data->queryMempool) { @@ -1040,7 +1026,7 @@ async_get_tx_after(uv_work_t *r) { HandleScope scope(isolate); CTransaction ctx = req->ctx; - TryCatch try_catch; + Nan::TryCatch try_catch; Local cb = Local::New(isolate, req->callback); if (req->err_msg != "") { @@ -1049,28 +1035,32 @@ async_get_tx_after(uv_work_t *r) { cb->Call(isolate->GetCurrentContext()->Global(), 1, argv); } else { - Local result = Local::New(isolate, Null()); - if (!ctx.IsNull()) { CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << ctx; std::string stx = ssTx.str(); - result = node::Buffer::New(isolate, stx.c_str(), stx.size()); + Nan::MaybeLocal result = Nan::CopyBuffer((char *)stx.c_str(), stx.size()); + Local argv[2] = { + Local::New(isolate, Null()), + result.ToLocalChecked() + }; + cb->Call(isolate->GetCurrentContext()->Global(), 2, argv); + + } else { + Local argv[2] = { + Local::New(isolate, Null()), + Local::New(isolate, Null()) + }; + cb->Call(isolate->GetCurrentContext()->Global(), 2, argv); } - Local argv[2] = { - Local::New(isolate, Null()), - result - }; - cb->Call(isolate->GetCurrentContext()->Global(), 2, argv); } if (try_catch.HasCaught()) { - node::FatalException(try_catch); + Nan::FatalException(try_catch); } req->callback.Reset(); - delete req; } /** @@ -1182,7 +1172,7 @@ async_get_tx_and_info_after(uv_work_t *r) { HandleScope scope(isolate); CTransaction ctx = req->ctx; - TryCatch try_catch; + Nan::TryCatch try_catch; Local cb = Local::New(isolate, req->callback); Local obj = New(); @@ -1195,12 +1185,12 @@ async_get_tx_and_info_after(uv_work_t *r) { CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << ctx; std::string stx = ssTx.str(); - Local rawNodeBuffer = node::Buffer::New(isolate, stx.c_str(), stx.size()); + Nan::MaybeLocal rawNodeBuffer = Nan::CopyBuffer((char *)stx.c_str(), stx.size()); - Set(obj, New("blockHash").ToLocalChecked(), New(req->blockHash).ToLocalChecked()); - Set(obj, New("height").ToLocalChecked(), New(req->height)); - Set(obj, New("timestamp").ToLocalChecked(), New(req->nTime)); - Set(obj, New("buffer").ToLocalChecked(), rawNodeBuffer); + Nan::Set(obj, New("blockHash").ToLocalChecked(), New(req->blockHash).ToLocalChecked()); + Nan::Set(obj, New("height").ToLocalChecked(), New(req->height)); + Nan::Set(obj, New("timestamp").ToLocalChecked(), New(req->nTime)); + Nan::Set(obj, New("buffer").ToLocalChecked(), rawNodeBuffer.ToLocalChecked()); Local argv[2] = { Local::New(isolate, Null()), @@ -1209,10 +1199,9 @@ async_get_tx_and_info_after(uv_work_t *r) { cb->Call(isolate->GetCurrentContext()->Global(), 2, argv); } if (try_catch.HasCaught()) { - node::FatalException(try_catch); + Nan::FatalException(try_catch); } req->callback.Reset(); - delete req; } /** @@ -1290,15 +1279,15 @@ NAN_METHOD(GetBlockIndex) { CBlockIndex* prevBlockIndex = blockIndex->pprev; if (&prevBlockIndex->phashBlock != 0) { const uint256* prevHash = prevBlockIndex->phashBlock; - Set(obj, New("prevHash").ToLocalChecked(), New(prevHash->GetHex()).ToLocalChecked()); + Nan::Set(obj, New("prevHash").ToLocalChecked(), New(prevHash->GetHex()).ToLocalChecked()); } else { - Set(obj, New("prevHash").ToLocalChecked(), Null()); + Nan::Set(obj, New("prevHash").ToLocalChecked(), Null()); } - Set(obj, New("hash").ToLocalChecked(), New(blockIndex->phashBlock->GetHex()).ToLocalChecked()); - Set(obj, New("chainWork").ToLocalChecked(), New(cw.GetHex()).ToLocalChecked()); + Nan::Set(obj, New("hash").ToLocalChecked(), New(blockIndex->phashBlock->GetHex()).ToLocalChecked()); + Nan::Set(obj, New("chainWork").ToLocalChecked(), New(cw.GetHex()).ToLocalChecked()); - Set(obj, New("height").ToLocalChecked(), New(blockIndex->nHeight)); + Nan::Set(obj, New("height").ToLocalChecked(), New(blockIndex->nHeight)); info.GetReturnValue().Set(obj); }; @@ -1350,15 +1339,15 @@ NAN_METHOD(GetInfo) { proxyType proxy; GetProxy(NET_IPV4, proxy); - Set(obj, New("version").ToLocalChecked(), New(CLIENT_VERSION)); - Set(obj, New("protocolversion").ToLocalChecked(), New(PROTOCOL_VERSION)); - Set(obj, New("blocks").ToLocalChecked(), New((int)chainActive.Height())->ToInt32()); - Set(obj, New("timeoffset").ToLocalChecked(), New(GetTimeOffset())); - Set(obj, New("connections").ToLocalChecked(), New((int)vNodes.size())->ToInt32()); - Set(obj, New("difficulty").ToLocalChecked(), New((double)GetDifficulty())); - Set(obj, New("testnet").ToLocalChecked(), New(Params().NetworkIDString() == "test")); - Set(obj, New("relayfee").ToLocalChecked(), New(::minRelayTxFee.GetFeePerK())); // double - Set(obj, New("errors").ToLocalChecked(), New(GetWarnings("statusbar")).ToLocalChecked()); + Nan::Set(obj, New("version").ToLocalChecked(), New(CLIENT_VERSION)); + Nan::Set(obj, New("protocolversion").ToLocalChecked(), New(PROTOCOL_VERSION)); + Nan::Set(obj, New("blocks").ToLocalChecked(), New((int)chainActive.Height())->ToInt32()); + Nan::Set(obj, New("timeoffset").ToLocalChecked(), New(GetTimeOffset())); + Nan::Set(obj, New("connections").ToLocalChecked(), New((int)vNodes.size())->ToInt32()); + Nan::Set(obj, New("difficulty").ToLocalChecked(), New((double)GetDifficulty())); + Nan::Set(obj, New("testnet").ToLocalChecked(), New(Params().NetworkIDString() == "test")); + Nan::Set(obj, New("relayfee").ToLocalChecked(), New(::minRelayTxFee.GetFeePerK())); // double + Nan::Set(obj, New("errors").ToLocalChecked(), New(GetWarnings("statusbar")).ToLocalChecked()); info.GetReturnValue().Set(obj); } @@ -1473,8 +1462,8 @@ NAN_METHOD(GetMempoolTransactions) { CDataStream dataStreamTx(SER_NETWORK, PROTOCOL_VERSION); dataStreamTx << tx; std::string txString = dataStreamTx.str(); - Local txBuffer = node::Buffer::New(isolate, txString.c_str(), txString.size()); - transactions->Set(arrayIndex, txBuffer); + Nan::MaybeLocal txBuffer = Nan::CopyBuffer((char *)txString.c_str(), txString.size()); + transactions->Set(arrayIndex, txBuffer.ToLocalChecked()); arrayIndex++; } } @@ -1521,28 +1510,27 @@ set_cooked(void) { * Init() * Initialize the singleton object known as bitcoind. */ - NAN_MODULE_INIT(init) { - Set(target, New("start").ToLocalChecked(), GetFunction(New(StartBitcoind)).ToLocalChecked()); - Set(target, New("onBlocksReady").ToLocalChecked(), GetFunction(New(OnBlocksReady)).ToLocalChecked()); - Set(target, New("onTipUpdate").ToLocalChecked(), GetFunction(New(OnTipUpdate)).ToLocalChecked()); - Set(target, New("stop").ToLocalChecked(), GetFunction(New(StopBitcoind)).ToLocalChecked()); - Set(target, New("getBlock").ToLocalChecked(), GetFunction(New(GetBlock)).ToLocalChecked()); - Set(target, New("getTransaction").ToLocalChecked(), GetFunction(New(GetTransaction)).ToLocalChecked()); - Set(target, New("getTransactionWithBlockInfo").ToLocalChecked(), GetFunction(New(GetTransactionWithBlockInfo)).ToLocalChecked()); - Set(target, New("getInfo").ToLocalChecked(), GetFunction(New(GetInfo)).ToLocalChecked()); - Set(target, New("isSpent").ToLocalChecked(), GetFunction(New(IsSpent)).ToLocalChecked()); - Set(target, New("getBlockIndex").ToLocalChecked(), GetFunction(New(GetBlockIndex)).ToLocalChecked()); - Set(target, New("isMainChain").ToLocalChecked(), GetFunction(New(IsMainChain)).ToLocalChecked()); - Set(target, New("getMempoolTransactions").ToLocalChecked(), GetFunction(New(GetMempoolTransactions)).ToLocalChecked()); - Set(target, New("addMempoolUncheckedTransaction").ToLocalChecked(), GetFunction(New(AddMempoolUncheckedTransaction)).ToLocalChecked()); - Set(target, New("sendTransaction").ToLocalChecked(), GetFunction(New(SendTransaction)).ToLocalChecked()); - Set(target, New("estimateFee").ToLocalChecked(), GetFunction(New(EstimateFee)).ToLocalChecked()); - Set(target, New("startTxMon").ToLocalChecked(), GetFunction(New(StartTxMon)).ToLocalChecked()); - Set(target, New("syncPercentage").ToLocalChecked(), GetFunction(New(SyncPercentage)).ToLocalChecked()); - Set(target, New("isSynced").ToLocalChecked(), GetFunction(New(IsSynced)).ToLocalChecked()); - Set(target, New("getBestBlockHash").ToLocalChecked(), GetFunction(New(GetBestBlockHash)).ToLocalChecked()); - Set(target, New("getNextBlockHash").ToLocalChecked(), GetFunction(New(GetNextBlockHash)).ToLocalChecked()); + Nan::Set(target, New("start").ToLocalChecked(), GetFunction(New(StartBitcoind)).ToLocalChecked()); + Nan::Set(target, New("onBlocksReady").ToLocalChecked(), GetFunction(New(OnBlocksReady)).ToLocalChecked()); + Nan::Set(target, New("onTipUpdate").ToLocalChecked(), GetFunction(New(OnTipUpdate)).ToLocalChecked()); + Nan::Set(target, New("stop").ToLocalChecked(), GetFunction(New(StopBitcoind)).ToLocalChecked()); + Nan::Set(target, New("getBlock").ToLocalChecked(), GetFunction(New(GetBlock)).ToLocalChecked()); + Nan::Set(target, New("getTransaction").ToLocalChecked(), GetFunction(New(GetTransaction)).ToLocalChecked()); + Nan::Set(target, New("getTransactionWithBlockInfo").ToLocalChecked(), GetFunction(New(GetTransactionWithBlockInfo)).ToLocalChecked()); + Nan::Set(target, New("getInfo").ToLocalChecked(), GetFunction(New(GetInfo)).ToLocalChecked()); + Nan::Set(target, New("isSpent").ToLocalChecked(), GetFunction(New(IsSpent)).ToLocalChecked()); + Nan::Set(target, New("getBlockIndex").ToLocalChecked(), GetFunction(New(GetBlockIndex)).ToLocalChecked()); + Nan::Set(target, New("isMainChain").ToLocalChecked(), GetFunction(New(IsMainChain)).ToLocalChecked()); + Nan::Set(target, New("getMempoolTransactions").ToLocalChecked(), GetFunction(New(GetMempoolTransactions)).ToLocalChecked()); + Nan::Set(target, New("addMempoolUncheckedTransaction").ToLocalChecked(), GetFunction(New(AddMempoolUncheckedTransaction)).ToLocalChecked()); + Nan::Set(target, New("sendTransaction").ToLocalChecked(), GetFunction(New(SendTransaction)).ToLocalChecked()); + Nan::Set(target, New("estimateFee").ToLocalChecked(), GetFunction(New(EstimateFee)).ToLocalChecked()); + Nan::Set(target, New("startTxMon").ToLocalChecked(), GetFunction(New(StartTxMon)).ToLocalChecked()); + Nan::Set(target, New("syncPercentage").ToLocalChecked(), GetFunction(New(SyncPercentage)).ToLocalChecked()); + Nan::Set(target, New("isSynced").ToLocalChecked(), GetFunction(New(IsSynced)).ToLocalChecked()); + Nan::Set(target, New("getBestBlockHash").ToLocalChecked(), GetFunction(New(GetBestBlockHash)).ToLocalChecked()); + Nan::Set(target, New("getNextBlockHash").ToLocalChecked(), GetFunction(New(GetNextBlockHash)).ToLocalChecked()); } NODE_MODULE(libbitcoind, init); diff --git a/test/bin/get-tarball-name.js b/test/bin/get-tarball-name.js new file mode 100644 index 00000000..fa2b0601 --- /dev/null +++ b/test/bin/get-tarball-name.js @@ -0,0 +1,17 @@ +'use strict'; + +var should = require('chai').should(); +var path = require('path'); +var getTarballName = require('../../bin/get-tarball-name'); + +describe('#getTarballName', function() { + it('will return the expected tarball name', function() { + var name = getTarballName(); + var version = require(path.resolve(__dirname + '../../../package.json')).version; + var platform = process.platform; + var arch = process.arch; + var abi = process.versions.modules; + var expected = 'libbitcoind-' + version + '-node' + abi + '-' + platform + '-' + arch + '.tgz'; + name.should.equal(expected); + }); +});