fix block polling and emitting blocks.
This commit is contained in:
parent
ffc26d93e7
commit
932d0fd1a0
@ -211,7 +211,13 @@ Bitcoin.prototype._pollBlocks = function() {
|
|||||||
this._pollingBlocks = true;
|
this._pollingBlocks = true;
|
||||||
(function next() {
|
(function next() {
|
||||||
return bitcoindjs.pollBlocks(function(err, blocks) {
|
return bitcoindjs.pollBlocks(function(err, blocks) {
|
||||||
if (err) return setTimeout(next, self.pollInterval);
|
if (err) {
|
||||||
|
if (self.debug) {
|
||||||
|
console.log('poll error:');
|
||||||
|
console.log(err.message);
|
||||||
|
}
|
||||||
|
return setTimeout(next, self.pollInterval);
|
||||||
|
}
|
||||||
return utils.forEach(blocks, function(block, nextBlock) {
|
return utils.forEach(blocks, function(block, nextBlock) {
|
||||||
block = bitcoin.block(block);
|
block = bitcoin.block(block);
|
||||||
|
|
||||||
@ -225,6 +231,12 @@ Bitcoin.prototype._pollBlocks = function() {
|
|||||||
|
|
||||||
self.emit('block', block);
|
self.emit('block', block);
|
||||||
|
|
||||||
|
if (!self._pollingTxs) {
|
||||||
|
return setImmediate(function() {
|
||||||
|
return nextBlock();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return utils.forEach(block.tx, function(tx, nextTx) {
|
return utils.forEach(block.tx, function(tx, nextTx) {
|
||||||
tx = bitcoin.tx(tx);
|
tx = bitcoin.tx(tx);
|
||||||
self.emit('tx', tx);
|
self.emit('tx', tx);
|
||||||
@ -237,6 +249,9 @@ Bitcoin.prototype._pollBlocks = function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, function() {
|
}, function() {
|
||||||
|
if (self.debug) {
|
||||||
|
console.log('emission finished');
|
||||||
|
}
|
||||||
return setTimeout(next, self.pollInterval);
|
return setTimeout(next, self.pollInterval);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -245,8 +260,8 @@ Bitcoin.prototype._pollBlocks = function() {
|
|||||||
|
|
||||||
Bitcoin.prototype._pollMempool = function() {
|
Bitcoin.prototype._pollMempool = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (this._pollingMempool) return;
|
if (this._pollingTxs) return;
|
||||||
this._pollingMempool = true;
|
this._pollingTxs = true;
|
||||||
(function next() {
|
(function next() {
|
||||||
return bitcoindjs.pollMempool(function(err, txs) {
|
return bitcoindjs.pollMempool(function(err, txs) {
|
||||||
if (err) return setTimeout(next, self.pollInterval);
|
if (err) return setTimeout(next, self.pollInterval);
|
||||||
@ -360,7 +375,6 @@ Block.isBlock = function(block) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: Could just call tx.GetHash().ToString() in C++
|
// NOTE: Could just call tx.GetHash().ToString() in C++
|
||||||
Block.prototype.hash =
|
|
||||||
Block.prototype.getHash = function(enc) {
|
Block.prototype.getHash = function(enc) {
|
||||||
if (!this._hash) {
|
if (!this._hash) {
|
||||||
this._hash = utils.dsha256(this.rawHeader(), 'hex');
|
this._hash = utils.dsha256(this.rawHeader(), 'hex');
|
||||||
|
|||||||
@ -250,6 +250,7 @@ init(Handle<Object>);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static volatile bool shutdownComplete = false;
|
static volatile bool shutdownComplete = false;
|
||||||
|
static int block_poll_top_height = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* async_node_data
|
* async_node_data
|
||||||
@ -299,8 +300,6 @@ typedef struct _poll_blocks_list {
|
|||||||
struct async_poll_blocks_data {
|
struct async_poll_blocks_data {
|
||||||
std::string err_msg;
|
std::string err_msg;
|
||||||
poll_blocks_list *head;
|
poll_blocks_list *head;
|
||||||
int poll_saved_height;
|
|
||||||
int poll_top_height;
|
|
||||||
Persistent<Array> result_array;
|
Persistent<Array> result_array;
|
||||||
Persistent<Function> callback;
|
Persistent<Function> callback;
|
||||||
};
|
};
|
||||||
@ -311,8 +310,6 @@ struct async_poll_blocks_data {
|
|||||||
|
|
||||||
struct async_poll_mempool_data {
|
struct async_poll_mempool_data {
|
||||||
std::string err_msg;
|
std::string err_msg;
|
||||||
int poll_saved_height;
|
|
||||||
int poll_top_height;
|
|
||||||
Persistent<Array> result_array;
|
Persistent<Array> result_array;
|
||||||
Persistent<Function> callback;
|
Persistent<Function> callback;
|
||||||
};
|
};
|
||||||
@ -831,8 +828,6 @@ async_get_tx_after(uv_work_t *req) {
|
|||||||
* bitcoind.pollBlocks(callback)
|
* bitcoind.pollBlocks(callback)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int block_poll_top_height = -1;
|
|
||||||
|
|
||||||
NAN_METHOD(PollBlocks) {
|
NAN_METHOD(PollBlocks) {
|
||||||
NanScope();
|
NanScope();
|
||||||
|
|
||||||
@ -933,7 +928,6 @@ async_poll_blocks_after(uv_work_t *req) {
|
|||||||
blocks->Set(i, obj);
|
blocks->Set(i, obj);
|
||||||
i++;
|
i++;
|
||||||
next = cur->next;
|
next = cur->next;
|
||||||
//free(cur);
|
|
||||||
delete cur;
|
delete cur;
|
||||||
cur = next;
|
cur = next;
|
||||||
}
|
}
|
||||||
@ -955,113 +949,6 @@ async_poll_blocks_after(uv_work_t *req) {
|
|||||||
delete req;
|
delete req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PollBlocks
|
|
||||||
* bitcoind.pollBlocks(callback)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
NAN_METHOD(PollBlocks) {
|
|
||||||
NanScope();
|
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsFunction()) {
|
|
||||||
return NanThrowError(
|
|
||||||
"Usage: bitcoindjs.pollBlocks(callback)");
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Function> callback = Local<Function>::Cast(args[0]);
|
|
||||||
|
|
||||||
async_poll_blocks_data *data = new async_poll_blocks_data();
|
|
||||||
data->poll_saved_height = -1;
|
|
||||||
data->poll_top_height = -1;
|
|
||||||
data->err_msg = std::string("");
|
|
||||||
data->callback = Persistent<Function>::New(callback);
|
|
||||||
|
|
||||||
uv_work_t *req = new uv_work_t();
|
|
||||||
req->data = data;
|
|
||||||
|
|
||||||
int status = uv_queue_work(uv_default_loop(),
|
|
||||||
req, async_poll_blocks,
|
|
||||||
(uv_after_work_cb)async_poll_blocks_after);
|
|
||||||
|
|
||||||
assert(status == 0);
|
|
||||||
|
|
||||||
NanReturnValue(Undefined());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_poll_blocks(uv_work_t *req) {
|
|
||||||
async_poll_blocks_data* data = static_cast<async_poll_blocks_data*>(req->data);
|
|
||||||
|
|
||||||
data->poll_saved_height = data->poll_top_height;
|
|
||||||
|
|
||||||
while (chainActive.Tip()) {
|
|
||||||
int cur_height = chainActive.Height();
|
|
||||||
if (cur_height != data->poll_top_height) {
|
|
||||||
data->poll_top_height = cur_height;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// 100 milliseconds
|
|
||||||
useconds_t usec = 100 * 1000;
|
|
||||||
usleep(usec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_poll_blocks_after(uv_work_t *req) {
|
|
||||||
NanScope();
|
|
||||||
async_poll_blocks_data* data = static_cast<async_poll_blocks_data*>(req->data);
|
|
||||||
|
|
||||||
if (!data->err_msg.empty()) {
|
|
||||||
Local<Value> err = Exception::Error(String::New(data->err_msg.c_str()));
|
|
||||||
const unsigned argc = 1;
|
|
||||||
Local<Value> argv[argc] = { err };
|
|
||||||
TryCatch try_catch;
|
|
||||||
data->callback->Call(Context::GetCurrent()->Global(), argc, argv);
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
node::FatalException(try_catch);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const unsigned argc = 2;
|
|
||||||
Local<Array> blocks = NanNew<Array>();
|
|
||||||
|
|
||||||
for (int i = data->poll_saved_height, j = 0; i < data->poll_top_height; i++) {
|
|
||||||
if (i == -1) continue;
|
|
||||||
CBlockIndex *pindex = chainActive[i];
|
|
||||||
if (pindex != NULL) {
|
|
||||||
CBlock block;
|
|
||||||
// XXX Move this to async_poll_blocks!
|
|
||||||
if (ReadBlockFromDisk(block, pindex)) {
|
|
||||||
Local<Object> obj = NanNew<Object>();
|
|
||||||
cblock_to_jsblock(block, pindex, obj);
|
|
||||||
blocks->Set(j, obj);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Value> argv[argc] = {
|
|
||||||
Local<Value>::New(Null()),
|
|
||||||
Local<Value>::New(blocks)
|
|
||||||
};
|
|
||||||
TryCatch try_catch;
|
|
||||||
data->callback->Call(Context::GetCurrent()->Global(), argc, argv);
|
|
||||||
if (try_catch.HasCaught()) {
|
|
||||||
node::FatalException(try_catch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data->callback.Dispose();
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
delete req;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PollMempool
|
* PollMempool
|
||||||
* bitcoind.pollMempool(callback)
|
* bitcoind.pollMempool(callback)
|
||||||
@ -1078,8 +965,6 @@ NAN_METHOD(PollMempool) {
|
|||||||
Local<Function> callback = Local<Function>::Cast(args[0]);
|
Local<Function> callback = Local<Function>::Cast(args[0]);
|
||||||
|
|
||||||
async_poll_mempool_data *data = new async_poll_mempool_data();
|
async_poll_mempool_data *data = new async_poll_mempool_data();
|
||||||
data->poll_saved_height = -1;
|
|
||||||
data->poll_top_height = -1;
|
|
||||||
data->err_msg = std::string("");
|
data->err_msg = std::string("");
|
||||||
data->callback = Persistent<Function>::New(callback);
|
data->callback = Persistent<Function>::New(callback);
|
||||||
|
|
||||||
@ -1097,9 +982,10 @@ NAN_METHOD(PollMempool) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
async_poll_mempool(uv_work_t *req) {
|
async_poll_mempool(uv_work_t *req) {
|
||||||
// async_poll_blocks_data* data = static_cast<async_poll_blocks_data*>(req->data);
|
// XXX Potentially do everything async, but would it matter? Everything is in
|
||||||
// Nothing really async to do here. It's all in memory. Placeholder for now.
|
// memory. There aren't really any harsh blocking calls. Leave this here as a
|
||||||
useconds_t usec = 20 * 1000;
|
// placeholder.
|
||||||
|
useconds_t usec = 5 * 1000;
|
||||||
usleep(usec);
|
usleep(usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user