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;
241 GetPrivKey(0, arg, tmp_provider);
242 return !tmp_provider.
keys.empty();
246 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
248 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
251 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
254 virtual bool IsBIP32()
const = 0;
257 virtual size_t GetKeyCount()
const {
return 1; }
260 virtual bool CanSelfExpand()
const = 0;
263class OriginPubkeyProvider final :
public PubkeyProvider
266 std::unique_ptr<PubkeyProvider> m_provider;
269 std::string OriginString(StringType type,
bool normalized=
false)
const
272 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
277 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) {}
280 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg,
out, read_cache, write_cache);
281 if (!pub)
return std::nullopt;
282 Assert(
out.pubkeys.contains(pub->GetID()));
283 auto& [pubkey, suborigin] =
out.origins[pub->GetID()];
285 suborigin.fingerprint = m_origin.fingerprint;
286 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
289 bool IsRange()
const override {
return m_provider->IsRange(); }
290 size_t GetSize()
const override {
return m_provider->GetSize(); }
291 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
292 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
296 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
297 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
303 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
309 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
311 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
317 m_provider->GetPrivKey(pos, arg,
out);
319 std::optional<CPubKey> GetRootPubKey()
const override
321 return m_provider->GetRootPubKey();
323 std::optional<CExtPubKey> GetRootExtPubKey()
const override
325 return m_provider->GetRootExtPubKey();
327 std::unique_ptr<PubkeyProvider> Clone()
const override
329 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
331 bool CanSelfExpand()
const override {
return m_provider->CanSelfExpand(); }
335class ConstPubkeyProvider final :
public PubkeyProvider
344 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
349 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
353 CKeyID keyid = m_pubkey.GetID();
355 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
356 out.pubkeys.emplace(keyid, m_pubkey);
359 bool IsRange()
const override {
return false; }
360 size_t GetSize()
const override {
return m_pubkey.size(); }
361 bool IsBIP32()
const override {
return false; }
362 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
365 std::optional<CKey> key = GetPrivKey(arg);
380 std::optional<CKey> key = GetPrivKey(arg);
382 out.keys.emplace(key->GetPubKey().GetID(), *key);
384 std::optional<CPubKey> GetRootPubKey()
const override
388 std::optional<CExtPubKey> GetRootExtPubKey()
const override
392 std::unique_ptr<PubkeyProvider> Clone()
const override
394 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
396 bool CanSelfExpand() const final {
return true; }
399enum class DeriveType {
406class BIP32PubkeyProvider final :
public PubkeyProvider
418 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
419 ret.nDepth = m_root_extkey.nDepth;
420 ret.fingerprint = m_root_extkey.fingerprint;
421 ret.nChild = m_root_extkey.nChild;
422 ret.chaincode = m_root_extkey.chaincode;
430 if (!GetExtKey(arg, xprv))
return false;
431 for (
auto entry :
m_path) {
432 if (!xprv.
Derive(xprv, entry))
return false;
434 last_hardened = xprv;
440 bool IsHardened()
const
442 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
443 for (
auto entry :
m_path) {
444 if (entry >> 31)
return true;
450 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) {}
451 bool IsRange()
const override {
return m_derive != DeriveType::NON_RANGED; }
452 size_t GetSize()
const override {
return 33; }
453 bool IsBIP32()
const override {
return true; }
457 info.
fingerprint = m_root_extkey.id_key_fingerprint();
459 if (m_derive == DeriveType::UNHARDENED_RANGED) info.
path.push_back((uint32_t)pos);
460 if (m_derive == DeriveType::HARDENED_RANGED) info.
path.push_back(((uint32_t)pos) | 0x80000000L);
468 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
469 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
471 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
472 final_extkey = parent_extkey;
473 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
475 }
else if (IsHardened()) {
478 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
479 parent_extkey = xprv.
Neuter();
480 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.
Derive(xprv, pos);
481 if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
482 final_extkey = xprv.
Neuter();
484 last_hardened_extkey = lh_xprv.
Neuter();
487 for (
auto entry :
m_path) {
488 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
490 final_extkey = parent_extkey;
491 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
492 assert(m_derive != DeriveType::HARDENED_RANGED);
494 if (!der)
return std::nullopt;
501 if (m_derive != DeriveType::HARDENED_RANGED) {
502 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
505 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
507 }
else if (info.
path.size() > 0) {
508 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
512 return final_extkey.
pubkey;
514 std::string
ToString(StringType type,
bool normalized)
const
517 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
521 if (m_derive == DeriveType::HARDENED_RANGED)
ret += use_apostrophe ?
'\'' :
'h';
525 std::string
ToString(StringType type=StringType::PUBLIC)
const override
532 if (!GetExtKey(arg, key)) {
539 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
545 if (m_derive == DeriveType::HARDENED_RANGED) {
551 int i = (int)
m_path.size() - 1;
552 for (; i >= 0; --i) {
565 for (;
k <= i; ++
k) {
571 for (;
k < (int)
m_path.size(); ++
k) {
572 end_path.push_back(
m_path.at(
k));
574 origin.
fingerprint = m_root_extkey.id_key_fingerprint();
579 if (cache !=
nullptr) {
585 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
595 assert(m_derive == DeriveType::UNHARDENED_RANGED);
603 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
604 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.
Derive(extkey, pos))
return;
605 if (m_derive == DeriveType::HARDENED_RANGED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return;
608 std::optional<CPubKey> GetRootPubKey()
const override
612 std::optional<CExtPubKey> GetRootExtPubKey()
const override
614 return m_root_extkey;
616 std::unique_ptr<PubkeyProvider> Clone()
const override
618 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey,
m_path, m_derive, m_apostrophe);
620 bool CanSelfExpand()
const override {
return !IsHardened(); }
624class MuSigPubkeyProvider final :
public PubkeyProvider
628 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
632 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
633 mutable std::optional<CPubKey> m_aggregate_pubkey;
634 const DeriveType m_derive;
635 const bool m_ranged_participants;
637 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NON_RANGED; }
642 std::vector<std::unique_ptr<PubkeyProvider>> providers,
646 : PubkeyProvider(exp_index),
647 m_participants(
std::move(providers)),
650 m_ranged_participants(
std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
652 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
653 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
655 if (!
Assume(m_derive != DeriveType::HARDENED_RANGED)) {
656 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
664 if (!m_aggregate_provider && !m_ranged_participants) {
666 std::vector<CPubKey> pubkeys;
667 for (
const auto& prov : m_participants) {
668 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
669 if (!pubkey.has_value()) {
672 pubkeys.push_back(pubkey.value());
674 std::sort(pubkeys.begin(), pubkeys.end());
678 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
681 if (IsRangedDerivation() || !
m_path.empty()) {
684 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub,
m_path, m_derive,
false);
686 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
691 std::vector<CPubKey> pubkeys;
692 for (
const auto& prov : m_participants) {
693 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
694 if (!pub)
return std::nullopt;
695 pubkeys.emplace_back(*pub);
697 std::sort(pubkeys.begin(), pubkeys.end());
700 if (m_aggregate_provider) {
704 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
705 if (!pub)
return std::nullopt;
707 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
712 if (!aggregate_pubkey)
return std::nullopt;
713 pubout = *aggregate_pubkey;
715 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
716 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
717 out.aggregate_pubkeys.emplace(pubout, pubkeys);
723 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
725 size_t GetSize()
const override {
return 32; }
727 std::string
ToString(StringType type=StringType::PUBLIC)
const override
729 std::string
out =
"musig(";
730 for (
size_t i = 0; i < m_participants.size(); ++i) {
731 const auto& pubkey = m_participants.at(i);
733 out += pubkey->ToString(type);
737 if (IsRangedDerivation()) {
744 bool any_privkeys =
false;
746 for (
size_t i = 0; i < m_participants.size(); ++i) {
747 const auto& pubkey = m_participants.at(i);
750 if (pubkey->ToPrivateString(arg, tmp)) {
757 if (IsRangedDerivation()) {
765 for (
size_t i = 0; i < m_participants.size(); ++i) {
766 const auto& pubkey = m_participants.at(i);
769 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
776 if (IsRangedDerivation()) {
787 for (
const auto& prov : m_participants) {
788 prov->GetPrivKey(pos, arg,
out);
794 return std::ranges::all_of(m_participants, [&](
const auto& prov) {
return prov->HavePrivateKeys(arg); });
802 std::optional<CPubKey> GetRootPubKey()
const override
806 std::optional<CExtPubKey> GetRootExtPubKey()
const override
811 std::unique_ptr<PubkeyProvider> Clone()
const override
813 std::vector<std::unique_ptr<PubkeyProvider>> providers;
814 providers.reserve(m_participants.size());
815 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
816 providers.emplace_back(p->Clone());
818 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers),
m_path, m_derive);
820 bool IsBIP32()
const override
823 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
825 size_t GetKeyCount()
const override
827 return 1 + m_participants.size();
829 bool CanSelfExpand()
const override
833 for (
const auto& key : m_participants) {
834 if (!key->CanSelfExpand())
return false;
845 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
847 const std::string m_name;
849 std::vector<std::string> m_warnings;
855 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
858 virtual std::string ToStringExtra()
const {
return ""; }
870 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
873 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
874 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))) {}
875 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)) {}
877 enum class StringType
888 for (
const auto& arg : m_subdescriptor_args) {
889 if (!arg->IsSolvable())
return false;
897 if (m_pubkey_args.empty() && m_subdescriptor_args.empty())
return false;
899 for (
const auto& sub: m_subdescriptor_args) {
900 if (!sub->HavePrivateKeys(arg))
return false;
903 for (
const auto& pubkey : m_pubkey_args) {
904 if (!pubkey->HavePrivateKeys(arg))
return false;
913 for (
const auto& pubkey : m_pubkey_args) {
914 if (pubkey->IsRange())
return true;
916 for (
const auto& arg : m_subdescriptor_args) {
917 if (arg->IsRange())
return true;
926 bool is_private{type == StringType::PRIVATE};
929 bool any_success{!is_private};
930 for (
const auto& scriptarg : m_subdescriptor_args) {
931 if (pos++)
ret +=
",";
933 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
934 if (!is_private && !subscript_res)
return false;
935 any_success = any_success || subscript_res;
944 std::string extra = ToStringExtra();
945 size_t pos = extra.size() > 0 ? 1 : 0;
946 std::string
ret = m_name +
"(" + extra;
947 bool is_private{type == StringType::PRIVATE};
950 bool any_success{!is_private};
952 for (
const auto& pubkey : m_pubkey_args) {
953 if (pos++)
ret +=
",";
956 case StringType::NORMALIZED:
957 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
959 case StringType::PRIVATE:
960 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
962 case StringType::PUBLIC:
963 tmp = pubkey->ToString();
965 case StringType::COMPAT:
966 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
971 std::string subscript;
972 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
973 if (!is_private && !subscript_res)
return false;
974 any_success = any_success || subscript_res;
975 if (pos && subscript.size())
ret +=
',';
976 out = std::move(
ret) + std::move(subscript) +
")";
980 std::string
ToString(
bool compat_format)
const final
983 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
984 return AddChecksum(
ret);
989 bool has_priv_key{ToStringHelper(&arg,
out, StringType::PRIVATE)};
996 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
1005 std::vector<CPubKey> pubkeys;
1006 pubkeys.reserve(m_pubkey_args.size());
1009 for (
const auto& p : m_pubkey_args) {
1010 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
1011 if (!pubkey)
return false;
1012 pubkeys.push_back(pubkey.value());
1014 std::vector<CScript> subscripts;
1015 for (
const auto& subarg : m_subdescriptor_args) {
1016 std::vector<CScript> outscripts;
1017 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
1018 assert(outscripts.size() == 1);
1019 subscripts.emplace_back(std::move(outscripts[0]));
1021 out.Merge(std::move(subprovider));
1023 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
1029 return ExpandHelper(pos,
provider,
nullptr, output_scripts,
out, write_cache);
1040 for (
const auto& p : m_pubkey_args) {
1043 for (
const auto& arg : m_subdescriptor_args) {
1048 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
1050 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
1057 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
1064 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
1066 for (
const auto& p : m_pubkey_args) {
1067 std::optional<CPubKey> pub = p->GetRootPubKey();
1068 if (pub) pubkeys.insert(*pub);
1069 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1070 if (ext_pub) ext_pubs.insert(*ext_pub);
1072 for (
const auto& arg : m_subdescriptor_args) {
1073 arg->GetPubKeys(pubkeys, ext_pubs);
1077 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1079 bool HasScripts()
const override {
return true; }
1082 std::vector<std::string>
Warnings()
const override {
1083 std::vector<std::string> all = m_warnings;
1084 for (
const auto& sub : m_subdescriptor_args) {
1085 auto sub_w = sub->Warnings();
1086 all.insert(all.end(), sub_w.begin(), sub_w.end());
1093 uint32_t max_key_expr{0};
1094 std::vector<const DescriptorImpl*> todo = {
this};
1095 while (!todo.empty()) {
1096 const DescriptorImpl* desc = todo.back();
1098 for (
const auto& p : desc->m_pubkey_args) {
1099 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1101 for (
const auto&
s : desc->m_subdescriptor_args) {
1102 todo.push_back(
s.get());
1105 return max_key_expr;
1108 size_t GetKeyCount() const final
1111 std::vector<const DescriptorImpl*> todo = {
this};
1112 while (!todo.empty()) {
1113 const DescriptorImpl* desc = todo.back();
1115 for (
const auto& p : desc->m_pubkey_args) {
1116 count += p->GetKeyCount();
1118 for (
const auto&
s : desc->m_subdescriptor_args) {
1119 todo.push_back(
s.get());
1126 bool CanSelfExpand()
const override
1128 for (
const auto& key : m_pubkey_args) {
1129 if (!key->CanSelfExpand())
return false;
1131 for (
const auto& sub : m_subdescriptor_args) {
1132 if (!sub->CanSelfExpand())
return false;
1139class AddressDescriptor final :
public DescriptorImpl
1143 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1146 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1147 bool IsSolvable() const final {
return false; }
1153 bool IsSingleType() const final {
return true; }
1154 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1157 std::unique_ptr<DescriptorImpl> Clone()
const override
1159 return std::make_unique<AddressDescriptor>(m_destination);
1164class RawDescriptor final :
public DescriptorImpl
1168 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1169 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1172 bool IsSolvable() const final {
return false; }
1180 bool IsSingleType() const final {
return true; }
1181 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1183 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1185 std::unique_ptr<DescriptorImpl> Clone()
const override
1187 return std::make_unique<RawDescriptor>(m_script);
1192class PKDescriptor final :
public DescriptorImpl
1197 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1207 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1208 bool IsSingleType() const final {
return true; }
1210 std::optional<int64_t> ScriptSize()
const override {
1211 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1214 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1215 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1216 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1219 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1223 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1225 std::unique_ptr<DescriptorImpl> Clone()
const override
1227 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1232class PKHDescriptor final :
public DescriptorImpl
1235 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1241 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1243 bool IsSingleType() const final {
return true; }
1245 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1247 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1248 const auto sig_size = use_max_sig ? 72 : 71;
1249 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1252 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1256 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1258 std::unique_ptr<DescriptorImpl> Clone()
const override
1260 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1265class WPKHDescriptor final :
public DescriptorImpl
1268 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1274 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1276 bool IsSingleType() const final {
return true; }
1278 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1280 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1281 const auto sig_size = use_max_sig ? 72 : 71;
1285 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1286 return MaxSatSize(use_max_sig);
1289 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1291 std::unique_ptr<DescriptorImpl> Clone()
const override
1293 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1298class ComboDescriptor final :
public DescriptorImpl
1301 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
1303 std::vector<CScript>
ret;
1307 if (
keys[0].IsCompressed()) {
1310 ret.emplace_back(p2wpkh);
1316 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1317 bool IsSingleType() const final {
return false; }
1318 std::unique_ptr<DescriptorImpl> Clone()
const override
1320 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1325class MultisigDescriptor final :
public DescriptorImpl
1327 const int m_threshold;
1328 const bool m_sorted;
1330 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1331 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1333 std::vector<CPubKey> sorted_keys(
keys);
1334 std::sort(sorted_keys.begin(), sorted_keys.end());
1340 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) {}
1341 bool IsSingleType() const final {
return true; }
1343 std::optional<int64_t> ScriptSize()
const override {
1344 const auto n_keys = m_pubkey_args.size();
1345 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1346 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1350 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1351 const auto sig_size = use_max_sig ? 72 : 71;
1352 return (1 + (1 +
sig_size) * m_threshold);
1355 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1359 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1361 std::unique_ptr<DescriptorImpl> Clone()
const override
1363 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1364 providers.reserve(m_pubkey_args.size());
1365 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1366 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1371class MultiADescriptor final :
public DescriptorImpl
1373 const int m_threshold;
1374 const bool m_sorted;
1376 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1377 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1379 std::vector<XOnlyPubKey> xkeys;
1380 xkeys.reserve(
keys.size());
1381 for (
const auto& key :
keys) xkeys.emplace_back(key);
1382 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1384 for (
size_t i = 1; i <
keys.size(); ++i) {
1391 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) {}
1392 bool IsSingleType() const final {
return true; }
1394 std::optional<int64_t> ScriptSize()
const override {
1395 const auto n_keys = m_pubkey_args.size();
1399 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1400 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1403 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1405 std::unique_ptr<DescriptorImpl> Clone()
const override
1407 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1408 providers.reserve(m_pubkey_args.size());
1409 for (
const auto& arg : m_pubkey_args) {
1410 providers.push_back(arg->Clone());
1412 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1417class SHDescriptor final :
public DescriptorImpl
1420 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1423 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1430 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1434 assert(m_subdescriptor_args.size() == 1);
1438 bool IsSingleType() const final {
return true; }
1440 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1442 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1443 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1444 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1448 if (
IsSegwit())
return subscript_weight + *sat_size;
1455 std::optional<int64_t> MaxSatisfactionElems()
const override {
1456 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1460 std::unique_ptr<DescriptorImpl> Clone()
const override
1462 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1467class WSHDescriptor final :
public DescriptorImpl
1470 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1473 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1477 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1479 bool IsSingleType() const final {
return true; }
1481 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1483 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1484 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1485 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1492 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1493 return MaxSatSize(use_max_sig);
1496 std::optional<int64_t> MaxSatisfactionElems()
const override {
1497 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1501 std::unique_ptr<DescriptorImpl> Clone()
const override
1503 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1508class TRDescriptor final :
public DescriptorImpl
1510 std::vector<int> m_depths;
1512 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1515 assert(m_depths.size() == scripts.size());
1516 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1522 if (!xpk.IsFullyValid())
return {};
1525 out.tr_trees[output] = builder;
1530 if (m_depths.empty()) {
1536 return type != StringType::PRIVATE;
1538 std::vector<bool> path;
1539 bool is_private{type == StringType::PRIVATE};
1542 bool any_success{!is_private};
1544 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1545 if (pos)
ret +=
',';
1546 while ((
int)path.size() <= m_depths[pos]) {
1547 if (path.size())
ret +=
'{';
1548 path.push_back(
false);
1551 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1552 if (!is_private && !subscript_res)
return false;
1553 any_success = any_success || subscript_res;
1555 while (!path.empty() && path.back()) {
1556 if (path.size() > 1)
ret +=
'}';
1559 if (!path.empty()) path.back() =
true;
1564 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1565 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1567 assert(m_subdescriptor_args.size() == m_depths.size());
1570 bool IsSingleType() const final {
return true; }
1572 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1574 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1579 std::optional<int64_t> MaxSatisfactionElems()
const override {
1584 std::unique_ptr<DescriptorImpl> Clone()
const override
1586 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1587 subdescs.reserve(m_subdescriptor_args.size());
1588 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1589 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1603 const std::vector<CPubKey>& m_keys;
1610 uint160 GetHash160(uint32_t key)
const {
1614 return m_keys[key].GetID();
1620 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1623 return {m_keys[key].begin(), m_keys[key].end()};
1626 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1629 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1630 auto id = GetHash160(key);
1631 return {
id.begin(),
id.end()};
1642 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1644 const DescriptorImpl::StringType m_type;
1649 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1650 DescriptorImpl::StringType type,
1652 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1654 std::optional<std::string>
ToString(uint32_t key,
bool& has_priv_key)
const
1657 has_priv_key =
false;
1659 case DescriptorImpl::StringType::PUBLIC:
1660 ret = m_pubkeys[key]->ToString();
1662 case DescriptorImpl::StringType::PRIVATE:
1663 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg,
ret);
1665 case DescriptorImpl::StringType::NORMALIZED:
1666 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1668 case DescriptorImpl::StringType::COMPAT:
1669 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1676class MiniscriptDescriptor final :
public DescriptorImpl
1682 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
1685 const auto script_ctx{
m_node.GetMsCtx()};
1686 for (
const auto& key :
keys) {
1690 provider.pubkeys.emplace(key.GetID(), key);
1703 const uint32_t raw = node.K();
1704 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1705 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1706 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1707 if (is_time_based) {
1708 m_warnings.push_back(strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1710 m_warnings.push_back(strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1717 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1720 bool has_priv_key{
false};
1721 auto res =
m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1722 if (res)
out = *res;
1723 if (type == StringType::PRIVATE) {
1725 return has_priv_key;
1727 return res.has_value();
1731 bool IsSolvable()
const override {
return true; }
1732 bool IsSingleType() const final {
return true; }
1734 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1736 std::optional<int64_t> MaxSatSize(
bool)
const override
1739 return m_node.GetWitnessSize();
1742 std::optional<int64_t> MaxSatisfactionElems()
const override
1744 return m_node.GetStackSize();
1747 std::unique_ptr<DescriptorImpl> Clone()
const override
1749 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1750 providers.reserve(m_pubkey_args.size());
1751 for (
const auto& arg : m_pubkey_args) {
1752 providers.push_back(arg->Clone());
1754 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node.Clone());
1759class RawTRDescriptor final :
public DescriptorImpl
1762 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1766 if (!xpk.IsFullyValid())
return {};
1771 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1773 bool IsSingleType() const final {
return true; }
1775 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1777 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1782 std::optional<int64_t> MaxSatisfactionElems()
const override {
1787 std::unique_ptr<DescriptorImpl> Clone()
const override
1789 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1794class UnusedDescriptor final :
public DescriptorImpl
1797 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override {
return {}; }
1799 UnusedDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"unused") {}
1800 bool IsSingleType() const final {
return true; }
1801 bool HasScripts()
const override {
return false; }
1803 std::unique_ptr<DescriptorImpl> Clone()
const override
1805 return std::make_unique<UnusedDescriptor>(m_pubkey_args.at(0)->Clone());
1814enum class ParseScriptContext {
1823std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error,
bool& has_hardened)
1825 bool hardened =
false;
1826 if (elem.size() > 0) {
1827 const char last = elem[elem.size() - 1];
1828 if (last ==
'\'' || last ==
'h') {
1829 elem = elem.first(elem.size() - 1);
1831 apostrophe = last ==
'\'';
1834 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1836 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1837 return std::nullopt;
1838 }
else if (*p > 0x7FFFFFFFUL) {
1839 error =
strprintf(
"Key path value %u is out of range", *p);
1840 return std::nullopt;
1842 has_hardened = has_hardened || hardened;
1844 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1858[[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)
1861 struct MultipathSubstitutes {
1862 size_t placeholder_index;
1863 std::vector<uint32_t>
values;
1865 std::optional<MultipathSubstitutes> substitutes;
1866 has_hardened =
false;
1868 for (
size_t i = 1; i <
split.size(); ++i) {
1869 const std::span<const char>& elem =
split[i];
1872 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1873 if (!allow_multipath) {
1874 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1878 error =
"Multiple multipath key path specifiers found";
1883 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1884 if (nums.size() < 2) {
1885 error =
"Multipath key path specifiers must have at least two items";
1889 substitutes.emplace();
1890 std::unordered_set<uint32_t> seen_substitutes;
1891 for (
const auto& num : nums) {
1892 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1893 if (!op_num)
return false;
1894 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1896 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1899 substitutes->values.emplace_back(*op_num);
1902 path.emplace_back();
1903 substitutes->placeholder_index = path.size() - 1;
1905 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1906 if (!op_num)
return false;
1907 path.emplace_back(*op_num);
1912 out.emplace_back(std::move(path));
1915 for (uint32_t substitute : substitutes->values) {
1916 KeyPath branch_path = path;
1917 branch_path[substitutes->placeholder_index] = substitute;
1918 out.emplace_back(std::move(branch_path));
1924[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1927 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1930static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1932 DeriveType type = DeriveType::NON_RANGED;
1933 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1935 type = DeriveType::UNHARDENED_RANGED;
1936 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1937 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1939 type = DeriveType::HARDENED_RANGED;
1945std::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)
1947 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1948 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1950 std::string str(
split[0].begin(),
split[0].end());
1951 if (str.size() == 0) {
1952 error =
"No key provided";
1956 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1959 if (
split.size() == 1) {
1963 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1964 error =
"Hybrid public keys are not allowed";
1967 if (pubkey.IsFullyValid()) {
1968 if (permit_uncompressed || pubkey.IsCompressed()) {
1969 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1973 error =
"Uncompressed keys are not allowed";
1976 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1977 unsigned char fullkey[33] = {0x02};
1978 std::copy(
data.begin(),
data.end(), fullkey + 1);
1979 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1980 if (pubkey.IsFullyValid()) {
1981 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1986 error =
strprintf(
"Pubkey '%s' is invalid", str);
1993 out.keys.emplace(pubkey.
GetID(), key);
1994 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1998 error =
"Uncompressed keys are not allowed";
2006 error =
strprintf(
"key '%s' is not valid", str);
2009 std::vector<KeyPath> paths;
2010 DeriveType type = ParseDeriveType(
split, apostrophe);
2011 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
2013 extpubkey = extkey.
Neuter();
2016 for (
auto& path : paths) {
2017 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
2025std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2027 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
2032 std::span<const char> span = sp;
2033 if (
Const(
"musig(", span,
false)) {
2034 if (ctx != ParseScriptContext::P2TR) {
2035 error =
"musig() is only allowed in tr() and rawtr()";
2042 if (
split.size() > 2) {
2043 error =
"Too many ')' in musig() expression";
2046 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
2047 if (!
Func(
"musig", expr)) {
2048 error =
"Invalid musig() expression";
2053 bool any_ranged =
false;
2054 bool all_bip32 =
true;
2055 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2056 bool any_key_parsed =
false;
2057 size_t max_multipath_len = 0;
2058 while (expr.size()) {
2059 if (any_key_parsed && !
Const(
",", expr)) {
2060 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
2063 auto arg =
Expr(expr);
2064 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
2066 error =
strprintf(
"musig(): %s", error);
2069 any_key_parsed =
true;
2071 any_ranged = any_ranged ||
pk.at(0)->IsRange();
2072 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
2074 max_multipath_len = std::max(max_multipath_len,
pk.size());
2076 providers.emplace_back(std::move(
pk));
2078 if (!any_key_parsed) {
2079 error =
"musig(): Must contain key expressions";
2084 DeriveType deriv_type = DeriveType::NON_RANGED;
2085 std::vector<KeyPath> derivation_multipaths;
2088 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2092 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2097 deriv_type = ParseDeriveType(deriv_split, dummy);
2098 if (deriv_type == DeriveType::HARDENED_RANGED) {
2099 error =
"musig(): Cannot have hardened child derivation";
2102 bool has_hardened =
false;
2103 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
2104 error =
"musig(): " + error;
2108 error =
"musig(): cannot have hardened derivation steps";
2112 derivation_multipaths.emplace_back();
2117 const auto& clone_providers = [&providers](
size_t length) ->
bool {
2118 for (
auto& multipath_providers : providers) {
2119 if (multipath_providers.size() == 1) {
2120 for (
size_t i = 1; i < length; ++i) {
2121 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2123 }
else if (multipath_providers.size() != length) {
2132 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
2133 KeyPath& path = derivation_multipaths.at(path_idx);
2134 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2135 pubs.reserve(providers.size());
2136 for (
auto& vec : providers) {
2137 pubs.emplace_back(std::move(vec.at(vec_idx)));
2139 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2142 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2143 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2145 }
else if (max_multipath_len > 1) {
2146 if (!clone_providers(max_multipath_len)) {
2147 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2150 for (
size_t i = 0; i < max_multipath_len; ++i) {
2152 emplace_final_provider(i, 0);
2154 }
else if (derivation_multipaths.size() > 1) {
2156 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
2157 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2160 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
2162 emplace_final_provider(i, i);
2166 emplace_final_provider(0, 0);
2172 auto origin_split =
Split(sp,
']');
2173 if (origin_split.size() > 2) {
2174 error =
"Multiple ']' characters found for a single pubkey";
2178 bool apostrophe =
false;
2179 if (origin_split.size() == 1) {
2180 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
2182 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
2183 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2184 origin_split[0].empty() ?
']' : origin_split[0][0]);
2187 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
2188 if (slash_split[0].size() != 8) {
2189 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2192 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2193 if (!
IsHex(fpr_hex)) {
2194 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
2197 auto fpr_bytes =
ParseHex(fpr_hex);
2199 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2200 assert(fpr_bytes.size() == 4);
2202 std::vector<KeyPath> path;
2203 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2204 info.
path = path.at(0);
2205 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
2206 if (providers.empty())
return {};
2207 ret.reserve(providers.size());
2208 for (
auto& prov : providers) {
2209 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2221 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2224 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2227 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2229 return key_provider;
2235 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2237 if (
provider.GetKeyOriginByXOnly(xkey, info)) {
2238 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2240 return key_provider;
2248 using Key = uint32_t;
2254 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2256 mutable std::string m_key_parsing_error;
2260 uint32_t& m_expr_index;
2264 : m_out(
out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2266 bool KeyCompare(
const Key& a,
const Key& b)
const {
2267 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2271 switch (m_script_ctx) {
2278 std::optional<Key>
FromString(std::span<const char>& in)
const
2281 Key key = m_keys.
size();
2282 auto pk = ParsePubkey(m_expr_index, in,
ParseContext(), *m_out, m_key_parsing_error);
2283 if (
pk.empty())
return {};
2284 m_keys.emplace_back(std::move(
pk));
2288 std::optional<std::string>
ToString(
const Key& key,
bool&)
const
2290 return m_keys.at(key).at(0)->ToString();
2293 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2296 Key key = m_keys.size();
2299 std::copy(begin, end, pubkey.
begin());
2300 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2301 m_keys.emplace_back();
2302 m_keys.back().push_back(std::move(pubkey_provider));
2307 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2308 m_keys.emplace_back();
2309 m_keys.back().push_back(std::move(pubkey_provider));
2316 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2318 assert(end - begin == 20);
2321 std::copy(begin, end, hash.
begin());
2325 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2326 Key key = m_keys.
size();
2327 m_keys.emplace_back();
2328 m_keys.back().push_back(std::move(pubkey_provider));
2336 return m_script_ctx;
2342std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2345 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2346 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2347 auto expr =
Expr(sp);
2348 if (
Func(
"pk", expr)) {
2349 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2350 if (pubkeys.empty()) {
2354 for (
auto& pubkey : pubkeys) {
2355 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2359 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2360 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2361 if (pubkeys.empty()) {
2365 for (
auto& pubkey : pubkeys) {
2366 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2370 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2371 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2372 if (pubkeys.empty()) {
2373 error =
strprintf(
"combo(): %s", error);
2376 for (
auto& pubkey : pubkeys) {
2377 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2380 }
else if (
Func(
"combo", expr)) {
2381 error =
"Can only have combo() at top level";
2384 const bool multi =
Func(
"multi", expr);
2385 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2386 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2387 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2388 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2389 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2390 auto threshold =
Expr(expr);
2392 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2393 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2394 thres = *maybe_thres;
2396 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2399 size_t script_size = 0;
2400 size_t max_providers_len = 0;
2401 while (expr.size()) {
2402 if (!
Const(
",", expr)) {
2403 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2406 auto arg =
Expr(expr);
2407 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2412 script_size += pks.at(0)->GetSize() + 1;
2413 max_providers_len = std::max(max_providers_len, pks.size());
2414 providers.emplace_back(std::move(pks));
2422 }
else if (thres < 1) {
2423 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2425 }
else if (thres > providers.size()) {
2426 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2429 if (ctx == ParseScriptContext::TOP) {
2430 if (providers.size() > 3) {
2431 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2435 if (ctx == ParseScriptContext::P2SH) {
2445 for (
auto& vec : providers) {
2446 if (vec.size() == 1) {
2447 for (
size_t i = 1; i < max_providers_len; ++i) {
2448 vec.emplace_back(vec.at(0)->Clone());
2450 }
else if (vec.size() != max_providers_len) {
2451 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2457 for (
size_t i = 0; i < max_providers_len; ++i) {
2459 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2460 pubs.reserve(providers.size());
2461 for (
auto& pub : providers) {
2462 pubs.emplace_back(std::move(pub.at(i)));
2464 if (multi || sortedmulti) {
2465 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2467 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2471 }
else if (multi || sortedmulti) {
2472 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2474 }
else if (multi_a || sortedmulti_a) {
2475 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2478 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2479 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2480 if (pubkeys.empty()) {
2484 for (
auto& pubkey : pubkeys) {
2485 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2488 }
else if (
Func(
"wpkh", expr)) {
2489 error =
"Can only have wpkh() at top level or inside sh()";
2492 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2493 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2494 if (descs.empty() || expr.size())
return {};
2495 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2496 ret.reserve(descs.size());
2497 for (
auto& desc : descs) {
2498 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2501 }
else if (
Func(
"sh", expr)) {
2502 error =
"Can only have sh() at top level";
2505 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2506 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2507 if (descs.empty() || expr.size())
return {};
2508 for (
auto& desc : descs) {
2509 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2512 }
else if (
Func(
"wsh", expr)) {
2513 error =
"Can only have wsh() at top level or inside sh()";
2516 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2519 error =
"Address is not valid";
2522 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2524 }
else if (
Func(
"addr", expr)) {
2525 error =
"Can only have addr() at top level";
2528 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2529 auto arg =
Expr(expr);
2530 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2531 if (internal_keys.empty()) {
2535 size_t max_providers_len = internal_keys.size();
2536 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2537 std::vector<int> depths;
2539 if (!
Const(
",", expr)) {
2540 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2546 std::vector<bool> branches;
2551 while (
Const(
"{", expr)) {
2552 branches.push_back(
false);
2559 auto sarg =
Expr(expr);
2560 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2561 if (subscripts.back().empty())
return {};
2562 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2563 depths.push_back(branches.size());
2565 while (branches.size() && branches.back()) {
2566 if (!
Const(
"}", expr)) {
2567 error =
strprintf(
"tr(): expected '}' after script expression");
2570 branches.pop_back();
2573 if (branches.size() && !branches.back()) {
2574 if (!
Const(
",", expr)) {
2575 error =
strprintf(
"tr(): expected ',' after script expression");
2578 branches.back() =
true;
2580 }
while (branches.size());
2583 error =
strprintf(
"tr(): expected ')' after script expression");
2591 for (
auto& vec : subscripts) {
2592 if (vec.size() == 1) {
2593 for (
size_t i = 1; i < max_providers_len; ++i) {
2594 vec.emplace_back(vec.at(0)->Clone());
2596 }
else if (vec.size() != max_providers_len) {
2597 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2602 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2603 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2607 while (internal_keys.size() < max_providers_len) {
2608 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2612 for (
size_t i = 0; i < max_providers_len; ++i) {
2614 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2615 this_subs.reserve(subscripts.size());
2616 for (
auto& subs : subscripts) {
2617 this_subs.emplace_back(std::move(subs.at(i)));
2619 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2624 }
else if (
Func(
"tr", expr)) {
2625 error =
"Can only have tr at top level";
2628 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2629 auto arg =
Expr(expr);
2631 error =
strprintf(
"rawtr(): only one key expected.");
2634 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2635 if (output_keys.empty()) {
2636 error =
strprintf(
"rawtr(): %s", error);
2639 for (
auto& pubkey : output_keys) {
2640 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2643 }
else if (
Func(
"rawtr", expr)) {
2644 error =
"Can only have rawtr at top level";
2647 if (ctx == ParseScriptContext::TOP &&
Func(
"unused", expr)) {
2649 auto arg =
Expr(expr);
2651 error =
strprintf(
"unused(): only one key expected");
2654 auto keys = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2655 if (
keys.empty())
return {};
2656 for (
auto& pubkey :
keys) {
2657 if (pubkey->IsRange()) {
2658 error =
"unused(): key cannot be ranged";
2661 ret.emplace_back(std::make_unique<UnusedDescriptor>(std::move(pubkey)));
2664 }
else if (
Func(
"unused", expr)) {
2665 error =
"Can only have unused at top level";
2668 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2669 std::string str(expr.begin(), expr.end());
2671 error =
"Raw script is not hex";
2675 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2677 }
else if (
Func(
"raw", expr)) {
2678 error =
"Can only have raw() at top level";
2684 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2686 if (parser.m_key_parsing_error !=
"") {
2687 error = std::move(parser.m_key_parsing_error);
2691 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2692 error =
"Miniscript expressions can only be used in wsh or tr.";
2695 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2697 const auto* insane_node = &
node.value();
2698 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2699 error = *insane_node->ToString(parser);
2700 if (!insane_node->IsValid()) {
2701 error +=
" is invalid";
2702 }
else if (!
node->IsSane()) {
2703 error +=
" is not sane";
2704 if (!insane_node->IsNonMalleable()) {
2705 error +=
": malleable witnesses exist";
2706 }
else if (insane_node == &
node.value() && !insane_node->NeedsSignature()) {
2707 error +=
": witnesses without signature exist";
2708 }
else if (!insane_node->CheckTimeLocksMix()) {
2709 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2710 }
else if (!insane_node->CheckDuplicateKey()) {
2711 error +=
": contains duplicate public keys";
2712 }
else if (!insane_node->ValidSatisfactions()) {
2713 error +=
": needs witnesses that may exceed resource limits";
2716 error +=
" is not satisfiable";
2725 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2726 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2727 return a.size() < b.size();
2730 for (
auto& vec : parser.m_keys) {
2731 if (vec.size() == 1) {
2732 for (
size_t i = 1; i < num_multipath; ++i) {
2733 vec.emplace_back(vec.at(0)->Clone());
2735 }
else if (vec.size() != num_multipath) {
2736 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2742 for (
size_t i = 0; i < num_multipath; ++i) {
2744 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2745 pubs.reserve(parser.m_keys.size());
2746 for (
auto& pub : parser.m_keys) {
2747 pubs.emplace_back(std::move(pub.at(i)));
2749 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2754 if (ctx == ParseScriptContext::P2SH) {
2755 error =
"A function is needed within P2SH";
2757 }
else if (ctx == ParseScriptContext::P2WSH) {
2758 error =
"A function is needed within P2WSH";
2761 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2768 if (!match)
return {};
2769 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2770 keys.reserve(match->second.size());
2771 for (
const auto keyspan : match->second) {
2772 if (keyspan.size() != 32)
return {};
2774 if (!key)
return {};
2775 keys.push_back(std::move(key));
2777 return std::make_unique<MultiADescriptor>(match->first, std::move(
keys));
2785 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx,
provider),
true);
2788 if (ctx == ParseScriptContext::P2TR) {
2793 std::vector<std::vector<unsigned char>>
data;
2796 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2798 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2799 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2802 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2806 if (
provider.GetPubKey(keyid, pubkey)) {
2807 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2808 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2816 if (
provider.GetPubKey(keyid, pubkey)) {
2817 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH,
provider)) {
2818 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2822 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2824 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2825 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2827 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2828 providers.push_back(std::move(pubkey_provider));
2834 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2840 if (
provider.GetCScript(scriptid, subscript)) {
2841 auto sub = InferScript(subscript, ParseScriptContext::P2SH,
provider);
2842 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2848 if (
provider.GetCScript(scriptid, subscript)) {
2849 auto sub = InferScript(subscript, ParseScriptContext::P2WSH,
provider);
2850 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2859 if (
provider.GetTaprootSpendData(pubkey, tap)) {
2865 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2866 std::vector<int> depths;
2867 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2868 std::unique_ptr<DescriptorImpl> subdesc;
2876 subscripts.push_back(std::move(subdesc));
2877 depths.push_back(depth);
2882 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2888 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR,
provider);
2890 return std::make_unique<RawTRDescriptor>(std::move(key));
2895 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2897 uint32_t key_exp_index = 0;
2898 KeyParser parser(
nullptr, &
provider, script_ctx, key_exp_index);
2901 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2902 keys.reserve(parser.m_keys.size());
2903 for (
auto& key : parser.m_keys) {
2904 keys.emplace_back(std::move(key.at(0)));
2906 return std::make_unique<MiniscriptDescriptor>(std::move(
keys), std::move(*
node));
2912 if (ctx != ParseScriptContext::TOP)
return nullptr;
2917 return std::make_unique<AddressDescriptor>(std::move(dest));
2921 return std::make_unique<RawDescriptor>(
script);
2928bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2930 auto check_split =
Split(sp,
'#');
2931 if (check_split.size() > 2) {
2932 error =
"Multiple '#' symbols";
2935 if (check_split.size() == 1 && require_checksum){
2936 error =
"Missing checksum";
2939 if (check_split.size() == 2) {
2940 if (check_split[1].size() != 8) {
2941 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2945 auto checksum = DescriptorChecksum(check_split[0]);
2946 if (checksum.empty()) {
2947 error =
"Invalid characters in payload";
2950 if (check_split.size() == 2) {
2951 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2952 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2956 if (out_checksum) *out_checksum = std::move(checksum);
2957 sp = check_split[0];
2963 std::span<const char> sp{descriptor};
2965 uint32_t key_exp_index = 0;
2967 if (sp.empty() && !
ret.empty()) {
2968 std::vector<std::unique_ptr<Descriptor>> descs;
2969 descs.reserve(
ret.size());
2970 for (
auto& r :
ret) {
2971 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2982 std::span<const char> sp{descriptor};
2994 std::string desc_str = desc.
ToString(
true);
3008 xpubs[der_index] = xpub;
3028 const auto& der_it = key_exp_it->second.find(der_index);
3029 if (der_it == key_exp_it->second.end())
return false;
3030 xpub = der_it->second;
3048 if (xpub != parent_xpub_pair.second) {
3049 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
3057 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
3060 if (xpub != derived_xpub_pair.second) {
3061 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
3065 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3066 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3072 if (xpub != lh_xpub_pair.second) {
3073 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.
KeyFingerprint fingerprint() const
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
KeyFingerprint fingerprint
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.