diff options
author | Russell Yanofsky <russ@yanofsky.org> | 2017-11-15 15:44:36 -0500 |
---|---|---|
committer | Russell Yanofsky <russ@yanofsky.org> | 2018-03-03 10:26:55 -0500 |
commit | be8ab7d082228d09ca529d1a08730d7d5aacb0ed (patch) | |
tree | d1fc152627f6c6daf32034520d51abbb2701d9ae /src/wallet | |
parent | 26c06f24e5dcc32a7599abb8d670d22993c82bc2 (diff) |
Create new wallet databases as directories rather than files
This change should make it easier for users to make complete backups of wallets
because they can now just back up the specified `-wallet=<path>` path directly,
instead of having to back up the specified path as well as the transaction log
directory (for incompletely flushed wallets).
Another advantage of this change is that if two wallets are located in the same
directory, they will now use their own BerkeleyDB environments instead using a
shared environment. Using a shared environment makes it difficult to manage and
back up wallets separately because transaction log files will contain a mix of
data from all wallets in the environment.
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/db.cpp | 15 | ||||
-rw-r--r-- | src/wallet/init.cpp | 22 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 1 | ||||
-rw-r--r-- | src/wallet/wallet.h | 2 |
4 files changed, 30 insertions, 10 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 0ef3b7e926..ebe7b48da0 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -59,8 +59,19 @@ std::map<std::string, CDBEnv> g_dbenvs; //!< Map from directory name to open db CDBEnv* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename) { - fs::path env_directory = wallet_path.parent_path(); - database_filename = wallet_path.filename().string(); + fs::path env_directory; + if (fs::is_regular_file(wallet_path)) { + // Special case for backwards compatibility: if wallet path points to an + // existing file, treat it as the path to a BDB data file in a parent + // directory that also contains BDB log files. + env_directory = wallet_path.parent_path(); + database_filename = wallet_path.filename().string(); + } else { + // Normal case: Interpret wallet path as a directory path containing + // data and log files. + env_directory = wallet_path; + database_filename = "wallet.dat"; + } LOCK(cs_db); // Note: An ununsed temporary CDBEnv object may be created inside the // emplace function if the key already exists. This is a little inefficient, diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 11fd067b4b..e028cf4210 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -35,7 +35,7 @@ std::string GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); - strUsage += HelpMessageOpt("-wallet=<path>", _("Specify wallet database path. Can be specified multiple times to load multiple wallets. Path is interpreted relative to <walletdir> if it is not absolute, and will be created if it does not exist.") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); + strUsage += HelpMessageOpt("-wallet=<path>", _("Specify wallet database path. Can be specified multiple times to load multiple wallets. Path is interpreted relative to <walletdir> if it is not absolute, and will be created if it does not exist (as a directory containing a wallet.dat file and log files). For backwards compatibility this will also accept names of existing data files in <walletdir>.)")); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); strUsage += HelpMessageOpt("-walletdir=<dir>", _("Specify directory to hold wallets (default: <datadir>/wallets if it exists, otherwise <datadir>)")); strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); @@ -66,7 +66,7 @@ bool WalletParameterInteraction() return true; } - gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT); + gArgs.SoftSetArg("-wallet", ""); const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && gArgs.SoftSetBoolArg("-walletbroadcast", false)) { @@ -230,10 +230,22 @@ bool VerifyWallets() std::set<fs::path> wallet_paths; for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { + // Do some checking on wallet path. It should be either a: + // + // 1. Path where a directory can be created. + // 2. Path to an existing directory. + // 3. Path to a symlink to a directory. + // 4. For backwards compatibility, the name of a data file in -walletdir. fs::path wallet_path = fs::absolute(walletFile, GetWalletDir()); - - if (fs::exists(wallet_path) && (!fs::is_regular_file(wallet_path) || fs::is_symlink(wallet_path))) { - return InitError(strprintf(_("Error loading wallet %s. -wallet filename must be a regular file."), walletFile)); + fs::file_type path_type = fs::symlink_status(wallet_path).type(); + if (!(path_type == fs::file_not_found || path_type == fs::directory_file || + (path_type == fs::symlink_file && fs::is_directory(wallet_path)) || + (path_type == fs::regular_file && fs::path(walletFile).filename() == walletFile))) { + return InitError(strprintf( + _("Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and " + "database/log.?????????? files can be stored, a location where such a directory could be created, " + "or (for backwards compatibility) the name of an existing data file in -walletdir (%s)"), + walletFile, GetWalletDir())); } if (!wallet_paths.insert(wallet_path).second) { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b1e2181ec7..960c192640 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -45,7 +45,6 @@ OutputType g_address_type = OUTPUT_TYPE_NONE; OutputType g_change_type = OUTPUT_TYPE_NONE; bool g_wallet_allow_fallback_fee = true; //<! will be defined via chainparams -const char * DEFAULT_WALLET_DAT = "wallet.dat"; const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; /** diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 76a411d81b..3e2d1794d8 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -68,8 +68,6 @@ static const bool DEFAULT_WALLET_RBF = false; static const bool DEFAULT_WALLETBROADCAST = true; static const bool DEFAULT_DISABLE_WALLET = false; -extern const char * DEFAULT_WALLET_DAT; - static const int64_t TIMESTAMP_MIN = 0; class CBlockIndex; |