Bitcoin ABC  0.24.7
P2P Digital Currency
load.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <wallet/load.h>
7 
8 #include <fs.h>
9 #include <interfaces/chain.h>
10 #include <scheduler.h>
11 #include <util/string.h>
12 #include <util/system.h>
13 #include <util/translation.h>
14 #include <wallet/wallet.h>
15 #include <wallet/walletdb.h>
16 
17 #include <univalue.h>
18 
20  if (gArgs.IsArgSet("-walletdir")) {
21  fs::path wallet_dir = gArgs.GetArg("-walletdir", "");
22  boost::system::error_code error;
23  // The canonical path cleans the path, preventing >1 Berkeley
24  // environment instances for the same directory
25  fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
26  if (error || !fs::exists(wallet_dir)) {
27  chain.initError(
28  strprintf(_("Specified -walletdir \"%s\" does not exist"),
29  wallet_dir.string()));
30  return false;
31  } else if (!fs::is_directory(wallet_dir)) {
32  chain.initError(
33  strprintf(_("Specified -walletdir \"%s\" is not a directory"),
34  wallet_dir.string()));
35  return false;
36  // The canonical path transforms relative paths into absolute ones,
37  // so we check the non-canonical version
38  } else if (!wallet_dir.is_absolute()) {
39  chain.initError(
40  strprintf(_("Specified -walletdir \"%s\" is a relative path"),
41  wallet_dir.string()));
42  return false;
43  }
44  gArgs.ForceSetArg("-walletdir", canonical_wallet_dir.string());
45  }
46 
47  LogPrintf("Using wallet directory %s\n", GetWalletDir().string());
48 
49  chain.initMessage(_("Verifying wallet(s)...").translated);
50 
51  // For backwards compatibility if an unnamed top level wallet exists in the
52  // wallets directory, include it in the default list of wallets to load.
53  if (!gArgs.IsArgSet("wallet")) {
54  DatabaseOptions options;
55  DatabaseStatus status;
56  bilingual_str error_string;
57  options.require_existing = true;
58  options.verify = false;
59  if (MakeWalletDatabase("", options, status, error_string)) {
60  gArgs.LockSettings([&](util::Settings &settings) {
62  // Default wallet name is ""
63  wallets.push_back("");
64  settings.rw_settings["wallet"] = wallets;
65  });
66  }
67  }
68 
69  // Keep track of each wallet absolute path to detect duplicates.
70  std::set<fs::path> wallet_paths;
71 
72  for (const auto &wallet_file : gArgs.GetArgs("-wallet")) {
73  const fs::path path = fs::absolute(wallet_file, GetWalletDir());
74 
75  if (!wallet_paths.insert(path).second) {
76  chain.initError(strprintf(_("Error loading wallet %s. Duplicate "
77  "-wallet filename specified."),
78  wallet_file));
79  return false;
80  }
81 
82  DatabaseOptions options;
83  DatabaseStatus status;
84  options.verify = true;
85  bilingual_str error_string;
86  if (!MakeWalletDatabase(wallet_file, options, status, error_string)) {
87  chain.initError(error_string);
88  return false;
89  }
90  }
91 
92  return true;
93 }
94 
96  try {
97  for (const std::string &name : gArgs.GetArgs("-wallet")) {
98  DatabaseOptions options;
99  DatabaseStatus status;
100  // No need to verify, assuming verified earlier in VerifyWallets()
101  options.verify = false;
103  std::vector<bilingual_str> warnings;
104  std::unique_ptr<WalletDatabase> database =
105  MakeWalletDatabase(name, options, status, error);
106  std::shared_ptr<CWallet> pwallet =
107  database
108  ? CWallet::Create(chain, name, std::move(database),
109  options.create_flags, error, warnings)
110  : nullptr;
111 
112  if (!warnings.empty()) {
113  chain.initWarning(Join(warnings, Untranslated("\n")));
114  }
115  if (!pwallet) {
116  chain.initError(error);
117  return false;
118  }
119  AddWallet(pwallet);
120  }
121  return true;
122  } catch (const std::runtime_error &e) {
123  chain.initError(Untranslated(e.what()));
124  return false;
125  }
126 }
127 
128 void StartWallets(CScheduler &scheduler, const ArgsManager &args) {
129  for (const std::shared_ptr<CWallet> &pwallet : GetWallets()) {
130  pwallet->postInitProcess();
131  }
132 
133  // Schedule periodic wallet flushes and tx rebroadcasts
134  if (args.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) {
135  scheduler.scheduleEvery(
136  [] {
138  return true;
139  },
140  std::chrono::milliseconds{500});
141  }
142  scheduler.scheduleEvery(
143  [] {
145  return true;
146  },
147  std::chrono::milliseconds{1000});
148 }
149 
150 void FlushWallets() {
151  for (const std::shared_ptr<CWallet> &pwallet : GetWallets()) {
152  pwallet->Flush();
153  }
154 }
155 
156 void StopWallets() {
157  for (const std::shared_ptr<CWallet> &pwallet : GetWallets()) {
158  pwallet->Close();
159  }
160 }
161 
163  auto wallets = GetWallets();
164  while (!wallets.empty()) {
165  auto wallet = wallets.back();
166  wallets.pop_back();
167  std::vector<bilingual_str> warnings;
168  RemoveWallet(wallet, std::nullopt, warnings);
169  UnloadWallet(std::move(wallet));
170  }
171 }
DatabaseOptions::require_existing
bool require_existing
Definition: db.h:222
DatabaseOptions
Definition: db.h:221
CScheduler
Simple class for background tasks that should be run periodically or once "after a while".
Definition: scheduler.h:35
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:517
_
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:55
MaybeCompactWalletDB
void MaybeCompactWalletDB()
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
Definition: walletdb.cpp:1044
wallet.h
util::Settings
Stored settings.
Definition: settings.h:31
DEFAULT_FLUSHWALLET
static const bool DEFAULT_FLUSHWALLET
Overview of wallet database classes:
Definition: walletdb.h:34
DatabaseOptions::verify
bool verify
Definition: db.h:226
fs.h
string.h
bilingual_str
Bilingual messages:
Definition: translation.h:17
RemoveWallet
bool RemoveWallet(const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:117
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:400
MakeWalletDatabase
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
Definition: wallet.cpp:4221
LoadWallets
bool LoadWallets(interfaces::Chain &chain)
Load wallet databases.
Definition: load.cpp:95
chain.h
scheduler.h
UniValue
Definition: univalue.h:23
CScheduler::scheduleEvery
void scheduleEvery(Predicate p, std::chrono::milliseconds delta)
Repeat p until it return false.
Definition: scheduler.cpp:112
VerifyWallets
bool VerifyWallets(interfaces::Chain &chain)
Responsible for reading and validating the -wallet arguments and verifying the wallet database.
Definition: load.cpp:19
load.h
interfaces::Chain
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:108
Untranslated
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:36
FlushWallets
void FlushWallets()
Flush all wallets in preparation for shutdown.
Definition: load.cpp:150
univalue.h
CWallet::Create
static std::shared_ptr< CWallet > Create(interfaces::Chain &chain, const std::string &name, std::unique_ptr< WalletDatabase > database, uint64_t wallet_creation_flags, bilingual_str &error, std::vector< bilingual_str > &warnings)
Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error.
Definition: wallet.cpp:4250
ArgsManager::ForceSetArg
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:542
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:498
StopWallets
void StopWallets()
Stop all wallets. Wallets will be flushed first.
Definition: load.cpp:156
name
const char * name
Definition: rest.cpp:43
UnloadWallet
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
Definition: wallet.cpp:198
interfaces::Chain::initWarning
virtual void initWarning(const bilingual_str &message)=0
Send init warning.
system.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
ArgsManager::LockSettings
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:389
Join
auto Join(const std::vector< T > &list, const BaseType &separator, UnaryOp unary_op) -> decltype(unary_op(list.at(0)))
Join a list of items.
Definition: string.h:36
MaybeResendWalletTxs
void MaybeResendWalletTxs()
Called periodically by the schedule thread.
Definition: wallet.cpp:2395
ArgsManager
Definition: system.h:152
translation.h
gArgs
ArgsManager gArgs
Definition: system.cpp:75
AddWallet
bool AddWallet(const std::shared_ptr< CWallet > &wallet)
Definition: wallet.cpp:104
interfaces::Chain::initMessage
virtual void initMessage(const std::string &message)=0
Send init message.
UniValue::push_back
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
DatabaseStatus
DatabaseStatus
Definition: db.h:229
StartWallets
void StartWallets(CScheduler &scheduler, const ArgsManager &args)
Complete startup of wallets.
Definition: load.cpp:128
util::Settings::rw_settings
std::map< std::string, SettingsValue > rw_settings
Map of setting name to read-write file setting value.
Definition: settings.h:37
walletdb.h
interfaces::Chain::initError
virtual void initError(const bilingual_str &message)=0
Send init error.
ArgsManager::GetArgs
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:391
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
GetWallets
std::vector< std::shared_ptr< CWallet > > GetWallets()
Definition: wallet.cpp:147
UniValue::VARR
@ VARR
Definition: univalue.h:27
GetWalletDir
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:10
LogPrintf
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:175
UnloadWallets
void UnloadWallets()
Close all wallets.
Definition: load.cpp:162
DatabaseOptions::create_flags
uint64_t create_flags
Definition: db.h:224