mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 06:28:31 +01:00
Merge bitcoin/bitcoin#19651: wallet: importdescriptors update existing
3efaf83c75wallet: deactivate descriptor (S3RK)6737d9655btest: wallet importdescriptors update existing (S3RK)586f1d53d6wallet: maintain SPK consistency on internal flag change (S3RK)f1b7db1474wallet: don't mute exceptions in importdescriptors (S3RK)bf68ebc1cdwallet: allow to import same descriptor twice (S3RK) Pull request description: Rationale: allow updating existing descriptors with `importdescriptors` command. Currently if you run same `importdescriptors` command twice with a descriptor containing private key you will get very confusing error — `Missing required fields`. What happens is that Wallet tries to write imported private key to the disk, but it exists already so we get `DB_KEYEXIST (-30995)` from BerkelyDB. Please note, that we set `DB_NOOVERWRITE` (I guess not to lose some keys accidentally). The exception is caught in `catch (...)` in rpcdump.cpp with a generic error. With this PR if a descriptor is already present than we will update its activeness, internalness, label, range and next_index. For the range only expansion is allowed (range start can only decrease, range end increase). ACKs for top commit: achow101: re-ACK3efaf83c75meshcollider: Code review ACK3efaf83c75jonatack: Light ACK3efaf83c75per `git range-diffa000cb05d96704 3efaf83` and as a sanity check, re-debug-built on debian with gcc 10.2.1 and clang 11, ran wallet_importdescriptors.py Tree-SHA512: 122c4b621d64ec8a3b625f3aed9f01a2b5cbaf2029ad0325b5ff38d67fff5cd35324335fabe2dd5169548b01b267c81be6ae0f5c834342f3d5f6eeed515c4843
This commit is contained in:
@@ -1851,6 +1851,12 @@ bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const
|
||||
AssertLockHeld(cs_desc_man);
|
||||
assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
|
||||
|
||||
// Check if provided key already exists
|
||||
if (m_map_keys.find(pubkey.GetID()) != m_map_keys.end() ||
|
||||
m_map_crypted_keys.find(pubkey.GetID()) != m_map_crypted_keys.end()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_storage.HasEncryptionKeys()) {
|
||||
if (m_storage.IsLocked()) {
|
||||
return false;
|
||||
@@ -2304,3 +2310,37 @@ void DescriptorScriptPubKeyMan::UpgradeDescriptorCache()
|
||||
throw std::runtime_error(std::string(__func__) + ": writing cache items failed");
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorScriptPubKeyMan::UpdateWalletDescriptor(WalletDescriptor& descriptor)
|
||||
{
|
||||
LOCK(cs_desc_man);
|
||||
std::string error;
|
||||
if (!CanUpdateToWalletDescriptor(descriptor, error)) {
|
||||
throw std::runtime_error(std::string(__func__) + ": " + error);
|
||||
}
|
||||
|
||||
m_map_pubkeys.clear();
|
||||
m_map_script_pub_keys.clear();
|
||||
m_max_cached_index = -1;
|
||||
m_wallet_descriptor = descriptor;
|
||||
}
|
||||
|
||||
bool DescriptorScriptPubKeyMan::CanUpdateToWalletDescriptor(const WalletDescriptor& descriptor, std::string& error)
|
||||
{
|
||||
LOCK(cs_desc_man);
|
||||
if (!HasWalletDescriptor(descriptor)) {
|
||||
error = "can only update matching descriptor";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (descriptor.range_start > m_wallet_descriptor.range_start ||
|
||||
descriptor.range_end < m_wallet_descriptor.range_end) {
|
||||
// Use inclusive range for error
|
||||
error = strprintf("new range must include current range = [%d,%d]",
|
||||
m_wallet_descriptor.range_start,
|
||||
m_wallet_descriptor.range_end - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user