aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/rpcwallet.cpp
diff options
context:
space:
mode:
authorJonas Schnelli <dev@jonasschnelli.ch>2017-09-07 16:29:59 -0700
committerJonas Schnelli <dev@jonasschnelli.ch>2018-01-23 20:22:33 -1000
commit8d0b610fe8d0916404aa9158c525b80b1c581c0e (patch)
tree7a6c2475b238cd1ee809bb2bf6fd98a52088adc7 /src/wallet/rpcwallet.cpp
parent0910cbe4ef31eb95fd76c7c2f820419fe64a3150 (diff)
downloadbitcoin-8d0b610fe8d0916404aa9158c525b80b1c581c0e.tar.xz
Avoid pemanent cs_main/cs_wallet lock during wallet rescans
Diffstat (limited to 'src/wallet/rpcwallet.cpp')
-rw-r--r--src/wallet/rpcwallet.cpp43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index e307623fd5..bc0d544aab 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -3398,30 +3398,40 @@ UniValue rescanblockchain(const JSONRPCRequest& request)
);
}
- LOCK2(cs_main, pwallet->cs_wallet);
+ if (pwallet->IsScanning()) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
+ }
- CBlockIndex *pindexStart = chainActive.Genesis();
+ CBlockIndex *pindexStart = nullptr;
CBlockIndex *pindexStop = nullptr;
- if (!request.params[0].isNull()) {
- pindexStart = chainActive[request.params[0].get_int()];
- if (!pindexStart) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid start_height");
- }
- }
+ CBlockIndex *pChainTip = nullptr;
+ {
+ LOCK(cs_main);
+ pindexStart = chainActive.Genesis();
+ pChainTip = chainActive.Tip();
- if (!request.params[1].isNull()) {
- pindexStop = chainActive[request.params[1].get_int()];
- if (!pindexStop) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid stop_height");
+ if (!request.params[0].isNull()) {
+ pindexStart = chainActive[request.params[0].get_int()];
+ if (!pindexStart) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid start_height");
+ }
}
- else if (pindexStop->nHeight < pindexStart->nHeight) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "stop_height must be greater then start_height");
+
+ if (!request.params[1].isNull()) {
+ pindexStop = chainActive[request.params[1].get_int()];
+ if (!pindexStop) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid stop_height");
+ }
+ else if (pindexStop->nHeight < pindexStart->nHeight) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "stop_height must be greater then start_height");
+ }
}
}
// We can't rescan beyond non-pruned blocks, stop and throw an error
if (fPruneMode) {
- CBlockIndex *block = pindexStop ? pindexStop : chainActive.Tip();
+ LOCK(cs_main);
+ CBlockIndex *block = pindexStop ? pindexStop : pChainTip;
while (block && block->nHeight >= pindexStart->nHeight) {
if (!(block->nStatus & BLOCK_HAVE_DATA)) {
throw JSONRPCError(RPC_MISC_ERROR, "Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height.");
@@ -3436,12 +3446,11 @@ UniValue rescanblockchain(const JSONRPCRequest& request)
throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted.");
}
// if we got a nullptr returned, ScanForWalletTransactions did rescan up to the requested stopindex
- stopBlock = pindexStop ? pindexStop : chainActive.Tip();
+ stopBlock = pindexStop ? pindexStop : pChainTip;
}
else {
throw JSONRPCError(RPC_MISC_ERROR, "Rescan failed. Potentially corrupted data files.");
}
-
UniValue response(UniValue::VOBJ);
response.pushKV("start_height", pindexStart->nHeight);
response.pushKV("stop_height", stopBlock->nHeight);