merge bitcoin#18923: Never schedule MaybeCompactWalletDB when -flushwallet is off

Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
Kittywhiskers Van Gogh 2022-06-12 19:41:56 +05:30
parent 9e50d3a159
commit af2984b2ae
11 changed files with 37 additions and 20 deletions

View File

@ -15,6 +15,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
class ArgsManager;
class CBlock; class CBlock;
class CConnman; class CConnman;
class CFeeRate; class CFeeRate;

View File

@ -558,10 +558,11 @@ public:
class WalletClientImpl : public WalletClient class WalletClientImpl : public WalletClient
{ {
public: public:
WalletClientImpl(Chain& chain, std::vector<std::string> wallet_filenames) WalletClientImpl(Chain& chain, ArgsManager& args, std::vector<std::string> wallet_filenames)
: m_wallet_filenames(std::move(wallet_filenames)) : m_wallet_filenames(std::move(wallet_filenames))
{ {
m_context.chain = &chain; m_context.chain = &chain;
m_context.args = &args;
} }
~WalletClientImpl() override { UnloadWallets(); } ~WalletClientImpl() override { UnloadWallets(); }
@ -577,7 +578,7 @@ public:
} }
bool verify() override { return VerifyWallets(*m_context.chain, m_wallet_filenames); } bool verify() override { return VerifyWallets(*m_context.chain, m_wallet_filenames); }
bool load() override { return LoadWallets(*m_context.chain, m_wallet_filenames); } bool load() override { return LoadWallets(*m_context.chain, m_wallet_filenames); }
void start(CScheduler& scheduler) override { return StartWallets(scheduler); } void start(CScheduler& scheduler) override { return StartWallets(scheduler, *Assert(m_context.args)); }
void flush() override { return FlushWallets(); } void flush() override { return FlushWallets(); }
void stop() override { return StopWallets(); } void stop() override { return StopWallets(); }
void setMockTime(int64_t time) override { return SetMockTime(time); } void setMockTime(int64_t time) override { return SetMockTime(time); }
@ -619,7 +620,7 @@ public:
} }
WalletContext m_context; WalletContext m_context;
std::vector<std::string> m_wallet_filenames; const std::vector<std::string> m_wallet_filenames;
std::vector<std::unique_ptr<Handler>> m_rpc_handlers; std::vector<std::unique_ptr<Handler>> m_rpc_handlers;
std::list<CRPCCommand> m_rpc_commands; std::list<CRPCCommand> m_rpc_commands;
}; };
@ -628,9 +629,9 @@ public:
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet) { return wallet ? MakeUnique<WalletImpl>(wallet) : nullptr; } std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet) { return wallet ? MakeUnique<WalletImpl>(wallet) : nullptr; }
std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, std::vector<std::string> wallet_filenames) std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, ArgsManager& args, std::vector<std::string> wallet_filenames)
{ {
return MakeUnique<WalletClientImpl>(chain, std::move(wallet_filenames)); return MakeUnique<WalletClientImpl>(chain, args, std::move(wallet_filenames));
} }
} // namespace interfaces } // namespace interfaces

View File

@ -450,7 +450,7 @@ std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet);
//! Return implementation of ChainClient interface for a wallet client. This //! Return implementation of ChainClient interface for a wallet client. This
//! function will be undefined in builds where ENABLE_WALLET is false. //! function will be undefined in builds where ENABLE_WALLET is false.
std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, std::vector<std::string> wallet_filenames); std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, ArgsManager& args, std::vector<std::string> wallet_filenames);
} // namespace interfaces } // namespace interfaces

View File

