Skip to content

Commit ea961c3

Browse files
committed
Remove direct node->wallet calls in init.cpp
Route calls during node initialization and shutdown that would happen between a node process and wallet processes through the serializable `Chain::Client` interface, rather than `WalletInitInterface` which is now simpler and only deals with early initialization and parameter interaction. This commit mostly does not change behavior. The only change is that the "Wallet disabled!" and "No wallet support compiled in!" messages are now logged earlier during startup.
1 parent 8db11dd commit ea961c3

File tree

11 files changed

+114
-85
lines changed

11 files changed

+114
-85
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ endif
467467
bitcoind_LDADD = \
468468
$(LIBBITCOIN_SERVER) \
469469
$(LIBBITCOIN_WALLET) \
470+
$(LIBBITCOIN_SERVER) \
470471
$(LIBBITCOIN_COMMON) \
471472
$(LIBUNIVALUE) \
472473
$(LIBBITCOIN_UTIL) \

src/dummywallet.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,7 @@ class DummyWalletInit : public WalletInitInterface {
1414
bool HasWalletSupport() const override {return false;}
1515
void AddWalletOptions() const override;
1616
bool ParameterInteraction() const override {return true;}
17-
void RegisterRPC(CRPCTable &) const override {}
18-
bool Verify(interfaces::Chain& chain) const override {return true;}
19-
bool Open(interfaces::Chain& chain) const override {LogPrintf("No wallet support compiled in!\n"); return true;}
20-
void Start(CScheduler& scheduler) const override {}
21-
void Flush() const override {}
22-
void Stop() const override {}
23-
void Close() const override {}
17+
void Construct(InitInterfaces& interfaces) const override {LogPrintf("No wallet support compiled in!\n");}
2418
};
2519

2620
void DummyWalletInit::AddWalletOptions() const

src/init.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <fs.h>
2020
#include <httpserver.h>
2121
#include <httprpc.h>
22+
#include <interfaces/chain.h>
2223
#include <index/txindex.h>
2324
#include <key.h>
2425
#include <validation.h>
@@ -177,7 +178,9 @@ void Shutdown(InitInterfaces& interfaces)
177178
StopREST();
178179
StopRPC();
179180
StopHTTPServer();
180-
g_wallet_init_interface.Flush();
181+
for (const auto& client : interfaces.chain_clients) {
182+
client->flush();
183+
}
181184
StopMapPort();
182185

183186
// Because these depend on each-other, we make sure that neither can be
@@ -240,7 +243,9 @@ void Shutdown(InitInterfaces& interfaces)
240243
pcoinsdbview.reset();
241244
pblocktree.reset();
242245
}
243-
g_wallet_init_interface.Stop();
246+
for (const auto& client : interfaces.chain_clients) {
247+
client->stop();
248+
}
244249

245250
#if ENABLE_ZMQ
246251
if (g_zmq_notification_interface) {
@@ -260,7 +265,7 @@ void Shutdown(InitInterfaces& interfaces)
260265
UnregisterAllValidationInterfaces();
261266
GetMainSignals().UnregisterBackgroundSignalScheduler();
262267
GetMainSignals().UnregisterWithMempoolSignals(mempool);
263-
g_wallet_init_interface.Close();
268+
interfaces.chain_clients.clear();
264269
globalVerifyHandle.reset();
265270
ECC_Stop();
266271
LogPrintf("%s: done\n", __func__);
@@ -1222,11 +1227,19 @@ bool AppInitMain(InitInterfaces& interfaces)
12221227
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
12231228
GetMainSignals().RegisterWithMempoolSignals(mempool);
12241229

1230+
// Create client interfaces for wallets that are supposed to be loaded
1231+
// according to -wallet and -disablewallet options. This only constructs
1232+
// the interfaces, it doesn't load wallet data. Wallets actually get loaded
1233+
// when load() and start() interface methods are called below.
1234+
g_wallet_init_interface.Construct(interfaces);
1235+
12251236
/* Register RPC commands regardless of -server setting so they will be
12261237
* available in the GUI RPC console even if external calls are disabled.
12271238
*/
12281239
RegisterAllCoreRPCCommands(tableRPC);
1229-
g_wallet_init_interface.RegisterRPC(tableRPC);
1240+
for (const auto& client : interfaces.chain_clients) {
1241+
client->registerRpcs();
1242+
}
12301243
g_rpc_interfaces = &interfaces;
12311244
#if ENABLE_ZMQ
12321245
RegisterZMQRPCCommands(tableRPC);
@@ -1245,7 +1258,11 @@ bool AppInitMain(InitInterfaces& interfaces)
12451258
}
12461259

12471260
// ********************************************************* Step 5: verify wallet database integrity
1248-
if (!g_wallet_init_interface.Verify(*interfaces.chain)) return false;
1261+
for (const auto& client : interfaces.chain_clients) {
1262+
if (!client->verify()) {
1263+
return false;
1264+
}
1265+
}
12491266

