From 6f588fd2276e5b713c6d36e3b01288484ddb59c0 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 4 Oct 2019 15:31:47 -0400 Subject: Add sortedmulti descriptor and unit tests --- src/script/descriptor.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src/script/descriptor.cpp') diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index b782ebbd1f..b223349eb1 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -593,15 +593,23 @@ public: ComboDescriptor(std::unique_ptr prov) : DescriptorImpl(Singleton(std::move(prov)), {}, "combo") {} }; -/** A parsed multi(...) descriptor. */ +/** A parsed multi(...) or sortedmulti(...) descriptor */ class MultisigDescriptor final : public DescriptorImpl { const int m_threshold; + const bool m_sorted; protected: std::string ToStringExtra() const override { return strprintf("%i", m_threshold); } - std::vector MakeScripts(const std::vector& keys, const CScript*, FlatSigningProvider&) const override { return Singleton(GetScriptForMultisig(m_threshold, keys)); } + std::vector MakeScripts(const std::vector& keys, const CScript*, FlatSigningProvider&) const override { + if (m_sorted) { + std::vector sorted_keys(keys); + std::sort(sorted_keys.begin(), sorted_keys.end()); + return Singleton(GetScriptForMultisig(m_threshold, sorted_keys)); + } + return Singleton(GetScriptForMultisig(m_threshold, keys)); + } public: - MultisigDescriptor(int threshold, std::vector> providers) : DescriptorImpl(std::move(providers), {}, "multi"), m_threshold(threshold) {} + MultisigDescriptor(int threshold, std::vector> providers, bool sorted = false) : DescriptorImpl(std::move(providers), {}, sorted ? "sortedmulti" : "multi"), m_threshold(threshold), m_sorted(sorted) {} }; /** A parsed sh(...) descriptor. */ @@ -809,6 +817,7 @@ std::unique_ptr ParsePubkey(const Span& sp, bool per std::unique_ptr ParseScript(Span& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) { auto expr = Expr(sp); + bool sorted_multi = false; if (Func("pk", expr)) { auto pubkey = ParsePubkey(expr, ctx != ParseScriptContext::P2WSH, out, error); if (!pubkey) return nullptr; @@ -827,7 +836,7 @@ std::unique_ptr ParseScript(Span& sp, ParseScriptCon error = "Cannot have combo in non-top level"; return nullptr; } - if (Func("multi", expr)) { + if ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr)) { auto threshold = Expr(expr); uint32_t thres; std::vector> providers; @@ -869,7 +878,7 @@ std::unique_ptr ParseScript(Span& sp, ParseScriptCon return nullptr; } } - return MakeUnique(thres, std::move(providers)); + return MakeUnique(thres, std::move(providers), sorted_multi); } if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) { auto pubkey = ParsePubkey(expr, false, out, error); -- cgit v1.2.3