44#include <unordered_set>
110uint64_t
PolyMod(uint64_t c,
int val)
112 uint8_t c0 = c >> 35;
113 c = ((c & 0x7ffffffff) << 5) ^ val;
114 if (c0 & 1) c ^= 0xf5dee51989;
115 if (c0 & 2) c ^= 0xa9fdca3312;
116 if (c0 & 4) c ^= 0x1bab10e32d;
117 if (c0 & 8) c ^= 0x3706b1677a;
118 if (c0 & 16) c ^= 0x644d626ffd;
122std::string DescriptorChecksum(
const std::span<const char>& span)
137 static const std::string INPUT_CHARSET =
138 "0123456789()[],'/*abcdefgh@:$%{}"
139 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
140 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
143 static const std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
148 for (
auto ch : span) {
149 auto pos = INPUT_CHARSET.find(ch);
150 if (pos == std::string::npos)
return "";
152 cls = cls * 3 + (pos >> 5);
153 if (++clscount == 3) {
160 if (clscount > 0) c =
PolyMod(c, cls);
161 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
164 std::string
ret(8,
' ');
165 for (
int j = 0; j < 8; ++j)
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
169std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
175typedef std::vector<uint32_t> KeyPath;
183 const uint32_t m_expr_index;
185 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
187 virtual ~PubkeyProvider() =
default;
192 bool operator<(PubkeyProvider& other)
const {
195 std::optional<CPubKey> a =
GetPubKey(0, dummy, dummy);
196 std::optional<CPubKey> b = other.GetPubKey(0, dummy, dummy);
209 virtual bool IsRange()
const = 0;
212 virtual size_t GetSize()
const = 0;
214 enum class StringType {
220 virtual std::string
ToString(StringType type=StringType::PUBLIC)
const = 0;
238 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
240 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
243 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
246 virtual bool IsBIP32()
const = 0;
249 virtual size_t GetKeyCount()
const {
return 1; }
252 virtual bool CanSelfExpand()
const = 0;
255class OriginPubkeyProvider final :
public PubkeyProvider
258 std::unique_ptr<PubkeyProvider> m_provider;
261 std::string OriginString(StringType type,
bool normalized=
false)
const
264 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
269 OriginPubkeyProvider(uint32_t exp_index,
KeyOriginInfo info, std::unique_ptr<PubkeyProvider>
provider,
bool apostrophe) : PubkeyProvider(exp_index), m_origin(
std::move(info)), m_provider(
std::move(
provider)), m_apostrophe(apostrophe) {}
272 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg,
out, read_cache, write_cache);
273 if (!pub)
return std::nullopt;
274 Assert(
out.pubkeys.contains(pub->GetID()));
275 auto& [pubkey, suborigin] =
out.origins[pub->GetID()];
277 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), suborigin.fingerprint);
278 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
281 bool IsRange()
const override {
return m_provider->IsRange(); }
282 size_t GetSize()
const override {
return m_provider->GetSize(); }
283 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
284 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
288 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
289 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
295 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
301 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
303 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
309 m_provider->GetPrivKey(pos, arg,
out);
311 std::optional<CPubKey> GetRootPubKey()
const override
313 return m_provider->GetRootPubKey();
315 std::optional<CExtPubKey> GetRootExtPubKey()
const override
317 return m_provider->GetRootExtPubKey();
319 std::unique_ptr<PubkeyProvider> Clone()
const override
321 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
323 bool CanSelfExpand()
const override {
return m_provider->CanSelfExpand(); }
327class ConstPubkeyProvider final :
public PubkeyProvider
336 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
341 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
345 CKeyID keyid = m_pubkey.GetID();
347 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
348 out.pubkeys.emplace(keyid, m_pubkey);
351 bool IsRange()
const override {
return false; }
352 size_t GetSize()
const override {
return m_pubkey.size(); }
353 bool IsBIP32()
const override {
return false; }
354 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
357 std::optional<CKey> key = GetPrivKey(arg);
372 std::optional<CKey> key = GetPrivKey(arg);
374 out.keys.emplace(key->GetPubKey().GetID(), *key);
376 std::optional<CPubKey> GetRootPubKey()
const override
380 std::optional<CExtPubKey> GetRootExtPubKey()
const override
384 std::unique_ptr<PubkeyProvider> Clone()
const override
386 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
388 bool CanSelfExpand() const final {
return true; }
391enum class DeriveType {
398class BIP32PubkeyProvider final :
public PubkeyProvider
410 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
411 ret.nDepth = m_root_extkey.nDepth;
412 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint +
sizeof(
ret.vchFingerprint),
ret.vchFingerprint);
413 ret.nChild = m_root_extkey.nChild;
414 ret.chaincode = m_root_extkey.chaincode;
422 if (!GetExtKey(arg, xprv))
return false;
423 for (
auto entry :
m_path) {
424 if (!xprv.
Derive(xprv, entry))
return false;
426 last_hardened = xprv;
432 bool IsHardened()
const
434 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
435 for (
auto entry :
m_path) {
436 if (entry >> 31)
return true;
442 BIP32PubkeyProvider(uint32_t exp_index,
const CExtPubKey& extkey, KeyPath path, DeriveType derive,
bool apostrophe) : PubkeyProvider(exp_index), m_root_extkey(extkey),
m_path(
std::move(path)), m_derive(derive), m_apostrophe(apostrophe) {}
443 bool IsRange()
const override {
return m_derive != DeriveType::NON_RANGED; }
444 size_t GetSize()
const override {
return 33; }
445 bool IsBIP32()
const override {
return true; }
449 CKeyID keyid = m_root_extkey.pubkey.GetID();
452 if (m_derive == DeriveType::UNHARDENED_RANGED) info.
path.push_back((uint32_t)pos);
453 if (m_derive == DeriveType::HARDENED_RANGED) info.
path.push_back(((uint32_t)pos) | 0x80000000L);
461 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
462 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
464 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
465 final_extkey = parent_extkey;
466 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
468 }
else if (IsHardened()) {
471 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
472 parent_extkey = xprv.
Neuter();
473 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.
Derive(xprv, pos);
474 if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
475 final_extkey = xprv.
Neuter();
477 last_hardened_extkey = lh_xprv.
Neuter();
480 for (
auto entry :
m_path) {
481 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
483 final_extkey = parent_extkey;
484 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
485 assert(m_derive != DeriveType::HARDENED_RANGED);
487 if (!der)
return std::nullopt;
494 if (m_derive != DeriveType::HARDENED_RANGED) {
495 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
498 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
500 }
else if (info.
path.size() > 0) {
501 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
505 return final_extkey.
pubkey;
507 std::string
ToString(StringType type,
bool normalized)
const
510 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
514 if (m_derive == DeriveType::HARDENED_RANGED)
ret += use_apostrophe ?
'\'' :
'h';
518 std::string
ToString(StringType type=StringType::PUBLIC)
const override
525 if (!GetExtKey(arg, key)) {
532 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
538 if (m_derive == DeriveType::HARDENED_RANGED) {
544 int i = (int)
m_path.size() - 1;
545 for (; i >= 0; --i) {
558 for (;
k <= i; ++
k) {
564 for (;
k < (int)
m_path.size(); ++
k) {
565 end_path.push_back(
m_path.at(
k));
568 CKeyID id = m_root_extkey.pubkey.GetID();
569 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
574 if (cache !=
nullptr) {
580 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
590 assert(m_derive == DeriveType::UNHARDENED_RANGED);
598 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
599 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.
Derive(extkey, pos))
return;
600 if (m_derive == DeriveType::HARDENED_RANGED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return;
603 std::optional<CPubKey> GetRootPubKey()
const override
607 std::optional<CExtPubKey> GetRootExtPubKey()
const override
609 return m_root_extkey;
611 std::unique_ptr<PubkeyProvider> Clone()
const override
613 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey,
m_path, m_derive, m_apostrophe);
615 bool CanSelfExpand()
const override {
return !IsHardened(); }
619class MuSigPubkeyProvider final :
public PubkeyProvider
623 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
627 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
628 mutable std::optional<CPubKey> m_aggregate_pubkey;
629 const DeriveType m_derive;
630 const bool m_ranged_participants;
632 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NON_RANGED; }
637 std::vector<std::unique_ptr<PubkeyProvider>> providers,
641 : PubkeyProvider(exp_index),
642 m_participants(
std::move(providers)),
645 m_ranged_participants(
std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
647 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
648 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
650 if (!
Assume(m_derive != DeriveType::HARDENED_RANGED)) {
651 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
659 if (!m_aggregate_provider && !m_ranged_participants) {
661 std::vector<CPubKey> pubkeys;
662 for (
const auto& prov : m_participants) {
663 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
664 if (!pubkey.has_value()) {
667 pubkeys.push_back(pubkey.value());
669 std::sort(pubkeys.begin(), pubkeys.end());
673 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
676 if (IsRangedDerivation() || !
m_path.empty()) {
679 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub,
m_path, m_derive,
false);
681 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
686 std::vector<CPubKey> pubkeys;
687 for (
const auto& prov : m_participants) {
688 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
689 if (!pub)
return std::nullopt;
690 pubkeys.emplace_back(*pub);
692 std::sort(pubkeys.begin(), pubkeys.end());
695 if (m_aggregate_provider) {
699 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
700 if (!pub)
return std::nullopt;
702 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
707 if (!aggregate_pubkey)
return std::nullopt;
708 pubout = *aggregate_pubkey;
710 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
711 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
712 out.aggregate_pubkeys.emplace(pubout, pubkeys);
718 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
720 size_t GetSize()
const override {
return 32; }
722 std::string
ToString(StringType type=StringType::PUBLIC)
const override
724 std::string
out =
"musig(";
725 for (
size_t i = 0; i < m_participants.size(); ++i) {
726 const auto& pubkey = m_participants.at(i);
728 out += pubkey->ToString(type);
732 if (IsRangedDerivation()) {
739 bool any_privkeys =
false;
741 for (
size_t i = 0; i < m_participants.size(); ++i) {
742 const auto& pubkey = m_participants.at(i);
745 if (pubkey->ToPrivateString(arg, tmp)) {
752 if (IsRangedDerivation()) {
760 for (
size_t i = 0; i < m_participants.size(); ++i) {
761 const auto& pubkey = m_participants.at(i);
764 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
771 if (IsRangedDerivation()) {
782 for (
const auto& prov : m_participants) {
783 prov->GetPrivKey(pos, arg,
out);
792 std::optional<CPubKey> GetRootPubKey()
const override
796 std::optional<CExtPubKey> GetRootExtPubKey()
const override
801 std::unique_ptr<PubkeyProvider> Clone()
const override
803 std::vector<std::unique_ptr<PubkeyProvider>> providers;
804 providers.reserve(m_participants.size());
805 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
806 providers.emplace_back(p->Clone());
808 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers),
m_path, m_derive);
810 bool IsBIP32()
const override
813 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
815 size_t GetKeyCount()
const override
817 return 1 + m_participants.size();
819 bool CanSelfExpand()
const override
823 for (
const auto& key : m_participants) {
824 if (!key->CanSelfExpand())
return false;
835 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
837 const std::string m_name;
839 std::vector<std::string> m_warnings;
845 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
848 virtual std::string ToStringExtra()
const {
return ""; }
860 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
863 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
864 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl>
script,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args(
Vector(
std::move(
script))) {}
865 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::vector<std::unique_ptr<DescriptorImpl>> scripts,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args(
std::move(scripts)) {}
867 enum class StringType
878 for (
const auto& arg : m_subdescriptor_args) {
879 if (!arg->IsSolvable())
return false;
887 if (m_pubkey_args.empty() && m_subdescriptor_args.empty())
return false;
889 for (
const auto& sub: m_subdescriptor_args) {
890 if (!sub->HavePrivateKeys(arg))
return false;
894 for (
const auto& pubkey : m_pubkey_args) {
895 tmp_provider.
keys.clear();
896 pubkey->GetPrivKey(0, arg, tmp_provider);
897 if (tmp_provider.
keys.empty())
return false;
906 for (
const auto& pubkey : m_pubkey_args) {
907 if (pubkey->IsRange())
return true;
909 for (
const auto& arg : m_subdescriptor_args) {
910 if (arg->IsRange())
return true;
919 bool is_private{type == StringType::PRIVATE};
922 bool any_success{!is_private};
923 for (
const auto& scriptarg : m_subdescriptor_args) {
924 if (pos++)
ret +=
",";
926 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
927 if (!is_private && !subscript_res)
return false;
928 any_success = any_success || subscript_res;
937 std::string extra = ToStringExtra();
938 size_t pos = extra.size() > 0 ? 1 : 0;
939 std::string
ret = m_name +
"(" + extra;
940 bool is_private{type == StringType::PRIVATE};
943 bool any_success{!is_private};
945 for (
const auto& pubkey : m_pubkey_args) {
946 if (pos++)
ret +=
",";
949 case StringType::NORMALIZED:
950 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
952 case StringType::PRIVATE:
953 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
955 case StringType::PUBLIC:
956 tmp = pubkey->ToString();
958 case StringType::COMPAT:
959 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
964 std::string subscript;
965 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
966 if (!is_private && !subscript_res)
return false;
967 any_success = any_success || subscript_res;
968 if (pos && subscript.size())
ret +=
',';
969 out = std::move(
ret) + std::move(subscript) +
")";
973 std::string
ToString(
bool compat_format)
const final
976 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
977 return AddChecksum(
ret);
982 bool has_priv_key{ToStringHelper(&arg,
out, StringType::PRIVATE)};
989 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
998 std::vector<CPubKey> pubkeys;
999 pubkeys.reserve(m_pubkey_args.size());
1002 for (
const auto& p : m_pubkey_args) {
1003 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
1004 if (!pubkey)
return false;
1005 pubkeys.push_back(pubkey.value());
1007 std::vector<CScript> subscripts;
1008 for (
const auto& subarg : m_subdescriptor_args) {
1009 std::vector<CScript> outscripts;
1010 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
1011 assert(outscripts.size() == 1);
1012 subscripts.emplace_back(std::move(outscripts[0]));
1014 out.Merge(std::move(subprovider));
1016 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
1022 return ExpandHelper(pos,
provider,
nullptr, output_scripts,
out, write_cache);
1033 for (
const auto& p : m_pubkey_args) {
1036 for (
const auto& arg : m_subdescriptor_args) {
1041 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
1043 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
1050 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
1057 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
1059 for (
const auto& p : m_pubkey_args) {
1060 std::optional<CPubKey> pub = p->GetRootPubKey();
1061 if (pub) pubkeys.insert(*pub);
1062 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1063 if (ext_pub) ext_pubs.insert(*ext_pub);
1065 for (
const auto& arg : m_subdescriptor_args) {
1066 arg->GetPubKeys(pubkeys, ext_pubs);
1070 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1072 bool HasScripts()
const override {
return true; }
1075 std::vector<std::string>
Warnings()
const override {
1076 std::vector<std::string> all = m_warnings;
1077 for (
const auto& sub : m_subdescriptor_args) {
1078 auto sub_w = sub->Warnings();
1079 all.insert(all.end(), sub_w.begin(), sub_w.end());
1086 uint32_t max_key_expr{0};
1087 std::vector<const DescriptorImpl*> todo = {
this};
1088 while (!todo.empty()) {
1089 const DescriptorImpl* desc = todo.back();
1091 for (
const auto& p : desc->m_pubkey_args) {
1092 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1094 for (
const auto&
s : desc->m_subdescriptor_args) {
1095 todo.push_back(
s.get());
1098 return max_key_expr;
1101 size_t GetKeyCount() const final
1104 std::vector<const DescriptorImpl*> todo = {
this};
1105 while (!todo.empty()) {
1106 const DescriptorImpl* desc = todo.back();
1108 for (
const auto& p : desc->m_pubkey_args) {
1109 count += p->GetKeyCount();
1111 for (
const auto&
s : desc->m_subdescriptor_args) {
1112 todo.push_back(
s.get());
1119 bool CanSelfExpand()
const override
1121 for (
const auto& key : m_pubkey_args) {
1122 if (!key->CanSelfExpand())
return false;
1124 for (
const auto& sub : m_subdescriptor_args) {
1125 if (!sub->CanSelfExpand())
return false;
1132class AddressDescriptor final :
public DescriptorImpl
1136 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1139 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1140 bool IsSolvable() const final {
return false; }
1146 bool IsSingleType() const final {
return true; }
1147 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1150 std::unique_ptr<DescriptorImpl> Clone()
const override
1152 return std::make_unique<AddressDescriptor>(m_destination);
1157class RawDescriptor final :
public DescriptorImpl
1161 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1162 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1165 bool IsSolvable() const final {
return false; }
1173 bool IsSingleType() const final {
return true; }
1174 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1176 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1178 std::unique_ptr<DescriptorImpl> Clone()
const override
1180 return std::make_unique<RawDescriptor>(m_script);
1185class PKDescriptor final :
public DescriptorImpl
1190 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1200 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1201 bool IsSingleType() const final {
return true; }
1203 std::optional<int64_t> ScriptSize()
const override {
1204 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1207 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1208 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1209 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1212 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1216 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1218 std::unique_ptr<DescriptorImpl> Clone()
const override
1220 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1225class PKHDescriptor final :
public DescriptorImpl
1228 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1234 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1236 bool IsSingleType() const final {
return true; }
1238 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1240 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1241 const auto sig_size = use_max_sig ? 72 : 71;
1242 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1245 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1249 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1251 std::unique_ptr<DescriptorImpl> Clone()
const override
1253 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1258class WPKHDescriptor final :
public DescriptorImpl
1261 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1267 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1269 bool IsSingleType() const final {
return true; }
1271 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1273 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1274 const auto sig_size = use_max_sig ? 72 : 71;
1278 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1279 return MaxSatSize(use_max_sig);
1282 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1284 std::unique_ptr<DescriptorImpl> Clone()
const override
1286 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1291class ComboDescriptor final :
public DescriptorImpl
1294 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
1296 std::vector<CScript>
ret;
1300 if (
keys[0].IsCompressed()) {
1303 ret.emplace_back(p2wpkh);
1309 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1310 bool IsSingleType() const final {
return false; }
1311 std::unique_ptr<DescriptorImpl> Clone()
const override
1313 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1318class MultisigDescriptor final :
public DescriptorImpl
1320 const int m_threshold;
1321 const bool m_sorted;
1323 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1324 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1326 std::vector<CPubKey> sorted_keys(
keys);
1327 std::sort(sorted_keys.begin(), sorted_keys.end());
1333 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) {}
1334 bool IsSingleType() const final {
return true; }
1336 std::optional<int64_t> ScriptSize()
const override {
1337 const auto n_keys = m_pubkey_args.size();
1338 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1339 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1343 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1344 const auto sig_size = use_max_sig ? 72 : 71;
1345 return (1 + (1 +
sig_size) * m_threshold);
1348 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1352 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1354 std::unique_ptr<DescriptorImpl> Clone()
const override
1356 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1357 providers.reserve(m_pubkey_args.size());
1358 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1359 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1364class MultiADescriptor final :
public DescriptorImpl
1366 const int m_threshold;
1367 const bool m_sorted;
1369 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1370 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1372 std::vector<XOnlyPubKey> xkeys;
1373 xkeys.reserve(
keys.size());
1374 for (
const auto& key :
keys) xkeys.emplace_back(key);
1375 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1377 for (
size_t i = 1; i <
keys.size(); ++i) {
1384 MultiADescriptor(
int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers,
bool sorted =
false) : DescriptorImpl(
std::move(providers), sorted ?
"sortedmulti_a" :
"multi_a"), m_threshold(threshold), m_sorted(sorted) {}
1385 bool IsSingleType() const final {
return true; }
1387 std::optional<int64_t> ScriptSize()
const override {
1388 const auto n_keys = m_pubkey_args.size();
1392 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1393 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1396 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1398 std::unique_ptr<DescriptorImpl> Clone()
const override
1400 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1401 providers.reserve(m_pubkey_args.size());
1402 for (
const auto& arg : m_pubkey_args) {
1403 providers.push_back(arg->Clone());
1405 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1410class SHDescriptor final :
public DescriptorImpl
1413 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1416 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1423 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1427 assert(m_subdescriptor_args.size() == 1);
1431 bool IsSingleType() const final {
return true; }
1433 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1435 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1436 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1437 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1441 if (
IsSegwit())
return subscript_weight + *sat_size;
1448 std::optional<int64_t> MaxSatisfactionElems()
const override {
1449 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1453 std::unique_ptr<DescriptorImpl> Clone()
const override
1455 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1460class WSHDescriptor final :
public DescriptorImpl
1463 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1466 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1470 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1472 bool IsSingleType() const final {
return true; }
1474 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1476 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1477 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1478 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1485 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1486 return MaxSatSize(use_max_sig);
1489 std::optional<int64_t> MaxSatisfactionElems()
const override {
1490 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1494 std::unique_ptr<DescriptorImpl> Clone()
const override
1496 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1501class TRDescriptor final :
public DescriptorImpl
1503 std::vector<int> m_depths;
1505 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1508 assert(m_depths.size() == scripts.size());
1509 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1515 if (!xpk.IsFullyValid())
return {};
1518 out.tr_trees[output] = builder;
1523 if (m_depths.empty()) {
1529 return type != StringType::PRIVATE;
1531 std::vector<bool> path;
1532 bool is_private{type == StringType::PRIVATE};
1535 bool any_success{!is_private};
1537 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1538 if (pos)
ret +=
',';
1539 while ((
int)path.size() <= m_depths[pos]) {
1540 if (path.size())
ret +=
'{';
1541 path.push_back(
false);
1544 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1545 if (!is_private && !subscript_res)
return false;
1546 any_success = any_success || subscript_res;
1548 while (!path.empty() && path.back()) {
1549 if (path.size() > 1)
ret +=
'}';
1552 if (!path.empty()) path.back() =
true;
1557 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1558 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1560 assert(m_subdescriptor_args.size() == m_depths.size());
1563 bool IsSingleType() const final {
return true; }
1565 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1567 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1572 std::optional<int64_t> MaxSatisfactionElems()
const override {
1577 std::unique_ptr<DescriptorImpl> Clone()
const override
1579 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1580 subdescs.reserve(m_subdescriptor_args.size());
1581 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1582 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1596 const std::vector<CPubKey>& m_keys;
1603 uint160 GetHash160(uint32_t key)
const {
1607 return m_keys[key].GetID();
1613 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1616 return {m_keys[key].begin(), m_keys[key].end()};
1619 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1622 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1623 auto id = GetHash160(key);
1624 return {
id.begin(),
id.end()};
1635 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1637 const DescriptorImpl::StringType m_type;
1642 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1643 DescriptorImpl::StringType type,
1645 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1647 std::optional<std::string>
ToString(uint32_t key,
bool& has_priv_key)
const
1650 has_priv_key =
false;
1652 case DescriptorImpl::StringType::PUBLIC:
1653 ret = m_pubkeys[key]->ToString();
1655 case DescriptorImpl::StringType::PRIVATE:
1656 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg,
ret);
1658 case DescriptorImpl::StringType::NORMALIZED:
1659 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1661 case DescriptorImpl::StringType::COMPAT:
1662 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1669class MiniscriptDescriptor final :
public DescriptorImpl
1675 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
1678 const auto script_ctx{
m_node.GetMsCtx()};
1679 for (
const auto& key :
keys) {
1683 provider.pubkeys.emplace(key.GetID(), key);
1696 const uint32_t raw = node.K();
1697 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1698 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1699 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1700 if (is_time_based) {
1701 m_warnings.push_back(strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1703 m_warnings.push_back(strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1710 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1713 bool has_priv_key{
false};
1714 auto res =
m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1715 if (res)
out = *res;
1716 if (type == StringType::PRIVATE) {
1718 return has_priv_key;
1720 return res.has_value();
1724 bool IsSolvable()
const override {
return true; }
1725 bool IsSingleType() const final {
return true; }
1727 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1729 std::optional<int64_t> MaxSatSize(
bool)
const override
1732 return m_node.GetWitnessSize();
1735 std::optional<int64_t> MaxSatisfactionElems()
const override
1737 return m_node.GetStackSize();
1740 std::unique_ptr<DescriptorImpl> Clone()
const override
1742 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1743 providers.reserve(m_pubkey_args.size());
1744 for (
const auto& arg : m_pubkey_args) {
1745 providers.push_back(arg->Clone());
1747 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node.Clone());
1752class RawTRDescriptor final :
public DescriptorImpl
1755 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1759 if (!xpk.IsFullyValid())
return {};
1764 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1766 bool IsSingleType() const final {
return true; }
1768 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1770 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1775 std::optional<int64_t> MaxSatisfactionElems()
const override {
1780 std::unique_ptr<DescriptorImpl> Clone()
const override
1782 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1787class UnusedDescriptor final :
public DescriptorImpl
1790 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override {
return {}; }
1792 UnusedDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"unused") {}
1793 bool IsSingleType() const final {
return true; }
1794 bool HasScripts()
const override {
return false; }
1796 std::unique_ptr<DescriptorImpl> Clone()
const override
1798 return std::make_unique<UnusedDescriptor>(m_pubkey_args.at(0)->Clone());
1807enum class ParseScriptContext {
1816std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error,
bool& has_hardened)
1818 bool hardened =
false;
1819 if (elem.size() > 0) {
1820 const char last = elem[elem.size() - 1];
1821 if (last ==
'\'' || last ==
'h') {
1822 elem = elem.first(elem.size() - 1);
1824 apostrophe = last ==
'\'';
1827 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1829 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1830 return std::nullopt;
1831 }
else if (*p > 0x7FFFFFFFUL) {
1832 error =
strprintf(
"Key path value %u is out of range", *p);
1833 return std::nullopt;
1835 has_hardened = has_hardened || hardened;
1837 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1851[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath,
bool& has_hardened)
1854 struct MultipathSubstitutes {
1855 size_t placeholder_index;
1856 std::vector<uint32_t>
values;
1858 std::optional<MultipathSubstitutes> substitutes;
1859 has_hardened =
false;
1861 for (
size_t i = 1; i <
split.size(); ++i) {
1862 const std::span<const char>& elem =
split[i];
1865 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1866 if (!allow_multipath) {
1867 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1871 error =
"Multiple multipath key path specifiers found";
1876 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1877 if (nums.size() < 2) {
1878 error =
"Multipath key path specifiers must have at least two items";
1882 substitutes.emplace();
1883 std::unordered_set<uint32_t> seen_substitutes;
1884 for (
const auto& num : nums) {
1885 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1886 if (!op_num)
return false;
1887 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1889 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1892 substitutes->values.emplace_back(*op_num);
1895 path.emplace_back();
1896 substitutes->placeholder_index = path.size() - 1;
1898 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1899 if (!op_num)
return false;
1900 path.emplace_back(*op_num);
1905 out.emplace_back(std::move(path));
1908 for (uint32_t substitute : substitutes->values) {
1909 KeyPath branch_path = path;
1910 branch_path[substitutes->placeholder_index] = substitute;
1911 out.emplace_back(std::move(branch_path));
1917[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1920 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1923static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1925 DeriveType type = DeriveType::NON_RANGED;
1926 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1928 type = DeriveType::UNHARDENED_RANGED;
1929 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1930 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1932 type = DeriveType::HARDENED_RANGED;
1938std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out,
bool& apostrophe, std::string& error)
1940 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1941 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1943 std::string str(
split[0].begin(),
split[0].end());
1944 if (str.size() == 0) {
1945 error =
"No key provided";
1949 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1952 if (
split.size() == 1) {
1956 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1957 error =
"Hybrid public keys are not allowed";
1960 if (pubkey.IsFullyValid()) {
1961 if (permit_uncompressed || pubkey.IsCompressed()) {
1962 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1966 error =
"Uncompressed keys are not allowed";
1969 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1970 unsigned char fullkey[33] = {0x02};
1971 std::copy(
data.begin(),
data.end(), fullkey + 1);
1972 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1973 if (pubkey.IsFullyValid()) {
1974 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1979 error =
strprintf(
"Pubkey '%s' is invalid", str);
1986 out.keys.emplace(pubkey.
GetID(), key);
1987 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1991 error =
"Uncompressed keys are not allowed";
1999 error =
strprintf(
"key '%s' is not valid", str);
2002 std::vector<KeyPath> paths;
2003 DeriveType type = ParseDeriveType(
split, apostrophe);
2004 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
2006 extpubkey = extkey.
Neuter();
2009 for (
auto& path : paths) {
2010 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
2018std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2020 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
2025 std::span<const char> span = sp;
2026 if (
Const(
"musig(", span,
false)) {
2027 if (ctx != ParseScriptContext::P2TR) {
2028 error =
"musig() is only allowed in tr() and rawtr()";
2035 if (
split.size() > 2) {
2036 error =
"Too many ')' in musig() expression";
2039 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
2040 if (!
Func(
"musig", expr)) {
2041 error =
"Invalid musig() expression";
2046 bool any_ranged =
false;
2047 bool all_bip32 =
true;
2048 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2049 bool any_key_parsed =
false;
2050 size_t max_multipath_len = 0;
2051 while (expr.size()) {
2052 if (any_key_parsed && !
Const(
",", expr)) {
2053 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
2056 auto arg =
Expr(expr);
2057 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
2059 error =
strprintf(
"musig(): %s", error);
2062 any_key_parsed =
true;
2064 any_ranged = any_ranged ||
pk.at(0)->IsRange();
2065 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
2067 max_multipath_len = std::max(max_multipath_len,
pk.size());
2069 providers.emplace_back(std::move(
pk));
2071 if (!any_key_parsed) {
2072 error =
"musig(): Must contain key expressions";
2077 DeriveType deriv_type = DeriveType::NON_RANGED;
2078 std::vector<KeyPath> derivation_multipaths;
2081 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2085 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2090 deriv_type = ParseDeriveType(deriv_split, dummy);
2091 if (deriv_type == DeriveType::HARDENED_RANGED) {
2092 error =
"musig(): Cannot have hardened child derivation";
2095 bool has_hardened =
false;
2096 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
2097 error =
"musig(): " + error;
2101 error =
"musig(): cannot have hardened derivation steps";
2105 derivation_multipaths.emplace_back();
2110 const auto& clone_providers = [&providers](
size_t length) ->
bool {
2111 for (
auto& multipath_providers : providers) {
2112 if (multipath_providers.size() == 1) {
2113 for (
size_t i = 1; i < length; ++i) {
2114 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2116 }
else if (multipath_providers.size() != length) {
2125 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
2126 KeyPath& path = derivation_multipaths.at(path_idx);
2127 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2128 pubs.reserve(providers.size());
2129 for (
auto& vec : providers) {
2130 pubs.emplace_back(std::move(vec.at(vec_idx)));
2132 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2135 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2136 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2138 }
else if (max_multipath_len > 1) {
2139 if (!clone_providers(max_multipath_len)) {
2140 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2143 for (
size_t i = 0; i < max_multipath_len; ++i) {
2145 emplace_final_provider(i, 0);
2147 }
else if (derivation_multipaths.size() > 1) {
2149 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
2150 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2153 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
2155 emplace_final_provider(i, i);
2159 emplace_final_provider(0, 0);
2165 auto origin_split =
Split(sp,
']');
2166 if (origin_split.size() > 2) {
2167 error =
"Multiple ']' characters found for a single pubkey";
2171 bool apostrophe =
false;
2172 if (origin_split.size() == 1) {
2173 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
2175 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
2176 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2177 origin_split[0].empty() ?
']' : origin_split[0][0]);
2180 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
2181 if (slash_split[0].size() != 8) {
2182 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2185 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2186 if (!
IsHex(fpr_hex)) {
2187 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
2190 auto fpr_bytes =
ParseHex(fpr_hex);
2192 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2193 assert(fpr_bytes.size() == 4);
2194 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
2195 std::vector<KeyPath> path;
2196 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2197 info.
path = path.at(0);
2198 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
2199 if (providers.empty())
return {};
2200 ret.reserve(providers.size());
2201 for (
auto& prov : providers) {
2202 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2214 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2217 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2220 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2222 return key_provider;
2228 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2230 if (
provider.GetKeyOriginByXOnly(xkey, info)) {
2231 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2233 return key_provider;
2241 using Key = uint32_t;
2247 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2249 mutable std::string m_key_parsing_error;
2253 uint32_t& m_expr_index;
2257 : m_out(
out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2259 bool KeyCompare(
const Key& a,
const Key& b)
const {
2260 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2264 switch (m_script_ctx) {
2271 std::optional<Key>
FromString(std::span<const char>& in)
const
2274 Key key = m_keys.
size();
2275 auto pk = ParsePubkey(m_expr_index, in,
ParseContext(), *m_out, m_key_parsing_error);
2276 if (
pk.empty())
return {};
2277 m_keys.emplace_back(std::move(
pk));
2281 std::optional<std::string>
ToString(
const Key& key,
bool&)
const
2283 return m_keys.at(key).at(0)->ToString();
2286 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2289 Key key = m_keys.size();
2292 std::copy(begin, end, pubkey.
begin());
2293 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2294 m_keys.emplace_back();
2295 m_keys.back().push_back(std::move(pubkey_provider));
2300 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2301 m_keys.emplace_back();
2302 m_keys.back().push_back(std::move(pubkey_provider));
2309 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2311 assert(end - begin == 20);
2314 std::copy(begin, end, hash.
begin());
2318 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2319 Key key = m_keys.
size();
2320 m_keys.emplace_back();
2321 m_keys.back().push_back(std::move(pubkey_provider));
2329 return m_script_ctx;
2335std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2338 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2339 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2340 auto expr =
Expr(sp);
2341 if (
Func(
"pk", expr)) {
2342 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2343 if (pubkeys.empty()) {
2347 for (
auto& pubkey : pubkeys) {
2348 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2352 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2353 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2354 if (pubkeys.empty()) {
2358 for (
auto& pubkey : pubkeys) {
2359 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2363 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2364 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2365 if (pubkeys.empty()) {
2366 error =
strprintf(
"combo(): %s", error);
2369 for (
auto& pubkey : pubkeys) {
2370 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2373 }
else if (
Func(
"combo", expr)) {
2374 error =
"Can only have combo() at top level";
2377 const bool multi =
Func(
"multi", expr);
2378 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2379 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2380 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2381 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2382 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2383 auto threshold =
Expr(expr);
2385 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2386 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2387 thres = *maybe_thres;
2389 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2392 size_t script_size = 0;
2393 size_t max_providers_len = 0;
2394 while (expr.size()) {
2395 if (!
Const(
",", expr)) {
2396 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2399 auto arg =
Expr(expr);
2400 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2405 script_size += pks.at(0)->GetSize() + 1;
2406 max_providers_len = std::max(max_providers_len, pks.size());
2407 providers.emplace_back(std::move(pks));
2415 }
else if (thres < 1) {
2416 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2418 }
else if (thres > providers.size()) {
2419 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2422 if (ctx == ParseScriptContext::TOP) {
2423 if (providers.size() > 3) {
2424 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2428 if (ctx == ParseScriptContext::P2SH) {
2438 for (
auto& vec : providers) {
2439 if (vec.size() == 1) {
2440 for (
size_t i = 1; i < max_providers_len; ++i) {
2441 vec.emplace_back(vec.at(0)->Clone());
2443 }
else if (vec.size() != max_providers_len) {
2444 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2450 for (
size_t i = 0; i < max_providers_len; ++i) {
2452 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2453 pubs.reserve(providers.size());
2454 for (
auto& pub : providers) {
2455 pubs.emplace_back(std::move(pub.at(i)));
2457 if (multi || sortedmulti) {
2458 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2460 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2464 }
else if (multi || sortedmulti) {
2465 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2467 }
else if (multi_a || sortedmulti_a) {
2468 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2471 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2472 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2473 if (pubkeys.empty()) {
2477 for (
auto& pubkey : pubkeys) {
2478 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2481 }
else if (
Func(
"wpkh", expr)) {
2482 error =
"Can only have wpkh() at top level or inside sh()";
2485 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2486 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2487 if (descs.empty() || expr.size())
return {};
2488 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2489 ret.reserve(descs.size());
2490 for (
auto& desc : descs) {
2491 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2494 }
else if (
Func(
"sh", expr)) {
2495 error =
"Can only have sh() at top level";
2498 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2499 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2500 if (descs.empty() || expr.size())
return {};
2501 for (
auto& desc : descs) {
2502 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2505 }
else if (
Func(
"wsh", expr)) {
2506 error =
"Can only have wsh() at top level or inside sh()";
2509 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2512 error =
"Address is not valid";
2515 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2517 }
else if (
Func(
"addr", expr)) {
2518 error =
"Can only have addr() at top level";
2521 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2522 auto arg =
Expr(expr);
2523 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2524 if (internal_keys.empty()) {
2528 size_t max_providers_len = internal_keys.size();
2529 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2530 std::vector<int> depths;
2532 if (!
Const(
",", expr)) {
2533 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2539 std::vector<bool> branches;
2544 while (
Const(
"{", expr)) {
2545 branches.push_back(
false);
2552 auto sarg =
Expr(expr);
2553 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2554 if (subscripts.back().empty())
return {};
2555 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2556 depths.push_back(branches.size());
2558 while (branches.size() && branches.back()) {
2559 if (!
Const(
"}", expr)) {
2560 error =
strprintf(
"tr(): expected '}' after script expression");
2563 branches.pop_back();
2566 if (branches.size() && !branches.back()) {
2567 if (!
Const(
",", expr)) {
2568 error =
strprintf(
"tr(): expected ',' after script expression");
2571 branches.back() =
true;
2573 }
while (branches.size());
2576 error =
strprintf(
"tr(): expected ')' after script expression");
2584 for (
auto& vec : subscripts) {
2585 if (vec.size() == 1) {
2586 for (
size_t i = 1; i < max_providers_len; ++i) {
2587 vec.emplace_back(vec.at(0)->Clone());
2589 }
else if (vec.size() != max_providers_len) {
2590 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2595 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2596 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2600 while (internal_keys.size() < max_providers_len) {
2601 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2605 for (
size_t i = 0; i < max_providers_len; ++i) {
2607 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2608 this_subs.reserve(subscripts.size());
2609 for (
auto& subs : subscripts) {
2610 this_subs.emplace_back(std::move(subs.at(i)));
2612 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2617 }
else if (
Func(
"tr", expr)) {
2618 error =
"Can only have tr at top level";
2621 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2622 auto arg =
Expr(expr);
2624 error =
strprintf(
"rawtr(): only one key expected.");
2627 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2628 if (output_keys.empty()) {
2629 error =
strprintf(
"rawtr(): %s", error);
2632 for (
auto& pubkey : output_keys) {
2633 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2636 }
else if (
Func(
"rawtr", expr)) {
2637 error =
"Can only have rawtr at top level";
2640 if (ctx == ParseScriptContext::TOP &&
Func(
"unused", expr)) {
2642 auto arg =
Expr(expr);
2644 error =
strprintf(
"unused(): only one key expected");
2647 auto keys = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2648 if (
keys.empty())
return {};
2649 for (
auto& pubkey :
keys) {
2650 if (pubkey->IsRange()) {
2651 error =
"unused(): key cannot be ranged";
2654 ret.emplace_back(std::make_unique<UnusedDescriptor>(std::move(pubkey)));
2657 }
else if (
Func(
"unused", expr)) {
2658 error =
"Can only have unused at top level";
2661 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2662 std::string str(expr.begin(), expr.end());
2664 error =
"Raw script is not hex";
2668 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2670 }
else if (
Func(
"raw", expr)) {
2671 error =
"Can only have raw() at top level";
2677 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2679 if (parser.m_key_parsing_error !=
"") {
2680 error = std::move(parser.m_key_parsing_error);
2684 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2685 error =
"Miniscript expressions can only be used in wsh or tr.";
2688 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2690 const auto* insane_node = &
node.value();
2691 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2692 error = *insane_node->ToString(parser);
2693 if (!insane_node->IsValid()) {
2694 error +=
" is invalid";
2695 }
else if (!
node->IsSane()) {
2696 error +=
" is not sane";
2697 if (!insane_node->IsNonMalleable()) {
2698 error +=
": malleable witnesses exist";
2699 }
else if (insane_node == &
node.value() && !insane_node->NeedsSignature()) {
2700 error +=
": witnesses without signature exist";
2701 }
else if (!insane_node->CheckTimeLocksMix()) {
2702 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2703 }
else if (!insane_node->CheckDuplicateKey()) {
2704 error +=
": contains duplicate public keys";
2705 }
else if (!insane_node->ValidSatisfactions()) {
2706 error +=
": needs witnesses that may exceed resource limits";
2709 error +=
" is not satisfiable";
2718 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2719 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2720 return a.size() < b.size();
2723 for (
auto& vec : parser.m_keys) {
2724 if (vec.size() == 1) {
2725 for (
size_t i = 1; i < num_multipath; ++i) {
2726 vec.emplace_back(vec.at(0)->Clone());
2728 }
else if (vec.size() != num_multipath) {
2729 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2735 for (
size_t i = 0; i < num_multipath; ++i) {
2737 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2738 pubs.reserve(parser.m_keys.size());
2739 for (
auto& pub : parser.m_keys) {
2740 pubs.emplace_back(std::move(pub.at(i)));
2742 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2747 if (ctx == ParseScriptContext::P2SH) {
2748 error =
"A function is needed within P2SH";
2750 }
else if (ctx == ParseScriptContext::P2WSH) {
2751 error =
"A function is needed within P2WSH";
2754 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2761 if (!match)
return {};
2762 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2763 keys.reserve(match->second.size());
2764 for (
const auto keyspan : match->second) {
2765 if (keyspan.size() != 32)
return {};
2767 if (!key)
return {};
2768 keys.push_back(std::move(key));
2770 return std::make_unique<MultiADescriptor>(match->first, std::move(
keys));
2778 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx,
provider),
true);
2781 if (ctx == ParseScriptContext::P2TR) {
2786 std::vector<std::vector<unsigned char>>
data;
2789 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2791 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2792 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2795 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2799 if (
provider.GetPubKey(keyid, pubkey)) {
2800 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2801 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2809 if (
provider.GetPubKey(keyid, pubkey)) {
2810 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH,
provider)) {
2811 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2815 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2817 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2818 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2820 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2821 providers.push_back(std::move(pubkey_provider));
2827 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2833 if (
provider.GetCScript(scriptid, subscript)) {
2834 auto sub = InferScript(subscript, ParseScriptContext::P2SH,
provider);
2835 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2841 if (
provider.GetCScript(scriptid, subscript)) {
2842 auto sub = InferScript(subscript, ParseScriptContext::P2WSH,
provider);
2843 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2852 if (
provider.GetTaprootSpendData(pubkey, tap)) {
2858 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2859 std::vector<int> depths;
2860 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2861 std::unique_ptr<DescriptorImpl> subdesc;
2869 subscripts.push_back(std::move(subdesc));
2870 depths.push_back(depth);
2875 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2881 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR,
provider);
2883 return std::make_unique<RawTRDescriptor>(std::move(key));
2888 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2890 uint32_t key_exp_index = 0;
2891 KeyParser parser(
nullptr, &
provider, script_ctx, key_exp_index);
2894 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2895 keys.reserve(parser.m_keys.size());
2896 for (
auto& key : parser.m_keys) {
2897 keys.emplace_back(std::move(key.at(0)));
2899 return std::make_unique<MiniscriptDescriptor>(std::move(
keys), std::move(*
node));
2905 if (ctx != ParseScriptContext::TOP)
return nullptr;
2910 return std::make_unique<AddressDescriptor>(std::move(dest));
2914 return std::make_unique<RawDescriptor>(
script);
2921bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2923 auto check_split =
Split(sp,
'#');
2924 if (check_split.size() > 2) {
2925 error =
"Multiple '#' symbols";
2928 if (check_split.size() == 1 && require_checksum){
2929 error =
"Missing checksum";
2932 if (check_split.size() == 2) {
2933 if (check_split[1].size() != 8) {
2934 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2938 auto checksum = DescriptorChecksum(check_split[0]);
2939 if (checksum.empty()) {
2940 error =
"Invalid characters in payload";
2943 if (check_split.size() == 2) {
2944 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2945 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2949 if (out_checksum) *out_checksum = std::move(checksum);
2950 sp = check_split[0];
2956 std::span<const char> sp{descriptor};
2958 uint32_t key_exp_index = 0;
2960 if (sp.empty() && !
ret.empty()) {
2961 std::vector<std::unique_ptr<Descriptor>> descs;
2962 descs.reserve(
ret.size());
2963 for (
auto& r :
ret) {
2964 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2975 std::span<const char> sp{descriptor};
2987 std::string desc_str = desc.
ToString(
true);
3001 xpubs[der_index] = xpub;
3021 const auto& der_it = key_exp_it->second.find(der_index);
3022 if (der_it == key_exp_it->second.end())
return false;
3023 xpub = der_it->second;
3041 if (xpub != parent_xpub_pair.second) {
3042 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
3050 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
3053 if (xpub != derived_xpub_pair.second) {
3054 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
3058 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3059 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3065 if (xpub != lh_xpub_pair.second) {
3066 throw std::runtime_error(std::string(__func__) +
": New cached last hardened xpub does not match already cached last hardened xpub");
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
#define CHECK_NONFATAL(condition)
Identity function.
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
An encapsulated private key.
unsigned int size() const
Simple read-only vector-like interface.
bool IsValid() const
Check whether this private key is valid.
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
CPubKey GetPubKey() const
Compute the public key from a private key.
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
Cache for single descriptor's derived extended pubkeys.
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
ExtPubKeyMap m_last_hardened_xpubs
Map key expression index -> last hardened xpub.
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey &xpub) const
Retrieve a cached xpub derived at an index.
std::unordered_map< uint32_t, ExtPubKeyMap > m_derived_xpubs
Map key expression index -> map of (key derivation index -> xpub)
bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached last hardened xpub.
ExtPubKeyMap m_parent_xpubs
Map key expression index -> parent xpub.
An interface to be implemented by keystores that support signing.
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
TaprootBuilder & Add(int depth, std::span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * begin() const
static constexpr size_t size()
CPubKey GetEvenCorrespondingCPubKey() const
bool IsFullyValid() const
Determine if this pubkey is fully valid.
constexpr unsigned char * begin()
A node in a miniscript expression.
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
static const int WITNESS_SCALE_FACTOR
CScript ParseScript(const std::string &s)
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
std::string EncodeExtKey(const CExtKey &key)
CExtPubKey DecodeExtPubKey(const std::string &str)
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
std::string EncodeSecret(const CKey &key)
std::string EncodeDestination(const CTxDestination &dest)
CKey DecodeSecret(const std::string &str)
std::string EncodeExtPubKey(const CExtPubKey &key)
CExtKey DecodeExtKey(const std::string &str)
CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey &pubkey)
Construct the BIP 328 synthetic xpub for a pubkey.
std::optional< CPubKey > MuSig2AggregatePubkeys(const std::vector< CPubKey > &pubkeys, secp256k1_musig_keyagg_cache &keyagg_cache, const std::optional< CPubKey > &expected_aggregate)
Compute the full aggregate pubkey from the given participant pubkeys in their current order.
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
std::optional< Node< typename Ctx::Key > > FromScript(const CScript &script, const Ctx &ctx)
void ForEachNode(const Node< Key > &root, Fn &&fn)
Unordered traversal of a miniscript node tree.
std::optional< Node< typename Ctx::Key > > FromString(const std::string &str, const Ctx &ctx)
@ OLDER
[n] OP_CHECKSEQUENCEVERIFY
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
std::string ToString(const T &t)
Locale-independent version of std::to_string.
std::vector< T > Split(const std::span< const char > &sp, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
bool operator<(const CNetAddr &a, const CNetAddr &b)
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::vector< std::unique_ptr< Descriptor > > Parse(std::string_view descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
static const int MAX_PUBKEYS_PER_MULTISIG
std::vector< unsigned char > ToByteVector(const T &in)
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
std::optional< std::vector< std::tuple< int, std::vector< unsigned char >, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
const SigningProvider & DUMMY_SIGNING_PROVIDER
void PolyMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, const F &field)
Compute the remainder of a polynomial division of val by mod, putting the result in mod.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &script)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
bool Derive(CExtPubKey &out, unsigned int nChild, uint256 *bip32_tweak_out=nullptr) const
Interface for parsed descriptor objects.
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
virtual void GetPubKeys(std::set< CPubKey > &pubkeys, std::set< CExtPubKey > &ext_pubs) const =0
Return all (extended) public keys for this descriptor, including any from subdescriptors.
virtual bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const =0
Convert the descriptor to a normalized string.
virtual std::optional< int64_t > MaxSatisfactionWeight(bool use_max_sig) const =0
Get the maximum size of a satisfaction for this descriptor, in weight units.
virtual std::vector< std::string > Warnings() const =0
Semantic/safety warnings (includes subdescriptors).
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
virtual std::optional< OutputType > GetOutputType() const =0
virtual bool HasScripts() const =0
Whether this descriptor produces any scripts with the Expand functions.
virtual bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const =0
Expand a descriptor at a specified position.
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys.
virtual void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const =0
Expand the private key for a descriptor at a specified position, if possible.
virtual uint32_t GetMaxKeyExpr() const =0
Get the maximum key expression index.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool HavePrivateKeys(const SigningProvider &provider) const =0
Whether the given provider has all private keys required by this descriptor.
virtual bool ExpandFromCache(int pos, const DescriptorCache &read_cache, std::vector< CScript > &output_scripts, FlatSigningProvider &out) const =0
Expand a descriptor at a specified position using cached expansion data.
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
std::map< CKeyID, CKey > keys
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
std::vector< uint32_t > path
XOnlyPubKey internal_key
The BIP341 internal key.
std::vector< uint16_t > keys
FuzzedDataProvider provider
consteval auto _(util::TranslatedLiteral str)
bool IsHex(std::string_view str)
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.