diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -3,4 +3,5 @@
This release includes the following features and fixes:
+ - Backport abortrescan RPC call from bitcoin core.
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -168,6 +168,33 @@
return NullUniValue;
}
+UniValue abortrescan(const Config &config, const JSONRPCRequest &request) {
+ CWallet *const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
+ return NullUniValue;
+ }
+
+ if (request.fHelp || request.params.size() > 0) {
+ throw std::runtime_error("abortrescan\n"
+ "\nStops current wallet rescan triggered e.g. "
+ "by an importprivkey call.\n"
+ "\nExamples:\n"
+ "\nImport a private key\n" +
+ HelpExampleCli("importprivkey", "\"mykey\"") +
+ "\nAbort the running wallet rescan\n" +
+ HelpExampleCli("abortrescan", "") +
+ "\nAs a JSON-RPC call\n" +
+ HelpExampleRpc("abortrescan", ""));
+ }
+
+ if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) {
+ return false;
+ }
+
+ pwallet->AbortRescan();
+ return true;
+}
+
void ImportAddress(CWallet *, const CTxDestination &dest,
const std::string &strLabel);
void ImportScript(CWallet *const pwallet, const CScript &script,
@@ -1351,6 +1378,7 @@
static const ContextFreeRPCCommand commands[] = {
// category name actor (function) okSafeMode
// ------------------- ------------------------ ---------------------- ----------
+ { "wallet", "abortrescan", abortrescan, false, {} },
{ "wallet", "dumpprivkey", dumpprivkey, true, {"address"} },
{ "wallet", "dumpwallet", dumpwallet, true, {"filename"} },
{ "wallet", "importmulti", importmulti, true, {"requests","options"} },
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -594,6 +594,8 @@
class CWallet final : public CCryptoKeyStore, public CValidationInterface {
private:
static std::atomic fFlushScheduled;
+ std::atomic fAbortRescan;
+ std::atomic fScanningWallet;
/**
* Select a set of coins such that nValueRet >= nTargetValue and at least
@@ -737,6 +739,8 @@
m_max_keypool_index = 0;
nTimeFirstKey = 0;
fBroadcastTransactions = false;
+ fAbortRescan = false;
+ fScanningWallet = false;
}
std::map mapWallet;
@@ -790,6 +794,13 @@
void UnlockAllCoins();
void ListLockedCoins(std::vector &vOutpts);
+ /*
+ * Rescan abort properties
+ */
+ void AbortRescan() { fAbortRescan = true; }
+ bool IsAbortingRescan() { return fAbortRescan; }
+ bool IsScanning() { return fScanningWallet; }
+
/**
* keystore implementation
* Generate a new key
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1712,6 +1712,8 @@
CBlockIndex *ret = nullptr;
LOCK2(cs_main, cs_wallet);
+ fAbortRescan = false;
+ fScanningWallet = true;
// No need to read and scan block, if block was created before our wallet
// birthday (as adjusted for block time variability)
@@ -1727,16 +1729,16 @@
GuessVerificationProgress(chainParams.TxData(), pindex);
double dProgressTip =
GuessVerificationProgress(chainParams.TxData(), chainActive.Tip());
- while (pindex) {
+ while (pindex && !fAbortRescan) {
if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0) {
ShowProgress(
_("Rescanning..."),
- std::max(1,
- std::min(99, (int)((GuessVerificationProgress(
- chainParams.TxData(), pindex) -
- dProgressStart) /
- (dProgressTip - dProgressStart) *
- 100))));
+ std::max(1, std::min(99,
+ (GuessVerificationProgress(
+ chainParams.TxData(), pindex) -
+ dProgressStart) /
+ (dProgressTip - dProgressStart) *
+ 100)));
}
CBlock block;
@@ -1759,8 +1761,14 @@
}
}
+ if (pindex && fAbortRescan) {
+ LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight,
+ GuessVerificationProgress(chainParams.TxData(), pindex));
+ }
+
// Hide progress dialog in GUI.
ShowProgress(_("Rescanning..."), 100);
+ fScanningWallet = false;
return ret;
}