diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/bdb.h | 1 | ||||
-rw-r--r-- | src/wallet/db.h | 3 | ||||
-rw-r--r-- | src/wallet/init.cpp | 2 | ||||
-rw-r--r-- | src/wallet/load.cpp | 13 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 18 | ||||
-rw-r--r-- | src/wallet/scriptpubkeyman.cpp | 2 | ||||
-rw-r--r-- | src/wallet/scriptpubkeyman.h | 2 | ||||
-rw-r--r-- | src/wallet/sqlite.cpp | 4 | ||||
-rw-r--r-- | src/wallet/sqlite.h | 1 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 1 | ||||
-rw-r--r-- | src/wallet/wallet.h | 2 | ||||
-rw-r--r-- | src/wallet/walletdb.cpp | 8 | ||||
-rw-r--r-- | src/wallet/wallettool.cpp | 3 | ||||
-rw-r--r-- | src/wallet/walletutil.cpp | 4 |
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() { |