From f1fde6ee40ecac9fbcc7ad135f632c1fba5b8b68 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Sep 2014 17:58:59 -0700 Subject: [PATCH] emit block events. --- example/index.js | 3 +- lib/bitcoind.js | 15 ++--- src/bitcoindjs.cc | 140 ++++++++++++++++------------------------------ 3 files changed, 57 insertions(+), 101 deletions(-) diff --git a/example/index.js b/example/index.js index 3e3930c0..0d894e90 100755 --- a/example/index.js +++ b/example/index.js @@ -16,8 +16,7 @@ bitcoind.start(function(err) { console.log('bitcoind: status="%s"', status); // getBlocks(bitcoind); bitcoind.on('block', function(block) { - console.log('Found block'); - console.log('Next: %s', block.nextblockhash); + console.log('Found block: %j', block); }); }); }); diff --git a/lib/bitcoind.js b/lib/bitcoind.js index 16beac21..43b076f9 100644 --- a/lib/bitcoind.js +++ b/lib/bitcoind.js @@ -128,13 +128,14 @@ Bitcoin.prototype.start = function(callback) { } }, 1000); - bitcoindjs.onBlock(function(block) { - self.emit('block', block); - }); - - bitcoindjs.onTx(function(tx) { - self.emit('tx', tx); - }); + (function next() { + bitcoindjs.pollBlocks(function(err, blocks) { + blocks.forEach(function(block) { + self.emit('block', block); + }); + setTimeout(next, 1000); + }); + })(); if (this.log_pipe !== -1) { this.log('log pipe opened: %d', this.log_pipe); diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index 40b3906b..108fedc8 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -123,8 +123,7 @@ NAN_METHOD(IsStopped); NAN_METHOD(StopBitcoind); NAN_METHOD(GetBlock); NAN_METHOD(GetTx); -NAN_METHOD(OnBlock); -NAN_METHOD(OnTx); +NAN_METHOD(PollBlocks); static void async_start_node_work(uv_work_t *req); @@ -144,9 +143,6 @@ start_node(void); static void start_node_thread(void); -static void -poll_blocks(void); - #if OUTPUT_REDIR static void open_pipes(int **out_pipe, int **log_pipe); @@ -173,6 +169,12 @@ async_get_tx(uv_work_t *req); static void async_get_tx_after(uv_work_t *req); +static void +async_poll_blocks(uv_work_t *req); + +static void +async_poll_blocks_after(uv_work_t *req); + extern "C" void init(Handle); @@ -180,8 +182,6 @@ init(Handle); * Private Variables */ -static volatile CBlockIndex *lastindex = NULL; - static volatile bool shutdownComplete = false; /** @@ -238,6 +238,9 @@ struct async_tx_data { struct async_poll_blocks_data { std::string err_msg; + uint256 poll_last_hash; + CBlockIndex *poll_last_index; + CBlockIndex *poll_prev_index; Persistent result_array; Persistent callback; }; @@ -397,8 +400,6 @@ start_node(void) { (boost::thread *)new boost::thread(boost::bind(&start_node_thread)); - (boost::thread *)new boost::thread(boost::bind(&poll_blocks)); - // horrible fix for a race condition sleep(2); signal(SIGINT, SIG_DFL); @@ -1098,45 +1099,10 @@ async_get_tx_after(uv_work_t *req) { } /** - * OnBlock(callback) - * bitcoind.onBlock(callback) + * PollBlocks(callback) + * bitcoind.pollBlocks(callback) */ -Persistent onBlockCb; -static bool blockCbSet = false; - -NAN_METHOD(OnBlock) { - NanScope(); - - if (args.Length() < 1 || !args[0]->IsFunction()) { - return NanThrowError( - "Usage: bitcoindjs.onBlock(callback)"); - } - - Local callback = Local::Cast(args[0]); - - onBlockCb = Persistent::New(callback); - blockCbSet = true; - -#if 0 - Persistent cb; - cb = Persistent::New(callback); - Local block = NanNew(); - - const unsigned argc = 1; - Local argv[argc] = { - Local::New(block) - }; - TryCatch try_catch; - cb->Call(Context::GetCurrent()->Global(), argc, argv); - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } -#endif - - NanReturnValue(Undefined()); -} - NAN_METHOD(PollBlocks) { NanScope(); @@ -1147,13 +1113,10 @@ NAN_METHOD(PollBlocks) { Local callback = Local::Cast(args[0]); - - String::Utf8Value hash(args[0]->ToString()); - Local callback = Local::Cast(args[1]); - - std::string hashp = std::string(*hash); - async_poll_blocks_data *data = new async_poll_blocks_data(); + data->poll_last_hash = 0; + data->poll_last_index = NULL; + data->poll_prev_index = NULL; data->err_msg = std::string(""); data->callback = Persistent::New(callback); @@ -1173,11 +1136,14 @@ static void async_poll_blocks(uv_work_t *req) { async_poll_blocks_data* data = static_cast(req->data); - while (chainActive.Tip()) { - uint256 cur = chainActive.Tip()->GetBlockHash(); - if (cur != poll_lasthash) { - printf("Found block\n"); - poll_lasthash = cur; + data->poll_prev_index = data->poll_last_index; + CBlockIndex *cur_index; + + while ((cur_index = chainActive.Tip())) { + uint256 cur_hash = cur_index->GetBlockHash(); + if (cur_hash != data->poll_last_hash) { + data->poll_last_hash = cur_hash; + data->poll_last_index = cur_index; sleep(1); } else { break; @@ -1201,9 +1167,32 @@ async_poll_blocks_after(uv_work_t *req) { } } else { const unsigned argc = 2; + Local blocks = NanNew(); + + CBlockIndex *pnext = data->poll_prev_index; + + if (!pnext) { + if (data->poll_last_index) { + CBlock block; + if (ReadBlockFromDisk(block, data->poll_last_index)) { + blocks->Set(0, NanNew(block.GetHash().GetHex().c_str())); + } + } + } else { + int i = 0; + do { + CBlock block; + if (ReadBlockFromDisk(block, pnext)) { + blocks->Set(i, NanNew(block.GetHash().GetHex().c_str())); + i++; + } + if (pnext == data->poll_last_index) break; + } while ((pnext = chainActive.Next((const CBlockIndex *)pnext))); + } + Local argv[argc] = { Local::New(Null()), - Local::New(entry) + Local::New(blocks) }; TryCatch try_catch; data->callback->Call(Context::GetCurrent()->Global(), argc, argv); @@ -1218,38 +1207,6 @@ async_poll_blocks_after(uv_work_t *req) { delete req; } -uint256 poll_lasthash = 0; - -static void -poll_blocks(void) { - for (;;) { - while (chainActive.Tip()) { - uint256 cur = chainActive.Tip()->GetBlockHash(); - if (cur != poll_lasthash) { - printf("Found block\n"); -#if 0 - if (blockCbSet) { - Local block = NanNew(); - block->Set(NanNew("hash"), NanNew(cur.GetHex().c_str())); - const unsigned argc = 1; - Local argv[argc] = { - Local::New(block) - }; - TryCatch try_catch; - onBlockCb->Call(Context::GetCurrent()->Global(), argc, argv); - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } -#endif - poll_lasthash = cur; - } - sleep(1); - } - sleep(1); - } -} - /** * Init */ @@ -1263,8 +1220,7 @@ init(Handle target) { NODE_SET_METHOD(target, "stopped", IsStopped); NODE_SET_METHOD(target, "getBlock", GetBlock); NODE_SET_METHOD(target, "getTx", GetTx); - NODE_SET_METHOD(target, "onBlock", OnBlock); - NODE_SET_METHOD(target, "onTx", OnTx); + NODE_SET_METHOD(target, "pollBlocks", PollBlocks); } NODE_MODULE(bitcoindjs, init)