12501267
// ********************************************************* Step 6: network initialization
12511268
// Note that we absolutely cannot open any actual connections
@@ -1564,7 +1581,11 @@ bool AppInitMain(InitInterfaces& interfaces)
15641581
}
15651582

15661583
// ********************************************************* Step 9: load wallet
1567-
if (!g_wallet_init_interface.Open(*interfaces.chain)) return false;
1584+
for (const auto& client : interfaces.chain_clients) {
1585+
if (!client->load()) {
1586+
return false;
1587+
}
1588+
}
15681589

15691590
// ********************************************************* Step 10: data directory maintenance
15701591

@@ -1710,7 +1731,9 @@ bool AppInitMain(InitInterfaces& interfaces)
17101731
SetRPCWarmupFinished();
17111732
uiInterface.InitMessage(_("Done loading"));
17121733

1713-
g_wallet_init_interface.Start(scheduler);
1734+
for (const auto& client : interfaces.chain_clients) {
1735+
client->start(scheduler);
1736+
}
17141737

17151738
return true;
17161739
}

src/interfaces/chain.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <string>
1010
#include <vector>
1111

12+
class CScheduler;
13+
1214
namespace interfaces {
1315

1416
//! Interface for giving wallet processes access to blockchain state.
@@ -24,6 +26,24 @@ class ChainClient
2426
{
2527
public:
2628
virtual ~ChainClient() {}
29+
30+
//! Register rpcs.
31+
virtual void registerRpcs() = 0;
32+
33+
//! Check for errors before loading.
34+
virtual bool verify() = 0;
35+
36+
//! Load saved state.
37+
virtual bool load() = 0;
38+
39+
//! Start client execution and provide a scheduler.
40+
virtual void start(CScheduler& scheduler) = 0;
41+
42+
//! Save state to disk.
43+
virtual void flush() = 0;
44+
45+
//! Shut down client.
46+
virtual void stop() = 0;
2747
};
2848

2949
//! Return implementation of Chain interface.

src/interfaces/wallet.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
#include <amount.h>
88
#include <chain.h>
99
#include <consensus/validation.h>
10+
#include <init.h>
1011
#include <interfaces/chain.h>
1112
#include <interfaces/handler.h>
1213
#include <net.h>
1314
#include <policy/feerate.h>
1415
#include <policy/fees.h>
1516
#include <policy/policy.h>
1617
#include <primitives/transaction.h>
18+
#include <rpc/server.h>
19+
#include <scheduler.h>
1720
#include <script/ismine.h>
1821
#include <script/standard.h>
1922
#include <support/allocators/secure.h>
@@ -25,7 +28,9 @@
2528
#include <validation.h>
2629
#include <wallet/feebumper.h>
2730
#include <wallet/fees.h>
31+
#include <wallet/rpcwallet.h>
2832
#include <wallet/wallet.h>
33+
#include <wallet/walletutil.h>
2934

3035
#include <memory>
3136
#include <string>
@@ -470,6 +475,13 @@ class WalletClientImpl : public ChainClient
470475
: m_chain(chain), m_wallet_filenames(std::move(wallet_filenames))
471476
{
472477
}
478+
void registerRpcs() override { return RegisterWalletRPCCommands(::tableRPC); }
479+
bool verify() override { return VerifyWallets(m_chain, m_wallet_filenames); }
480+
bool load() override { return LoadWallets(m_chain, m_wallet_filenames); }
481+
void start(CScheduler& scheduler) override { return StartWallets(scheduler); }
482+
void flush() override { return FlushWallets(); }
483+
void stop() override { return StopWallets(); }
484+
~WalletClientImpl() override { UnloadWallets(); }
473485

474486
Chain& m_chain;
475487
std::vector<std::string> m_wallet_filenames;

src/wallet/init.cpp

Lines changed: 16 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <chainparams.h>
77
#include <init.h>
8+
#include <interfaces/chain.h>
89
#include <net.h>
910
#include <scheduler.h>
1011
#include <outputtype.h>
@@ -28,28 +29,8 @@ class WalletInit : public WalletInitInterface {
2829
//! Wallets parameter interaction
2930
bool ParameterInteraction() const override;
3031

31-
//! Register wallet RPCs.
32-
void RegisterRPC(CRPCTable &tableRPC) const override;
33-
34-
//! Responsible for reading and validating the -wallet arguments and verifying the wallet database.
35-
// This function will perform salvage on the wallet if requested, as long as only one wallet is
36-
// being loaded (WalletParameterInteraction forbids -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet).
37-
bool Verify(interfaces::Chain& chain) const override;
38-
39-
//! Load wallet databases.
40-
bool Open(interfaces::Chain& chain) const override;
41-
42-
//! Complete startup of wallets.
43-
void Start(CScheduler& scheduler) const override;
44-
45-
//! Flush all wallets in preparation for shutdown.
46-
void Flush() const override;
47-
48-
//! Stop all wallets. Wallets will be flushed first.
49-
void Stop() const override;
50-
51-
//! Close all wallets.
52-
void Close() const override;
32+
//! Add wallets that should be opened to list of init interfaces.
33+
void Construct(InitInterfaces& interfaces) const override;
5334
};
5435

5536
const WalletInitInterface& g_wallet_init_interface = WalletInit();
@@ -99,7 +80,6 @@ bool WalletInit::ParameterInteraction() const
9980
return true;
10081
}
10182

102-
gArgs.SoftSetArg("-wallet", "");
10383
const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1;
10484

10585
if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && gArgs.SoftSetBoolArg("-walletbroadcast", false)) {
@@ -165,21 +145,8 @@ bool WalletInit::ParameterInteraction() const
165145
return true;
166146
}
167147

168-
void WalletInit::RegisterRPC(CRPCTable &t) const
169-
{
170-
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
171-
return;
172-
}
173-
174-
RegisterWalletRPCCommands(t);
175-
}
176-
177-
bool WalletInit::Verify(interfaces::Chain& chain) const
148+
bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wallet_files)
178149
{
179-
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
180-
return true;
181-
}
182-
183150
if (gArgs.IsArgSet("-walletdir")) {
184151
fs::path wallet_dir = gArgs.GetArg("-walletdir", "");
185152
boost::system::error_code error;
@@ -200,8 +167,6 @@ bool WalletInit::Verify(interfaces::Chain& chain) const
200167

201168
uiInterface.InitMessage(_("Verifying wallet(s)..."));
202169

203-
std::vector<std::string> wallet_files = gArgs.GetArgs("-wallet");
204-
205170
// Parameter interaction code should have thrown an error if -salvagewallet
206171
// was enabled with more than wallet file, so the wallet_files size check
207172
// here should have no effect.
@@ -228,14 +193,19 @@ bool WalletInit::Verify(interfaces::Chain& chain) const
228193
return true;
229194
}
230195

231-
bool WalletInit::Open(interfaces::Chain& chain) const
196+
void WalletInit::Construct(InitInterfaces& interfaces) const
232197
{
233198
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
234199
LogPrintf("Wallet disabled!\n");
235-
return true;
200+
return;
236201
}
202+
gArgs.SoftSetArg("-wallet", "");
203+
interfaces.chain_clients.emplace_back(interfaces::MakeWalletClient(*interfaces.chain, gArgs.GetArgs("-wallet")));
204+
}
237205

238-
for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
206+
bool LoadWallets(interfaces::Chain& chain, const std::vector<std::string>& wallet_files)
207+
{
208+
for (const std::string& walletFile : wallet_files) {
239209
std::shared_ptr<CWallet> pwallet = CWallet::CreateWalletFromFile(chain, WalletLocation(walletFile));
240210
if (!pwallet) {
241211
return false;
@@ -246,7 +216,7 @@ bool WalletInit::Open(interfaces::Chain& chain) const
246216
return true;
247217
}
248218

249-
void WalletInit::Start(CScheduler& scheduler) const
219+
void StartWallets(CScheduler& scheduler)
250220
{
251221
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
252222
pwallet->postInitProcess();
@@ -256,21 +226,21 @@ void WalletInit::Start(CScheduler& scheduler) const
256226
scheduler.scheduleEvery(MaybeCompactWalletDB, 500);
257227
}
258228

259-
void WalletInit::Flush() const
229+
void FlushWallets()
260230
{
261231
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
262232
pwallet->Flush(false);
263233
}
264234
}
265235

266-
void WalletInit::Stop() const
236+
void StopWallets()
267237
{
268238
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
269239
pwallet->Flush(true);
270240
}
271241
}
272242

273-
void WalletInit::Close() const
243+
void UnloadWallets()
274244
{
275245
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
276246
RemoveWallet(pwallet);

src/wallet/test/init_test_fixture.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainName): BasicTestingSetup(chainName)
1010
{
11+
m_chain_client = MakeWalletClient(*m_chain, {});
12+
1113
std::string sep;
1214
sep += fs::path::preferred_separator;
1315

src/wallet/test/init_test_fixture.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct InitWalletDirTestingSetup: public BasicTestingSetup {
1818
fs::path m_cwd;
1919
std::map<std::string, fs::path> m_walletdir_path_cases;
2020
std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain();
21+
std::unique_ptr<interfaces::ChainClient> m_chain_client;
2122
};
2223

2324
#endif // BITCOIN_WALLET_TEST_INIT_TEST_FIXTURE_H

0 commit comments

Comments
 (0)