aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/rpcwallet.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2018-01-24 12:29:30 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2018-01-24 12:56:23 +0100
commit8470e64724cb4a668079e7516dc61ec230346618 (patch)
tree1b9cbf3fd953b70fce01bd17ce7a1d739bfb3db9 /src/wallet/rpcwallet.cpp
parentb5e4b9b5100ec15217d43edb5f4149439f4b20a5 (diff)
parent7f812502b78b76653bbef19169e8a05873ee3b8d (diff)
downloadbitcoin-8470e64724cb4a668079e7516dc61ec230346618.tar.xz
Merge #11281: Avoid permanent cs_main/cs_wallet lock during RescanFromTime
7f81250 Mention that other RPC calls report keys as "imported" while txns are still missing (Jonas Schnelli) ccd8ef6 Reduce cs_main lock in ReadBlockFromDisk, only read GetBlockPos under the lock (Jonas Schnelli) bc356b4 Make sure WalletRescanReserver has successfully reserved the rescan (Jonas Schnelli) dbf8556 Add RAII wallet rescan reserver (Jonas Schnelli) 8d0b610 Avoid pemanent cs_main/cs_wallet lock during wallet rescans (Jonas Schnelli) Pull request description: Right now, we are holding `cs_main`/`cs_wallet` during the whole rescan process (which can take a couple of hours). This was probably only done because of laziness and it is an important show-stopper for #11200 (GUI rescan abort). Tree-SHA512: 0fc3f82d0ee9b2f013e6bacba8d59f7334306660cd676cd64c47bb305c4cb7c7a36219d6a6f76023b74e5fe87f3ab9fc7fd2439e939f71aef653fddb0a1e23b1
Diffstat (limited to 'src/wallet/rpcwallet.cpp')
-rw-r--r--src/wallet/rpcwallet.cpp46
1 files changed, 28 insertions, 18 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index ad0ebcce22..7770b41e56 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -3416,30 +3416,41 @@ UniValue rescanblockchain(const JSONRPCRequest& request)
);
}
- LOCK2(cs_main, pwallet->cs_wallet);
+ WalletRescanReserver reserver(pwallet);
+ if (!reserver.reserve()) {
+ 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.");
@@ -3448,18 +3459,17 @@ UniValue rescanblockchain(const JSONRPCRequest& request)
}
}
- CBlockIndex *stopBlock = pwallet->ScanForWalletTransactions(pindexStart, pindexStop, true);
+ CBlockIndex *stopBlock = pwallet->ScanForWalletTransactions(pindexStart, pindexStop, reserver, true);
if (!stopBlock) {
if (pwallet->IsAbortingRescan()) {
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);