diff options
Diffstat (limited to 'src/wallet/rpcwallet.cpp')
-rw-r--r-- | src/wallet/rpcwallet.cpp | 85 |
1 files changed, 41 insertions, 44 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4529e39124..270a61ade8 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -102,7 +102,10 @@ static void WalletTxToJSON(interfaces::Chain& chain, interfaces::Chain::Lock& lo { entry.pushKV("blockhash", wtx.hashBlock.GetHex()); entry.pushKV("blockindex", wtx.nIndex); - entry.pushKV("blocktime", LookupBlockIndex(wtx.hashBlock)->GetBlockTime()); + int64_t block_time; + bool found_block = chain.findBlock(wtx.hashBlock, nullptr /* block */, &block_time); + assert(found_block); + entry.pushKV("blocktime", block_time); } else { entry.pushKV("trusted", wtx.IsTrusted(locked_chain)); } @@ -1588,24 +1591,18 @@ static UniValue listsinceblock(const JSONRPCRequest& request) auto locked_chain = pwallet->chain().lock(); LOCK(pwallet->cs_wallet); - const CBlockIndex* pindex = nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain. - const CBlockIndex* paltindex = nullptr; // Block index of the specified block, even if it's in a deactivated chain. + Optional<int> height; // Height of the specified block or the common ancestor, if the block provided was in a deactivated chain. + Optional<int> altheight; // Height of the specified block, even if it's in a deactivated chain. int target_confirms = 1; isminefilter filter = ISMINE_SPENDABLE; + uint256 blockId; if (!request.params[0].isNull() && !request.params[0].get_str().empty()) { - uint256 blockId(ParseHashV(request.params[0], "blockhash")); - - paltindex = pindex = LookupBlockIndex(blockId); - if (!pindex) { + blockId = ParseHashV(request.params[0], "blockhash"); + height = locked_chain->findFork(blockId, &altheight); + if (!height) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); } - if (chainActive[pindex->nHeight] != pindex) { - // the block being asked for is a part of a deactivated chain; - // we don't want to depend on its perceived height in the block - // chain, we want to instead use the last common ancestor - pindex = chainActive.FindFork(pindex); - } } if (!request.params[1].isNull()) { @@ -1622,7 +1619,8 @@ static UniValue listsinceblock(const JSONRPCRequest& request) bool include_removed = (request.params[3].isNull() || request.params[3].get_bool()); - int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1; + const Optional<int> tip_height = locked_chain->getHeight(); + int depth = tip_height && height ? (1 + *tip_height - *height) : -1; UniValue transactions(UniValue::VARR); @@ -1637,9 +1635,9 @@ static UniValue listsinceblock(const JSONRPCRequest& request) // when a reorg'd block is requested, we also list any relevant transactions // in the blocks of the chain that was detached UniValue removed(UniValue::VARR); - while (include_removed && paltindex && paltindex != pindex) { + while (include_removed && altheight && *altheight > *height) { CBlock block; - if (!ReadBlockFromDisk(block, paltindex, Params().GetConsensus())) { + if (!pwallet->chain().findBlock(blockId, &block) || block.IsNull()) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); } for (const CTransactionRef& tx : block.vtx) { @@ -1650,11 +1648,12 @@ static UniValue listsinceblock(const JSONRPCRequest& request) ListTransactions(*locked_chain, pwallet, it->second, -100000000, true, removed, filter, nullptr /* filter_label */); } } - paltindex = paltindex->pprev; + blockId = block.hashPrevBlock; + --*altheight; } - CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; - uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256(); + int last_height = tip_height ? *tip_height + 1 - target_confirms : -1; + uint256 lastblock = last_height >= 0 ? locked_chain->getBlockHash(last_height) : uint256(); UniValue ret(UniValue::VOBJ); ret.pushKV("transactions", transactions); @@ -3428,50 +3427,48 @@ UniValue rescanblockchain(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait."); } - CBlockIndex *pindexStart = nullptr; - CBlockIndex *pindexStop = nullptr; - CBlockIndex *pChainTip = nullptr; + int start_height = 0; + uint256 start_block, stop_block; { auto locked_chain = pwallet->chain().lock(); - pindexStart = chainActive.Genesis(); - pChainTip = chainActive.Tip(); + Optional<int> tip_height = locked_chain->getHeight(); if (!request.params[0].isNull()) { - pindexStart = chainActive[request.params[0].get_int()]; - if (!pindexStart) { + start_height = request.params[0].get_int(); + if (start_height < 0 || !tip_height || start_height > *tip_height) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid start_height"); } } + Optional<int> stop_height; if (!request.params[1].isNull()) { - pindexStop = chainActive[request.params[1].get_int()]; - if (!pindexStop) { + stop_height = request.params[1].get_int(); + if (*stop_height < 0 || !tip_height || *stop_height > *tip_height) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid stop_height"); } - else if (pindexStop->nHeight < pindexStart->nHeight) { + else if (*stop_height < start_height) { throw JSONRPCError(RPC_INVALID_PARAMETER, "stop_height must be greater than start_height"); } } - } - // We can't rescan beyond non-pruned blocks, stop and throw an error - if (fPruneMode) { - auto locked_chain = pwallet->chain().lock(); - 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."); + // We can't rescan beyond non-pruned blocks, stop and throw an error + if (locked_chain->findPruned(start_height, stop_height)) { + throw JSONRPCError(RPC_MISC_ERROR, "Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height."); + } + + if (tip_height) { + start_block = locked_chain->getBlockHash(start_height); + if (stop_height) { + stop_block = locked_chain->getBlockHash(*stop_height); } - block = block->pprev; } } - const CBlockIndex *failed_block, *stopBlock; CWallet::ScanResult result = - pwallet->ScanForWalletTransactions(pindexStart, pindexStop, reserver, failed_block, stopBlock, true); - switch (result) { + pwallet->ScanForWalletTransactions(start_block, stop_block, reserver, true /* fUpdate */); + switch (result.status) { case CWallet::ScanResult::SUCCESS: - break; // stopBlock set by ScanForWalletTransactions + break; case CWallet::ScanResult::FAILURE: throw JSONRPCError(RPC_MISC_ERROR, "Rescan failed. Potentially corrupted data files."); case CWallet::ScanResult::USER_ABORT: @@ -3479,8 +3476,8 @@ UniValue rescanblockchain(const JSONRPCRequest& request) // no default case, so the compiler can warn about missing cases } UniValue response(UniValue::VOBJ); - response.pushKV("start_height", pindexStart->nHeight); - response.pushKV("stop_height", stopBlock->nHeight); + response.pushKV("start_height", start_height); + response.pushKV("stop_height", result.stop_height ? *result.stop_height : UniValue()); return response; } |