@ -42,7 +42,7 @@ Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
const std::function<void(const std::string&)> G_TEST_LOG_FUN{}; const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
// This is all you need to run all the tests // This is all you need to run all the tests
int main(int argc, char *argv[]) int main(int argc, char* argv[])
{ {
// Initialize persistent globals with the testing setup state for sanity. // Initialize persistent globals with the testing setup state for sanity.
// E.g. -datadir in gArgs is set to a temp directory dummy value (instead // E.g. -datadir in gArgs is set to a temp directory dummy value (instead
@ -73,6 +73,8 @@ int main(int argc, char *argv[])
BitcoinApplication app(*node); BitcoinApplication app(*node);
app.setApplicationName("Dash-Qt-test"); app.setApplicationName("Dash-Qt-test");
node->setupServerArgs(); // Make gArgs available in the NodeContext
node->context()->args->ClearArgs(); // Clear added args again
AppTests app_tests(app); AppTests app_tests(app);
if (QTest::qExec(&app_tests) != 0) { if (QTest::qExec(&app_tests) != 0) {
fInvalid = true; fInvalid = true;

View File

@ -5,6 +5,7 @@
#ifndef BITCOIN_WALLET_CONTEXT_H #ifndef BITCOIN_WALLET_CONTEXT_H
#define BITCOIN_WALLET_CONTEXT_H #define BITCOIN_WALLET_CONTEXT_H
class ArgsManager;
namespace interfaces { namespace interfaces {
class Chain; class Chain;
} // namespace interfaces } // namespace interfaces
@ -21,6 +22,7 @@ class Chain;
//! behavior. //! behavior.
struct WalletContext { struct WalletContext {
interfaces::Chain* chain{nullptr}; interfaces::Chain* chain{nullptr};
ArgsManager* args{nullptr};
//! Declare default constructor and destructor that are not inline, so code //! Declare default constructor and destructor that are not inline, so code
//! instantiating the WalletContext struct doesn't need to #include class //! instantiating the WalletContext struct doesn't need to #include class

View File

@ -10,6 +10,7 @@
#include <net.h> #include <net.h>
#include <node/context.h> #include <node/context.h>
#include <univalue.h> #include <univalue.h>
#include <util/check.h>
#include <util/error.h> #include <util/error.h>
#include <util/system.h> #include <util/system.h>
#include <util/moneystr.h> #include <util/moneystr.h>
@ -21,9 +22,9 @@
#include <coinjoin/client.h> #include <coinjoin/client.h>
#include <coinjoin/options.h> #include <coinjoin/options.h>
class WalletInit : public WalletInitInterface { class WalletInit : public WalletInitInterface
{
public: public:
//! Was the wallet component compiled in. //! Was the wallet component compiled in.
bool HasWalletSupport() const override {return true;} bool HasWalletSupport() const override {return true;}
@ -160,20 +161,21 @@ bool WalletInit::ParameterInteraction() const
void WalletInit::Construct(NodeContext& node) const 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"); LogPrintf("Wallet disabled!\n");
return; return;
} }
// If there's no -wallet setting with a list of wallets to load, set it to // If there's no -wallet setting with a list of wallets to load, set it to
// load the default "" wallet. // load the default "" wallet.
if (!gArgs.IsArgSet("wallet")) { if (!args.IsArgSet("wallet")) {
gArgs.LockSettings([&](util::Settings& settings) { args.LockSettings([&](util::Settings& settings) {
util::SettingsValue wallets(util::SettingsValue::VARR); util::SettingsValue wallets(util::SettingsValue::VARR);
wallets.push_back(""); // Default wallet name is "" wallets.push_back(""); // Default wallet name is ""
settings.rw_settings["wallet"] = wallets; settings.rw_settings["wallet"] = wallets;
}); });
} }
auto wallet_client = interfaces::MakeWalletClient(*node.chain, gArgs.GetArgs("-wallet")); auto wallet_client = interfaces::MakeWalletClient(*node.chain, args, args.GetArgs("-wallet"));
node.wallet_client = wallet_client.get(); node.wallet_client = wallet_client.get();
node.chain_clients.emplace_back(std::move(wallet_client)); node.chain_clients.emplace_back(std::move(wallet_client));
} }

View File

@ -88,14 +88,14 @@ bool LoadWallets(interfaces::Chain& chain, const std::vector<std::string>& walle
} }
} }
void StartWallets(CScheduler& scheduler) void StartWallets(CScheduler& scheduler, const ArgsManager& args)
{ {
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) { for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
pwallet->postInitProcess(); pwallet->postInitProcess();
} }
// Schedule periodic wallet flushes and tx rebroadcasts // Schedule periodic wallet flushes and tx rebroadcasts
if (gArgs.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) { if (args.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) {
scheduler.scheduleEvery(MaybeCompactWalletDB, 500); scheduler.scheduleEvery(MaybeCompactWalletDB, 500);
} }
scheduler.scheduleEvery(MaybeResendWalletTxs, 1000); scheduler.scheduleEvery(MaybeResendWalletTxs, 1000);

View File

@ -9,6 +9,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
class ArgsManager;
class CConnman; class CConnman;
class CScheduler; class CScheduler;
@ -23,7 +24,7 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
bool LoadWallets(interfaces::Chain& chain, const std::vector<std::string>& wallet_files); bool LoadWallets(interfaces::Chain& chain, const std::vector<std::string>& wallet_files);
//! Complete startup of wallets. //! Complete startup of wallets.
void StartWallets(CScheduler& scheduler); void StartWallets(CScheduler& scheduler, const ArgsManager& args);
//! Flush all wallets in preparation for shutdown. //! Flush all wallets in preparation for shutdown.
void FlushWallets(); void FlushWallets();

View File

@ -3,13 +3,14 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <fs.h> #include <fs.h>
#include <util/check.h>
#include <util/system.h> #include <util/system.h>
#include <wallet/test/init_test_fixture.h> #include <wallet/test/init_test_fixture.h>
InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainName): BasicTestingSetup(chainName) InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{ {
m_wallet_client = MakeWalletClient(*m_chain, {}); m_wallet_client = MakeWalletClient(*m_chain, *Assert(m_node.args), {});
std::string sep; std::string sep;
sep += fs::path::preferred_separator; sep += fs::path::preferred_separator;

View File

@ -10,17 +10,18 @@
#include <interfaces/chain.h> #include <interfaces/chain.h>
#include <interfaces/wallet.h> #include <interfaces/wallet.h>
#include <node/context.h> #include <node/context.h>
#include <util/check.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
#include <memory> #include <memory>
/** Testing setup and teardown for wallet. /** Testing setup and teardown for wallet.
*/ */
struct WalletTestingSetup: public TestingSetup { struct WalletTestingSetup : public TestingSetup {
explicit WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); explicit WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain(m_node); std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain(m_node);
std::unique_ptr<interfaces::WalletClient> m_wallet_client = interfaces::MakeWalletClient(*m_chain, {}); std::unique_ptr<interfaces::WalletClient> m_wallet_client = interfaces::MakeWalletClient(*m_chain, *Assert(m_node.args), {});
CWallet m_wallet; CWallet m_wallet;
std::unique_ptr<interfaces::Handler> m_chain_notifications_handler; std::unique_ptr<interfaces::Handler> m_chain_notifications_handler;
}; };

View File

@ -86,6 +86,7 @@ class WalletDumpTest(BitcoinTestFramework):
self.skip_if_no_wallet() self.skip_if_no_wallet()
def setup_network(self): def setup_network(self):
self.disable_mocktime()
self.add_nodes(self.num_nodes, extra_args=self.extra_args) self.add_nodes(self.num_nodes, extra_args=self.extra_args)
self.start_nodes() self.start_nodes()
@ -152,5 +153,10 @@ class WalletDumpTest(BitcoinTestFramework):
result = self.nodes[0].getaddressinfo(multisig_addr) result = self.nodes[0].getaddressinfo(multisig_addr)
assert result['ismine'] == True assert result['ismine'] == 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__': if __name__ == '__main__':
WalletDumpTest().main() WalletDumpTest().main()