Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show First 20 Lines • Show All 3,988 Lines • ▼ Show 20 Lines | UniValue rescanblockchain(const Config &config, const JSONRPCRequest &request) { | ||||
WalletRescanReserver reserver(*pwallet); | WalletRescanReserver reserver(*pwallet); | ||||
if (!reserver.reserve()) { | if (!reserver.reserve()) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_WALLET_ERROR, | RPC_WALLET_ERROR, | ||||
"Wallet is currently rescanning. Abort existing rescan or wait."); | "Wallet is currently rescanning. Abort existing rescan or wait."); | ||||
} | } | ||||
int start_height = 0; | int start_height = 0; | ||||
BlockHash start_block, stop_block; | Optional<int> stop_height; | ||||
BlockHash start_block; | |||||
{ | { | ||||
auto locked_chain = pwallet->chain().lock(); | auto locked_chain = pwallet->chain().lock(); | ||||
Optional<int> tip_height = locked_chain->getHeight(); | LOCK(pwallet->cs_wallet); | ||||
int tip_height = pwallet->GetLastBlockHeight(); | |||||
if (!request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
start_height = request.params[0].get_int(); | start_height = request.params[0].get_int(); | ||||
if (start_height < 0 || !tip_height || start_height > *tip_height) { | if (start_height < 0 || start_height > tip_height) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
"Invalid start_height"); | "Invalid start_height"); | ||||
} | } | ||||
} | } | ||||
Optional<int> stop_height; | |||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
stop_height = request.params[1].get_int(); | stop_height = request.params[1].get_int(); | ||||
if (*stop_height < 0 || !tip_height || *stop_height > *tip_height) { | if (*stop_height < 0 || *stop_height > tip_height) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
"Invalid stop_height"); | "Invalid stop_height"); | ||||
} else if (*stop_height < start_height) { | } else if (*stop_height < start_height) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_INVALID_PARAMETER, | RPC_INVALID_PARAMETER, | ||||
"stop_height must be greater than start_height"); | "stop_height must be greater than 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 (locked_chain->findPruned(start_height, stop_height)) { | if (!pwallet->chain().hasBlocks(pwallet->GetLastBlockHash(), | ||||
start_height, stop_height)) { | |||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_MISC_ERROR, | RPC_MISC_ERROR, | ||||
"Can't rescan beyond pruned data. Use RPC call " | "Can't rescan beyond pruned data. Use RPC call " | ||||
"getblockchaininfo to determine your pruned height."); | "getblockchaininfo to determine your pruned height."); | ||||
} | } | ||||
if (tip_height) { | CHECK_NONFATAL(pwallet->chain().findAncestorByHeight( | ||||
start_block = locked_chain->getBlockHash(start_height); | pwallet->GetLastBlockHash(), start_height, | ||||
FoundBlock().hash(start_block))); | |||||
// If called with a stop_height, set the stop_height here to | |||||
// trigger a rescan to that height. | |||||
// If called without a stop height, leave stop_height as null here | |||||
// so rescan continues to the tip (even if the tip advances during | |||||
// rescan). | |||||
if (stop_height) { | |||||
stop_block = locked_chain->getBlockHash(*stop_height); | |||||
} | |||||
} | |||||
} | } | ||||
CWallet::ScanResult result = pwallet->ScanForWalletTransactions( | CWallet::ScanResult result = pwallet->ScanForWalletTransactions( | ||||
start_block, stop_block, reserver, true /* fUpdate */); | start_block, stop_height, reserver, true /* fUpdate */); | ||||
switch (result.status) { | switch (result.status) { | ||||
case CWallet::ScanResult::SUCCESS: | case CWallet::ScanResult::SUCCESS: | ||||
break; | break; | ||||
case CWallet::ScanResult::FAILURE: | case CWallet::ScanResult::FAILURE: | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_MISC_ERROR, | RPC_MISC_ERROR, | ||||
"Rescan failed. Potentially corrupted data files."); | "Rescan failed. Potentially corrupted data files."); | ||||
case CWallet::ScanResult::USER_ABORT: | case CWallet::ScanResult::USER_ABORT: | ||||
▲ Show 20 Lines • Show All 842 Lines • Show Last 20 Lines |