remove packet polling code.
This commit is contained in:
parent
7977247b79
commit
090eb9ab42
167
lib/bitcoind.js
167
lib/bitcoind.js
|
@ -310,30 +310,6 @@ Bitcoin.prototype.start = function(options, callback) {
|
||||||
|
|
||||||
this._emitted = {};
|
this._emitted = {};
|
||||||
|
|
||||||
// this.on('newListener', function(name) {
|
|
||||||
// if (name === 'version' || name === 'peer') {
|
|
||||||
// self._pollPeers();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if (name === 'addr') {
|
|
||||||
// self._pollAddresses();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if (name === 'block') {
|
|
||||||
// self._pollBlocks();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if (name === 'tx') {
|
|
||||||
// self._pollBlocks();
|
|
||||||
// self._pollMempool();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if (name === 'mptx') {
|
|
||||||
// self._pollMempool();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (this.log_pipe !== -1) {
|
if (this.log_pipe !== -1) {
|
||||||
this.log('log pipe opened: %d', this.log_pipe);
|
this.log('log pipe opened: %d', this.log_pipe);
|
||||||
this._pipe = new net.Socket(this.log_pipe);
|
this._pipe = new net.Socket(this.log_pipe);
|
||||||
|
@ -347,149 +323,6 @@ Bitcoin.prototype.start = function(options, callback) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Bitcoin.prototype._pollBlocks = function() {
|
|
||||||
var self = this;
|
|
||||||
if (this._pollingBlocks) return;
|
|
||||||
this._pollingBlocks = true;
|
|
||||||
(function next() {
|
|
||||||
return bitcoindjs.pollBlocks(function(err, blocks) {
|
|
||||||
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) {
|
|
||||||
block = bitcoin.block(block);
|
|
||||||
|
|
||||||
// XXX Bad workaround
|
|
||||||
if (self._emitted[block.hash]) {
|
|
||||||
if (Object.keys(self._emitted[block.hash]).length > 10000) {
|
|
||||||
self._emitted = {};
|
|
||||||
}
|
|
||||||
return setImmediate(function() {
|
|
||||||
return nextBlock();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
self._emitted[block.hash] = true;
|
|
||||||
|
|
||||||
self.emit('block', block);
|
|
||||||
|
|
||||||
if (!self._pollingTxs) {
|
|
||||||
return setImmediate(function() {
|
|
||||||
return nextBlock();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.forEach(block.tx, function(tx, nextTx) {
|
|
||||||
tx = bitcoin.tx(tx);
|
|
||||||
self.emit('tx', tx);
|
|
||||||
return setImmediate(function() {
|
|
||||||
return nextTx();
|
|
||||||
});
|
|
||||||
}, function() {
|
|
||||||
return setImmediate(function() {
|
|
||||||
return nextBlock();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, function() {
|
|
||||||
if (self.debug) {
|
|
||||||
console.log('emission finished');
|
|
||||||
}
|
|
||||||
return setTimeout(next, self.pollInterval);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
};
|
|
||||||
|
|
||||||
Bitcoin.prototype._pollMempool = function() {
|
|
||||||
var self = this;
|
|
||||||
if (this._pollingTxs) return;
|
|
||||||
this._pollingTxs = true;
|
|
||||||
(function next() {
|
|
||||||
return bitcoindjs.pollMempool(function(err, txs) {
|
|
||||||
if (err) return setTimeout(next, self.pollInterval);
|
|
||||||
return utils.forEach(txs, function(tx, nextTx) {
|
|
||||||
tx = bitcoin.tx(tx);
|
|
||||||
|
|
||||||
// XXX Bad workaround
|
|
||||||
if (self._emitted[tx.txid]) {
|
|
||||||
if (Object.keys(self._emitted[block.hash]).length > 10000) {
|
|
||||||
self._emitted = {};
|
|
||||||
}
|
|
||||||
return setImmediate(function() {
|
|
||||||
return nextTx();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
self._emitted[tx.txid] = true;
|
|
||||||
|
|
||||||
self.emit('mptx', tx);
|
|
||||||
self.emit('tx', tx);
|
|
||||||
|
|
||||||
return setImmediate(function() {
|
|
||||||
return nextTx();
|
|
||||||
});
|
|
||||||
}, function() {
|
|
||||||
return setTimeout(next, self.pollInterval);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
};
|
|
||||||
|
|
||||||
// XXX Not perfect - will not catch all version packets.
|
|
||||||
Bitcoin.prototype._pollPeers = function() {
|
|
||||||
var self = this;
|
|
||||||
if (this._pollingPeers) return;
|
|
||||||
this._pollingPeers = true;
|
|
||||||
var lastPeers = bitcoindjs.getPeerInfo();
|
|
||||||
(function next() {
|
|
||||||
var peers = bitcoindjs.getPeerInfo();
|
|
||||||
peers = peers.filter(function(peer, i) {
|
|
||||||
return !lastPeers[i] || peer.addr !== lastPeers[i].addr;
|
|
||||||
});
|
|
||||||
peers.forEach(function(peer) {
|
|
||||||
self.emit('peer', peer);
|
|
||||||
self.emit('version', {
|
|
||||||
version: peer.version,
|
|
||||||
services: peer.services,
|
|
||||||
time: peer.conntime,
|
|
||||||
nonce: null,
|
|
||||||
useragent: peer.subver,
|
|
||||||
startheight: peer.startingheight,
|
|
||||||
relay: null // peer.fRelayTxes
|
|
||||||
});
|
|
||||||
});
|
|
||||||
lastPeers = peers;
|
|
||||||
return setTimeout(next, self.pollInterval);
|
|
||||||
})();
|
|
||||||
};
|
|
||||||
|
|
||||||
Bitcoin.prototype._pollAddresses = function() {
|
|
||||||
var self = this;
|
|
||||||
if (this._pollingAddresses) return;
|
|
||||||
this._pollingAddresses = true;
|
|
||||||
var lastAddrs = bitcoindjs.getAddresses();
|
|
||||||
(function next() {
|
|
||||||
var addrs = bitcoindjs.getAddresses();
|
|
||||||
addrs = addrs.filter(function(addr, i) {
|
|
||||||
return !lastAddrs[i] || addr.time !== lastAddrs[i].time;
|
|
||||||
});
|
|
||||||
addrs.forEach(function(addr) {
|
|
||||||
self.emit('addr', {
|
|
||||||
services: addr.services,
|
|
||||||
time: addr.time,
|
|
||||||
last: addr.last,
|
|
||||||
ip: addr.ip,
|
|
||||||
port: addr.port,
|
|
||||||
address: addr.address
|
|
||||||
});
|
|
||||||
});
|
|
||||||
lastAddrs = addrs;
|
|
||||||
return setTimeout(next, self.pollInterval);
|
|
||||||
})();
|
|
||||||
};
|
|
||||||
|
|
||||||
Bitcoin.prototype.getBlock = function(blockHash, callback) {
|
Bitcoin.prototype.getBlock = function(blockHash, callback) {
|
||||||
return bitcoindjs.getBlock(blockHash, function(err, block) {
|
return bitcoindjs.getBlock(blockHash, function(err, block) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
|
|
|
@ -160,8 +160,6 @@ NAN_METHOD(IsStopped);
|
||||||
NAN_METHOD(StopBitcoind);
|
NAN_METHOD(StopBitcoind);
|
||||||
NAN_METHOD(GetBlock);
|
NAN_METHOD(GetBlock);
|
||||||
NAN_METHOD(GetTx);
|
NAN_METHOD(GetTx);
|
||||||
NAN_METHOD(PollBlocks);
|
|
||||||
NAN_METHOD(PollMempool);
|
|
||||||
NAN_METHOD(BroadcastTx);
|
NAN_METHOD(BroadcastTx);
|
||||||
NAN_METHOD(VerifyBlock);
|
NAN_METHOD(VerifyBlock);
|
||||||
NAN_METHOD(VerifyTransaction);
|
NAN_METHOD(VerifyTransaction);
|
||||||
|
@ -231,18 +229,6 @@ async_get_tx(uv_work_t *req);
|
||||||
static void
|
static void
|
||||||
async_get_tx_after(uv_work_t *req);
|
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);
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_poll_mempool(uv_work_t *req);
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_poll_mempool_after(uv_work_t *req);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
async_broadcast_tx(uv_work_t *req);
|
async_broadcast_tx(uv_work_t *req);
|
||||||
|
|
||||||
|
@ -300,7 +286,6 @@ init(Handle<Object>);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static volatile bool shutdown_complete = false;
|
static volatile bool shutdown_complete = false;
|
||||||
static int block_poll_top_height = -1;
|
|
||||||
static char *g_data_dir = NULL;
|
static char *g_data_dir = NULL;
|
||||||
static bool g_rpc = false;
|
static bool g_rpc = false;
|
||||||
static bool g_testnet = false;
|
static bool g_testnet = false;
|
||||||
|
@ -360,39 +345,6 @@ struct async_tx_data {
|
||||||
Persistent<Function> callback;
|
Persistent<Function> callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* poll_blocks_list
|
|
||||||
* A singly linked list containing any polled CBlocks and CBlockIndexes.
|
|
||||||
* Contained by async_poll_blocks_data struct.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct _poll_blocks_list {
|
|
||||||
CBlock cblock;
|
|
||||||
CBlockIndex *cblock_index;
|
|
||||||
struct _poll_blocks_list *next;
|
|
||||||
} poll_blocks_list;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* async_poll_blocks_data
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct async_poll_blocks_data {
|
|
||||||
std::string err_msg;
|
|
||||||
poll_blocks_list *head;
|
|
||||||
Persistent<Array> result_array;
|
|
||||||
Persistent<Function> callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* async_poll_mempool_data
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct async_poll_mempool_data {
|
|
||||||
std::string err_msg;
|
|
||||||
Persistent<Array> result_array;
|
|
||||||
Persistent<Function> callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* async_broadcast_tx_data
|
* async_broadcast_tx_data
|
||||||
*/
|
*/
|
||||||
|
@ -1010,245 +962,6 @@ async_get_tx_after(uv_work_t *req) {
|
||||||
delete req;
|
delete req;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* PollBlocks()
|
|
||||||
* bitcoind.pollBlocks(callback)
|
|
||||||
* Poll for new blocks on the chain. This is necessary since we have no way of
|
|
||||||
* hooking in to AcceptBlock(). Instead, we constant check for new blocks using
|
|
||||||
* a SetTimeout() within node.js.
|
|
||||||
* Creating a linked list of all blocks within the work function is necessary
|
|
||||||
* due to doing v8 things within the libuv thread pool will cause a segfault.
|
|
||||||
* Since this reads full blocks, obviously it will poll for transactions which
|
|
||||||
* have already been included in blocks as well.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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->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);
|
|
||||||
|
|
||||||
int poll_saved_height = block_poll_top_height;
|
|
||||||
|
|
||||||
// Poll, wait until we actually have a blockchain download.
|
|
||||||
// Once we've noticed the height changed, assume we gained a few blocks.
|
|
||||||
while (chainActive.Tip()) {
|
|
||||||
int cur_height = chainActive.Height();
|
|
||||||
if (cur_height != block_poll_top_height) {
|
|
||||||
block_poll_top_height = cur_height;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Try again in 100ms
|
|
||||||
useconds_t usec = 100 * 1000;
|
|
||||||
usleep(usec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Since we can't do v8 stuff on the uv thread pool, we need to create
|
|
||||||
// a linked list for all the blocks and free them up later.
|
|
||||||
poll_blocks_list *head = NULL;
|
|
||||||
poll_blocks_list *cur = NULL;
|
|
||||||
|
|
||||||
for (int i = poll_saved_height; i < block_poll_top_height; i++) {
|
|
||||||
if (i == -1) continue;
|
|
||||||
CBlockIndex *cblock_index = chainActive[i];
|
|
||||||
if (cblock_index != NULL) {
|
|
||||||
CBlock cblock;
|
|
||||||
if (ReadBlockFromDisk(cblock, cblock_index)) {
|
|
||||||
poll_blocks_list *next = new poll_blocks_list();
|
|
||||||
next->next = NULL;
|
|
||||||
if (cur == NULL) {
|
|
||||||
head = next;
|
|
||||||
cur = next;
|
|
||||||
} else {
|
|
||||||
cur->next = next;
|
|
||||||
cur = next;
|
|
||||||
}
|
|
||||||
cur->cblock = cblock;
|
|
||||||
cur->cblock_index = cblock_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data->head = head;
|
|
||||||
}
|
|
||||||
|
|
||||||
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>();
|
|
||||||
|
|
||||||
poll_blocks_list *cur = static_cast<poll_blocks_list*>(data->head);
|
|
||||||
poll_blocks_list *next;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (cur != NULL) {
|
|
||||||
CBlock cblock = cur->cblock;
|
|
||||||
CBlockIndex *cblock_index = cur->cblock_index;
|
|
||||||
Local<Object> jsblock = NanNew<Object>();
|
|
||||||
cblock_to_jsblock(cblock, cblock_index, jsblock);
|
|
||||||
blocks->Set(i, jsblock);
|
|
||||||
i++;
|
|
||||||
next = cur->next;
|
|
||||||
delete cur;
|
|
||||||
cur = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PollMempool()
|
|
||||||
* bitcoind.pollMempool(callback)
|
|
||||||
* This will poll for any transactions in the mempool. i.e. Transactions which
|
|
||||||
* have not been included in blocks yet. This is not technically necessary to
|
|
||||||
* be done asynchronously since there are no real blocking calls done here, but
|
|
||||||
* we will leave the async function here as a placeholder in case we're wrong.
|
|
||||||
*/
|
|
||||||
|
|
||||||
NAN_METHOD(PollMempool) {
|
|
||||||
NanScope();
|
|
||||||
|
|
||||||
if (args.Length() < 1 || !args[0]->IsFunction()) {
|
|
||||||
return NanThrowError(
|
|
||||||
"Usage: bitcoindjs.pollMempool(callback)");
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Function> callback = Local<Function>::Cast(args[0]);
|
|
||||||
|
|
||||||
async_poll_mempool_data *data = new async_poll_mempool_data();
|
|
||||||
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_mempool,
|
|
||||||
(uv_after_work_cb)async_poll_mempool_after);
|
|
||||||
|
|
||||||
assert(status == 0);
|
|
||||||
|
|
||||||
NanReturnValue(Undefined());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_poll_mempool(uv_work_t *req) {
|
|
||||||
// XXX Potentially do everything async, but would it matter? Everything is in
|
|
||||||
// memory. There aren't really any harsh blocking calls. Leave this here as a
|
|
||||||
// placeholder.
|
|
||||||
useconds_t usec = 5 * 1000;
|
|
||||||
usleep(usec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
async_poll_mempool_after(uv_work_t *req) {
|
|
||||||
NanScope();
|
|
||||||
async_poll_mempool_data* data = static_cast<async_poll_mempool_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 {
|
|
||||||
int ti = 0;
|
|
||||||
Local<Array> txs = NanNew<Array>();
|
|
||||||
|
|
||||||
{
|
|
||||||
std::map<uint256, CTxMemPoolEntry>::const_iterator it = mempool.mapTx.begin();
|
|
||||||
for (; it != mempool.mapTx.end(); it++) {
|
|
||||||
const CTransaction& ctx = it->second.GetTx();
|
|
||||||
Local<Object> jstx = NanNew<Object>();
|
|
||||||
ctx_to_jstx(ctx, 0, jstx);
|
|
||||||
txs->Set(ti, jstx);
|
|
||||||
ti++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::map<COutPoint, CInPoint>::const_iterator it = mempool.mapNextTx.begin();
|
|
||||||
for (; it != mempool.mapNextTx.end(); it++) {
|
|
||||||
const CTransaction ctx = *it->second.ptx;
|
|
||||||
Local<Object> jstx = NanNew<Object>();
|
|
||||||
ctx_to_jstx(ctx, 0, jstx);
|
|
||||||
txs->Set(ti, jstx);
|
|
||||||
ti++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned argc = 2;
|
|
||||||
Local<Value> argv[argc] = {
|
|
||||||
Local<Value>::New(Null()),
|
|
||||||
Local<Value>::New(txs)
|
|
||||||
};
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BroadcastTx()
|
* BroadcastTx()
|
||||||
* bitcoind.broadcastTx(tx, override_fees, own_only, callback)
|
* bitcoind.broadcastTx(tx, override_fees, own_only, callback)
|
||||||
|
@ -3964,8 +3677,6 @@ init(Handle<Object> target) {
|
||||||
NODE_SET_METHOD(target, "stopped", IsStopped);
|
NODE_SET_METHOD(target, "stopped", IsStopped);
|
||||||
NODE_SET_METHOD(target, "getBlock", GetBlock);
|
NODE_SET_METHOD(target, "getBlock", GetBlock);
|
||||||
NODE_SET_METHOD(target, "getTx", GetTx);
|
NODE_SET_METHOD(target, "getTx", GetTx);
|
||||||
NODE_SET_METHOD(target, "pollBlocks", PollBlocks);
|
|
||||||
NODE_SET_METHOD(target, "pollMempool", PollMempool);
|
|
||||||
NODE_SET_METHOD(target, "broadcastTx", BroadcastTx);
|
NODE_SET_METHOD(target, "broadcastTx", BroadcastTx);
|
||||||
NODE_SET_METHOD(target, "verifyBlock", VerifyBlock);
|
NODE_SET_METHOD(target, "verifyBlock", VerifyBlock);
|
||||||
NODE_SET_METHOD(target, "verifyTransaction", VerifyTransaction);
|
NODE_SET_METHOD(target, "verifyTransaction", VerifyTransaction);
|
||||||
|
|
Loading…
Reference in New Issue