mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Change MigrateLegacyToDescriptor to reopen wallet as BERKELEY_RO
When we reopen the wallet to do the migration, instead of opening using BDB, open it using the BerkeleyRO implementation.
This commit is contained in:
parent
a786fd2041
commit
517e204bac
@ -2923,7 +2923,7 @@ bool CWallet::EraseAddressReceiveRequest(WalletBatch& batch, const CTxDestinatio
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string)
|
static util::Result<fs::path> GetWalletPath(const std::string& name)
|
||||||
{
|
{
|
||||||
// Do some checking on wallet path. It should be either a:
|
// Do some checking on wallet path. It should be either a:
|
||||||
//
|
//
|
||||||
@ -2936,15 +2936,24 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
|
|||||||
if (!(path_type == fs::file_type::not_found || path_type == fs::file_type::directory ||
|
if (!(path_type == fs::file_type::not_found || path_type == fs::file_type::directory ||
|
||||||
(path_type == fs::file_type::symlink && fs::is_directory(wallet_path)) ||
|
(path_type == fs::file_type::symlink && fs::is_directory(wallet_path)) ||
|
||||||
(path_type == fs::file_type::regular && fs::PathFromString(name).filename() == fs::PathFromString(name)))) {
|
(path_type == fs::file_type::regular && fs::PathFromString(name).filename() == fs::PathFromString(name)))) {
|
||||||
error_string = Untranslated(strprintf(
|
return util::Error{Untranslated(strprintf(
|
||||||
"Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
|
"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, "
|
"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)",
|
"or (for backwards compatibility) the name of an existing data file in -walletdir (%s)",
|
||||||
name, fs::quoted(fs::PathToString(GetWalletDir()))));
|
name, fs::quoted(fs::PathToString(GetWalletDir()))))};
|
||||||
|
}
|
||||||
|
return wallet_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string)
|
||||||
|
{
|
||||||
|
const auto& wallet_path = GetWalletPath(name);
|
||||||
|
if (!wallet_path) {
|
||||||
|
error_string = util::ErrorString(wallet_path);
|
||||||
status = DatabaseStatus::FAILED_BAD_PATH;
|
status = DatabaseStatus::FAILED_BAD_PATH;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return MakeDatabase(wallet_path, options, status, error_string);
|
return MakeDatabase(*wallet_path, options, status, error_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
||||||
@ -4346,11 +4355,24 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
|
|||||||
// If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
|
// If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
|
||||||
bool was_loaded = false;
|
bool was_loaded = false;
|
||||||
if (auto wallet = GetWallet(context, wallet_name)) {
|
if (auto wallet = GetWallet(context, wallet_name)) {
|
||||||
|
if (wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
|
||||||
|
return util::Error{_("Error: This wallet is already a descriptor wallet")};
|
||||||
|
}
|
||||||
|
|
||||||
if (!RemoveWallet(context, wallet, /*load_on_start=*/std::nullopt, warnings)) {
|
if (!RemoveWallet(context, wallet, /*load_on_start=*/std::nullopt, warnings)) {
|
||||||
return util::Error{_("Unable to unload the wallet before migrating")};
|
return util::Error{_("Unable to unload the wallet before migrating")};
|
||||||
}
|
}
|
||||||
UnloadWallet(std::move(wallet));
|
UnloadWallet(std::move(wallet));
|
||||||
was_loaded = true;
|
was_loaded = true;
|
||||||
|
} else {
|
||||||
|
// Check if the wallet is BDB
|
||||||
|
const auto& wallet_path = GetWalletPath(wallet_name);
|
||||||
|
if (!wallet_path) {
|
||||||
|
return util::Error{util::ErrorString(wallet_path)};
|
||||||
|
}
|
||||||
|
if (!IsBDBFile(BDBDataFile(*wallet_path))) {
|
||||||
|
return util::Error{_("Error: This wallet is already a descriptor wallet")};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the wallet but only in the context of this function.
|
// Load the wallet but only in the context of this function.
|
||||||
@ -4359,6 +4381,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
|
|||||||
empty_context.args = context.args;
|
empty_context.args = context.args;
|
||||||
DatabaseOptions options;
|
DatabaseOptions options;
|
||||||
options.require_existing = true;
|
options.require_existing = true;
|
||||||
|
options.require_format = DatabaseFormat::BERKELEY_RO;
|
||||||
DatabaseStatus status;
|
DatabaseStatus status;
|
||||||
std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(wallet_name, options, status, error);
|
std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(wallet_name, options, status, error);
|
||||||
if (!database) {
|
if (!database) {
|
||||||
@ -4373,6 +4396,8 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
|
|||||||
|
|
||||||
// Helper to reload as normal for some of our exit scenarios
|
// Helper to reload as normal for some of our exit scenarios
|
||||||
const auto& reload_wallet = [&](std::shared_ptr<CWallet>& to_reload) {
|
const auto& reload_wallet = [&](std::shared_ptr<CWallet>& to_reload) {
|
||||||
|
// Reset options.require_format as wallets of any format may be reloaded.
|
||||||
|
options.require_format = std::nullopt;
|
||||||
assert(to_reload.use_count() == 1);
|
assert(to_reload.use_count() == 1);
|
||||||
std::string name = to_reload->GetName();
|
std::string name = to_reload->GetName();
|
||||||
to_reload.reset();
|
to_reload.reset();
|
||||||
|
@ -205,9 +205,13 @@ class WalletMigrationTest(BitcoinTestFramework):
|
|||||||
self.assert_list_txs_equal(basic2.listtransactions(), basic2_txs)
|
self.assert_list_txs_equal(basic2.listtransactions(), basic2_txs)
|
||||||
|
|
||||||
# Now test migration on a descriptor wallet
|
# Now test migration on a descriptor wallet
|
||||||
self.log.info("Test \"nothing to migrate\" when the user tries to migrate a wallet with no legacy data")
|
self.log.info("Test \"nothing to migrate\" when the user tries to migrate a loaded wallet with no legacy data")
|
||||||
assert_raises_rpc_error(-4, "Error: This wallet is already a descriptor wallet", basic2.migratewallet)
|
assert_raises_rpc_error(-4, "Error: This wallet is already a descriptor wallet", basic2.migratewallet)
|
||||||
|
|
||||||
|
self.log.info("Test \"nothing to migrate\" when the user tries to migrate an unloaded wallet with no legacy data")
|
||||||
|
basic2.unloadwallet()
|
||||||
|
assert_raises_rpc_error(-4, "Error: This wallet is already a descriptor wallet", self.nodes[0].migratewallet, "basic2")
|
||||||
|
|
||||||
def test_multisig(self):
|
def test_multisig(self):
|
||||||
default = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
|
default = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user