@@ -3169,6 +3169,81 @@ UniValue generate(const JSONRPCRequest& request)
3169
3169
return generateBlocks (coinbase_script, num_generate, max_tries, true );
3170
3170
}
3171
3171
3172
+ UniValue rescanblockchain (const JSONRPCRequest& request)
3173
+ {
3174
+ CWallet * const pwallet = GetWalletForJSONRPCRequest (request);
3175
+ if (!EnsureWalletIsAvailable (pwallet, request.fHelp )) {
3176
+ return NullUniValue;
3177
+ }
3178
+
3179
+ if (request.fHelp || request.params .size () > 2 ) {
3180
+ throw std::runtime_error (
3181
+ " rescanblockchain (\" start_height\" ) (\" stop_height\" )\n "
3182
+ " \n Rescan the local blockchain for wallet related transactions.\n "
3183
+ " \n Arguments:\n "
3184
+ " 1. \" start_height\" (numeric, optional) block height where the rescan should start\n "
3185
+ " 2. \" stop_height\" (numeric, optional) the last block height that should be scanned\n "
3186
+ " \n Result:\n "
3187
+ " {\n "
3188
+ " \" start_height\" (numeric) The block height where the rescan has started. If omitted, rescan started from the genesis block.\n "
3189
+ " \" stop_height\" (numeric) The height of the last rescanned block. If omitted, rescan stopped at the chain tip.\n "
3190
+ " }\n "
3191
+ " \n Examples:\n "
3192
+ + HelpExampleCli (" rescanblockchain" , " 100000 120000" )
3193
+ + HelpExampleRpc (" rescanblockchain" , " 100000 120000" )
3194
+ );
3195
+ }
3196
+
3197
+ LOCK2 (cs_main, pwallet->cs_wallet );
3198
+
3199
+ CBlockIndex *pindexStart = chainActive.Genesis ();
3200
+ CBlockIndex *pindexStop = nullptr ;
3201
+ if (!request.params [0 ].isNull ()) {
3202
+ pindexStart = chainActive[request.params [0 ].get_int ()];
3203
+ if (!pindexStart) {
3204
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Invalid start_height" );
3205
+ }
3206
+ }
3207
+
3208
+ if (!request.params [1 ].isNull ()) {
3209
+ pindexStop = chainActive[request.params [1 ].get_int ()];
3210
+ if (!pindexStop) {
3211
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Invalid stop_height" );
3212
+ }
3213
+ else if (pindexStop->nHeight < pindexStart->nHeight ) {
3214
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " stop_height must be greater then start_height" );
3215
+ }
3216
+ }
3217
+
3218
+ // We can't rescan beyond non-pruned blocks, stop and throw an error
3219
+ if (fPruneMode ) {
3220
+ CBlockIndex *block = pindexStop ? pindexStop : chainActive.Tip ();
3221
+ while (block && block->nHeight >= pindexStart->nHeight ) {
3222
+ if (!(block->nStatus & BLOCK_HAVE_DATA)) {
3223
+ throw JSONRPCError (RPC_MISC_ERROR, " Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height." );
3224
+ }
3225
+ block = block->pprev ;
3226
+ }
3227
+ }
3228
+
3229
+ CBlockIndex *stopBlock = pwallet->ScanForWalletTransactions (pindexStart, pindexStop, true );
3230
+ if (!stopBlock) {
3231
+ if (pwallet->IsAbortingRescan ()) {
3232
+ throw JSONRPCError (RPC_MISC_ERROR, " Rescan aborted." );
3233
+ }
3234
+ // if we got a nullptr returned, ScanForWalletTransactions did rescan up to the requested stopindex
3235
+ stopBlock = pindexStop ? pindexStop : chainActive.Tip ();
3236
+ }
3237
+ else {
3238
+ throw JSONRPCError (RPC_MISC_ERROR, " Rescan failed. Potentially corrupted data files." );
3239
+ }
3240
+
3241
+ UniValue response (UniValue::VOBJ);
3242
+ response.pushKV (" start_height" , pindexStart->nHeight );
3243
+ response.pushKV (" stop_height" , stopBlock->nHeight );
3244
+ return response;
3245
+ }
3246
+
3172
3247
extern UniValue abortrescan (const JSONRPCRequest& request); // in rpcdump.cpp
3173
3248
extern UniValue dumpprivkey (const JSONRPCRequest& request); // in rpcdump.cpp
3174
3249
extern UniValue importprivkey (const JSONRPCRequest& request);
@@ -3179,6 +3254,7 @@ extern UniValue importwallet(const JSONRPCRequest& request);
3179
3254
extern UniValue importprunedfunds (const JSONRPCRequest& request);
3180
3255
extern UniValue removeprunedfunds (const JSONRPCRequest& request);
3181
3256
extern UniValue importmulti (const JSONRPCRequest& request);
3257
+ extern UniValue rescanblockchain (const JSONRPCRequest& request);
3182
3258
3183
3259
static const CRPCCommand commands[] =
3184
3260
{ // category name actor (function) argNames
@@ -3233,6 +3309,7 @@ static const CRPCCommand commands[] =
3233
3309
{ " wallet" , " walletpassphrasechange" , &walletpassphrasechange, {" oldpassphrase" ," newpassphrase" } },
3234
3310
{ " wallet" , " walletpassphrase" , &walletpassphrase, {" passphrase" ," timeout" } },
3235
3311
{ " wallet" , " removeprunedfunds" , &removeprunedfunds, {" txid" } },
3312
+ { " wallet" , " rescanblockchain" , &rescanblockchain, {" start_height" , " stop_height" } },
3236
3313
3237
3314
{ " generating" , " generate" , &generate, {" nblocks" ," maxtries" } },
3238
3315
};
0 commit comments