From 0d55deae157f4f8226b2419d55e7dc0dfb6e4aec Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Wed, 7 Aug 2024 16:28:59 -0400 Subject: [PATCH] descriptors: Add DescriptorImpl::Clone --- src/script/descriptor.cpp | 81 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 46f3e9677f9d5..08416f0d5f2b5 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -786,6 +786,8 @@ class DescriptorImpl : public Descriptor arg->GetPubKeys(pubkeys, ext_pubs); } } + + virtual std::unique_ptr Clone() const = 0; }; /** A parsed addr(A) descriptor. */ @@ -807,6 +809,10 @@ class AddressDescriptor final : public DescriptorImpl bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; } std::optional ScriptSize() const override { return GetScriptForDestination(m_destination).size(); } + std::unique_ptr Clone() const override + { + return std::make_unique(m_destination); + } }; /** A parsed raw(H) descriptor. */ @@ -830,6 +836,11 @@ class RawDescriptor final : public DescriptorImpl bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; } std::optional ScriptSize() const override { return m_script.size(); } + + std::unique_ptr Clone() const override + { + return std::make_unique(m_script); + } }; /** A parsed pk(P) descriptor. */ @@ -865,6 +876,11 @@ class PKDescriptor final : public DescriptorImpl } std::optional MaxSatisfactionElems() const override { return 1; } + + std::unique_ptr Clone() const override + { + return std::make_unique(m_pubkey_args.at(0)->Clone(), m_xonly); + } }; /** A parsed pkh(P) descriptor. */ @@ -894,6 +910,11 @@ class PKHDescriptor final : public DescriptorImpl } std::optional MaxSatisfactionElems() const override { return 2; } + + std::unique_ptr Clone() const override + { + return std::make_unique(m_pubkey_args.at(0)->Clone()); + } }; /** A parsed wpkh(P) descriptor. */ @@ -923,6 +944,11 @@ class WPKHDescriptor final : public DescriptorImpl } std::optional MaxSatisfactionElems() const override { return 2; } + + std::unique_ptr Clone() const override + { + return std::make_unique(m_pubkey_args.at(0)->Clone()); + } }; /** A parsed combo(P) descriptor. */ @@ -947,6 +973,10 @@ class ComboDescriptor final : public DescriptorImpl public: ComboDescriptor(std::unique_ptr prov) : DescriptorImpl(Vector(std::move(prov)), "combo") {} bool IsSingleType() const final { return false; } + std::unique_ptr Clone() const override + { + return std::make_unique(m_pubkey_args.at(0)->Clone()); + } }; /** A parsed multi(...) or sortedmulti(...) descriptor */ @@ -985,6 +1015,14 @@ class MultisigDescriptor final : public DescriptorImpl } std::optional MaxSatisfactionElems() const override { return 1 + m_threshold; } + + std::unique_ptr Clone() const override + { + std::vector> providers; + providers.reserve(m_pubkey_args.size()); + std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), providers.begin(), [](const std::unique_ptr& p) { return p->Clone(); }); + return std::make_unique(m_threshold, std::move(providers), m_sorted); + } }; /** A parsed (sorted)multi_a(...) descriptor. Always uses x-only pubkeys. */ @@ -1021,6 +1059,16 @@ class MultiADescriptor final : public DescriptorImpl } std::optional MaxSatisfactionElems() const override { return m_pubkey_args.size(); } + + std::unique_ptr Clone() const override + { + std::vector> providers; + providers.reserve(m_pubkey_args.size()); + for (const auto& arg : m_pubkey_args) { + providers.push_back(arg->Clone()); + } + return std::make_unique(m_threshold, std::move(providers), m_sorted); + } }; /** A parsed sh(...) descriptor. */ @@ -1066,6 +1114,11 @@ class SHDescriptor final : public DescriptorImpl if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems; return {}; } + + std::unique_ptr Clone() const override + { + return std::make_unique(m_subdescriptor_args.at(0)->Clone()); + } }; /** A parsed wsh(...) descriptor. */ @@ -1102,6 +1155,11 @@ class WSHDescriptor final : public DescriptorImpl if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems; return {}; } + + std::unique_ptr Clone() const override + { + return std::make_unique(m_subdescriptor_args.at(0)->Clone()); + } }; /** A parsed tr(...) descriptor. */ @@ -1167,6 +1225,14 @@ class TRDescriptor final : public DescriptorImpl // FIXME: See above, we assume keypath spend. return 1; } + + std::unique_ptr Clone() const override + { + std::vector> subdescs; + subdescs.reserve(m_subdescriptor_args.size()); + std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), subdescs.begin(), [](const std::unique_ptr& d) { return d->Clone(); }); + return std::make_unique(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths); + } }; /* We instantiate Miniscript here with a simple integer as key type. @@ -1285,6 +1351,16 @@ class MiniscriptDescriptor final : public DescriptorImpl std::optional MaxSatisfactionElems() const override { return m_node->GetStackSize(); } + + std::unique_ptr Clone() const override + { + std::vector> providers; + providers.reserve(m_pubkey_args.size()); + for (const auto& arg : m_pubkey_args) { + providers.push_back(arg->Clone()); + } + return std::make_unique(std::move(providers), miniscript::MakeNodeRef(*m_node)); + } }; /** A parsed rawtr(...) descriptor. */ @@ -1315,6 +1391,11 @@ class RawTRDescriptor final : public DescriptorImpl // See above, we assume keypath spend. return 1; } + + std::unique_ptr Clone() const override + { + return std::make_unique(m_pubkey_args.at(0)->Clone()); + } }; ////////////////////////////////////////////////////////////////////////////