From e7dcd415554aeb9f252f394776cb88d7766ebc76 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 7 Jul 2015 15:36:17 -0400 Subject: [PATCH 1/2] Fix block segfault --- bin/build-libbitcoind | 4 +++- src/bitcoindjs.cc | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/bin/build-libbitcoind b/bin/build-libbitcoind index 12991f4e..c2b81e9f 100755 --- a/bin/build-libbitcoind +++ b/bin/build-libbitcoind @@ -67,7 +67,9 @@ if test -e "${root_dir}/libbitcoind/src/.libs/libbitcoind.${ext}"; then cp "${root_dir}/libbitcoind/src/.libs/libbitcoind.0.dylib" "${os_dir}/" cp "${root_dir}/libbitcoind/src/.libs/libbitcoind.dylib" "${os_dir}/" else - cp "${root_dir}/libbitcoind/src/.libs/libbitcoind.so*" "${os_dir}/" + cp "${root_dir}/libbitcoind/src/.libs/libbitcoind.so" "${os_dir}/" + cp "${root_dir}/libbitcoind/src/.libs/libbitcoind.so.0" "${os_dir}/" + cp "${root_dir}/libbitcoind/src/.libs/libbitcoind.so.0.0.0" "${os_dir}/" fi fi diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index ce4623c1..d51ac389 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -746,15 +746,20 @@ async_get_block(uv_work_t *req) { std::string strHash = data->hash; uint256 hash(strHash); - CBlock cblock; - CBlockIndex* pblockindex = mapBlockIndex[hash]; - - if (ReadBlockFromDisk(cblock, pblockindex)) { - data->cblock = cblock; - data->cblock_index = pblockindex; + if (mapBlockIndex.count(hash) == 0) { + data->err_msg = std::string("Block not found."); } else { - data->err_msg = std::string("Block not found."); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if(!ReadBlockFromDisk(block, pblockindex)) { + data->err_msg = std::string("Can't read block from disk"); + } else { + data->cblock = block; + data->cblock_index = pblockindex; + } } } From 618fcf65a9f36949d0ca18f5e581029ee8744758 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 7 Jul 2015 17:02:03 -0400 Subject: [PATCH 2/2] Added onBlocksReady --- example/getblock.js | 35 +++++++++++++++++ lib/bitcoind.js | 4 ++ src/bitcoindjs.cc | 94 +++++++++++++++++++++++++++++++++++++++++++++ src/bitcoindjs.h | 1 + 4 files changed, 134 insertions(+) create mode 100644 example/getblock.js diff --git a/example/getblock.js b/example/getblock.js new file mode 100644 index 00000000..18ff23fd --- /dev/null +++ b/example/getblock.js @@ -0,0 +1,35 @@ +#!/usr/bin/env node + +/** + * bitcoind.js example + */ + +process.title = 'bitcoind.js'; + +/** + * bitcoind + */ + +var bitcoind = require('../index.js')({ + directory: '~/.bitcoin' +}); + +bitcoind.on('error', function(err) { + bitcoind.log('error="%s"', err.message); +}); + +bitcoind.on('ready', function(err, result) { + console.log('Ready!'); + + bitcoind.getBlock('000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254', function(err, block) { + if (err) { + console.log(err); + } + console.log('block', block); + }); + +}); + +bitcoind.on('open', function(status) { + bitcoind.log('status="%s"', status); +}); diff --git a/lib/bitcoind.js b/lib/bitcoind.js index 5aa6baca..3515e834 100644 --- a/lib/bitcoind.js +++ b/lib/bitcoind.js @@ -304,6 +304,10 @@ Bitcoin.prototype.start = function(options, callback) { self.stop(); }); + bitcoindjs.onBlocksReady(function(err, result) { + self.emit('ready', result); + }); + setTimeout(function callee() { // Wait until wallet is loaded: if (callback) { diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index d51ac389..10ceccd2 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -43,6 +43,12 @@ async_start_node(uv_work_t *req); static void async_start_node_after(uv_work_t *req); +static void +async_blocks_ready(uv_work_t *req); + +static void +async_blocks_ready_after(uv_work_t *req); + static void async_stop_node(uv_work_t *req); @@ -149,6 +155,17 @@ static bool g_txindex = false; * Used for async functions and necessary linked lists at points. */ +/** + * async_node_data + * Where the uv async request data resides. + */ + +struct async_block_ready_data { + std::string err_msg; + std::string result; + Eternal callback; +}; + /** * async_node_data * Where the uv async request data resides. @@ -292,6 +309,82 @@ set_cooked(void); * Functions */ +NAN_METHOD(OnBlocksReady) { + Isolate* isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + + Local callback; + callback = Local::Cast(args[0]); + + async_block_ready_data *data = new async_block_ready_data(); + data->err_msg = std::string(""); + data->result = std::string(""); + + Eternal 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_blocks_ready, + (uv_after_work_cb)async_blocks_ready_after); + + assert(status == 0); + + NanReturnValue(Undefined(isolate)); + +} + +/** + * async_start_node() + * Call start_node() and start all our boost threads. + */ + +static void +async_blocks_ready(uv_work_t *req) { + async_block_ready_data *data = static_cast(req->data); + data->result = std::string(""); + + while(!chainActive.Tip()) { + usleep(1E4); + } + +} + +static void +async_blocks_ready_after(uv_work_t *req) { + Isolate* isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + async_block_ready_data *data = static_cast(req->data); + + Local cb = data->callback.Get(isolate); + if (data->err_msg != "") { + Local err = Exception::Error(NanNew(data->err_msg)); + const unsigned argc = 1; + Local 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 argv[argc] = { + v8::Null(isolate), + Local::New(isolate, NanNew(data->result)) + }; + TryCatch try_catch; + cb->Call(isolate->GetCurrentContext()->Global(), argc, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } + + delete data; + delete req; +} + /** * StartBitcoind() * bitcoind.start(callback) @@ -3499,6 +3592,7 @@ init(Handle target) { NanScope(); NODE_SET_METHOD(target, "start", StartBitcoind); + NODE_SET_METHOD(target, "onBlocksReady", OnBlocksReady); NODE_SET_METHOD(target, "stop", StopBitcoind); NODE_SET_METHOD(target, "stopping", IsStopping); NODE_SET_METHOD(target, "stopped", IsStopped); diff --git a/src/bitcoindjs.h b/src/bitcoindjs.h index ae3cef48..73fc6c7c 100644 --- a/src/bitcoindjs.h +++ b/src/bitcoindjs.h @@ -18,6 +18,7 @@ #include NAN_METHOD(StartBitcoind); +NAN_METHOD(OnBlocksReady); NAN_METHOD(IsStopping); NAN_METHOD(IsStopped); NAN_METHOD(StopBitcoind);