Merge #10208: [wallet] Rescan abortability
9141622
[rpc] Add abortrescan command to RPC interface. (Kalle Alm)75a08e7
[wallet] Add support for aborting wallet transaction rescans. (Kalle Alm) Tree-SHA512: 18545a1dc48c6dc112993f971f3adc7c0341fa621186c6d70bef1052e1d127ca116c5769595d721a209d502ca2019f2ad33876fe35d2b17216393404607a6c76
This commit is contained in:
commit
393160cf6c
4 changed files with 46 additions and 1 deletions
|
@ -156,6 +156,31 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniValue abortrescan(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 CBitcoinAddress& address, const std::string& strLabel);
|
void ImportAddress(CWallet*, const CBitcoinAddress& address, const std::string& strLabel);
|
||||||
void ImportScript(CWallet* const pwallet, const CScript& script, const std::string& strLabel, bool isRedeemScript)
|
void ImportScript(CWallet* const pwallet, const CScript& script, const std::string& strLabel, bool isRedeemScript)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2914,6 +2914,7 @@ UniValue bumpfee(const JSONRPCRequest& request)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
|
||||||
extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
|
extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
|
||||||
extern UniValue importprivkey(const JSONRPCRequest& request);
|
extern UniValue importprivkey(const JSONRPCRequest& request);
|
||||||
extern UniValue importaddress(const JSONRPCRequest& request);
|
extern UniValue importaddress(const JSONRPCRequest& request);
|
||||||
|
@ -2930,6 +2931,7 @@ static const CRPCCommand commands[] =
|
||||||
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false, {"hexstring","options"} },
|
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false, {"hexstring","options"} },
|
||||||
{ "hidden", "resendwallettransactions", &resendwallettransactions, true, {} },
|
{ "hidden", "resendwallettransactions", &resendwallettransactions, true, {} },
|
||||||
{ "wallet", "abandontransaction", &abandontransaction, false, {"txid"} },
|
{ "wallet", "abandontransaction", &abandontransaction, false, {"txid"} },
|
||||||
|
{ "wallet", "abortrescan", &abortrescan, false, {} },
|
||||||
{ "wallet", "addmultisigaddress", &addmultisigaddress, true, {"nrequired","keys","account"} },
|
{ "wallet", "addmultisigaddress", &addmultisigaddress, true, {"nrequired","keys","account"} },
|
||||||
{ "wallet", "addwitnessaddress", &addwitnessaddress, true, {"address"} },
|
{ "wallet", "addwitnessaddress", &addwitnessaddress, true, {"address"} },
|
||||||
{ "wallet", "backupwallet", &backupwallet, true, {"destination"} },
|
{ "wallet", "backupwallet", &backupwallet, true, {"destination"} },
|
||||||
|
|
|
@ -1554,6 +1554,8 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool f
|
||||||
CBlockIndex* pindex = pindexStart;
|
CBlockIndex* pindex = pindexStart;
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
|
fAbortRescan = false;
|
||||||
|
fScanningWallet = true;
|
||||||
|
|
||||||
// no need to read and scan block, if block was created before
|
// no need to read and scan block, if block was created before
|
||||||
// our wallet birthday (as adjusted for block time variability)
|
// our wallet birthday (as adjusted for block time variability)
|
||||||
|
@ -1563,7 +1565,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool f
|
||||||
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
|
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
|
||||||
double dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex);
|
double dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex);
|
||||||
double dProgressTip = GuessVerificationProgress(chainParams.TxData(), chainActive.Tip());
|
double dProgressTip = GuessVerificationProgress(chainParams.TxData(), chainActive.Tip());
|
||||||
while (pindex)
|
while (pindex && !fAbortRescan)
|
||||||
{
|
{
|
||||||
if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
|
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))));
|
ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((GuessVerificationProgress(chainParams.TxData(), pindex) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
|
||||||
|
@ -1585,7 +1587,12 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool f
|
||||||
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
|
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pindex && fAbortRescan) {
|
||||||
|
LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
|
||||||
|
}
|
||||||
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
|
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
|
||||||
|
|
||||||
|
fScanningWallet = false;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -651,6 +651,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static std::atomic<bool> fFlushScheduled;
|
static std::atomic<bool> fFlushScheduled;
|
||||||
|
std::atomic<bool> fAbortRescan;
|
||||||
|
std::atomic<bool> fScanningWallet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select a set of coins such that nValueRet >= nTargetValue and at least
|
* Select a set of coins such that nValueRet >= nTargetValue and at least
|
||||||
|
@ -779,6 +781,8 @@ public:
|
||||||
nTimeFirstKey = 0;
|
nTimeFirstKey = 0;
|
||||||
fBroadcastTransactions = false;
|
fBroadcastTransactions = false;
|
||||||
nRelockTime = 0;
|
nRelockTime = 0;
|
||||||
|
fAbortRescan = false;
|
||||||
|
fScanningWallet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint256, CWalletTx> mapWallet;
|
std::map<uint256, CWalletTx> mapWallet;
|
||||||
|
@ -823,6 +827,13 @@ public:
|
||||||
void UnlockAllCoins();
|
void UnlockAllCoins();
|
||||||
void ListLockedCoins(std::vector<COutPoint>& vOutpts);
|
void ListLockedCoins(std::vector<COutPoint>& vOutpts);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rescan abort properties
|
||||||
|
*/
|
||||||
|
void AbortRescan() { fAbortRescan = true; }
|
||||||
|
bool IsAbortingRescan() { return fAbortRescan; }
|
||||||
|
bool IsScanning() { return fScanningWallet; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* keystore implementation
|
* keystore implementation
|
||||||
* Generate a new key
|
* Generate a new key
|
||||||
|
|
Loading…
Reference in a new issue