diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -16,6 +16,7 @@ #include #include +class ArgsManager; class CBlock; class CChainParams; class Coin; @@ -361,7 +362,8 @@ //! MakeXXXClient functions returning their implementations of the ChainClient //! interface. std::unique_ptr -MakeWalletClient(Chain &chain, std::vector wallet_filenames); +MakeWalletClient(Chain &chain, ArgsManager &args, + std::vector wallet_filenames); } // namespace interfaces diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -463,10 +463,11 @@ class WalletClientImpl : public ChainClient { public: - WalletClientImpl(Chain &chain, + WalletClientImpl(Chain &chain, ArgsManager &args, std::vector wallet_filenames) : m_wallet_filenames(std::move(wallet_filenames)) { m_context.chain = &chain; + m_context.args = &args; } void registerRpcs(const Span &commands) { @@ -498,7 +499,7 @@ m_wallet_filenames); } void start(CScheduler &scheduler) override { - return StartWallets(scheduler); + return StartWallets(scheduler, *Assert(m_context.args)); } void flush() override { return FlushWallets(); } void stop() override { return StopWallets(); } @@ -513,7 +514,7 @@ ~WalletClientImpl() override { UnloadWallets(); } WalletContext m_context; - std::vector m_wallet_filenames; + const std::vector m_wallet_filenames; std::vector> m_rpc_handlers; std::list m_rpc_commands; }; @@ -525,8 +526,9 @@ } std::unique_ptr -MakeWalletClient(Chain &chain, std::vector wallet_filenames) { - return std::make_unique(chain, +MakeWalletClient(Chain &chain, ArgsManager &args, + std::vector wallet_filenames) { + return std::make_unique(chain, args, std::move(wallet_filenames)); } diff --git a/src/qt/test/apptests.cpp b/src/qt/test/apptests.cpp --- a/src/qt/test/apptests.cpp +++ b/src/qt/test/apptests.cpp @@ -76,11 +76,10 @@ Config &config = const_cast(GetConfig()); // Create a temp data directory to backup the gui settings to - BasicTestingSetup test{CBaseChainParams::REGTEST}; - // Already started by the common test setup, so stop it to avoid - // interference - ECC_Stop(); - LogInstance().DisconnectTestLogger(); + fs::create_directories([] { + BasicTestingSetup test{CBaseChainParams::REGTEST}; + return GetDataDir() / "blocks"; + }()); m_app.parameterSetup(); m_app.createOptionsModel(true /* reset settings */); @@ -94,7 +93,7 @@ m_app.baseInitialize(config); RPCServer rpcServer; - util::Ref context{test.m_node}; + util::Ref context; HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer, context); m_app.requestInitialize(config, rpcServer, httpRPCRequestProcessor); m_app.exec(); @@ -102,6 +101,7 @@ m_app.exec(); // Reset global state to avoid interfering with later tests. + LogInstance().DisconnectTestLogger(); AbortShutdown(); UnloadBlockIndex(); WITH_LOCK(::cs_main, g_chainman.Reset()); diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -71,6 +71,10 @@ BitcoinApplication app(*node); app.setApplicationName("BitcoinABC-Qt-test"); + // Make gArgs available in the NodeContext + node->setupServerArgs(); + // Clear added args again + node->context()->args->ClearArgs(); AppTests app_tests(app); if (QTest::qExec(&app_tests) != 0) { fInvalid = true; diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -699,9 +699,8 @@ } // Don't flush if any databases are in use - for (auto it = env->mapFileUseCount.begin(); - it != env->mapFileUseCount.end(); it++) { - if ((*it).second > 0) { + for (const auto &use_count : env->mapFileUseCount) { + if (use_count.second > 0) { return false; } } diff --git a/src/wallet/context.h b/src/wallet/context.h --- a/src/wallet/context.h +++ b/src/wallet/context.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_WALLET_CONTEXT_H #define BITCOIN_WALLET_CONTEXT_H +class ArgsManager; namespace interfaces { class Chain; } // namespace interfaces @@ -21,6 +22,7 @@ //! behavior. struct WalletContext { interfaces::Chain *chain{nullptr}; + ArgsManager *args{nullptr}; //! Declare default constructor and destructor that are not inline, so code //! instantiating the WalletContext struct doesn't need to #include class diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -216,11 +217,12 @@ } void WalletInit::Construct(NodeContext &node) const { - if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { + ArgsManager &args = *Assert(node.args); + if (args.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { LogPrintf("Wallet disabled!\n"); return; } - gArgs.SoftSetArg("-wallet", ""); - node.chain_clients.emplace_back( - interfaces::MakeWalletClient(*node.chain, gArgs.GetArgs("-wallet"))); + args.SoftSetArg("-wallet", ""); + node.chain_clients.emplace_back(interfaces::MakeWalletClient( + *node.chain, args, args.GetArgs("-wallet"))); } diff --git a/src/wallet/load.h b/src/wallet/load.h --- a/src/wallet/load.h +++ b/src/wallet/load.h @@ -9,6 +9,7 @@ #include #include +class ArgsManager; class CChainParams; class CScheduler; @@ -26,7 +27,7 @@ const std::vector &wallet_files); //! Complete startup of wallets. -void StartWallets(CScheduler &scheduler); +void StartWallets(CScheduler &scheduler, const ArgsManager &args); //! Flush all wallets in preparation for shutdown. void FlushWallets(); diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -11,6 +11,7 @@ #include #include #include +#include bool VerifyWallets(const CChainParams &chainParams, interfaces::Chain &chain, const std::vector &wallet_files) { @@ -94,18 +95,20 @@ return true; } -void StartWallets(CScheduler &scheduler) { +void StartWallets(CScheduler &scheduler, const ArgsManager &args) { for (const std::shared_ptr &pwallet : GetWallets()) { pwallet->postInitProcess(); } // Schedule periodic wallet flushes and tx rebroadcasts - scheduler.scheduleEvery( - [] { - MaybeCompactWalletDB(); - return true; - }, - std::chrono::milliseconds{500}); + if (args.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) { + scheduler.scheduleEvery( + [] { + MaybeCompactWalletDB(); + return true; + }, + std::chrono::milliseconds{500}); + } scheduler.scheduleEvery( [] { MaybeResendWalletTxs(); diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp --- a/src/wallet/test/init_test_fixture.cpp +++ b/src/wallet/test/init_test_fixture.cpp @@ -6,13 +6,14 @@ #include #include +#include #include InitWalletDirTestingSetup::InitWalletDirTestingSetup( const std::string &chainName) : BasicTestingSetup(chainName) { m_chain = interfaces::MakeChain(m_node, Params()); - m_chain_client = MakeWalletClient(*m_chain, {}); + m_chain_client = MakeWalletClient(*m_chain, *Assert(m_node.args), {}); std::string sep; sep += fs::path::preferred_separator; diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h --- a/src/wallet/test/wallet_test_fixture.h +++ b/src/wallet/test/wallet_test_fixture.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -23,7 +24,7 @@ std::unique_ptr m_chain; std::unique_ptr m_chain_client = - interfaces::MakeWalletClient(*m_chain, {}); + interfaces::MakeWalletClient(*m_chain, *Assert(m_node.args), {}); CWallet m_wallet; std::unique_ptr m_chain_notifications_handler; }; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -936,9 +936,6 @@ if (fOneThread.exchange(true)) { return; } - if (!gArgs.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) { - return; - } for (const std::shared_ptr &pwallet : GetWallets()) { WalletDatabase &dbh = pwallet->GetDBHandle(); diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py --- a/test/functional/wallet_dump.py +++ b/test/functional/wallet_dump.py @@ -164,6 +164,10 @@ result = self.nodes[0].getaddressinfo(multisig_addr) assert result['ismine'] is True + self.log.info('Check that wallet is flushed') + with self.nodes[0].assert_debug_log(['Flushing wallet.dat'], timeout=20): + self.nodes[0].getnewaddress() + if __name__ == '__main__': WalletDumpTest().main()