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; }
252class OriginPubkeyProvider final :
public PubkeyProvider
255 std::unique_ptr<PubkeyProvider> m_provider;
258 std::string OriginString(StringType type,
bool normalized=
false)
const
261 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
266 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) {}
269 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg,
out, read_cache, write_cache);
270 if (!pub)
return std::nullopt;
271 Assert(
out.pubkeys.contains(pub->GetID()));
272 auto& [pubkey, suborigin] =
out.origins[pub->GetID()];
274 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), suborigin.fingerprint);
275 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
278 bool IsRange()
const override {
return m_provider->IsRange(); }
279 size_t GetSize()
const override {
return m_provider->GetSize(); }
280 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
281 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
285 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
286 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
292 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
298 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
300 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
306 m_provider->GetPrivKey(pos, arg,
out);
308 std::optional<CPubKey> GetRootPubKey()
const override
310 return m_provider->GetRootPubKey();
312 std::optional<CExtPubKey> GetRootExtPubKey()
const override
314 return m_provider->GetRootExtPubKey();
316 std::unique_ptr<PubkeyProvider> Clone()
const override
318 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
323class ConstPubkeyProvider final :
public PubkeyProvider
332 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
337 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
341 CKeyID keyid = m_pubkey.GetID();
343 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
344 out.pubkeys.emplace(keyid, m_pubkey);
347 bool IsRange()
const override {
return false; }
348 size_t GetSize()
const override {
return m_pubkey.size(); }
349 bool IsBIP32()
const override {
return false; }
350 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
353 std::optional<CKey> key = GetPrivKey(arg);
368 std::optional<CKey> key = GetPrivKey(arg);
370 out.keys.emplace(key->GetPubKey().GetID(), *key);
372 std::optional<CPubKey> GetRootPubKey()
const override
376 std::optional<CExtPubKey> GetRootExtPubKey()
const override
380 std::unique_ptr<PubkeyProvider> Clone()
const override
382 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
386enum class DeriveType {
393class BIP32PubkeyProvider final :
public PubkeyProvider
405 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
406 ret.nDepth = m_root_extkey.nDepth;
407 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint +
sizeof(
ret.vchFingerprint),
ret.vchFingerprint);
408 ret.nChild = m_root_extkey.nChild;
409 ret.chaincode = m_root_extkey.chaincode;
417 if (!GetExtKey(arg, xprv))
return false;
418 for (
auto entry : m_path) {
419 if (!xprv.
Derive(xprv, entry))
return false;
421 last_hardened = xprv;
427 bool IsHardened()
const
429 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
430 for (
auto entry : m_path) {
431 if (entry >> 31)
return true;
437 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) {}
438 bool IsRange()
const override {
return m_derive != DeriveType::NON_RANGED; }
439 size_t GetSize()
const override {
return 33; }
440 bool IsBIP32()
const override {
return true; }
444 CKeyID keyid = m_root_extkey.pubkey.GetID();
447 if (m_derive == DeriveType::UNHARDENED_RANGED) info.
path.push_back((uint32_t)pos);
448 if (m_derive == DeriveType::HARDENED_RANGED) info.
path.push_back(((uint32_t)pos) | 0x80000000L);
456 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
457 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
459 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
460 final_extkey = parent_extkey;
461 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
463 }
else if (IsHardened()) {
466 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
467 parent_extkey = xprv.
Neuter();
468 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.
Derive(xprv, pos);
469 if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
470 final_extkey = xprv.
Neuter();
472 last_hardened_extkey = lh_xprv.
Neuter();
475 for (
auto entry : m_path) {
476 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
478 final_extkey = parent_extkey;
479 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
480 assert(m_derive != DeriveType::HARDENED_RANGED);
482 if (!der)
return std::nullopt;
489 if (m_derive != DeriveType::HARDENED_RANGED) {
490 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
493 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
495 }
else if (info.
path.size() > 0) {
496 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
500 return final_extkey.
pubkey;
502 std::string
ToString(StringType type,
bool normalized)
const
505 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
509 if (m_derive == DeriveType::HARDENED_RANGED)
ret += use_apostrophe ?
'\'' :
'h';
513 std::string
ToString(StringType type=StringType::PUBLIC)
const override
520 if (!GetExtKey(arg, key)) {
527 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
533 if (m_derive == DeriveType::HARDENED_RANGED) {
539 int i = (int)m_path.size() - 1;
540 for (; i >= 0; --i) {
541 if (m_path.at(i) >> 31) {
553 for (;
k <= i; ++
k) {
555 origin.
path.push_back(m_path.at(
k));
559 for (;
k < (int)m_path.size(); ++
k) {
560 end_path.push_back(m_path.at(
k));
563 CKeyID id = m_root_extkey.pubkey.GetID();
564 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
569 if (cache !=
nullptr) {
575 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
585 assert(m_derive == DeriveType::UNHARDENED_RANGED);
593 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
594 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.
Derive(extkey, pos))
return;
595 if (m_derive == DeriveType::HARDENED_RANGED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return;
598 std::optional<CPubKey> GetRootPubKey()
const override
602 std::optional<CExtPubKey> GetRootExtPubKey()
const override
604 return m_root_extkey;
606 std::unique_ptr<PubkeyProvider> Clone()
const override
608 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey, m_path, m_derive, m_apostrophe);
613class MuSigPubkeyProvider final :
public PubkeyProvider
617 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
619 const KeyPath m_path;
621 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
622 mutable std::optional<CPubKey> m_aggregate_pubkey;
623 const DeriveType m_derive;
624 const bool m_ranged_participants;
626 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NON_RANGED; }
631 std::vector<std::unique_ptr<PubkeyProvider>> providers,
635 : PubkeyProvider(exp_index),
636 m_participants(
std::move(providers)),
637 m_path(
std::move(path)),
639 m_ranged_participants(
std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
641 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
642 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
644 if (!
Assume(m_derive != DeriveType::HARDENED_RANGED)) {
645 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
653 if (!m_aggregate_provider && !m_ranged_participants) {
655 std::vector<CPubKey> pubkeys;
656 for (
const auto& prov : m_participants) {
657 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
658 if (!pubkey.has_value()) {
661 pubkeys.push_back(pubkey.value());
663 std::sort(pubkeys.begin(), pubkeys.end());
667 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
670 if (IsRangedDerivation() || !m_path.empty()) {
673 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub, m_path, m_derive,
false);
675 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
680 std::vector<CPubKey> pubkeys;
681 for (
const auto& prov : m_participants) {
682 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
683 if (!pub)
return std::nullopt;
684 pubkeys.emplace_back(*pub);
686 std::sort(pubkeys.begin(), pubkeys.end());
689 if (m_aggregate_provider) {
693 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
694 if (!pub)
return std::nullopt;
696 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
698 if (!
Assume(m_ranged_participants) || !
Assume(m_path.empty()))
return std::nullopt;
701 if (!aggregate_pubkey)
return std::nullopt;
702 pubout = *aggregate_pubkey;
704 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
705 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
706 out.aggregate_pubkeys.emplace(pubout, pubkeys);
712 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
714 size_t GetSize()
const override {
return 32; }
716 std::string
ToString(StringType type=StringType::PUBLIC)
const override
718 std::string
out =
"musig(";
719 for (
size_t i = 0; i < m_participants.size(); ++i) {
720 const auto& pubkey = m_participants.at(i);
722 out += pubkey->ToString(type);
726 if (IsRangedDerivation()) {
733 bool any_privkeys =
false;
735 for (
size_t i = 0; i < m_participants.size(); ++i) {
736 const auto& pubkey = m_participants.at(i);
739 if (pubkey->ToPrivateString(arg, tmp)) {
746 if (IsRangedDerivation()) {
754 for (
size_t i = 0; i < m_participants.size(); ++i) {
755 const auto& pubkey = m_participants.at(i);
758 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
765 if (IsRangedDerivation()) {
776 for (
const auto& prov : m_participants) {
777 prov->GetPrivKey(pos, arg,
out);
786 std::optional<CPubKey> GetRootPubKey()
const override
790 std::optional<CExtPubKey> GetRootExtPubKey()
const override
795 std::unique_ptr<PubkeyProvider> Clone()
const override
797 std::vector<std::unique_ptr<PubkeyProvider>> providers;
798 providers.reserve(m_participants.size());
799 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
800 providers.emplace_back(p->Clone());
802 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers), m_path, m_derive);
804 bool IsBIP32()
const override
807 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
809 size_t GetKeyCount()
const override
811 return 1 + m_participants.size();
820 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
822 const std::string m_name;
824 std::vector<std::string> m_warnings;
830 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
833 virtual std::string ToStringExtra()
const {
return ""; }
845 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
848 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
849 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))) {}
850 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)) {}
852 enum class StringType
863 for (
const auto& arg : m_subdescriptor_args) {
864 if (!arg->IsSolvable())
return false;
872 if (m_pubkey_args.empty() && m_subdescriptor_args.empty())
return false;
874 for (
const auto& sub: m_subdescriptor_args) {
875 if (!sub->HavePrivateKeys(arg))
return false;
879 for (
const auto& pubkey : m_pubkey_args) {
880 tmp_provider.
keys.clear();
881 pubkey->GetPrivKey(0, arg, tmp_provider);
882 if (tmp_provider.
keys.empty())
return false;
891 for (
const auto& pubkey : m_pubkey_args) {
892 if (pubkey->IsRange())
return true;
894 for (
const auto& arg : m_subdescriptor_args) {
895 if (arg->IsRange())
return true;
904 bool is_private{type == StringType::PRIVATE};
907 bool any_success{!is_private};
908 for (
const auto& scriptarg : m_subdescriptor_args) {
909 if (pos++)
ret +=
",";
911 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
912 if (!is_private && !subscript_res)
return false;
913 any_success = any_success || subscript_res;
922 std::string extra = ToStringExtra();
923 size_t pos = extra.size() > 0 ? 1 : 0;
924 std::string
ret = m_name +
"(" + extra;
925 bool is_private{type == StringType::PRIVATE};
928 bool any_success{!is_private};
930 for (
const auto& pubkey : m_pubkey_args) {
931 if (pos++)
ret +=
",";
934 case StringType::NORMALIZED:
935 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
937 case StringType::PRIVATE:
938 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
940 case StringType::PUBLIC:
941 tmp = pubkey->ToString();
943 case StringType::COMPAT:
944 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
949 std::string subscript;
950 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
951 if (!is_private && !subscript_res)
return false;
952 any_success = any_success || subscript_res;
953 if (pos && subscript.size())
ret +=
',';
954 out = std::move(
ret) + std::move(subscript) +
")";
958 std::string
ToString(
bool compat_format)
const final
961 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
962 return AddChecksum(
ret);
967 bool has_priv_key{ToStringHelper(&arg,
out, StringType::PRIVATE)};
974 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
983 std::vector<CPubKey> pubkeys;
984 pubkeys.reserve(m_pubkey_args.size());
987 for (
const auto& p : m_pubkey_args) {
988 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
989 if (!pubkey)
return false;
990 pubkeys.push_back(pubkey.value());
992 std::vector<CScript> subscripts;
993 for (
const auto& subarg : m_subdescriptor_args) {
994 std::vector<CScript> outscripts;
995 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
996 assert(outscripts.size() == 1);
997 subscripts.emplace_back(std::move(outscripts[0]));
999 out.Merge(std::move(subprovider));
1001 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
1007 return ExpandHelper(pos, provider,
nullptr, output_scripts,
out, write_cache);
1018 for (
const auto& p : m_pubkey_args) {
1019 p->GetPrivKey(pos, provider,
out);
1021 for (
const auto& arg : m_subdescriptor_args) {
1022 arg->ExpandPrivate(pos, provider,
out);
1026 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
1028 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
1035 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
1042 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
1044 for (
const auto& p : m_pubkey_args) {
1045 std::optional<CPubKey> pub = p->GetRootPubKey();
1046 if (pub) pubkeys.insert(*pub);
1047 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1048 if (ext_pub) ext_pubs.insert(*ext_pub);
1050 for (
const auto& arg : m_subdescriptor_args) {
1051 arg->GetPubKeys(pubkeys, ext_pubs);
1055 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1057 bool HasScripts()
const override {
return true; }
1060 std::vector<std::string>
Warnings()
const override {
1061 std::vector<std::string> all = m_warnings;
1062 for (
const auto& sub : m_subdescriptor_args) {
1063 auto sub_w = sub->Warnings();
1064 all.insert(all.end(), sub_w.begin(), sub_w.end());
1071 uint32_t max_key_expr{0};
1072 std::vector<const DescriptorImpl*> todo = {
this};
1073 while (!todo.empty()) {
1074 const DescriptorImpl* desc = todo.back();
1076 for (
const auto& p : desc->m_pubkey_args) {
1077 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1079 for (
const auto&
s : desc->m_subdescriptor_args) {
1080 todo.push_back(
s.get());
1083 return max_key_expr;
1086 size_t GetKeyCount() const final
1089 std::vector<const DescriptorImpl*> todo = {
this};
1090 while (!todo.empty()) {
1091 const DescriptorImpl* desc = todo.back();
1093 for (
const auto& p : desc->m_pubkey_args) {
1094 count += p->GetKeyCount();
1096 for (
const auto&
s : desc->m_subdescriptor_args) {
1097 todo.push_back(
s.get());
1105class AddressDescriptor final :
public DescriptorImpl
1109 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1112 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1113 bool IsSolvable() const final {
return false; }
1119 bool IsSingleType() const final {
return true; }
1120 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1123 std::unique_ptr<DescriptorImpl> Clone()
const override
1125 return std::make_unique<AddressDescriptor>(m_destination);
1130class RawDescriptor final :
public DescriptorImpl
1134 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1135 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1138 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; }
1149 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1151 std::unique_ptr<DescriptorImpl> Clone()
const override
1153 return std::make_unique<RawDescriptor>(m_script);
1158class PKDescriptor final :
public DescriptorImpl
1163 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1173 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1174 bool IsSingleType() const final {
return true; }
1176 std::optional<int64_t> ScriptSize()
const override {
1177 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1180 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1181 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1182 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1185 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1189 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1191 std::unique_ptr<DescriptorImpl> Clone()
const override
1193 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1198class PKHDescriptor final :
public DescriptorImpl
1201 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1203 CKeyID id = keys[0].GetID();
1207 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1209 bool IsSingleType() const final {
return true; }
1211 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1213 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1214 const auto sig_size = use_max_sig ? 72 : 71;
1215 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1218 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1222 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1224 std::unique_ptr<DescriptorImpl> Clone()
const override
1226 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1231class WPKHDescriptor final :
public DescriptorImpl
1234 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1236 CKeyID id = keys[0].GetID();
1240 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1242 bool IsSingleType() const final {
return true; }
1244 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1246 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1247 const auto sig_size = use_max_sig ? 72 : 71;
1251 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1252 return MaxSatSize(use_max_sig);
1255 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1257 std::unique_ptr<DescriptorImpl> Clone()
const override
1259 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1264class ComboDescriptor final :
public DescriptorImpl
1267 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
1269 std::vector<CScript>
ret;
1270 CKeyID id = keys[0].GetID();
1273 if (keys[0].IsCompressed()) {
1276 ret.emplace_back(p2wpkh);
1282 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1283 bool IsSingleType() const final {
return false; }
1284 std::unique_ptr<DescriptorImpl> Clone()
const override
1286 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1291class MultisigDescriptor final :
public DescriptorImpl
1293 const int m_threshold;
1294 const bool m_sorted;
1296 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1297 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1299 std::vector<CPubKey> sorted_keys(keys);
1300 std::sort(sorted_keys.begin(), sorted_keys.end());
1306 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) {}
1307 bool IsSingleType() const final {
return true; }
1309 std::optional<int64_t> ScriptSize()
const override {
1310 const auto n_keys = m_pubkey_args.size();
1311 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1312 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1316 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1317 const auto sig_size = use_max_sig ? 72 : 71;
1318 return (1 + (1 +
sig_size) * m_threshold);
1321 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1325 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1327 std::unique_ptr<DescriptorImpl> Clone()
const override
1329 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1330 providers.reserve(m_pubkey_args.size());
1331 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1332 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1337class MultiADescriptor final :
public DescriptorImpl
1339 const int m_threshold;
1340 const bool m_sorted;
1342 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1343 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1345 std::vector<XOnlyPubKey> xkeys;
1346 xkeys.reserve(keys.size());
1347 for (
const auto& key : keys) xkeys.emplace_back(key);
1348 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1350 for (
size_t i = 1; i < keys.size(); ++i) {
1357 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) {}
1358 bool IsSingleType() const final {
return true; }
1360 std::optional<int64_t> ScriptSize()
const override {
1361 const auto n_keys = m_pubkey_args.size();
1365 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1366 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1369 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1371 std::unique_ptr<DescriptorImpl> Clone()
const override
1373 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1374 providers.reserve(m_pubkey_args.size());
1375 for (
const auto& arg : m_pubkey_args) {
1376 providers.push_back(arg->Clone());
1378 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1383class SHDescriptor final :
public DescriptorImpl
1386 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1389 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1396 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1400 assert(m_subdescriptor_args.size() == 1);
1404 bool IsSingleType() const final {
return true; }
1406 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1408 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1409 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1410 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1414 if (
IsSegwit())
return subscript_weight + *sat_size;
1421 std::optional<int64_t> MaxSatisfactionElems()
const override {
1422 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1426 std::unique_ptr<DescriptorImpl> Clone()
const override
1428 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1433class WSHDescriptor final :
public DescriptorImpl
1436 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1439 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1443 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1445 bool IsSingleType() const final {
return true; }
1447 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1449 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1450 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1451 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1458 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1459 return MaxSatSize(use_max_sig);
1462 std::optional<int64_t> MaxSatisfactionElems()
const override {
1463 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1467 std::unique_ptr<DescriptorImpl> Clone()
const override
1469 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1474class TRDescriptor final :
public DescriptorImpl
1476 std::vector<int> m_depths;
1478 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1481 assert(m_depths.size() == scripts.size());
1482 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1486 assert(keys.size() == 1);
1488 if (!xpk.IsFullyValid())
return {};
1491 out.tr_trees[output] = builder;
1496 if (m_depths.empty()) {
1502 return type != StringType::PRIVATE;
1504 std::vector<bool> path;
1505 bool is_private{type == StringType::PRIVATE};
1508 bool any_success{!is_private};
1510 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1511 if (pos)
ret +=
',';
1512 while ((
int)path.size() <= m_depths[pos]) {
1513 if (path.size())
ret +=
'{';
1514 path.push_back(
false);
1517 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1518 if (!is_private && !subscript_res)
return false;
1519 any_success = any_success || subscript_res;
1521 while (!path.empty() && path.back()) {
1522 if (path.size() > 1)
ret +=
'}';
1525 if (!path.empty()) path.back() =
true;
1530 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1531 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1533 assert(m_subdescriptor_args.size() == m_depths.size());
1536 bool IsSingleType() const final {
return true; }
1538 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1540 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1545 std::optional<int64_t> MaxSatisfactionElems()
const override {
1550 std::unique_ptr<DescriptorImpl> Clone()
const override
1552 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1553 subdescs.reserve(m_subdescriptor_args.size());
1554 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1555 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1569 const std::vector<CPubKey>& m_keys;
1576 uint160 GetHash160(uint32_t key)
const {
1580 return m_keys[key].GetID();
1586 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1589 return {m_keys[key].begin(), m_keys[key].end()};
1592 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1595 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1596 auto id = GetHash160(key);
1597 return {
id.begin(),
id.end()};
1608 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1610 const DescriptorImpl::StringType m_type;
1615 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1616 DescriptorImpl::StringType type,
1618 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1620 std::optional<std::string>
ToString(uint32_t key,
bool& has_priv_key)
const
1623 has_priv_key =
false;
1625 case DescriptorImpl::StringType::PUBLIC:
1626 ret = m_pubkeys[key]->ToString();
1628 case DescriptorImpl::StringType::PRIVATE:
1629 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg,
ret);
1631 case DescriptorImpl::StringType::NORMALIZED:
1632 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1634 case DescriptorImpl::StringType::COMPAT:
1635 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1642class MiniscriptDescriptor final :
public DescriptorImpl
1648 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1651 const auto script_ctx{
m_node.GetMsCtx()};
1652 for (
const auto& key : keys) {
1656 provider.
pubkeys.emplace(key.GetID(), key);
1659 return Vector(
m_node.ToScript(ScriptMaker(keys, script_ctx)));
1669 const uint32_t raw = node.K();
1670 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1671 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1672 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1673 if (is_time_based) {
1674 m_warnings.push_back(strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1676 m_warnings.push_back(strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1683 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1686 bool has_priv_key{
false};
1687 auto res =
m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1688 if (res)
out = *res;
1689 if (type == StringType::PRIVATE) {
1691 return has_priv_key;
1693 return res.has_value();
1697 bool IsSolvable()
const override {
return true; }
1698 bool IsSingleType() const final {
return true; }
1700 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1702 std::optional<int64_t> MaxSatSize(
bool)
const override
1705 return m_node.GetWitnessSize();
1708 std::optional<int64_t> MaxSatisfactionElems()
const override
1710 return m_node.GetStackSize();
1713 std::unique_ptr<DescriptorImpl> Clone()
const override
1715 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1716 providers.reserve(m_pubkey_args.size());
1717 for (
const auto& arg : m_pubkey_args) {
1718 providers.push_back(arg->Clone());
1720 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node.Clone());
1725class RawTRDescriptor final :
public DescriptorImpl
1728 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1730 assert(keys.size() == 1);
1732 if (!xpk.IsFullyValid())
return {};
1737 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1739 bool IsSingleType() const final {
return true; }
1741 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1743 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1748 std::optional<int64_t> MaxSatisfactionElems()
const override {
1753 std::unique_ptr<DescriptorImpl> Clone()
const override
1755 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1760class UnusedDescriptor final :
public DescriptorImpl
1763 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override {
return {}; }
1765 UnusedDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"unused") {}
1766 bool IsSingleType() const final {
return true; }
1767 bool HasScripts()
const override {
return false; }
1769 std::unique_ptr<DescriptorImpl> Clone()
const override
1771 return std::make_unique<UnusedDescriptor>(m_pubkey_args.at(0)->Clone());
1780enum class ParseScriptContext {
1789std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error,
bool& has_hardened)
1791 bool hardened =
false;
1792 if (elem.size() > 0) {
1793 const char last = elem[elem.size() - 1];
1794 if (last ==
'\'' || last ==
'h') {
1795 elem = elem.first(elem.size() - 1);
1797 apostrophe = last ==
'\'';
1800 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1802 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1803 return std::nullopt;
1804 }
else if (*p > 0x7FFFFFFFUL) {
1805 error =
strprintf(
"Key path value %u is out of range", *p);
1806 return std::nullopt;
1808 has_hardened = has_hardened || hardened;
1810 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1824[[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)
1827 struct MultipathSubstitutes {
1828 size_t placeholder_index;
1829 std::vector<uint32_t>
values;
1831 std::optional<MultipathSubstitutes> substitutes;
1832 has_hardened =
false;
1834 for (
size_t i = 1; i <
split.size(); ++i) {
1835 const std::span<const char>& elem =
split[i];
1838 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1839 if (!allow_multipath) {
1840 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1844 error =
"Multiple multipath key path specifiers found";
1849 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1850 if (nums.size() < 2) {
1851 error =
"Multipath key path specifiers must have at least two items";
1855 substitutes.emplace();
1856 std::unordered_set<uint32_t> seen_substitutes;
1857 for (
const auto& num : nums) {
1858 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1859 if (!op_num)
return false;
1860 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1862 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1865 substitutes->values.emplace_back(*op_num);
1868 path.emplace_back();
1869 substitutes->placeholder_index = path.size() - 1;
1871 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1872 if (!op_num)
return false;
1873 path.emplace_back(*op_num);
1878 out.emplace_back(std::move(path));
1881 for (uint32_t substitute : substitutes->values) {
1882 KeyPath branch_path = path;
1883 branch_path[substitutes->placeholder_index] = substitute;
1884 out.emplace_back(std::move(branch_path));
1890[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1893 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1896static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1898 DeriveType type = DeriveType::NON_RANGED;
1899 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1901 type = DeriveType::UNHARDENED_RANGED;
1902 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1903 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1905 type = DeriveType::HARDENED_RANGED;
1911std::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)
1913 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1914 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1916 std::string str(
split[0].begin(),
split[0].end());
1917 if (str.size() == 0) {
1918 error =
"No key provided";
1922 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1925 if (
split.size() == 1) {
1929 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1930 error =
"Hybrid public keys are not allowed";
1933 if (pubkey.IsFullyValid()) {
1934 if (permit_uncompressed || pubkey.IsCompressed()) {
1935 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1939 error =
"Uncompressed keys are not allowed";
1942 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1943 unsigned char fullkey[33] = {0x02};
1944 std::copy(
data.begin(),
data.end(), fullkey + 1);
1945 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1946 if (pubkey.IsFullyValid()) {
1947 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1952 error =
strprintf(
"Pubkey '%s' is invalid", str);
1959 out.keys.emplace(pubkey.
GetID(), key);
1960 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1964 error =
"Uncompressed keys are not allowed";
1972 error =
strprintf(
"key '%s' is not valid", str);
1975 std::vector<KeyPath> paths;
1976 DeriveType type = ParseDeriveType(
split, apostrophe);
1977 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
1979 extpubkey = extkey.
Neuter();
1982 for (
auto& path : paths) {
1983 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1991std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
1993 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1998 std::span<const char> span = sp;
1999 if (
Const(
"musig(", span,
false)) {
2000 if (ctx != ParseScriptContext::P2TR) {
2001 error =
"musig() is only allowed in tr() and rawtr()";
2008 if (
split.size() > 2) {
2009 error =
"Too many ')' in musig() expression";
2012 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
2013 if (!
Func(
"musig", expr)) {
2014 error =
"Invalid musig() expression";
2019 bool any_ranged =
false;
2020 bool all_bip32 =
true;
2021 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2022 bool any_key_parsed =
false;
2023 size_t max_multipath_len = 0;
2024 while (expr.size()) {
2025 if (any_key_parsed && !
Const(
",", expr)) {
2026 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
2029 auto arg =
Expr(expr);
2030 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
2032 error =
strprintf(
"musig(): %s", error);
2035 any_key_parsed =
true;
2037 any_ranged = any_ranged ||
pk.at(0)->IsRange();
2038 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
2040 max_multipath_len = std::max(max_multipath_len,
pk.size());
2042 providers.emplace_back(std::move(
pk));
2044 if (!any_key_parsed) {
2045 error =
"musig(): Must contain key expressions";
2050 DeriveType deriv_type = DeriveType::NON_RANGED;
2051 std::vector<KeyPath> derivation_multipaths;
2054 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2058 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2063 deriv_type = ParseDeriveType(deriv_split, dummy);
2064 if (deriv_type == DeriveType::HARDENED_RANGED) {
2065 error =
"musig(): Cannot have hardened child derivation";
2068 bool has_hardened =
false;
2069 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
2070 error =
"musig(): " + error;
2074 error =
"musig(): cannot have hardened derivation steps";
2078 derivation_multipaths.emplace_back();
2083 const auto& clone_providers = [&providers](
size_t length) ->
bool {
2084 for (
auto& multipath_providers : providers) {
2085 if (multipath_providers.size() == 1) {
2086 for (
size_t i = 1; i < length; ++i) {
2087 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2089 }
else if (multipath_providers.size() != length) {
2098 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
2099 KeyPath& path = derivation_multipaths.at(path_idx);
2100 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2101 pubs.reserve(providers.size());
2102 for (
auto& vec : providers) {
2103 pubs.emplace_back(std::move(vec.at(vec_idx)));
2105 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2108 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2109 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2111 }
else if (max_multipath_len > 1) {
2112 if (!clone_providers(max_multipath_len)) {
2113 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2116 for (
size_t i = 0; i < max_multipath_len; ++i) {
2118 emplace_final_provider(i, 0);
2120 }
else if (derivation_multipaths.size() > 1) {
2122 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
2123 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2126 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
2128 emplace_final_provider(i, i);
2132 emplace_final_provider(0, 0);
2138 auto origin_split =
Split(sp,
']');
2139 if (origin_split.size() > 2) {
2140 error =
"Multiple ']' characters found for a single pubkey";
2144 bool apostrophe =
false;
2145 if (origin_split.size() == 1) {
2146 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
2148 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
2149 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2150 origin_split[0].empty() ?
']' : origin_split[0][0]);
2153 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
2154 if (slash_split[0].size() != 8) {
2155 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2158 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2159 if (!
IsHex(fpr_hex)) {
2160 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
2163 auto fpr_bytes =
ParseHex(fpr_hex);
2165 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2166 assert(fpr_bytes.size() == 4);
2167 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
2168 std::vector<KeyPath> path;
2169 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2170 info.
path = path.at(0);
2171 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
2172 if (providers.empty())
return {};
2173 ret.reserve(providers.size());
2174 for (
auto& prov : providers) {
2175 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2180std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
2187 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2190 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2193 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2195 return key_provider;
2198std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& provider)
2201 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2204 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2206 return key_provider;
2214 using Key = uint32_t;
2220 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2222 mutable std::string m_key_parsing_error;
2226 uint32_t& m_expr_index;
2230 : m_out(
out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2232 bool KeyCompare(
const Key& a,
const Key& b)
const {
2233 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2237 switch (m_script_ctx) {
2244 std::optional<Key>
FromString(std::span<const char>& in)
const
2247 Key key = m_keys.
size();
2248 auto pk = ParsePubkey(m_expr_index, in,
ParseContext(), *m_out, m_key_parsing_error);
2249 if (
pk.empty())
return {};
2250 m_keys.emplace_back(std::move(
pk));
2254 std::optional<std::string>
ToString(
const Key& key,
bool&)
const
2256 return m_keys.at(key).at(0)->ToString();
2259 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2262 Key key = m_keys.size();
2265 std::copy(begin, end, pubkey.
begin());
2266 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2267 m_keys.emplace_back();
2268 m_keys.back().push_back(std::move(pubkey_provider));
2273 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2274 m_keys.emplace_back();
2275 m_keys.back().push_back(std::move(pubkey_provider));
2282 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2284 assert(end - begin == 20);
2287 std::copy(begin, end, hash.
begin());
2291 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2292 Key key = m_keys.
size();
2293 m_keys.emplace_back();
2294 m_keys.back().push_back(std::move(pubkey_provider));
2302 return m_script_ctx;
2308std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2311 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2312 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2313 auto expr =
Expr(sp);
2314 if (
Func(
"pk", expr)) {
2315 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2316 if (pubkeys.empty()) {
2320 for (
auto& pubkey : pubkeys) {
2321 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2325 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2326 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2327 if (pubkeys.empty()) {
2331 for (
auto& pubkey : pubkeys) {
2332 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2336 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2337 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2338 if (pubkeys.empty()) {
2339 error =
strprintf(
"combo(): %s", error);
2342 for (
auto& pubkey : pubkeys) {
2343 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2346 }
else if (
Func(
"combo", expr)) {
2347 error =
"Can only have combo() at top level";
2350 const bool multi =
Func(
"multi", expr);
2351 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2352 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2353 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2354 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2355 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2356 auto threshold =
Expr(expr);
2358 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2359 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2360 thres = *maybe_thres;
2362 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2365 size_t script_size = 0;
2366 size_t max_providers_len = 0;
2367 while (expr.size()) {
2368 if (!
Const(
",", expr)) {
2369 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2372 auto arg =
Expr(expr);
2373 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2378 script_size += pks.at(0)->GetSize() + 1;
2379 max_providers_len = std::max(max_providers_len, pks.size());
2380 providers.emplace_back(std::move(pks));
2388 }
else if (thres < 1) {
2389 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2391 }
else if (thres > providers.size()) {
2392 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2395 if (ctx == ParseScriptContext::TOP) {
2396 if (providers.size() > 3) {
2397 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2401 if (ctx == ParseScriptContext::P2SH) {
2411 for (
auto& vec : providers) {
2412 if (vec.size() == 1) {
2413 for (
size_t i = 1; i < max_providers_len; ++i) {
2414 vec.emplace_back(vec.at(0)->Clone());
2416 }
else if (vec.size() != max_providers_len) {
2417 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2423 for (
size_t i = 0; i < max_providers_len; ++i) {
2425 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2426 pubs.reserve(providers.size());
2427 for (
auto& pub : providers) {
2428 pubs.emplace_back(std::move(pub.at(i)));
2430 if (multi || sortedmulti) {
2431 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2433 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2437 }
else if (multi || sortedmulti) {
2438 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2440 }
else if (multi_a || sortedmulti_a) {
2441 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2444 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2445 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2446 if (pubkeys.empty()) {
2450 for (
auto& pubkey : pubkeys) {
2451 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2454 }
else if (
Func(
"wpkh", expr)) {
2455 error =
"Can only have wpkh() at top level or inside sh()";
2458 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2459 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2460 if (descs.empty() || expr.size())
return {};
2461 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2462 ret.reserve(descs.size());
2463 for (
auto& desc : descs) {
2464 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2467 }
else if (
Func(
"sh", expr)) {
2468 error =
"Can only have sh() at top level";
2471 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2472 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2473 if (descs.empty() || expr.size())
return {};
2474 for (
auto& desc : descs) {
2475 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2478 }
else if (
Func(
"wsh", expr)) {
2479 error =
"Can only have wsh() at top level or inside sh()";
2482 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2485 error =
"Address is not valid";
2488 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2490 }
else if (
Func(
"addr", expr)) {
2491 error =
"Can only have addr() at top level";
2494 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2495 auto arg =
Expr(expr);
2496 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2497 if (internal_keys.empty()) {
2501 size_t max_providers_len = internal_keys.size();
2502 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2503 std::vector<int> depths;
2505 if (!
Const(
",", expr)) {
2506 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2512 std::vector<bool> branches;
2517 while (
Const(
"{", expr)) {
2518 branches.push_back(
false);
2525 auto sarg =
Expr(expr);
2526 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2527 if (subscripts.back().empty())
return {};
2528 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2529 depths.push_back(branches.size());
2531 while (branches.size() && branches.back()) {
2532 if (!
Const(
"}", expr)) {
2533 error =
strprintf(
"tr(): expected '}' after script expression");
2536 branches.pop_back();
2539 if (branches.size() && !branches.back()) {
2540 if (!
Const(
",", expr)) {
2541 error =
strprintf(
"tr(): expected ',' after script expression");
2544 branches.back() =
true;
2546 }
while (branches.size());
2549 error =
strprintf(
"tr(): expected ')' after script expression");
2557 for (
auto& vec : subscripts) {
2558 if (vec.size() == 1) {
2559 for (
size_t i = 1; i < max_providers_len; ++i) {
2560 vec.emplace_back(vec.at(0)->Clone());
2562 }
else if (vec.size() != max_providers_len) {
2563 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2568 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2569 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2573 while (internal_keys.size() < max_providers_len) {
2574 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2578 for (
size_t i = 0; i < max_providers_len; ++i) {
2580 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2581 this_subs.reserve(subscripts.size());
2582 for (
auto& subs : subscripts) {
2583 this_subs.emplace_back(std::move(subs.at(i)));
2585 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2590 }
else if (
Func(
"tr", expr)) {
2591 error =
"Can only have tr at top level";
2594 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2595 auto arg =
Expr(expr);
2597 error =
strprintf(
"rawtr(): only one key expected.");
2600 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2601 if (output_keys.empty()) {
2602 error =
strprintf(
"rawtr(): %s", error);
2605 for (
auto& pubkey : output_keys) {
2606 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2609 }
else if (
Func(
"rawtr", expr)) {
2610 error =
"Can only have rawtr at top level";
2613 if (ctx == ParseScriptContext::TOP &&
Func(
"unused", expr)) {
2615 auto arg =
Expr(expr);
2617 error =
strprintf(
"unused(): only one key expected");
2620 auto keys = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2621 if (keys.empty())
return {};
2622 for (
auto& pubkey : keys) {
2623 if (pubkey->IsRange()) {
2624 error =
"unused(): key cannot be ranged";
2627 ret.emplace_back(std::make_unique<UnusedDescriptor>(std::move(pubkey)));
2630 }
else if (
Func(
"unused", expr)) {
2631 error =
"Can only have unused at top level";
2634 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2635 std::string str(expr.begin(), expr.end());
2637 error =
"Raw script is not hex";
2641 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2643 }
else if (
Func(
"raw", expr)) {
2644 error =
"Can only have raw() at top level";
2650 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2652 if (parser.m_key_parsing_error !=
"") {
2653 error = std::move(parser.m_key_parsing_error);
2657 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2658 error =
"Miniscript expressions can only be used in wsh or tr.";
2661 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2663 const auto* insane_node = &
node.value();
2664 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2665 error = *insane_node->ToString(parser);
2666 if (!insane_node->IsValid()) {
2667 error +=
" is invalid";
2668 }
else if (!
node->IsSane()) {
2669 error +=
" is not sane";
2670 if (!insane_node->IsNonMalleable()) {
2671 error +=
": malleable witnesses exist";
2672 }
else if (insane_node == &
node.value() && !insane_node->NeedsSignature()) {
2673 error +=
": witnesses without signature exist";
2674 }
else if (!insane_node->CheckTimeLocksMix()) {
2675 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2676 }
else if (!insane_node->CheckDuplicateKey()) {
2677 error +=
": contains duplicate public keys";
2678 }
else if (!insane_node->ValidSatisfactions()) {
2679 error +=
": needs witnesses that may exceed resource limits";
2682 error +=
" is not satisfiable";
2691 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2692 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2693 return a.size() < b.size();
2696 for (
auto& vec : parser.m_keys) {
2697 if (vec.size() == 1) {
2698 for (
size_t i = 1; i < num_multipath; ++i) {
2699 vec.emplace_back(vec.at(0)->Clone());
2701 }
else if (vec.size() != num_multipath) {
2702 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2708 for (
size_t i = 0; i < num_multipath; ++i) {
2710 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2711 pubs.reserve(parser.m_keys.size());
2712 for (
auto& pub : parser.m_keys) {
2713 pubs.emplace_back(std::move(pub.at(i)));
2715 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2720 if (ctx == ParseScriptContext::P2SH) {
2721 error =
"A function is needed within P2SH";
2723 }
else if (ctx == ParseScriptContext::P2WSH) {
2724 error =
"A function is needed within P2WSH";
2727 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2734 if (!match)
return {};
2735 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2736 keys.reserve(match->second.size());
2737 for (
const auto keyspan : match->second) {
2738 if (keyspan.size() != 32)
return {};
2739 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
2740 if (!key)
return {};
2741 keys.push_back(std::move(key));
2743 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2751 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
2754 if (ctx == ParseScriptContext::P2TR) {
2755 auto ret = InferMultiA(
script, ctx, provider);
2759 std::vector<std::vector<unsigned char>>
data;
2762 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2764 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2765 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2768 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2772 if (provider.
GetPubKey(keyid, pubkey)) {
2773 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2774 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2782 if (provider.
GetPubKey(keyid, pubkey)) {
2783 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2784 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2788 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2790 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2791 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2793 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2794 providers.push_back(std::move(pubkey_provider));
2800 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2806 if (provider.
GetCScript(scriptid, subscript)) {
2807 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2808 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2814 if (provider.
GetCScript(scriptid, subscript)) {
2815 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2816 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2831 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2832 std::vector<int> depths;
2833 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2834 std::unique_ptr<DescriptorImpl> subdesc;
2836 subdesc = InferScript(
CScript(
script.begin(),
script.end()), ParseScriptContext::P2TR, provider);
2842 subscripts.push_back(std::move(subdesc));
2843 depths.push_back(depth);
2847 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
2848 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2854 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2856 return std::make_unique<RawTRDescriptor>(std::move(key));
2861 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2863 uint32_t key_exp_index = 0;
2864 KeyParser parser(
nullptr, &provider, script_ctx, key_exp_index);
2867 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2868 keys.reserve(parser.m_keys.size());
2869 for (
auto& key : parser.m_keys) {
2870 keys.emplace_back(std::move(key.at(0)));
2872 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(*
node));
2878 if (ctx != ParseScriptContext::TOP)
return nullptr;
2883 return std::make_unique<AddressDescriptor>(std::move(dest));
2887 return std::make_unique<RawDescriptor>(
script);
2894bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2896 auto check_split =
Split(sp,
'#');
2897 if (check_split.size() > 2) {
2898 error =
"Multiple '#' symbols";
2901 if (check_split.size() == 1 && require_checksum){
2902 error =
"Missing checksum";
2905 if (check_split.size() == 2) {
2906 if (check_split[1].size() != 8) {
2907 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2911 auto checksum = DescriptorChecksum(check_split[0]);
2912 if (checksum.empty()) {
2913 error =
"Invalid characters in payload";
2916 if (check_split.size() == 2) {
2917 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2918 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2922 if (out_checksum) *out_checksum = std::move(checksum);
2923 sp = check_split[0];
2929 std::span<const char> sp{descriptor};
2931 uint32_t key_exp_index = 0;
2933 if (sp.empty() && !
ret.empty()) {
2934 std::vector<std::unique_ptr<Descriptor>> descs;
2935 descs.reserve(
ret.size());
2936 for (
auto& r :
ret) {
2937 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2948 std::span<const char> sp{descriptor};
2955 return InferScript(
script, ParseScriptContext::TOP, provider);
2960 std::string desc_str = desc.
ToString(
true);
2974 xpubs[der_index] = xpub;
2994 const auto& der_it = key_exp_it->second.find(der_index);
2995 if (der_it == key_exp_it->second.end())
return false;
2996 xpub = der_it->second;
3014 if (xpub != parent_xpub_pair.second) {
3015 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
3023 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
3026 if (xpub != derived_xpub_pair.second) {
3027 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
3031 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3032 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3038 if (xpub != lh_xpub_pair.second) {
3039 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.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool GetKeyOriginByXOnly(const XOnlyPubKey &pubkey, KeyOriginInfo &info) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) 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 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, CPubKey > pubkeys
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.
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.