mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-13 07:28:59 +01:00
Fix importmulti failure to return rescan errors
An off-by-one-block bug in importmulti rescan logic could cause it to return success in an edge case even when a rescan was not successful. The case where this would happen is if there were multiple blocks in a row with the same GetBlockTimeMax() value, and the last block was scanned successfully, but one or more of the earlier blocks was not readable.
This commit is contained in:
@@ -1121,13 +1121,13 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
|
||||
|
||||
if (fRescan && fRunScan && requests.size()) {
|
||||
CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(std::max<int64_t>(nLowestTimestamp - TIMESTAMP_WINDOW, 0)) : chainActive.Genesis();
|
||||
CBlockIndex* scannedRange = nullptr;
|
||||
CBlockIndex* scanFailed = nullptr;
|
||||
if (pindex) {
|
||||
scannedRange = pwallet->ScanForWalletTransactions(pindex, true);
|
||||
scanFailed = pwallet->ScanForWalletTransactions(pindex, true);
|
||||
pwallet->ReacceptWalletTransactions();
|
||||
}
|
||||
|
||||
if (!scannedRange || scannedRange->nHeight > pindex->nHeight) {
|
||||
if (scanFailed) {
|
||||
std::vector<UniValue> results = response.getValues();
|
||||
response.clear();
|
||||
response.setArray();
|
||||
@@ -1137,12 +1137,23 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
|
||||
// range, or if the import result already has an error set, let
|
||||
// the result stand unmodified. Otherwise replace the result
|
||||
// with an error message.
|
||||
if (GetImportTimestamp(request, now) - TIMESTAMP_WINDOW >= scannedRange->GetBlockTimeMax() || results.at(i).exists("error")) {
|
||||
if (GetImportTimestamp(request, now) - TIMESTAMP_WINDOW > scanFailed->GetBlockTimeMax() || results.at(i).exists("error")) {
|
||||
response.push_back(results.at(i));
|
||||
} else {
|
||||
UniValue result = UniValue(UniValue::VOBJ);
|
||||
result.pushKV("success", UniValue(false));
|
||||
result.pushKV("error", JSONRPCError(RPC_MISC_ERROR, strprintf("Failed to rescan before time %d, transactions may be missing.", scannedRange->GetBlockTimeMax())));
|
||||
result.pushKV(
|
||||
"error",
|
||||
JSONRPCError(
|
||||
RPC_MISC_ERROR,
|
||||
strprintf("Rescan failed for key with creation timestamp %d. There was an error reading a "
|
||||
"block from time %d, which is after or within %d seconds of key creation, and "
|
||||
"could contain transactions pertaining to the key. As a result, transactions "
|
||||
"and coins using this key may not appear in the wallet. This error could be "
|
||||
"caused by pruning or data corruption (see bitcoind log for details) and could "
|
||||
"be dealt with by downloading and rescanning the relevant blocks (see -reindex "
|
||||
"and -rescan options).",
|
||||
GetImportTimestamp(request, now), scanFailed->GetBlockTimeMax(), TIMESTAMP_WINDOW)));
|
||||
response.push_back(std::move(result));
|
||||
}
|
||||
++i;
|
||||
|
||||
Reference in New Issue
Block a user