diff --git a/lib/bitcoind.js b/lib/bitcoind.js index 4acc225d..53edd205 100644 --- a/lib/bitcoind.js +++ b/lib/bitcoind.js @@ -905,6 +905,10 @@ Wallet.prototype.isMine = function(options) { return bitcoindjs.walletIsMine(options || {}); }; +Wallet.prototype.rescan = function(options, callback) { + return bitcoindjs.walletRescan(options || {}, callback); +}; + Wallet = new Wallet; /** diff --git a/src/bitcoindjs.cc b/src/bitcoindjs.cc index 35e9c471..238f6d7f 100644 --- a/src/bitcoindjs.cc +++ b/src/bitcoindjs.cc @@ -295,6 +295,7 @@ NAN_METHOD(WalletImportWallet); NAN_METHOD(WalletChangeLabel); NAN_METHOD(WalletDeleteAccount); NAN_METHOD(WalletIsMine); +NAN_METHOD(WalletRescan); /** * Node.js Internal Function Templates @@ -582,6 +583,15 @@ struct async_dump_wallet_data { Persistent callback; }; +/** + * async_rescan_data + */ + +struct async_rescan_data { + std::string err_msg; + Persistent callback; +}; + /** * Read Raw DB */ @@ -5386,6 +5396,80 @@ NAN_METHOD(WalletIsMine) { NanReturnValue(NanNew(is_mine)); } +/** + * WalletRescan() + * bitcoindjs.walletRescan(options, callback) + * Rescan blockchain + */ + +NAN_METHOD(WalletRescan) { + NanScope(); + + if (args.Length() < 2 || !args[0]->IsObject() || !args[1]->IsFunction()) { + return NanThrowError( + "Usage: bitcoindjs.walletRescan(options, callback)"); + } + + async_rescan_data *data = new async_rescan_data(); + + //Local options = Local::Cast(args[0]); + Local callback = Local::Cast(args[1]); + + data->err_msg = std::string(""); + data->callback = Persistent::New(callback); + + uv_work_t *req = new uv_work_t(); + req->data = data; + + int status = uv_queue_work(uv_default_loop(), + req, async_rescan, + (uv_after_work_cb)async_rescan_after); + + assert(status == 0); + + NanReturnValue(Undefined()); +} + +static void +async_rescan(uv_work_t *req) { + async_rescan_data* data = static_cast(req->data); + // This may take a long time, do it on the libuv thread pool: + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); +} + +static void +async_rescan_after(uv_work_t *req) { + NanScope(); + async_rescan_data* data = static_cast(req->data); + + if (data->err_msg != "") { + Local err = Exception::Error(NanNew(data->err_msg)); + const unsigned argc = 1; + Local 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 argv[argc] = { + Local::New(Null()), + Local::New(True()) + }; + 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; +} + /** * Conversions * cblock_to_jsblock(cblock, cblock_index, jsblock, is_new) @@ -6059,6 +6143,7 @@ init(Handle target) { NODE_SET_METHOD(target, "walletChangeLabel", WalletChangeLabel); NODE_SET_METHOD(target, "walletDeleteAccount", WalletDeleteAccount); NODE_SET_METHOD(target, "walletIsMine", WalletIsMine); + NODE_SET_METHOD(target, "walletRescan", WalletRescan); } NODE_MODULE(bitcoindjs, init)