94uint64_t
PolyMod(uint64_t c,
int val)
97 c = ((c & 0x7ffffffff) << 5) ^ val;
98 if (c0 & 1) c ^= 0xf5dee51989;
99 if (c0 & 2) c ^= 0xa9fdca3312;
100 if (c0 & 4) c ^= 0x1bab10e32d;
101 if (c0 & 8) c ^= 0x3706b1677a;
102 if (c0 & 16) c ^= 0x644d626ffd;
106std::string DescriptorChecksum(
const std::span<const char>& span)
121 static const std::string INPUT_CHARSET =
122 "0123456789()[],'/*abcdefgh@:$%{}"
123 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
124 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
127 static const std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
132 for (
auto ch : span) {
133 auto pos = INPUT_CHARSET.find(ch);
134 if (pos == std::string::npos)
return "";
136 cls = cls * 3 + (pos >> 5);
137 if (++clscount == 3) {
144 if (clscount > 0) c =
PolyMod(c, cls);
145 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
148 std::string
ret(8,
' ');
149 for (
int j = 0; j < 8; ++j)
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
153std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
159typedef std::vector<uint32_t> KeyPath;
167 const uint32_t m_expr_index;
169 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
171 virtual ~PubkeyProvider() =
default;
176 bool operator<(PubkeyProvider& other)
const {
179 std::optional<CPubKey> a =
GetPubKey(0, dummy, dummy);
180 std::optional<CPubKey> b = other.GetPubKey(0, dummy, dummy);
193 virtual bool IsRange()
const = 0;
196 virtual size_t GetSize()
const = 0;
198 enum class StringType {
204 virtual std::string
ToString(StringType type=StringType::PUBLIC)
const = 0;
222 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
224 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
227 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
230 virtual bool IsBIP32()
const = 0;
233 virtual size_t GetKeyCount()
const {
return 1; }
236class OriginPubkeyProvider final :
public PubkeyProvider
239 std::unique_ptr<PubkeyProvider> m_provider;
242 std::string OriginString(StringType type,
bool normalized=
false)
const
245 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
250 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) {}
253 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg,
out, read_cache, write_cache);
254 if (!pub)
return std::nullopt;
255 Assert(
out.pubkeys.contains(pub->GetID()));
256 auto& [pubkey, suborigin] =
out.origins[pub->GetID()];
258 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), suborigin.fingerprint);
259 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
262 bool IsRange()
const override {
return m_provider->IsRange(); }
263 size_t GetSize()
const override {
return m_provider->GetSize(); }
264 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
265 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
269 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
270 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
276 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
282 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
284 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
290 m_provider->GetPrivKey(pos, arg,
out);
292 std::optional<CPubKey> GetRootPubKey()
const override
294 return m_provider->GetRootPubKey();
296 std::optional<CExtPubKey> GetRootExtPubKey()
const override
298 return m_provider->GetRootExtPubKey();
300 std::unique_ptr<PubkeyProvider> Clone()
const override
302 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
307class ConstPubkeyProvider final :
public PubkeyProvider
316 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
321 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
325 CKeyID keyid = m_pubkey.GetID();
327 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
328 out.pubkeys.emplace(keyid, m_pubkey);
331 bool IsRange()
const override {
return false; }
332 size_t GetSize()
const override {
return m_pubkey.size(); }
333 bool IsBIP32()
const override {
return false; }
334 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
337 std::optional<CKey> key = GetPrivKey(arg);
352 std::optional<CKey> key = GetPrivKey(arg);
354 out.keys.emplace(key->GetPubKey().GetID(), *key);
356 std::optional<CPubKey> GetRootPubKey()
const override
360 std::optional<CExtPubKey> GetRootExtPubKey()
const override
364 std::unique_ptr<PubkeyProvider> Clone()
const override
366 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
370enum class DeriveType {
377class BIP32PubkeyProvider final :
public PubkeyProvider
389 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
390 ret.nDepth = m_root_extkey.nDepth;
391 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint +
sizeof(
ret.vchFingerprint),
ret.vchFingerprint);
392 ret.nChild = m_root_extkey.nChild;
393 ret.chaincode = m_root_extkey.chaincode;
401 if (!GetExtKey(arg, xprv))
return false;
402 for (
auto entry : m_path) {
403 if (!xprv.
Derive(xprv, entry))
return false;
405 last_hardened = xprv;
411 bool IsHardened()
const
413 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
414 for (
auto entry : m_path) {
415 if (entry >> 31)
return true;
421 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) {}
422 bool IsRange()
const override {
return m_derive != DeriveType::NON_RANGED; }
423 size_t GetSize()
const override {
return 33; }
424 bool IsBIP32()
const override {
return true; }
428 CKeyID keyid = m_root_extkey.pubkey.GetID();
431 if (m_derive == DeriveType::UNHARDENED_RANGED) info.
path.push_back((uint32_t)pos);
432 if (m_derive == DeriveType::HARDENED_RANGED) info.
path.push_back(((uint32_t)pos) | 0x80000000L);
440 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
441 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
443 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
444 final_extkey = parent_extkey;
445 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
447 }
else if (IsHardened()) {
450 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
451 parent_extkey = xprv.
Neuter();
452 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.
Derive(xprv, pos);
453 if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
454 final_extkey = xprv.
Neuter();
456 last_hardened_extkey = lh_xprv.
Neuter();
459 for (
auto entry : m_path) {
460 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
462 final_extkey = parent_extkey;
463 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
464 assert(m_derive != DeriveType::HARDENED_RANGED);
466 if (!der)
return std::nullopt;
473 if (m_derive != DeriveType::HARDENED_RANGED) {
474 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
477 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
479 }
else if (info.
path.size() > 0) {
480 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
484 return final_extkey.
pubkey;
486 std::string
ToString(StringType type,
bool normalized)
const
489 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
493 if (m_derive == DeriveType::HARDENED_RANGED)
ret += use_apostrophe ?
'\'' :
'h';
497 std::string
ToString(StringType type=StringType::PUBLIC)
const override
504 if (!GetExtKey(arg, key)) {
511 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
517 if (m_derive == DeriveType::HARDENED_RANGED) {
523 int i = (int)m_path.size() - 1;
524 for (; i >= 0; --i) {
525 if (m_path.at(i) >> 31) {
537 for (;
k <= i; ++
k) {
539 origin.
path.push_back(m_path.at(
k));
543 for (;
k < (int)m_path.size(); ++
k) {
544 end_path.push_back(m_path.at(
k));
547 CKeyID id = m_root_extkey.pubkey.GetID();
548 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
553 if (cache !=
nullptr) {
559 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
569 assert(m_derive == DeriveType::UNHARDENED_RANGED);
577 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
578 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.
Derive(extkey, pos))
return;
579 if (m_derive == DeriveType::HARDENED_RANGED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return;
582 std::optional<CPubKey> GetRootPubKey()
const override
586 std::optional<CExtPubKey> GetRootExtPubKey()
const override
588 return m_root_extkey;
590 std::unique_ptr<PubkeyProvider> Clone()
const override
592 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey, m_path, m_derive, m_apostrophe);
597class MuSigPubkeyProvider final :
public PubkeyProvider
601 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
603 const KeyPath m_path;
605 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
606 mutable std::optional<CPubKey> m_aggregate_pubkey;
607 const DeriveType m_derive;
608 const bool m_ranged_participants;
610 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NON_RANGED; }
615 std::vector<std::unique_ptr<PubkeyProvider>> providers,
619 : PubkeyProvider(exp_index),
620 m_participants(
std::move(providers)),
621 m_path(
std::move(path)),
623 m_ranged_participants(
std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
625 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
626 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
628 if (!
Assume(m_derive != DeriveType::HARDENED_RANGED)) {
629 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
637 if (!m_aggregate_provider && !m_ranged_participants) {
639 std::vector<CPubKey> pubkeys;
640 for (
const auto& prov : m_participants) {
641 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
642 if (!pubkey.has_value()) {
645 pubkeys.push_back(pubkey.value());
647 std::sort(pubkeys.begin(), pubkeys.end());
651 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
654 if (IsRangedDerivation() || !m_path.empty()) {
657 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub, m_path, m_derive,
false);
659 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
664 std::vector<CPubKey> pubkeys;
665 for (
const auto& prov : m_participants) {
666 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
667 if (!pub)
return std::nullopt;
668 pubkeys.emplace_back(*pub);
670 std::sort(pubkeys.begin(), pubkeys.end());
673 if (m_aggregate_provider) {
677 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
678 if (!pub)
return std::nullopt;
680 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
682 if (!
Assume(m_ranged_participants) || !
Assume(m_path.empty()))
return std::nullopt;
685 if (!aggregate_pubkey)
return std::nullopt;
686 pubout = *aggregate_pubkey;
688 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
689 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
690 out.aggregate_pubkeys.emplace(pubout, pubkeys);
696 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
698 size_t GetSize()
const override {
return 32; }
700 std::string
ToString(StringType type=StringType::PUBLIC)
const override
702 std::string
out =
"musig(";
703 for (
size_t i = 0; i < m_participants.size(); ++i) {
704 const auto& pubkey = m_participants.at(i);
706 out += pubkey->ToString(type);
710 if (IsRangedDerivation()) {
717 bool any_privkeys =
false;
719 for (
size_t i = 0; i < m_participants.size(); ++i) {
720 const auto& pubkey = m_participants.at(i);
723 if (pubkey->ToPrivateString(arg, tmp)) {
730 if (IsRangedDerivation()) {
738 for (
size_t i = 0; i < m_participants.size(); ++i) {
739 const auto& pubkey = m_participants.at(i);
742 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
749 if (IsRangedDerivation()) {
760 for (
const auto& prov : m_participants) {
761 prov->GetPrivKey(pos, arg,
out);
770 std::optional<CPubKey> GetRootPubKey()
const override
774 std::optional<CExtPubKey> GetRootExtPubKey()
const override
779 std::unique_ptr<PubkeyProvider> Clone()
const override
781 std::vector<std::unique_ptr<PubkeyProvider>> providers;
782 providers.reserve(m_participants.size());
783 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
784 providers.emplace_back(p->Clone());
786 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers), m_path, m_derive);
788 bool IsBIP32()
const override
791 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
793 size_t GetKeyCount()
const override
795 return 1 + m_participants.size();
804 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
806 const std::string m_name;
808 std::vector<std::string> m_warnings;
814 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
817 virtual std::string ToStringExtra()
const {
return ""; }
829 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
832 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
833 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))) {}
834 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)) {}
836 enum class StringType
847 for (
const auto& arg : m_subdescriptor_args) {
848 if (!arg->IsSolvable())
return false;
856 if (m_pubkey_args.empty() && m_subdescriptor_args.empty())
return false;
858 for (
const auto& sub: m_subdescriptor_args) {
859 if (!sub->HavePrivateKeys(arg))
return false;
863 for (
const auto& pubkey : m_pubkey_args) {
864 tmp_provider.
keys.clear();
865 pubkey->GetPrivKey(0, arg, tmp_provider);
866 if (tmp_provider.
keys.empty())
return false;
875 for (
const auto& pubkey : m_pubkey_args) {
876 if (pubkey->IsRange())
return true;
878 for (
const auto& arg : m_subdescriptor_args) {
879 if (arg->IsRange())
return true;
888 bool is_private{type == StringType::PRIVATE};
891 bool any_success{!is_private};
892 for (
const auto& scriptarg : m_subdescriptor_args) {
893 if (pos++)
ret +=
",";
895 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
896 if (!is_private && !subscript_res)
return false;
897 any_success = any_success || subscript_res;
906 std::string extra = ToStringExtra();
907 size_t pos = extra.size() > 0 ? 1 : 0;
908 std::string
ret = m_name +
"(" + extra;
909 bool is_private{type == StringType::PRIVATE};
912 bool any_success{!is_private};
914 for (
const auto& pubkey : m_pubkey_args) {
915 if (pos++)
ret +=
",";
918 case StringType::NORMALIZED:
919 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
921 case StringType::PRIVATE:
922 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
924 case StringType::PUBLIC:
925 tmp = pubkey->ToString();
927 case StringType::COMPAT:
928 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
933 std::string subscript;
934 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
935 if (!is_private && !subscript_res)
return false;
936 any_success = any_success || subscript_res;
937 if (pos && subscript.size())
ret +=
',';
938 out = std::move(
ret) + std::move(subscript) +
")";
942 std::string
ToString(
bool compat_format)
const final
945 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
946 return AddChecksum(
ret);
951 bool has_priv_key{ToStringHelper(&arg,
out, StringType::PRIVATE)};
958 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
967 std::vector<CPubKey> pubkeys;
968 pubkeys.reserve(m_pubkey_args.size());
971 for (
const auto& p : m_pubkey_args) {
972 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
973 if (!pubkey)
return false;
974 pubkeys.push_back(pubkey.value());
976 std::vector<CScript> subscripts;
977 for (
const auto& subarg : m_subdescriptor_args) {
978 std::vector<CScript> outscripts;
979 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
980 assert(outscripts.size() == 1);
981 subscripts.emplace_back(std::move(outscripts[0]));
983 out.Merge(std::move(subprovider));
985 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
991 return ExpandHelper(pos, provider,
nullptr, output_scripts,
out, write_cache);
1002 for (
const auto& p : m_pubkey_args) {
1003 p->GetPrivKey(pos, provider,
out);
1005 for (
const auto& arg : m_subdescriptor_args) {
1006 arg->ExpandPrivate(pos, provider,
out);
1010 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
1012 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
1019 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
1026 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
1028 for (
const auto& p : m_pubkey_args) {
1029 std::optional<CPubKey> pub = p->GetRootPubKey();
1030 if (pub) pubkeys.insert(*pub);
1031 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1032 if (ext_pub) ext_pubs.insert(*ext_pub);
1034 for (
const auto& arg : m_subdescriptor_args) {
1035 arg->GetPubKeys(pubkeys, ext_pubs);
1039 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1041 bool HasScripts()
const override {
return true; }
1044 std::vector<std::string>
Warnings()
const override {
1045 std::vector<std::string> all = m_warnings;
1046 for (
const auto& sub : m_subdescriptor_args) {
1047 auto sub_w = sub->Warnings();
1048 all.insert(all.end(), sub_w.begin(), sub_w.end());
1055 uint32_t max_key_expr{0};
1056 std::vector<const DescriptorImpl*> todo = {
this};
1057 while (!todo.empty()) {
1058 const DescriptorImpl* desc = todo.back();
1060 for (
const auto& p : desc->m_pubkey_args) {
1061 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1063 for (
const auto&
s : desc->m_subdescriptor_args) {
1064 todo.push_back(
s.get());
1067 return max_key_expr;
1070 size_t GetKeyCount() const final
1073 std::vector<const DescriptorImpl*> todo = {
this};
1074 while (!todo.empty()) {
1075 const DescriptorImpl* desc = todo.back();
1077 for (
const auto& p : desc->m_pubkey_args) {
1078 count += p->GetKeyCount();
1080 for (
const auto&
s : desc->m_subdescriptor_args) {
1081 todo.push_back(
s.get());
1089class AddressDescriptor final :
public DescriptorImpl
1093 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1096 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1097 bool IsSolvable() const final {
return false; }
1103 bool IsSingleType() const final {
return true; }
1104 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1107 std::unique_ptr<DescriptorImpl> Clone()
const override
1109 return std::make_unique<AddressDescriptor>(m_destination);
1114class RawDescriptor final :
public DescriptorImpl
1118 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1119 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1122 bool IsSolvable() const final {
return false; }
1130 bool IsSingleType() const final {
return true; }
1131 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1133 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1135 std::unique_ptr<DescriptorImpl> Clone()
const override
1137 return std::make_unique<RawDescriptor>(m_script);
1142class PKDescriptor final :
public DescriptorImpl
1147 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1157 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1158 bool IsSingleType() const final {
return true; }
1160 std::optional<int64_t> ScriptSize()
const override {
1161 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1164 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1165 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1166 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1169 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1173 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1175 std::unique_ptr<DescriptorImpl> Clone()
const override
1177 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1182class PKHDescriptor final :
public DescriptorImpl
1185 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1187 CKeyID id = keys[0].GetID();
1191 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1193 bool IsSingleType() const final {
return true; }
1195 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1197 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1198 const auto sig_size = use_max_sig ? 72 : 71;
1199 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1202 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1206 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1208 std::unique_ptr<DescriptorImpl> Clone()
const override
1210 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1215class WPKHDescriptor final :
public DescriptorImpl
1218 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1220 CKeyID id = keys[0].GetID();
1224 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1226 bool IsSingleType() const final {
return true; }
1228 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1230 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1231 const auto sig_size = use_max_sig ? 72 : 71;
1235 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1236 return MaxSatSize(use_max_sig);
1239 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1241 std::unique_ptr<DescriptorImpl> Clone()
const override
1243 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1248class ComboDescriptor final :
public DescriptorImpl
1251 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
1253 std::vector<CScript>
ret;
1254 CKeyID id = keys[0].GetID();
1257 if (keys[0].IsCompressed()) {
1260 ret.emplace_back(p2wpkh);
1266 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1267 bool IsSingleType() const final {
return false; }
1268 std::unique_ptr<DescriptorImpl> Clone()
const override
1270 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1275class MultisigDescriptor final :
public DescriptorImpl
1277 const int m_threshold;
1278 const bool m_sorted;
1280 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1281 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1283 std::vector<CPubKey> sorted_keys(keys);
1284 std::sort(sorted_keys.begin(), sorted_keys.end());
1290 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) {}
1291 bool IsSingleType() const final {
return true; }
1293 std::optional<int64_t> ScriptSize()
const override {
1294 const auto n_keys = m_pubkey_args.size();
1295 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1296 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1300 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1301 const auto sig_size = use_max_sig ? 72 : 71;
1302 return (1 + (1 +
sig_size) * m_threshold);
1305 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1309 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1311 std::unique_ptr<DescriptorImpl> Clone()
const override
1313 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1314 providers.reserve(m_pubkey_args.size());
1315 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1316 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1321class MultiADescriptor final :
public DescriptorImpl
1323 const int m_threshold;
1324 const bool m_sorted;
1326 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1327 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1329 std::vector<XOnlyPubKey> xkeys;
1330 xkeys.reserve(keys.size());
1331 for (
const auto& key : keys) xkeys.emplace_back(key);
1332 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1334 for (
size_t i = 1; i < keys.size(); ++i) {
1341 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) {}
1342 bool IsSingleType() const final {
return true; }
1344 std::optional<int64_t> ScriptSize()
const override {
1345 const auto n_keys = m_pubkey_args.size();
1349 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1350 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1353 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1355 std::unique_ptr<DescriptorImpl> Clone()
const override
1357 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1358 providers.reserve(m_pubkey_args.size());
1359 for (
const auto& arg : m_pubkey_args) {
1360 providers.push_back(arg->Clone());
1362 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1367class SHDescriptor final :
public DescriptorImpl
1370 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1373 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1380 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1384 assert(m_subdescriptor_args.size() == 1);
1388 bool IsSingleType() const final {
return true; }
1390 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1392 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1393 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1394 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1398 if (
IsSegwit())
return subscript_weight + *sat_size;
1405 std::optional<int64_t> MaxSatisfactionElems()
const override {
1406 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1410 std::unique_ptr<DescriptorImpl> Clone()
const override
1412 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1417class WSHDescriptor 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]);
1427 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1429 bool IsSingleType() const final {
return true; }
1431 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1433 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1434 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1435 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1442 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1443 return MaxSatSize(use_max_sig);
1446 std::optional<int64_t> MaxSatisfactionElems()
const override {
1447 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1451 std::unique_ptr<DescriptorImpl> Clone()
const override
1453 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1458class TRDescriptor final :
public DescriptorImpl
1460 std::vector<int> m_depths;
1462 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1465 assert(m_depths.size() == scripts.size());
1466 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1470 assert(keys.size() == 1);
1472 if (!xpk.IsFullyValid())
return {};
1475 out.tr_trees[output] = builder;
1480 if (m_depths.empty()) {
1486 return type != StringType::PRIVATE;
1488 std::vector<bool> path;
1489 bool is_private{type == StringType::PRIVATE};
1492 bool any_success{!is_private};
1494 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1495 if (pos)
ret +=
',';
1496 while ((
int)path.size() <= m_depths[pos]) {
1497 if (path.size())
ret +=
'{';
1498 path.push_back(
false);
1501 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1502 if (!is_private && !subscript_res)
return false;
1503 any_success = any_success || subscript_res;
1505 while (!path.empty() && path.back()) {
1506 if (path.size() > 1)
ret +=
'}';
1509 if (!path.empty()) path.back() =
true;
1514 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1515 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1517 assert(m_subdescriptor_args.size() == m_depths.size());
1520 bool IsSingleType() const final {
return true; }
1522 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1524 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1529 std::optional<int64_t> MaxSatisfactionElems()
const override {
1534 std::unique_ptr<DescriptorImpl> Clone()
const override
1536 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1537 subdescs.reserve(m_subdescriptor_args.size());
1538 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1539 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1553 const std::vector<CPubKey>& m_keys;
1560 uint160 GetHash160(uint32_t key)
const {
1564 return m_keys[key].GetID();
1570 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1573 return {m_keys[key].begin(), m_keys[key].end()};
1576 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1579 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1580 auto id = GetHash160(key);
1581 return {
id.begin(),
id.end()};
1592 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1594 const DescriptorImpl::StringType m_type;
1599 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1600 DescriptorImpl::StringType type,
1602 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1604 std::optional<std::string>
ToString(uint32_t key,
bool& has_priv_key)
const
1607 has_priv_key =
false;
1609 case DescriptorImpl::StringType::PUBLIC:
1610 ret = m_pubkeys[key]->ToString();
1612 case DescriptorImpl::StringType::PRIVATE:
1613 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg,
ret);
1615 case DescriptorImpl::StringType::NORMALIZED:
1616 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1618 case DescriptorImpl::StringType::COMPAT:
1619 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1626class MiniscriptDescriptor final :
public DescriptorImpl
1632 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1635 const auto script_ctx{
m_node.GetMsCtx()};
1636 for (
const auto& key : keys) {
1640 provider.
pubkeys.emplace(key.GetID(), key);
1643 return Vector(
m_node.ToScript(ScriptMaker(keys, script_ctx)));
1653 const uint32_t raw = node.K();
1654 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1655 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1656 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1657 if (is_time_based) {
1658 m_warnings.push_back(strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1660 m_warnings.push_back(strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1667 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1670 bool has_priv_key{
false};
1671 auto res =
m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1672 if (res)
out = *res;
1673 if (type == StringType::PRIVATE) {
1675 return has_priv_key;
1677 return res.has_value();
1681 bool IsSolvable()
const override {
return true; }
1682 bool IsSingleType() const final {
return true; }
1684 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1686 std::optional<int64_t> MaxSatSize(
bool)
const override
1689 return m_node.GetWitnessSize();
1692 std::optional<int64_t> MaxSatisfactionElems()
const override
1694 return m_node.GetStackSize();
1697 std::unique_ptr<DescriptorImpl> Clone()
const override
1699 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1700 providers.reserve(m_pubkey_args.size());
1701 for (
const auto& arg : m_pubkey_args) {
1702 providers.push_back(arg->Clone());
1704 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node.Clone());
1709class RawTRDescriptor final :
public DescriptorImpl
1712 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1714 assert(keys.size() == 1);
1716 if (!xpk.IsFullyValid())
return {};
1721 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1723 bool IsSingleType() const final {
return true; }
1725 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1727 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1732 std::optional<int64_t> MaxSatisfactionElems()
const override {
1737 std::unique_ptr<DescriptorImpl> Clone()
const override
1739 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1744class UnusedDescriptor final :
public DescriptorImpl
1747 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override {
return {}; }
1749 UnusedDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"unused") {}
1750 bool IsSingleType() const final {
return true; }
1751 bool HasScripts()
const override {
return false; }
1753 std::unique_ptr<DescriptorImpl> Clone()
const override
1755 return std::make_unique<UnusedDescriptor>(m_pubkey_args.at(0)->Clone());
1764enum class ParseScriptContext {
1773std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error,
bool& has_hardened)
1775 bool hardened =
false;
1776 if (elem.size() > 0) {
1777 const char last = elem[elem.size() - 1];
1778 if (last ==
'\'' || last ==
'h') {
1779 elem = elem.first(elem.size() - 1);
1781 apostrophe = last ==
'\'';
1784 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1786 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1787 return std::nullopt;
1788 }
else if (*p > 0x7FFFFFFFUL) {
1789 error =
strprintf(
"Key path value %u is out of range", *p);
1790 return std::nullopt;
1792 has_hardened = has_hardened || hardened;
1794 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1808[[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)
1811 struct MultipathSubstitutes {
1812 size_t placeholder_index;
1813 std::vector<uint32_t>
values;
1815 std::optional<MultipathSubstitutes> substitutes;
1816 has_hardened =
false;
1818 for (
size_t i = 1; i <
split.size(); ++i) {
1819 const std::span<const char>& elem =
split[i];
1822 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1823 if (!allow_multipath) {
1824 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1828 error =
"Multiple multipath key path specifiers found";
1833 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1834 if (nums.size() < 2) {
1835 error =
"Multipath key path specifiers must have at least two items";
1839 substitutes.emplace();
1840 std::unordered_set<uint32_t> seen_substitutes;
1841 for (
const auto& num : nums) {
1842 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1843 if (!op_num)
return false;
1844 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1846 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1849 substitutes->values.emplace_back(*op_num);
1852 path.emplace_back();
1853 substitutes->placeholder_index = path.size() - 1;
1855 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1856 if (!op_num)
return false;
1857 path.emplace_back(*op_num);
1862 out.emplace_back(std::move(path));
1865 for (uint32_t substitute : substitutes->values) {
1866 KeyPath branch_path = path;
1867 branch_path[substitutes->placeholder_index] = substitute;
1868 out.emplace_back(std::move(branch_path));
1874[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1877 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1880static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1882 DeriveType type = DeriveType::NON_RANGED;
1883 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1885 type = DeriveType::UNHARDENED_RANGED;
1886 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1887 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1889 type = DeriveType::HARDENED_RANGED;
1895std::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)
1897 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1898 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1900 std::string str(
split[0].begin(),
split[0].end());
1901 if (str.size() == 0) {
1902 error =
"No key provided";
1906 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1909 if (
split.size() == 1) {
1913 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1914 error =
"Hybrid public keys are not allowed";
1917 if (pubkey.IsFullyValid()) {
1918 if (permit_uncompressed || pubkey.IsCompressed()) {
1919 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1923 error =
"Uncompressed keys are not allowed";
1926 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1927 unsigned char fullkey[33] = {0x02};
1928 std::copy(
data.begin(),
data.end(), fullkey + 1);
1929 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1930 if (pubkey.IsFullyValid()) {
1931 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1936 error =
strprintf(
"Pubkey '%s' is invalid", str);
1943 out.keys.emplace(pubkey.
GetID(), key);
1944 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1948 error =
"Uncompressed keys are not allowed";
1956 error =
strprintf(
"key '%s' is not valid", str);
1959 std::vector<KeyPath> paths;
1960 DeriveType type = ParseDeriveType(
split, apostrophe);
1961 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
1963 extpubkey = extkey.
Neuter();
1966 for (
auto& path : paths) {
1967 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1975std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
1977 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1982 std::span<const char> span = sp;
1983 if (
Const(
"musig(", span,
false)) {
1984 if (ctx != ParseScriptContext::P2TR) {
1985 error =
"musig() is only allowed in tr() and rawtr()";
1992 if (
split.size() > 2) {
1993 error =
"Too many ')' in musig() expression";
1996 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
1997 if (!
Func(
"musig", expr)) {
1998 error =
"Invalid musig() expression";
2003 bool any_ranged =
false;
2004 bool all_bip32 =
true;
2005 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2006 bool any_key_parsed =
false;
2007 size_t max_multipath_len = 0;
2008 while (expr.size()) {
2009 if (any_key_parsed && !
Const(
",", expr)) {
2010 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
2013 auto arg =
Expr(expr);
2014 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
2016 error =
strprintf(
"musig(): %s", error);
2019 any_key_parsed =
true;
2021 any_ranged = any_ranged ||
pk.at(0)->IsRange();
2022 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
2024 max_multipath_len = std::max(max_multipath_len,
pk.size());
2026 providers.emplace_back(std::move(
pk));
2028 if (!any_key_parsed) {
2029 error =
"musig(): Must contain key expressions";
2034 DeriveType deriv_type = DeriveType::NON_RANGED;
2035 std::vector<KeyPath> derivation_multipaths;
2038 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2042 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2047 deriv_type = ParseDeriveType(deriv_split, dummy);
2048 if (deriv_type == DeriveType::HARDENED_RANGED) {
2049 error =
"musig(): Cannot have hardened child derivation";
2052 bool has_hardened =
false;
2053 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
2054 error =
"musig(): " + error;
2058 error =
"musig(): cannot have hardened derivation steps";
2062 derivation_multipaths.emplace_back();
2067 const auto& clone_providers = [&providers](
size_t length) ->
bool {
2068 for (
auto& multipath_providers : providers) {
2069 if (multipath_providers.size() == 1) {
2070 for (
size_t i = 1; i < length; ++i) {
2071 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2073 }
else if (multipath_providers.size() != length) {
2082 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
2083 KeyPath& path = derivation_multipaths.at(path_idx);
2084 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2085 pubs.reserve(providers.size());
2086 for (
auto& vec : providers) {
2087 pubs.emplace_back(std::move(vec.at(vec_idx)));
2089 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2092 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2093 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2095 }
else if (max_multipath_len > 1) {
2096 if (!clone_providers(max_multipath_len)) {
2097 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2100 for (
size_t i = 0; i < max_multipath_len; ++i) {
2102 emplace_final_provider(i, 0);
2104 }
else if (derivation_multipaths.size() > 1) {
2106 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
2107 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2110 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
2112 emplace_final_provider(i, i);
2116 emplace_final_provider(0, 0);
2122 auto origin_split =
Split(sp,
']');
2123 if (origin_split.size() > 2) {
2124 error =
"Multiple ']' characters found for a single pubkey";
2128 bool apostrophe =
false;
2129 if (origin_split.size() == 1) {
2130 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
2132 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
2133 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2134 origin_split[0].empty() ?
']' : origin_split[0][0]);
2137 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
2138 if (slash_split[0].size() != 8) {
2139 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2142 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2143 if (!
IsHex(fpr_hex)) {
2144 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
2147 auto fpr_bytes =
ParseHex(fpr_hex);
2149 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2150 assert(fpr_bytes.size() == 4);
2151 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
2152 std::vector<KeyPath> path;
2153 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2154 info.
path = path.at(0);
2155 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
2156 if (providers.empty())
return {};
2157 ret.reserve(providers.size());
2158 for (
auto& prov : providers) {
2159 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2164std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
2171 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2174 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2177 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2179 return key_provider;
2182std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& provider)
2185 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2188 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2190 return key_provider;
2198 using Key = uint32_t;
2204 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2206 mutable std::string m_key_parsing_error;
2210 uint32_t& m_expr_index;
2214 : m_out(
out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2216 bool KeyCompare(
const Key& a,
const Key& b)
const {
2217 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2221 switch (m_script_ctx) {
2228 std::optional<Key>
FromString(std::span<const char>& in)
const
2231 Key key = m_keys.
size();
2232 auto pk = ParsePubkey(m_expr_index, in,
ParseContext(), *m_out, m_key_parsing_error);
2233 if (
pk.empty())
return {};
2234 m_keys.emplace_back(std::move(
pk));
2238 std::optional<std::string>
ToString(
const Key& key,
bool&)
const
2240 return m_keys.at(key).at(0)->ToString();
2243 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2246 Key key = m_keys.size();
2249 std::copy(begin, end, pubkey.
begin());
2250 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2251 m_keys.emplace_back();
2252 m_keys.back().push_back(std::move(pubkey_provider));
2257 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2258 m_keys.emplace_back();
2259 m_keys.back().push_back(std::move(pubkey_provider));
2266 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2268 assert(end - begin == 20);
2271 std::copy(begin, end, hash.
begin());
2275 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2276 Key key = m_keys.
size();
2277 m_keys.emplace_back();
2278 m_keys.back().push_back(std::move(pubkey_provider));
2286 return m_script_ctx;
2292std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2295 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2296 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2297 auto expr =
Expr(sp);
2298 if (
Func(
"pk", expr)) {
2299 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2300 if (pubkeys.empty()) {
2304 for (
auto& pubkey : pubkeys) {
2305 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2309 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2310 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2311 if (pubkeys.empty()) {
2315 for (
auto& pubkey : pubkeys) {
2316 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2320 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2321 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2322 if (pubkeys.empty()) {
2323 error =
strprintf(
"combo(): %s", error);
2326 for (
auto& pubkey : pubkeys) {
2327 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2330 }
else if (
Func(
"combo", expr)) {
2331 error =
"Can only have combo() at top level";
2334 const bool multi =
Func(
"multi", expr);
2335 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2336 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2337 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2338 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2339 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2340 auto threshold =
Expr(expr);
2342 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2343 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2344 thres = *maybe_thres;
2346 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2349 size_t script_size = 0;
2350 size_t max_providers_len = 0;
2351 while (expr.size()) {
2352 if (!
Const(
",", expr)) {
2353 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2356 auto arg =
Expr(expr);
2357 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2362 script_size += pks.at(0)->GetSize() + 1;
2363 max_providers_len = std::max(max_providers_len, pks.size());
2364 providers.emplace_back(std::move(pks));
2372 }
else if (thres < 1) {
2373 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2375 }
else if (thres > providers.size()) {
2376 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2379 if (ctx == ParseScriptContext::TOP) {
2380 if (providers.size() > 3) {
2381 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2385 if (ctx == ParseScriptContext::P2SH) {
2395 for (
auto& vec : providers) {
2396 if (vec.size() == 1) {
2397 for (
size_t i = 1; i < max_providers_len; ++i) {
2398 vec.emplace_back(vec.at(0)->Clone());
2400 }
else if (vec.size() != max_providers_len) {
2401 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2407 for (
size_t i = 0; i < max_providers_len; ++i) {
2409 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2410 pubs.reserve(providers.size());
2411 for (
auto& pub : providers) {
2412 pubs.emplace_back(std::move(pub.at(i)));
2414 if (multi || sortedmulti) {
2415 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2417 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2421 }
else if (multi || sortedmulti) {
2422 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2424 }
else if (multi_a || sortedmulti_a) {
2425 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2428 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2429 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2430 if (pubkeys.empty()) {
2434 for (
auto& pubkey : pubkeys) {
2435 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2438 }
else if (
Func(
"wpkh", expr)) {
2439 error =
"Can only have wpkh() at top level or inside sh()";
2442 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2443 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2444 if (descs.empty() || expr.size())
return {};
2445 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2446 ret.reserve(descs.size());
2447 for (
auto& desc : descs) {
2448 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2451 }
else if (
Func(
"sh", expr)) {
2452 error =
"Can only have sh() at top level";
2455 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2456 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2457 if (descs.empty() || expr.size())
return {};
2458 for (
auto& desc : descs) {
2459 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2462 }
else if (
Func(
"wsh", expr)) {
2463 error =
"Can only have wsh() at top level or inside sh()";
2466 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2469 error =
"Address is not valid";
2472 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2474 }
else if (
Func(
"addr", expr)) {
2475 error =
"Can only have addr() at top level";
2478 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2479 auto arg =
Expr(expr);
2480 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2481 if (internal_keys.empty()) {
2485 size_t max_providers_len = internal_keys.size();
2486 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2487 std::vector<int> depths;
2489 if (!
Const(
",", expr)) {
2490 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2496 std::vector<bool> branches;
2501 while (
Const(
"{", expr)) {
2502 branches.push_back(
false);
2509 auto sarg =
Expr(expr);
2510 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2511 if (subscripts.back().empty())
return {};
2512 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2513 depths.push_back(branches.size());
2515 while (branches.size() && branches.back()) {
2516 if (!
Const(
"}", expr)) {
2517 error =
strprintf(
"tr(): expected '}' after script expression");
2520 branches.pop_back();
2523 if (branches.size() && !branches.back()) {
2524 if (!
Const(
",", expr)) {
2525 error =
strprintf(
"tr(): expected ',' after script expression");
2528 branches.back() =
true;
2530 }
while (branches.size());
2533 error =
strprintf(
"tr(): expected ')' after script expression");
2541 for (
auto& vec : subscripts) {
2542 if (vec.size() == 1) {
2543 for (
size_t i = 1; i < max_providers_len; ++i) {
2544 vec.emplace_back(vec.at(0)->Clone());
2546 }
else if (vec.size() != max_providers_len) {
2547 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2552 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2553 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2557 while (internal_keys.size() < max_providers_len) {
2558 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2562 for (
size_t i = 0; i < max_providers_len; ++i) {
2564 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2565 this_subs.reserve(subscripts.size());
2566 for (
auto& subs : subscripts) {
2567 this_subs.emplace_back(std::move(subs.at(i)));
2569 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2574 }
else if (
Func(
"tr", expr)) {
2575 error =
"Can only have tr at top level";
2578 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2579 auto arg =
Expr(expr);
2581 error =
strprintf(
"rawtr(): only one key expected.");
2584 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2585 if (output_keys.empty()) {
2586 error =
strprintf(
"rawtr(): %s", error);
2589 for (
auto& pubkey : output_keys) {
2590 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2593 }
else if (
Func(
"rawtr", expr)) {
2594 error =
"Can only have rawtr at top level";
2597 if (ctx == ParseScriptContext::TOP &&
Func(
"unused", expr)) {
2599 auto arg =
Expr(expr);
2601 error =
strprintf(
"unused(): only one key expected");
2604 auto keys = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2605 if (keys.empty())
return {};
2606 for (
auto& pubkey : keys) {
2607 if (pubkey->IsRange()) {
2608 error =
"unused(): key cannot be ranged";
2611 ret.emplace_back(std::make_unique<UnusedDescriptor>(std::move(pubkey)));
2614 }
else if (
Func(
"unused", expr)) {
2615 error =
"Can only have unused at top level";
2618 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2619 std::string str(expr.begin(), expr.end());
2621 error =
"Raw script is not hex";
2625 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2627 }
else if (
Func(
"raw", expr)) {
2628 error =
"Can only have raw() at top level";
2634 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2636 if (parser.m_key_parsing_error !=
"") {
2637 error = std::move(parser.m_key_parsing_error);
2641 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2642 error =
"Miniscript expressions can only be used in wsh or tr.";
2645 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2647 const auto* insane_node = &
node.value();
2648 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2649 error = *insane_node->ToString(parser);
2650 if (!insane_node->IsValid()) {
2651 error +=
" is invalid";
2652 }
else if (!
node->IsSane()) {
2653 error +=
" is not sane";
2654 if (!insane_node->IsNonMalleable()) {
2655 error +=
": malleable witnesses exist";
2656 }
else if (insane_node == &
node.value() && !insane_node->NeedsSignature()) {
2657 error +=
": witnesses without signature exist";
2658 }
else if (!insane_node->CheckTimeLocksMix()) {
2659 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2660 }
else if (!insane_node->CheckDuplicateKey()) {
2661 error +=
": contains duplicate public keys";
2662 }
else if (!insane_node->ValidSatisfactions()) {
2663 error +=
": needs witnesses that may exceed resource limits";
2666 error +=
" is not satisfiable";
2675 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2676 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2677 return a.size() < b.size();
2680 for (
auto& vec : parser.m_keys) {
2681 if (vec.size() == 1) {
2682 for (
size_t i = 1; i < num_multipath; ++i) {
2683 vec.emplace_back(vec.at(0)->Clone());
2685 }
else if (vec.size() != num_multipath) {
2686 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2692 for (
size_t i = 0; i < num_multipath; ++i) {
2694 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2695 pubs.reserve(parser.m_keys.size());
2696 for (
auto& pub : parser.m_keys) {
2697 pubs.emplace_back(std::move(pub.at(i)));
2699 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2704 if (ctx == ParseScriptContext::P2SH) {
2705 error =
"A function is needed within P2SH";
2707 }
else if (ctx == ParseScriptContext::P2WSH) {
2708 error =
"A function is needed within P2WSH";
2711 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2718 if (!match)
return {};
2719 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2720 keys.reserve(match->second.size());
2721 for (
const auto keyspan : match->second) {
2722 if (keyspan.size() != 32)
return {};
2723 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
2724 if (!key)
return {};
2725 keys.push_back(std::move(key));
2727 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2735 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
2738 if (ctx == ParseScriptContext::P2TR) {
2739 auto ret = InferMultiA(
script, ctx, provider);
2743 std::vector<std::vector<unsigned char>>
data;
2746 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2748 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2749 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2752 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2756 if (provider.
GetPubKey(keyid, pubkey)) {
2757 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2758 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2766 if (provider.
GetPubKey(keyid, pubkey)) {
2767 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2768 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2772 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2774 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2775 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2777 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2778 providers.push_back(std::move(pubkey_provider));
2784 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2790 if (provider.
GetCScript(scriptid, subscript)) {
2791 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2792 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2798 if (provider.
GetCScript(scriptid, subscript)) {
2799 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2800 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2815 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2816 std::vector<int> depths;
2817 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2818 std::unique_ptr<DescriptorImpl> subdesc;
2820 subdesc = InferScript(
CScript(
script.begin(),
script.end()), ParseScriptContext::P2TR, provider);
2826 subscripts.push_back(std::move(subdesc));
2827 depths.push_back(depth);
2831 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
2832 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2838 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2840 return std::make_unique<RawTRDescriptor>(std::move(key));
2845 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2847 uint32_t key_exp_index = 0;
2848 KeyParser parser(
nullptr, &provider, script_ctx, key_exp_index);
2851 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2852 keys.reserve(parser.m_keys.size());
2853 for (
auto& key : parser.m_keys) {
2854 keys.emplace_back(std::move(key.at(0)));
2856 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(*
node));
2862 if (ctx != ParseScriptContext::TOP)
return nullptr;
2867 return std::make_unique<AddressDescriptor>(std::move(dest));
2871 return std::make_unique<RawDescriptor>(
script);
2878bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2880 auto check_split =
Split(sp,
'#');
2881 if (check_split.size() > 2) {
2882 error =
"Multiple '#' symbols";
2885 if (check_split.size() == 1 && require_checksum){
2886 error =
"Missing checksum";
2889 if (check_split.size() == 2) {
2890 if (check_split[1].size() != 8) {
2891 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2895 auto checksum = DescriptorChecksum(check_split[0]);
2896 if (checksum.empty()) {
2897 error =
"Invalid characters in payload";
2900 if (check_split.size() == 2) {
2901 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2902 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2906 if (out_checksum) *out_checksum = std::move(checksum);
2907 sp = check_split[0];
2913 std::span<const char> sp{descriptor};
2915 uint32_t key_exp_index = 0;
2917 if (sp.empty() && !
ret.empty()) {
2918 std::vector<std::unique_ptr<Descriptor>> descs;
2919 descs.reserve(
ret.size());
2920 for (
auto& r :
ret) {
2921 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2932 std::span<const char> sp{descriptor};
2939 return InferScript(
script, ParseScriptContext::TOP, provider);
2944 std::string desc_str = desc.
ToString(
true);
2958 xpubs[der_index] = xpub;
2978 const auto& der_it = key_exp_it->second.find(der_index);
2979 if (der_it == key_exp_it->second.end())
return false;
2980 xpub = der_it->second;
2998 if (xpub != parent_xpub_pair.second) {
2999 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
3007 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
3010 if (xpub != derived_xpub_pair.second) {
3011 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
3015 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3016 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3022 if (xpub != lh_xpub_pair.second) {
3023 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.