aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/bdb.h1
-rw-r--r--src/wallet/db.h3
-rw-r--r--src/wallet/init.cpp2
-rw-r--r--src/wallet/load.cpp13
-rw-r--r--src/wallet/rpcwallet.cpp18
-rw-r--r--src/wallet/scriptpubkeyman.cpp2
-rw-r--r--src/wallet/scriptpubkeyman.h2
-rw-r--r--src/wallet/sqlite.cpp4
-rw-r--r--src/wallet/sqlite.h1
-rw-r--r--src/wallet/wallet.cpp1
-rw-r--r--src/wallet/wallet.h2
-rw-r--r--src/wallet/walletdb.cpp8
-rw-r--r--src/wallet/wallettool.cpp3
-rw-r--r--src/wallet/walletutil.cpp4
14 files changed, 54 insertions, 10 deletions
diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h
index 5403e95ee4..9073c1b6b3 100644
--- a/src/wallet/bdb.h
+++ b/src/wallet/bdb.h
@@ -146,6 +146,7 @@ public:
/** Return path to main database filename */
std::string Filename() override { return (env->Directory() / strFile).string(); }
+ std::string Format() override { return "bdb"; }
/**
* Pointer to shared database environment.
*
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 3ecccd4e00..940d1cd242 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -144,6 +144,8 @@ public:
/** Return path to main database file for logs and error messages. */
virtual std::string Filename() = 0;
+ virtual std::string Format() = 0;
+
std::atomic<unsigned int> nUpdateCounter;
unsigned int nLastSeen;
unsigned int nLastFlushed;
@@ -190,6 +192,7 @@ public:
void IncrementUpdateCounter() override { ++nUpdateCounter; }
void ReloadDbEnv() override {}
std::string Filename() override { return "dummy"; }
+ std::string Format() override { return "dummy"; }
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override { return MakeUnique<DummyBatch>(); }
};
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 5d8c4fba29..8b2ef191fb 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -60,7 +60,7 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
argsman.AddArg("-rescan", "Rescan the block chain for missing wallet transactions on startup", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-spendzeroconfchange", strprintf("Spend unconfirmed change when sending transactions (default: %u)", DEFAULT_SPEND_ZEROCONF_CHANGE), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-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), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
- argsman.AddArg("-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>.)", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::WALLET);
+ argsman.AddArg("-wallet=<path>", "Specify wallet path to load at startup. Can be used multiple times to load multiple wallets. Path is to a directory containing wallet data and log files. If the path is not absolute, it is interpreted relative to <walletdir>. This only loads existing wallets and does not create new ones. For backwards compatibility this also accepts names of existing top-level data files in <walletdir>.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::WALLET);
argsman.AddArg("-walletbroadcast", strprintf("Make the wallet broadcast transactions (default: %u)", DEFAULT_WALLETBROADCAST), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-walletdir=<dir>", "Specify directory to hold wallets (default: <datadir>/wallets if it exists, otherwise <datadir>)", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::WALLET);
#if HAVE_SYSTEM
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index 1b057000d2..1cdcb35fc7 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -71,11 +71,16 @@ bool VerifyWallets(interfaces::Chain& chain)
DatabaseOptions options;
DatabaseStatus status;
+ options.require_existing = true;
options.verify = true;
bilingual_str error_string;
if (!MakeWalletDatabase(wallet_file, options, status, error_string)) {
- chain.initError(error_string);
- return false;
+ if (status == DatabaseStatus::FAILED_NOT_FOUND) {
+ chain.initWarning(Untranslated(strprintf("Skipping -wallet path that doesn't exist. %s\n", error_string.original)));
+ } else {
+ chain.initError(error_string);
+ return false;
+ }
}
}
@@ -88,10 +93,14 @@ bool LoadWallets(interfaces::Chain& chain)
for (const std::string& name : gArgs.GetArgs("-wallet")) {
DatabaseOptions options;
DatabaseStatus status;
+ options.require_existing = true;
options.verify = false; // No need to verify, assuming verified earlier in VerifyWallets()
bilingual_str error;
std::vector<bilingual_str> warnings;
std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(name, options, status, error);
+ if (!database && status == DatabaseStatus::FAILED_NOT_FOUND) {
+ continue;
+ }
std::shared_ptr<CWallet> pwallet = database ? CWallet::Create(chain, name, std::move(database), options.create_flags, error, warnings) : nullptr;
if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n")));
if (!pwallet) {
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index d4255d9eac..ebcab1227d 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2424,6 +2424,7 @@ static RPCHelpMan getwalletinfo()
{
{RPCResult::Type::STR, "walletname", "the wallet name"},
{RPCResult::Type::NUM, "walletversion", "the wallet version"},
+ {RPCResult::Type::STR, "format", "the database format (bdb or sqlite)"},
{RPCResult::Type::STR_AMOUNT, "balance", "DEPRECATED. Identical to getbalances().mine.trusted"},
{RPCResult::Type::STR_AMOUNT, "unconfirmed_balance", "DEPRECATED. Identical to getbalances().mine.untrusted_pending"},
{RPCResult::Type::STR_AMOUNT, "immature_balance", "DEPRECATED. Identical to getbalances().mine.immature"},
@@ -2467,6 +2468,7 @@ static RPCHelpMan getwalletinfo()
int64_t kp_oldest = pwallet->GetOldestKeyPoolTime();
obj.pushKV("walletname", pwallet->GetName());
obj.pushKV("walletversion", pwallet->GetVersion());
+ obj.pushKV("format", pwallet->GetDatabase().Format());
obj.pushKV("balance", ValueFromAmount(bal.m_mine_trusted));
obj.pushKV("unconfirmed_balance", ValueFromAmount(bal.m_mine_untrusted_pending));
obj.pushKV("immature_balance", ValueFromAmount(bal.m_mine_immature));
@@ -2742,6 +2744,9 @@ static RPCHelpMan createwallet()
flags |= WALLET_FLAG_AVOID_REUSE;
}
if (!request.params[5].isNull() && request.params[5].get_bool()) {
+#ifndef USE_SQLITE
+ throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without sqlite support (required for descriptor wallets)");
+#endif
flags |= WALLET_FLAG_DESCRIPTORS;
warnings.emplace_back(Untranslated("Wallet is an experimental descriptor wallet"));
}
@@ -4444,7 +4449,12 @@ static RPCHelpMan upgradewallet()
{
{"version", RPCArg::Type::NUM, /* default */ strprintf("%d", FEATURE_LATEST), "The version number to upgrade to. Default is the latest wallet version"}
},
- RPCResults{},
+ RPCResult{
+ RPCResult::Type::OBJ, "", "",
+ {
+ {RPCResult::Type::STR, "error", /* optional */ true, "Error message (if there is one)"}
+ },
+ },
RPCExamples{
HelpExampleCli("upgradewallet", "169900")
+ HelpExampleRpc("upgradewallet", "169900")
@@ -4469,7 +4479,11 @@ static RPCHelpMan upgradewallet()
if (!pwallet->UpgradeWallet(version, error, warnings)) {
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
}
- return error.original;
+ UniValue obj(UniValue::VOBJ);
+ if (!error.empty()) {
+ obj.pushKV("error", error.original);
+ }
+ return obj;
},
};
}
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index b7c70dac3a..188289b010 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -453,7 +453,7 @@ bool LegacyScriptPubKeyMan::Upgrade(int prev_version, bilingual_str& error)
hd_upgrade = true;
}
// Upgrade to HD chain split if necessary
- if (m_storage.CanSupportFeature(FEATURE_HD_SPLIT) && CHDChain::VERSION_HD_CHAIN_SPLIT) {
+ if (m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) {
WalletLogPrintf("Upgrading wallet to use HD chain split\n");
m_storage.SetMinVersion(FEATURE_PRE_SPLIT_KEYPOOL);
split_upgrade = FEATURE_HD_SPLIT > prev_version;
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index 14fb1fa89f..63c10b7a0d 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -33,7 +33,7 @@ class WalletStorage
public:
virtual ~WalletStorage() = default;
virtual const std::string GetDisplayName() const = 0;
- virtual WalletDatabase& GetDatabase() = 0;
+ virtual WalletDatabase& GetDatabase() const = 0;
virtual bool IsWalletFlagSet(uint64_t) const = 0;
virtual void UnsetBlankWalletFlag(WalletBatch&) = 0;
virtual bool CanSupportFeature(enum WalletFeature) const = 0;
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
index 02a161ecbd..6d2fdbe58b 100644
--- a/src/wallet/sqlite.cpp
+++ b/src/wallet/sqlite.cpp
@@ -619,8 +619,8 @@ bool IsSQLiteFile(const fs::path& path)
file.close();
// Check the magic, see https://sqlite.org/fileformat2.html
- std::string magic_str(magic);
- if (magic_str != std::string("SQLite format 3")) {
+ std::string magic_str(magic, 16);
+ if (magic_str != std::string("SQLite format 3", 16)) {
return false;
}
diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h
index 5e5e93903b..693a2ef55a 100644
--- a/src/wallet/sqlite.h
+++ b/src/wallet/sqlite.h
@@ -105,6 +105,7 @@ public:
void IncrementUpdateCounter() override { ++nUpdateCounter; }
std::string Filename() override { return m_file_path; }
+ std::string Format() override { return "sqlite"; }
/** Make a SQLiteBatch connected to this database */
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 6b7d05fdf3..d1cde6aa89 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -100,6 +100,7 @@ bool AddWallet(const std::shared_ptr<CWallet>& wallet)
if (i != vpwallets.end()) return false;
vpwallets.push_back(wallet);
wallet->ConnectScriptPubKeyManNotifiers();
+ wallet->NotifyCanGetAddressesChanged();
return true;
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 245144a1c9..74de55dcb5 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -739,7 +739,7 @@ public:
{
return *database;
}
- WalletDatabase& GetDatabase() override { return *database; }
+ WalletDatabase& GetDatabase() const override { return *database; }
/**
* Select a set of coins such that nValueRet >= nTargetValue and at least
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 0092a29cb4..aa3b3c10b0 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -15,7 +15,9 @@
#include <util/time.h>
#include <util/translation.h>
#include <wallet/bdb.h>
+#ifdef USE_SQLITE
#include <wallet/sqlite.h>
+#endif
#include <wallet/wallet.h>
#include <atomic>
@@ -1012,6 +1014,7 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas
if (ExistsBerkeleyDatabase(path)) {
format = DatabaseFormat::BERKELEY;
}
+#ifdef USE_SQLITE
if (ExistsSQLiteDatabase(path)) {
if (format) {
error = Untranslated(strprintf("Failed to load database path '%s'. Data is in ambiguous format.", path.string()));
@@ -1020,6 +1023,7 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas
}
format = DatabaseFormat::SQLITE;
}
+#endif
} else if (options.require_existing) {
error = Untranslated(strprintf("Failed to load database path '%s'. Path does not exist.", path.string()));
status = DatabaseStatus::FAILED_NOT_FOUND;
@@ -1048,9 +1052,13 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas
// Format is not set when a db doesn't already exist, so use the format specified by the options if it is set.
if (!format && options.require_format) format = options.require_format;
+#ifdef USE_SQLITE
if (format && format == DatabaseFormat::SQLITE) {
return MakeSQLiteDatabase(path, options, status, error);
}
+#else
+ assert(format != DatabaseFormat::SQLITE);
+#endif
return MakeBerkeleyDatabase(path, options, status, error);
}
diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp
index 4452840eb1..0e18d6a740 100644
--- a/src/wallet/wallettool.cpp
+++ b/src/wallet/wallettool.cpp
@@ -95,6 +95,9 @@ static void WalletShowInfo(CWallet* wallet_instance)
LOCK(wallet_instance->cs_wallet);
tfm::format(std::cout, "Wallet info\n===========\n");
+ tfm::format(std::cout, "Name: %s\n", wallet_instance->GetName());
+ tfm::format(std::cout, "Format: %s\n", wallet_instance->GetDatabase().Format());
+ tfm::format(std::cout, "Descriptors: %s\n", wallet_instance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) ? "yes" : "no");
tfm::format(std::cout, "Encrypted: %s\n", wallet_instance->IsCrypted() ? "yes" : "no");
tfm::format(std::cout, "HD (hd seed available): %s\n", wallet_instance->IsHDEnabled() ? "yes" : "no");
tfm::format(std::cout, "Keypool Size: %u\n", wallet_instance->GetKeyPoolSize());
diff --git a/src/wallet/walletutil.cpp b/src/wallet/walletutil.cpp
index a2a55f9751..2f3e597b90 100644
--- a/src/wallet/walletutil.cpp
+++ b/src/wallet/walletutil.cpp
@@ -8,7 +8,11 @@
#include <util/system.h>
bool ExistsBerkeleyDatabase(const fs::path& path);
+#ifdef USE_SQLITE
bool ExistsSQLiteDatabase(const fs::path& path);
+#else
+# define ExistsSQLiteDatabase(path) (false)
+#endif
fs::path GetWalletDir()
{