diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/db.cpp | 8 | ||||
-rw-r--r-- | src/wallet/rpcdump.cpp | 2 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 16 | ||||
-rw-r--r-- | src/wallet/test/wallet_tests.cpp | 30 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 38 | ||||
-rw-r--r-- | src/wallet/wallet.h | 6 |
6 files changed, 58 insertions, 42 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index ae40553268..c64a85c910 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -126,11 +126,18 @@ void BerkeleyEnvironment::Close() } } + FILE* error_file = nullptr; + dbenv->get_errfile(&error_file); + int ret = dbenv->close(0); if (ret != 0) LogPrintf("BerkeleyEnvironment::Close: Error %d closing database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) DbEnv((u_int32_t)0).remove(strPath.c_str(), 0); + + if (error_file) fclose(error_file); + + UnlockDirectory(strPath, ".walletlock"); } void BerkeleyEnvironment::Reset() @@ -147,6 +154,7 @@ BerkeleyEnvironment::BerkeleyEnvironment(const fs::path& dir_path) : strPath(dir BerkeleyEnvironment::~BerkeleyEnvironment() { + LOCK(cs_db); g_dbenvs.erase(strPath); Close(); } diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 0da2dda092..32c36ceaeb 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -814,7 +814,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) file << strprintf("# Wallet dump created by Bitcoin %s\n", CLIENT_BUILD); file << strprintf("# * Created on %s\n", FormatISO8601DateTime(GetTime())); const Optional<int> tip_height = locked_chain->getHeight(); - file << strprintf("# * Best block at time of backup was %i (%s),\n", tip_height.value_or(-1), tip_height ? locked_chain->getBlockHash(*tip_height).ToString() : "(missing block hash)"); + file << strprintf("# * Best block at time of backup was %i (%s),\n", tip_height.get_value_or(-1), tip_height ? locked_chain->getBlockHash(*tip_height).ToString() : "(missing block hash)"); file << strprintf("# mined on %s\n", tip_height ? FormatISO8601DateTime(locked_chain->getBlockTime(*tip_height)) : "(missing block time)"); file << "\n"; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c96a9b0aff..e38ad3a0ba 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3028,7 +3028,8 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) "This will not modify existing inputs, and will add at most one change output to the outputs.\n" "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n" "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" - "The inputs added will not be signed, use signrawtransaction for that.\n" + "The inputs added will not be signed, use signrawtransactionwithkey\n" + " or signrawtransactionwithwallet for that.\n" "Note that all existing inputs must have their previous output transaction be in the wallet.\n" "Note that all inputs selected must be of standard form and P2SH scripts must be\n" "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" @@ -3077,7 +3078,7 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) "\nAdd sufficient unsigned inputs to meet the output value\n" + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") + "\nSign the transaction\n" - + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") + + + HelpExampleCli("signrawtransactionwithwallet", "\"fundedtransactionhex\"") + "\nSend the transaction\n" + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") }, @@ -3412,8 +3413,8 @@ UniValue rescanblockchain(const JSONRPCRequest& request) }, RPCResult{ "{\n" - " \"start_height\" (numeric) The block height where the rescan has started.\n" - " \"stop_height\" (numeric) The height of the last rescanned block.\n" + " \"start_height\" (numeric) The block height where the rescan started (the requested height or 0)\n" + " \"stop_height\" (numeric) The height of the last rescanned block. May be null in rare cases if there was a reorg and the call didn't scan any blocks because they were already scanned in the background.\n" "}\n" }, RPCExamples{ @@ -3459,6 +3460,11 @@ UniValue rescanblockchain(const JSONRPCRequest& request) if (tip_height) { start_block = locked_chain->getBlockHash(start_height); + // 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); } @@ -3478,7 +3484,7 @@ UniValue rescanblockchain(const JSONRPCRequest& request) } UniValue response(UniValue::VOBJ); response.pushKV("start_height", start_height); - response.pushKV("stop_height", result.stop_height ? *result.stop_height : UniValue()); + response.pushKV("stop_height", result.last_scanned_height ? *result.last_scanned_height : UniValue()); return response; } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 2fe79bece7..c5efd32d77 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -55,9 +55,9 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) reserver.reserve(); CWallet::ScanResult result = wallet.ScanForWalletTransactions({} /* start_block */, {} /* stop_block */, reserver, false /* update */); BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); - BOOST_CHECK(result.failed_block.IsNull()); - BOOST_CHECK(result.stop_block.IsNull()); - BOOST_CHECK(!result.stop_height); + BOOST_CHECK(result.last_failed_block.IsNull()); + BOOST_CHECK(result.last_scanned_block.IsNull()); + BOOST_CHECK(!result.last_scanned_height); BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 0); } @@ -70,9 +70,9 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) reserver.reserve(); CWallet::ScanResult result = wallet.ScanForWalletTransactions(oldTip->GetBlockHash(), {} /* stop_block */, reserver, false /* update */); BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); - BOOST_CHECK(result.failed_block.IsNull()); - BOOST_CHECK_EQUAL(result.stop_block, newTip->GetBlockHash()); - BOOST_CHECK_EQUAL(*result.stop_height, newTip->nHeight); + BOOST_CHECK(result.last_failed_block.IsNull()); + BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash()); + BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight); BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 100 * COIN); } @@ -89,9 +89,9 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) reserver.reserve(); CWallet::ScanResult result = wallet.ScanForWalletTransactions(oldTip->GetBlockHash(), {} /* stop_block */, reserver, false /* update */); BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::FAILURE); - BOOST_CHECK_EQUAL(result.failed_block, oldTip->GetBlockHash()); - BOOST_CHECK_EQUAL(result.stop_block, newTip->GetBlockHash()); - BOOST_CHECK_EQUAL(*result.stop_height, newTip->nHeight); + BOOST_CHECK_EQUAL(result.last_failed_block, oldTip->GetBlockHash()); + BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash()); + BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight); BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); } @@ -107,9 +107,9 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) reserver.reserve(); CWallet::ScanResult result = wallet.ScanForWalletTransactions(oldTip->GetBlockHash(), {} /* stop_block */, reserver, false /* update */); BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::FAILURE); - BOOST_CHECK_EQUAL(result.failed_block, newTip->GetBlockHash()); - BOOST_CHECK(result.stop_block.IsNull()); - BOOST_CHECK(!result.stop_height); + BOOST_CHECK_EQUAL(result.last_failed_block, newTip->GetBlockHash()); + BOOST_CHECK(result.last_scanned_block.IsNull()); + BOOST_CHECK(!result.last_scanned_height); BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 0); } } @@ -348,9 +348,9 @@ public: reserver.reserve(); CWallet::ScanResult result = wallet->ScanForWalletTransactions(chainActive.Genesis()->GetBlockHash(), {} /* stop_block */, reserver, false /* update */); BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); - BOOST_CHECK_EQUAL(result.stop_block, chainActive.Tip()->GetBlockHash()); - BOOST_CHECK_EQUAL(*result.stop_height, chainActive.Height()); - BOOST_CHECK(result.failed_block.IsNull()); + BOOST_CHECK_EQUAL(result.last_scanned_block, chainActive.Tip()->GetBlockHash()); + BOOST_CHECK_EQUAL(*result.last_scanned_height, chainActive.Height()); + BOOST_CHECK(result.last_failed_block.IsNull()); } ~ListCoinsTestingSetup() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3ce8371abb..bdddcd718b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1603,7 +1603,7 @@ int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& r ScanResult result = ScanForWalletTransactions(start_block, {} /* stop_block */, reserver, update); if (result.status == ScanResult::FAILURE) { int64_t time_max; - if (!chain().findBlock(result.failed_block, nullptr /* block */, nullptr /* time */, &time_max)) { + if (!chain().findBlock(result.last_failed_block, nullptr /* block */, nullptr /* time */, &time_max)) { throw std::logic_error("ScanForWalletTransactions returned invalid block hash"); } return time_max + TIMESTAMP_WINDOW + 1; @@ -1617,15 +1617,17 @@ int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& r * from or to us. If fUpdate is true, found transactions that already * exist in the wallet will be updated. * - * @param[in] start_block if not null, the scan will start at this block instead - * of the genesis block - * @param[in] stop_block if not null, the scan will stop at this block instead - * of the chain tip + * @param[in] start_block Scan starting block. If block is not on the active + * chain, the scan will return SUCCESS immediately. + * @param[in] stop_block Scan ending block. If block is not on the active + * chain, the scan will continue until it reaches the + * chain tip. * - * @return ScanResult indicating success or failure of the scan. SUCCESS if - * scan was successful. FAILURE if a complete rescan was not possible (due to - * pruning or corruption). USER_ABORT if the rescan was aborted before it - * could complete. + * @return ScanResult returning scan information and indicating success or + * failure. Return status will be set to SUCCESS if scan was + * successful. FAILURE if a complete rescan was not possible (due to + * pruning or corruption). USER_ABORT if the rescan was aborted before + * it could complete. * * @pre Caller needs to make sure start_block (and the optional stop_block) are on * the main chain after to the addition of any new keys you want to detect @@ -1678,7 +1680,7 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc // marking transactions as coming from the wrong block. // TODO: This should return success instead of failure, see // https://github.com/bitcoin/bitcoin/pull/14711#issuecomment-458342518 - result.failed_block = block_hash; + result.last_failed_block = block_hash; result.status = ScanResult::FAILURE; break; } @@ -1686,11 +1688,11 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc SyncTransaction(block.vtx[posInBlock], block_hash, posInBlock, fUpdate); } // scan succeeded, record block as most recent successfully scanned - result.stop_block = block_hash; - result.stop_height = *block_height; + result.last_scanned_block = block_hash; + result.last_scanned_height = *block_height; } else { // could not scan block, keep scanning but record this block as the most recent failure - result.failed_block = block_hash; + result.last_failed_block = block_hash; result.status = ScanResult::FAILURE; } if (block_hash == stop_block) { @@ -1720,10 +1722,10 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc } ShowProgress(strprintf("%s " + _("Rescanning..."), GetDisplayName()), 100); // hide progress dialog in GUI if (block_height && fAbortRescan) { - WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", block_height.value_or(0), progress_current); + WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", *block_height, progress_current); result.status = ScanResult::USER_ABORT; } else if (block_height && ShutdownRequested()) { - WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", block_height.value_or(0), progress_current); + WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", *block_height, progress_current); result.status = ScanResult::USER_ABORT; } } @@ -2584,7 +2586,7 @@ static bool IsCurrentForAntiFeeSniping(interfaces::Chain::Lock& locked_chain) */ static uint32_t GetLocktimeForNewTransaction(interfaces::Chain::Lock& locked_chain) { - uint32_t const height = locked_chain.getHeight().value_or(-1); + uint32_t const height = locked_chain.getHeight().get_value_or(-1); uint32_t locktime; // Discourage fee sniping. // @@ -4084,7 +4086,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, } auto locked_chain = chain.assumeLocked(); // Temporary. Removed in upcoming lock cleanup - walletInstance->ChainStateFlushed(locked_chain->getLocator()); + walletInstance->ChainStateFlushed(locked_chain->getTipLocator()); } else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) { // Make it impossible to disable private keys after creation InitError(strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile)); @@ -4231,7 +4233,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, } } walletInstance->WalletLogPrintf("Rescan completed in %15dms\n", GetTimeMillis() - nStart); - walletInstance->ChainStateFlushed(locked_chain->getLocator()); + walletInstance->ChainStateFlushed(locked_chain->getTipLocator()); walletInstance->database->IncrementUpdateCounter(); // Restore wallet transaction metadata after -zapwallettxes=1 diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 4776b0eacc..cf3fa0aced 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -912,14 +912,14 @@ public: //! Hash and height of most recent block that was successfully scanned. //! Unset if no blocks were scanned due to read errors or the chain //! being empty. - uint256 stop_block; - Optional<int> stop_height; + uint256 last_scanned_block; + Optional<int> last_scanned_height; //! Height of the most recent block that could not be scanned due to //! read errors or pruning. Will be set if status is FAILURE, unset if //! status is SUCCESS, and may or may not be set if status is //! USER_ABORT. - uint256 failed_block; + uint256 last_failed_block; }; ScanResult ScanForWalletTransactions(const uint256& first_block, const uint256& last_block, const WalletRescanReserver& reserver, bool fUpdate); void TransactionRemovedFromMempool(const CTransactionRef &ptx) override; |