Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show First 20 Lines • Show All 3,858 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() > 2) { | ||||
" \"stop_height\" (numeric) The height of the last rescanned " | " \"stop_height\" (numeric) The height of the last rescanned " | ||||
"block. If omitted, rescan stopped at the chain tip.\n" | "block. If omitted, rescan stopped at the chain tip.\n" | ||||
"}\n" | "}\n" | ||||
"\nExamples:\n" + | "\nExamples:\n" + | ||||
HelpExampleCli("rescanblockchain", "100000 120000") + | HelpExampleCli("rescanblockchain", "100000 120000") + | ||||
HelpExampleRpc("rescanblockchain", "100000 120000")); | HelpExampleRpc("rescanblockchain", "100000 120000")); | ||||
} | } | ||||
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; | CBlockIndex *pindexStop = nullptr; | ||||
CBlockIndex *pChainTip = nullptr; | |||||
{ | |||||
LOCK(cs_main); | |||||
pindexStart = chainActive.Genesis(); | |||||
pChainTip = chainActive.Tip(); | |||||
if (!request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
pindexStart = chainActive[request.params[0].get_int()]; | pindexStart = chainActive[request.params[0].get_int()]; | ||||
if (!pindexStart) { | if (!pindexStart) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid start_height"); | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
"Invalid start_height"); | |||||
} | } | ||||
} | } | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
pindexStop = chainActive[request.params[1].get_int()]; | pindexStop = chainActive[request.params[1].get_int()]; | ||||
if (!pindexStop) { | if (!pindexStop) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid stop_height"); | |||||
} else if (pindexStop->nHeight < pindexStart->nHeight) { | |||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | 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"); | "stop_height must be greater then start_height"); | ||||
} | } | ||||
} | } | ||||
} | |||||
// We can't rescan beyond non-pruned blocks, stop and throw an error | // We can't rescan beyond non-pruned blocks, stop and throw an error | ||||
if (fPruneMode) { | if (fPruneMode) { | ||||
CBlockIndex *block = pindexStop ? pindexStop : chainActive.Tip(); | LOCK(cs_main); | ||||
CBlockIndex *block = pindexStop ? pindexStop : pChainTip; | |||||
while (block && block->nHeight >= pindexStart->nHeight) { | while (block && block->nHeight >= pindexStart->nHeight) { | ||||
if (!block->nStatus.hasData()) { | if (!block->nStatus.hasData()) { | ||||
throw JSONRPCError(RPC_MISC_ERROR, | throw JSONRPCError(RPC_MISC_ERROR, | ||||
"Can't rescan beyond pruned data. Use RPC " | "Can't rescan beyond pruned data. Use RPC " | ||||
"call getblockchaininfo to determine your " | "call getblockchaininfo to determine your " | ||||
"pruned height."); | "pruned height."); | ||||
} | } | ||||
block = block->pprev; | block = block->pprev; | ||||
} | } | ||||
} | } | ||||
CBlockIndex *stopBlock = | CBlockIndex *stopBlock = pwallet->ScanForWalletTransactions( | ||||
pwallet->ScanForWalletTransactions(pindexStart, pindexStop, true); | pindexStart, pindexStop, reserver, true); | ||||
if (!stopBlock) { | if (!stopBlock) { | ||||
if (pwallet->IsAbortingRescan()) { | if (pwallet->IsAbortingRescan()) { | ||||
throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted."); | throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted."); | ||||
} | } | ||||
// if we got a nullptr returned, ScanForWalletTransactions did rescan up | // if we got a nullptr returned, ScanForWalletTransactions did rescan up | ||||
// to the requested stopindex | // to the requested stopindex | ||||
stopBlock = pindexStop ? pindexStop : chainActive.Tip(); | stopBlock = pindexStop ? pindexStop : pChainTip; | ||||
} else { | } else { | ||||
throw JSONRPCError(RPC_MISC_ERROR, | throw JSONRPCError(RPC_MISC_ERROR, | ||||
"Rescan failed. Potentially corrupted data files."); | "Rescan failed. Potentially corrupted data files."); | ||||
} | } | ||||
UniValue response(UniValue::VOBJ); | UniValue response(UniValue::VOBJ); | ||||
response.pushKV("start_height", pindexStart->nHeight); | response.pushKV("start_height", pindexStart->nHeight); | ||||
response.pushKV("stop_height", stopBlock->nHeight); | response.pushKV("stop_height", stopBlock->nHeight); | ||||
return response; | return response; | ||||
} | } | ||||
// clang-format off | // clang-format off | ||||
static const ContextFreeRPCCommand commands[] = { | static const ContextFreeRPCCommand commands[] = { | ||||
▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines |