3333#include < wallet/coincontrol.h>
3434#include < wallet/fees.h>
3535
36+ #include < univalue.h>
37+
3638#include < algorithm>
3739#include < assert.h>
3840
@@ -54,6 +56,42 @@ static RecursiveMutex cs_wallets;
5456static std::vector<std::shared_ptr<CWallet>> vpwallets GUARDED_BY (cs_wallets);
5557static std::list<LoadWalletFn> g_load_wallet_fns GUARDED_BY (cs_wallets);
5658
59+ bool AddWalletSetting (interfaces::Chain& chain, const std::string& wallet_name)
60+ {
61+ util::SettingsValue setting_value = chain.getRwSetting (" wallet" );
62+ if (!setting_value.isArray ()) setting_value.setArray ();
63+ for (const util::SettingsValue& value : setting_value.getValues ()) {
64+ if (value.isStr () && value.get_str () == wallet_name) return true ;
65+ }
66+ setting_value.push_back (wallet_name);
67+ return chain.updateRwSetting (" wallet" , setting_value);
68+ }
69+
70+ bool RemoveWalletSetting (interfaces::Chain& chain, const std::string& wallet_name)
71+ {
72+ util::SettingsValue setting_value = chain.getRwSetting (" wallet" );
73+ if (!setting_value.isArray ()) return true ;
74+ util::SettingsValue new_value (util::SettingsValue::VARR);
75+ for (const util::SettingsValue& value : setting_value.getValues ()) {
76+ if (!value.isStr () || value.get_str () != wallet_name) new_value.push_back (value);
77+ }
78+ if (new_value.size () == setting_value.size ()) return true ;
79+ return chain.updateRwSetting (" wallet" , new_value);
80+ }
81+
82+ static void UpdateWalletSetting (interfaces::Chain& chain,
83+ const std::string& wallet_name,
84+ Optional<bool > load_on_startup,
85+ std::vector<bilingual_str>& warnings)
86+ {
87+ if (load_on_startup == nullopt ) return ;
88+ if (load_on_startup.get () && !AddWalletSetting (chain, wallet_name)) {
89+ warnings.emplace_back (Untranslated (" Wallet load on startup setting could not be updated, so wallet may not be loaded next node startup." ));
90+ } else if (!load_on_startup.get () && !RemoveWalletSetting (chain, wallet_name)) {
91+ warnings.emplace_back (Untranslated (" Wallet load on startup setting could not be updated, so wallet may still be loaded next node startup." ));
92+ }
93+ }
94+
5795bool AddWallet (const std::shared_ptr<CWallet>& wallet)
5896{
5997 LOCK (cs_wallets);
@@ -65,18 +103,32 @@ bool AddWallet(const std::shared_ptr<CWallet>& wallet)
65103 return true ;
66104}
67105
68- bool RemoveWallet (const std::shared_ptr<CWallet>& wallet)
106+ bool RemoveWallet (const std::shared_ptr<CWallet>& wallet, Optional< bool > load_on_start, std::vector<bilingual_str>& warnings )
69107{
70108 assert (wallet);
109+
110+ interfaces::Chain& chain = wallet->chain ();
111+ std::string name = wallet->GetName ();
112+
71113 // Unregister with the validation interface which also drops shared ponters.
72114 wallet->m_chain_notifications_handler .reset ();
73115 LOCK (cs_wallets);
74116 std::vector<std::shared_ptr<CWallet>>::iterator i = std::find (vpwallets.begin (), vpwallets.end (), wallet);
75117 if (i == vpwallets.end ()) return false ;
76118 vpwallets.erase (i);
119+
120+ // Write the wallet setting
121+ UpdateWalletSetting (chain, name, load_on_start, warnings);
122+
77123 return true ;
78124}
79125
126+ bool RemoveWallet (const std::shared_ptr<CWallet>& wallet, Optional<bool > load_on_start)
127+ {
128+ std::vector<bilingual_str> warnings;
129+ return RemoveWallet (wallet, load_on_start, warnings);
130+ }
131+
80132std::vector<std::shared_ptr<CWallet>> GetWallets ()
81133{
82134 LOCK (cs_wallets);
@@ -148,7 +200,7 @@ void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
148200}
149201
150202namespace {
151- std::shared_ptr<CWallet> LoadWalletInternal (interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
203+ std::shared_ptr<CWallet> LoadWalletInternal (interfaces::Chain& chain, const WalletLocation& location, Optional< bool > load_on_start, bilingual_str& error, std::vector<bilingual_str>& warnings)
152204{
153205 try {
154206 if (!CWallet::Verify (chain, location, error, warnings)) {
@@ -163,6 +215,10 @@ std::shared_ptr<CWallet> LoadWalletInternal(interfaces::Chain& chain, const Wall
163215 }
164216 AddWallet (wallet);
165217 wallet->postInitProcess ();
218+
219+ // Write the wallet setting
220+ UpdateWalletSetting (chain, location.GetName (), load_on_start, warnings);
221+
166222 return wallet;
167223 } catch (const std::runtime_error& e) {
168224 error = Untranslated (e.what ());
@@ -171,19 +227,19 @@ std::shared_ptr<CWallet> LoadWalletInternal(interfaces::Chain& chain, const Wall
171227}
172228} // namespace
173229
174- std::shared_ptr<CWallet> LoadWallet (interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
230+ std::shared_ptr<CWallet> LoadWallet (interfaces::Chain& chain, const WalletLocation& location, Optional< bool > load_on_start, bilingual_str& error, std::vector<bilingual_str>& warnings)
175231{
176232 auto result = WITH_LOCK (g_loading_wallet_mutex, return g_loading_wallet_set.insert (location.GetName ()));
177233 if (!result.second ) {
178234 error = Untranslated (" Wallet already being loading." );
179235 return nullptr ;
180236 }
181- auto wallet = LoadWalletInternal (chain, location, error, warnings);
237+ auto wallet = LoadWalletInternal (chain, location, load_on_start, error, warnings);
182238 WITH_LOCK (g_loading_wallet_mutex, g_loading_wallet_set.erase (result.first ));
183239 return wallet;
184240}
185241
186- WalletCreationStatus CreateWallet (interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings, std::shared_ptr<CWallet>& result)
242+ WalletCreationStatus CreateWallet (interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, Optional< bool > load_on_start, bilingual_str& error, std::vector<bilingual_str>& warnings, std::shared_ptr<CWallet>& result)
187243{
188244 // Indicate that the wallet is actually supposed to be blank and not just blank to make it encrypted
189245 bool create_blank = (wallet_creation_flags & WALLET_FLAG_BLANK_WALLET);
@@ -254,6 +310,10 @@ WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString&
254310 AddWallet (wallet);
255311 wallet->postInitProcess ();
256312 result = wallet;
313+
314+ // Write the wallet settings
315+ UpdateWalletSetting (chain, name, load_on_start, warnings);
316+
257317 return WalletCreationStatus::SUCCESS;
258318}
259319
0 commit comments