aboutsummaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2019-10-04 15:31:47 -0400
committerAndrew Chow <achow101-github@achow101.com>2019-10-08 13:56:56 -0400
commit6f588fd2276e5b713c6d36e3b01288484ddb59c0 (patch)
tree6fe20e8bb0efcac067cdd51de24233cc5d388c7a /src/script
parent917d3d9052b5d91ee4cfe1053077cbc0c67c0ce2 (diff)
Add sortedmulti descriptor and unit tests
Diffstat (limited to 'src/script')
-rw-r--r--src/script/descriptor.cpp19
1 files changed, 14 insertions, 5 deletions
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<PubkeyProvider> 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<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider&) const override { return Singleton(GetScriptForMultisig(m_threshold, keys)); }
+ std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, const CScript*, FlatSigningProvider&) const override {
+ if (m_sorted) {
+ std::vector<CPubKey> 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<std::unique_ptr<PubkeyProvider>> providers) : DescriptorImpl(std::move(providers), {}, "multi"), m_threshold(threshold) {}
+ MultisigDescriptor(int threshold, std::vector<std::unique_ptr<PubkeyProvider>> 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<PubkeyProvider> ParsePubkey(const Span<const char>& sp, bool per
std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& 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<DescriptorImpl> ParseScript(Span<const char>& 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<std::unique_ptr<PubkeyProvider>> providers;
@@ -869,7 +878,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& sp, ParseScriptCon
return nullptr;
}
}
- return MakeUnique<MultisigDescriptor>(thres, std::move(providers));
+ return MakeUnique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
}
if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) {
auto pubkey = ParsePubkey(expr, false, out, error);