From 975783cb79e929260873c1055d4b415cd33bb6b9 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Fri, 24 Jan 2025 07:31:09 +0100 Subject: [PATCH 1/2] descriptor: account for all StringType in MiniscriptDescriptor::ToStringHelper() --- src/script/descriptor.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 2e1a30744ec..99aba6c4641 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -1286,20 +1286,33 @@ class StringMaker { const SigningProvider* m_arg; //! Keys contained in the Miniscript (a reference to DescriptorImpl::m_pubkey_args). const std::vector>& m_pubkeys; - //! Whether to serialize keys as private or public. - bool m_private; + //! StringType to serialize keys + const DescriptorImpl::StringType m_type; + const DescriptorCache* m_cache; public: - StringMaker(const SigningProvider* arg LIFETIMEBOUND, const std::vector>& pubkeys LIFETIMEBOUND, bool priv) - : m_arg(arg), m_pubkeys(pubkeys), m_private(priv) {} + StringMaker(const SigningProvider* arg LIFETIMEBOUND, + const std::vector>& pubkeys LIFETIMEBOUND, + DescriptorImpl::StringType type, + const DescriptorCache* cache LIFETIMEBOUND) + : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {} std::optional ToString(uint32_t key) const { std::string ret; - if (m_private) { - if (!m_pubkeys[key]->ToPrivateString(*m_arg, ret)) return {}; - } else { + switch (m_type) { + case DescriptorImpl::StringType::PUBLIC: ret = m_pubkeys[key]->ToString(); + break; + case DescriptorImpl::StringType::PRIVATE: + if (!m_pubkeys[key]->ToPrivateString(*m_arg, ret)) return {}; + break; + case DescriptorImpl::StringType::NORMALIZED: + if (!m_pubkeys[key]->ToNormalizedString(*m_arg, ret, m_cache)) return {}; + break; + case DescriptorImpl::StringType::COMPAT: + ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT); + break; } return ret; } @@ -1332,7 +1345,7 @@ public: bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const override { - if (const auto res = m_node->ToString(StringMaker(arg, m_pubkey_args, type == StringType::PRIVATE))) { + if (const auto res = m_node->ToString(StringMaker(arg, m_pubkey_args, type, cache))) { out = *res; return true; } From 28a4fcb03c0fb1cd5112eca1eb36dcb13e0b4ff2 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Fri, 24 Jan 2025 17:27:06 +0100 Subject: [PATCH 2/2] test: check listdescriptors do not return a mix of hardened derivation marker --- test/functional/wallet_listdescriptors.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/functional/wallet_listdescriptors.py b/test/functional/wallet_listdescriptors.py index c9d6c1f190d..1b9d59a959c 100755 --- a/test/functional/wallet_listdescriptors.py +++ b/test/functional/wallet_listdescriptors.py @@ -134,6 +134,26 @@ class ListDescriptorsTest(BitcoinTestFramework): } assert_equal(expected, wallet.listdescriptors()) + self.log.info('Test taproot descriptor do not have mixed hardened derivation marker') + node.createwallet(wallet_name='w5', descriptors=True, disable_private_keys=True) + wallet = node.get_wallet_rpc('w5') + wallet.importdescriptors([{ + 'desc': "tr([1dce71b2/48'/1'/0'/2']tpubDEeP3GefjqbaDTTaVAF5JkXWhoFxFDXQ9KuhVrMBViFXXNR2B3Lvme2d2AoyiKfzRFZChq2AGMNbU1qTbkBMfNv7WGVXLt2pnYXY87gXqcs/0/*,and_v(v:pk([c658b283/48'/1'/0'/2']tpubDFL5wzgPBYK5pZ2Kh1T8qrxnp43kjE5CXfguZHHBrZSWpkfASy5rVfj7prh11XdqkC1P3kRwUPBeX7AHN8XBNx8UwiprnFnEm5jyswiRD4p/0/*),older(65535)))#xl20m6md", + 'timestamp': TIME_GENESIS_BLOCK, + }]) + expected = { + 'wallet_name': 'w5', + 'descriptors': [ + {'active': False, + 'desc': 'tr([1dce71b2/48h/1h/0h/2h]tpubDEeP3GefjqbaDTTaVAF5JkXWhoFxFDXQ9KuhVrMBViFXXNR2B3Lvme2d2AoyiKfzRFZChq2AGMNbU1qTbkBMfNv7WGVXLt2pnYXY87gXqcs/0/*,and_v(v:pk([c658b283/48h/1h/0h/2h]tpubDFL5wzgPBYK5pZ2Kh1T8qrxnp43kjE5CXfguZHHBrZSWpkfASy5rVfj7prh11XdqkC1P3kRwUPBeX7AHN8XBNx8UwiprnFnEm5jyswiRD4p/0/*),older(65535)))#m4uznndk', + 'timestamp': TIME_GENESIS_BLOCK, + 'range': [0, 0], + 'next': 0, + 'next_index': 0}, + ] + } + assert_equal(expected, wallet.listdescriptors()) + if __name__ == '__main__': ListDescriptorsTest(__file__).main()