From 2ae1788dd46a71cb47ec25e149ea11fa8689c64f Mon Sep 17 00:00:00 2001 From: Novo Date: Thu, 24 Apr 2025 19:53:51 +0100 Subject: [PATCH 1/2] Skip range verification for non-ranged desc Non-range desc are always added to the wallet with the range [0,0]. After the descriptor is added, the wallet will TopUp the keypool. For non-range descriptors, this process updates the desc range to [0,1]. Any attempts to update this non-range descriptor with a [0,0] range will result in an error because the range checks rejects new ranges not included in the old range. Since this is a non-range desc, the range information should be disregarded and AddWalletDescriptor should always succeed regardless of provided range information --- src/wallet/scriptpubkeyman.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 80f25c62c2b..cf0f370bcbe 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -2852,6 +2852,11 @@ bool DescriptorScriptPubKeyMan::CanUpdateToWalletDescriptor(const WalletDescript return false; } + if (!descriptor.descriptor->IsRange()) { + // Skip range check for non-range descriptors + return true; + } + if (descriptor.range_start > m_wallet_descriptor.range_start || descriptor.range_end < m_wallet_descriptor.range_end) { // Use inclusive range for error From fa0993462b3bc8db40c1a6ea2e7f5fd4a22353a6 Mon Sep 17 00:00:00 2001 From: Novo Date: Thu, 24 Apr 2025 20:00:37 +0100 Subject: [PATCH 2/2] Test updating non-ranged descriptor with [0,0] range succeeds --- src/wallet/test/wallet_tests.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index bb76e4219ca..b71417ba5c8 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -73,6 +73,27 @@ static void AddKey(CWallet& wallet, const CKey& key) assert(spk_manager); } +BOOST_FIXTURE_TEST_CASE(update_non_range_descriptor, TestingSetup) +{ + CWallet wallet(m_node.chain.get(), "", CreateMockableWalletDatabase()); + { + LOCK(wallet.cs_wallet); + wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS); + auto key{GenerateRandomKey()}; + auto desc_str{"combo(" + EncodeSecret(key) + ")"}; + for (size_t i = 0; i < 2; i++) + { + FlatSigningProvider provider; + std::string error; + auto descs{Parse(desc_str, provider, error, /* require_checksum=*/ false)}; + auto& desc{descs.at(0)}; + WalletDescriptor w_desc{std::move(desc), 0, 0, 0, 0}; + auto spk_manager{*Assert(wallet.AddWalletDescriptor(w_desc, provider, "", false))}; + assert(spk_manager); + } + } +} + BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) { // Cap last block file size, and mine new block in a new block file.