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;
122 "0123456789()[],'/*abcdefgh@:$%{}"
123 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
124 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
127 static const std::string
CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
132 for (
auto ch : span) {
134 if (pos == std::string::npos)
return "";
136 cls =
cls * 3 + (pos >> 5);
148 std::string
ret(8,
' ');
159typedef std::vector<uint32_t>
KeyPath;
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;
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;
254 if (!pub)
return std::nullopt;
255 Assert(
out.pubkeys.contains(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); }
276 if (!m_provider->ToNormalizedString(
arg,
sub, cache))
return false;
290 m_provider->GetPrivKey(pos,
arg, out);
294 return m_provider->GetRootPubKey();
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
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);
339 ret = ToString(StringType::PUBLIC);
347 ret = ToString(StringType::PUBLIC);
352 std::optional<CKey> key = GetPrivKey(
arg);
354 out.keys.emplace(key->GetPubKey().GetID(), *key);
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;
402 for (
auto entry : m_path) {
403 if (!
xprv.Derive(
xprv, entry))
return false;
413 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
414 for (
auto entry : m_path) {
415 if (entry >> 31)
return true;
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; }
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);
441 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
453 if (m_derive == DeriveType::HARDENED_RANGED)
der =
xprv.Derive(
xprv, pos | 0x80000000UL);
459 for (
auto entry : m_path) {
464 assert(m_derive != DeriveType::HARDENED_RANGED);
466 if (!
der)
return std::nullopt;
473 if (m_derive != DeriveType::HARDENED_RANGED) {
479 }
else if (info.
path.size() > 0) {
486 std::string ToString(StringType type,
bool normalized)
const
497 std::string ToString(StringType type=StringType::PUBLIC)
const override
499 return ToString(type,
false);
505 out = ToString(StringType::PUBLIC);
511 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
517 if (m_derive == DeriveType::HARDENED_RANGED) {
518 out = ToString(StringType::PUBLIC,
true);
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) {
547 CKeyID id = m_root_extkey.pubkey.GetID();
548 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
553 if (cache !=
nullptr) {
556 if (!
xpub.pubkey.IsValid()) {
569 assert(m_derive == DeriveType::UNHARDENED_RANGED);
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;
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;
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;
615 std::vector<std::unique_ptr<PubkeyProvider>>
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(); }))
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) {
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;
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) {
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;
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);
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)) {
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)) {
760 for (
const auto&
prov : m_participants) {
761 prov->GetPrivKey(pos,
arg, out);
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) {
786 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(
providers), m_path, m_derive);
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;
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
845 bool IsSolvable()
const override
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) {
873 bool IsRange() const final
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;
892 for (
const auto&
scriptarg : m_subdescriptor_args) {
893 if (pos++)
ret +=
",";
907 size_t pos =
extra.size() > 0 ? 1 : 0;
908 std::string
ret = m_name +
"(" +
extra;
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:
924 case StringType::PUBLIC:
925 tmp = pubkey->ToString();
927 case StringType::COMPAT:
928 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
967 std::vector<CPubKey> pubkeys;
968 pubkeys.reserve(m_pubkey_args.size());
971 for (
const auto&
p : m_pubkey_args) {
973 if (!pubkey)
return false;
974 pubkeys.push_back(pubkey.value());
977 for (
const auto&
subarg : m_subdescriptor_args) {
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 {}; }
1021 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
return {}; }
1023 std::optional<int64_t> MaxSatisfactionElems()
const override {
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();
1034 for (
const auto&
arg : m_subdescriptor_args) {
1039 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1042 std::vector<std::string> Warnings()
const override {
1043 std::vector<std::string>
all = m_warnings;
1044 for (
const auto&
sub : m_subdescriptor_args) {
1051 uint32_t GetMaxKeyExpr() const final
1054 std::vector<const DescriptorImpl*>
todo = {
this};
1055 while (!
todo.empty()) {
1056 const DescriptorImpl* desc =
todo.back();
1058 for (
const auto&
p : desc->m_pubkey_args) {
1061 for (
const auto& s : desc->m_subdescriptor_args) {
1062 todo.push_back(
s.get());
1068 size_t GetKeyCount() const final
1071 std::vector<const DescriptorImpl*>
todo = {
this};
1072 while (!
todo.empty()) {
1073 const DescriptorImpl* desc =
todo.back();
1075 for (
const auto&
p : desc->m_pubkey_args) {
1076 count +=
p->GetKeyCount();
1078 for (
const auto& s : desc->m_subdescriptor_args) {
1079 todo.push_back(
s.get());
1087class AddressDescriptor final :
public DescriptorImpl
1094 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1095 bool IsSolvable() const final {
return false; }
1097 std::optional<OutputType> GetOutputType()
const override
1101 bool IsSingleType() const final {
return true; }
1102 bool ToPrivateString(
const SigningProvider&
arg, std::string& out)
const final {
return false; }
1105 std::unique_ptr<DescriptorImpl> Clone()
const override
1107 return std::make_unique<AddressDescriptor>(m_destination);
1112class RawDescriptor final :
public DescriptorImpl
1120 bool IsSolvable() const final {
return false; }
1122 std::optional<OutputType> GetOutputType()
const override
1128 bool IsSingleType() const final {
return true; }
1129 bool ToPrivateString(
const SigningProvider&
arg, std::string& out)
const final {
return false; }
1131 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1133 std::unique_ptr<DescriptorImpl> Clone()
const override
1135 return std::make_unique<RawDescriptor>(m_script);
1140class PKDescriptor final :
public DescriptorImpl
1155 PKDescriptor(std::unique_ptr<PubkeyProvider>
prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(
prov)),
"pk"), m_xonly(
xonly) {}
1156 bool IsSingleType() const final {
return true; }
1158 std::optional<int64_t> ScriptSize()
const override {
1159 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1167 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1171 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1173 std::unique_ptr<DescriptorImpl> Clone()
const override
1175 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1180class PKHDescriptor final :
public DescriptorImpl
1185 CKeyID id = keys[0].GetID();
1189 PKHDescriptor(std::unique_ptr<PubkeyProvider>
prov) : DescriptorImpl(
Vector(
std::move(
prov)),
"pkh") {}
1190 std::optional<OutputType> GetOutputType()
const override {
return OutputType::LEGACY; }
1191 bool IsSingleType() const final {
return true; }
1193 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1197 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1200 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1204 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1206 std::unique_ptr<DescriptorImpl> Clone()
const override
1208 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1213class WPKHDescriptor final :
public DescriptorImpl
1218 CKeyID id = keys[0].GetID();
1222 WPKHDescriptor(std::unique_ptr<PubkeyProvider>
prov) : DescriptorImpl(
Vector(
std::move(
prov)),
"wpkh") {}
1223 std::optional<OutputType> GetOutputType()
const override {
return OutputType::BECH32; }
1224 bool IsSingleType() const final {
return true; }
1226 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1230 return (1 + sig_size + 1 + 33);
1233 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1237 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1239 std::unique_ptr<DescriptorImpl> Clone()
const override
1241 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1246class ComboDescriptor final :
public DescriptorImpl
1251 std::vector<CScript>
ret;
1252 CKeyID id = keys[0].GetID();
1255 if (keys[0].IsCompressed()) {
1264 ComboDescriptor(std::unique_ptr<PubkeyProvider>
prov) : DescriptorImpl(
Vector(
std::move(
prov)),
"combo") {}
1265 bool IsSingleType() const final {
return false; }
1266 std::unique_ptr<DescriptorImpl> Clone()
const override
1268 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1273class MultisigDescriptor final :
public DescriptorImpl
1275 const int m_threshold;
1276 const bool m_sorted;
1288 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) {}
1289 bool IsSingleType() const final {
return true; }
1291 std::optional<int64_t> ScriptSize()
const override {
1292 const auto n_keys = m_pubkey_args.size();
1293 auto op = [](
int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1294 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(),
int64_t{0}, op)};
1300 return (1 + (1 + sig_size) * m_threshold);
1303 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1307 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1309 std::unique_ptr<DescriptorImpl> Clone()
const override
1311 std::vector<std::unique_ptr<PubkeyProvider>>
providers;
1312 providers.reserve(m_pubkey_args.size());
1313 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(
providers), [](
const std::unique_ptr<PubkeyProvider>&
p) { return p->Clone(); });
1314 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(
providers), m_sorted);
1319class MultiADescriptor final :
public DescriptorImpl
1321 const int m_threshold;
1322 const bool m_sorted;
1327 std::vector<XOnlyPubKey>
xkeys;
1329 for (
const auto& key : keys)
xkeys.emplace_back(key);
1330 if (m_sorted) std::sort(
xkeys.begin(),
xkeys.end());
1332 for (
size_t i = 1; i < keys.size(); ++i) {
1339 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) {}
1340 bool IsSingleType() const final {
return true; }
1342 std::optional<int64_t> ScriptSize()
const override {
1343 const auto n_keys = m_pubkey_args.size();
1348 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1351 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1353 std::unique_ptr<DescriptorImpl> Clone()
const override
1355 std::vector<std::unique_ptr<PubkeyProvider>>
providers;
1356 providers.reserve(m_pubkey_args.size());
1357 for (
const auto&
arg : m_pubkey_args) {
1360 return std::make_unique<MultiADescriptor>(m_threshold, std::move(
providers), m_sorted);
1365class SHDescriptor final :
public DescriptorImpl
1371 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1375 bool IsSegwit()
const {
return m_subdescriptor_args[0]->GetOutputType() ==
OutputType::BECH32; }
1378 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1380 std::optional<OutputType> GetOutputType()
const override
1382 assert(m_subdescriptor_args.size() == 1);
1386 bool IsSingleType() const final {
return true; }
1388 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1390 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1392 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1403 std::optional<int64_t> MaxSatisfactionElems()
const override {
1404 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *
sub_elems;
1408 std::unique_ptr<DescriptorImpl> Clone()
const override
1410 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1415class WSHDescriptor final :
public DescriptorImpl
1421 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1425 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1426 std::optional<OutputType> GetOutputType()
const override {
return OutputType::BECH32; }
1427 bool IsSingleType() const final {
return true; }
1429 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1433 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1440 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1444 std::optional<int64_t> MaxSatisfactionElems()
const override {
1445 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *
sub_elems;
1449 std::unique_ptr<DescriptorImpl> Clone()
const override
1451 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1456class TRDescriptor final :
public DescriptorImpl
1458 std::vector<int> m_depths;
1463 assert(m_depths.size() == scripts.size());
1464 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1467 if (!
builder.IsComplete())
return {};
1468 assert(keys.size() == 1);
1470 if (!
xpk.IsFullyValid())
return {};
1478 if (m_depths.empty()) {
1484 return type != StringType::PRIVATE;
1486 std::vector<bool> path;
1487 bool is_private{type == StringType::PRIVATE};
1492 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1493 if (pos)
ret +=
',';
1494 while ((
int)path.size() <= m_depths[pos]) {
1495 if (path.size())
ret +=
'{';
1496 path.push_back(
false);
1503 while (!path.empty() && path.back()) {
1504 if (path.size() > 1)
ret +=
'}';
1507 if (!path.empty()) path.back() =
true;
1512 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>>
descs, std::vector<int>
depths) :
1515 assert(m_subdescriptor_args.size() == m_depths.size());
1518 bool IsSingleType() const final {
return true; }
1520 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1522 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1527 std::optional<int64_t> MaxSatisfactionElems()
const override {
1532 std::unique_ptr<DescriptorImpl> Clone()
const override
1534 std::vector<std::unique_ptr<DescriptorImpl>>
subdescs;
1535 subdescs.reserve(m_subdescriptor_args.size());
1536 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(
subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1537 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(
subdescs), m_depths);
1551 const std::vector<CPubKey>& m_keys;
1562 return m_keys[key].GetID();
1568 std::vector<unsigned char> ToPKBytes(
uint32_t key)
const {
1571 return {m_keys[key].begin(), m_keys[key].end()};
1579 return {
id.begin(),
id.end()};
1590 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1592 const DescriptorImpl::StringType m_type;
1597 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1598 DescriptorImpl::StringType type,
1600 : m_arg(
arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1607 case DescriptorImpl::StringType::PUBLIC:
1608 ret = m_pubkeys[key]->ToString();
1610 case DescriptorImpl::StringType::PRIVATE:
1613 case DescriptorImpl::StringType::NORMALIZED:
1614 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1616 case DescriptorImpl::StringType::COMPAT:
1617 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1624class MiniscriptDescriptor final :
public DescriptorImpl
1630 std::vector<CScript>
MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1633 const auto script_ctx{
m_node.GetMsCtx()};
1634 for (
const auto& key : keys) {
1638 provider.
pubkeys.emplace(key.GetID(), key);
1641 return Vector(
m_node.ToScript(ScriptMaker(keys, script_ctx)));
1651 const uint32_t raw = node.K();
1652 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1653 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1654 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1655 if (is_time_based) {
1656 m_warnings.push_back(strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1658 m_warnings.push_back(strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1671 if (type == StringType::PRIVATE) {
1675 return res.has_value();
1679 bool IsSolvable()
const override {
return true; }
1680 bool IsSingleType() const final {
return true; }
1682 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1684 std::optional<int64_t>
MaxSatSize(
bool)
const override
1687 return m_node.GetWitnessSize();
1690 std::optional<int64_t> MaxSatisfactionElems()
const override
1692 return m_node.GetStackSize();
1695 std::unique_ptr<DescriptorImpl> Clone()
const override
1697 std::vector<std::unique_ptr<PubkeyProvider>>
providers;
1698 providers.reserve(m_pubkey_args.size());
1699 for (
const auto&
arg : m_pubkey_args) {
1702 return std::make_unique<MiniscriptDescriptor>(std::move(
providers),
m_node.Clone());
1707class RawTRDescriptor final :
public DescriptorImpl
1712 assert(keys.size() == 1);
1714 if (!
xpk.IsFullyValid())
return {};
1721 bool IsSingleType() const final {
return true; }
1723 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1725 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1730 std::optional<int64_t> MaxSatisfactionElems()
const override {
1735 std::unique_ptr<DescriptorImpl> Clone()
const override
1737 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1745enum class ParseScriptContext {
1757 if (
elem.size() > 0) {
1767 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{
elem.begin(),
elem.end()});
1768 return std::nullopt;
1769 }
else if (*
p > 0x7FFFFFFFUL) {
1770 error =
strprintf(
"Key path value %u is out of range", *
p);
1771 return std::nullopt;
1794 std::vector<uint32_t>
values;
1799 for (
size_t i = 1; i < split.size(); ++i) {
1800 const std::span<const char>&
elem = split[i];
1803 if (!
elem.empty() &&
elem.front() ==
'<' &&
elem.back() ==
'>') {
1805 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(
elem.begin(),
elem.end()));
1809 error =
"Multiple multipath key path specifiers found";
1814 std::vector<std::span<const char>>
nums = Split(std::span(
elem.begin()+1,
elem.end()-1),
";");
1815 if (
nums.size() < 2) {
1816 error =
"Multipath key path specifiers must have at least two items";
1822 for (
const auto& num :
nums) {
1824 if (!
op_num)
return false;
1827 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *
op_num);
1833 path.emplace_back();
1837 if (!
op_num)
return false;
1838 path.emplace_back(*
op_num);
1843 out.emplace_back(std::move(path));
1863 DeriveType type = DeriveType::NON_RANGED;
1864 if (std::ranges::equal(split.back(), std::span{
"*"}.first(1))) {
1866 type = DeriveType::UNHARDENED_RANGED;
1867 }
else if (std::ranges::equal(split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(split.back(), std::span{
"*h"}.first(2))) {
1868 apostrophe = std::ranges::equal(split.back(), std::span{
"*'"}.first(2));
1870 type = DeriveType::HARDENED_RANGED;
1878 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1879 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1880 auto split = Split(
sp,
'/');
1881 std::string str(split[0].begin(), split[0].end());
1882 if (str.size() == 0) {
1883 error =
"No key provided";
1887 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1890 if (split.size() == 1) {
1894 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1895 error =
"Hybrid public keys are not allowed";
1898 if (pubkey.IsFullyValid()) {
1900 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(
key_exp_index, pubkey,
false));
1904 error =
"Uncompressed keys are not allowed";
1907 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1908 unsigned char fullkey[33] = {0x02};
1911 if (pubkey.IsFullyValid()) {
1912 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(
key_exp_index, pubkey,
true));
1917 error =
strprintf(
"Pubkey '%s' is invalid", str);
1924 out.keys.emplace(pubkey.
GetID(), key);
1925 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(
key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1929 error =
"Uncompressed keys are not allowed";
1937 error =
strprintf(
"key '%s' is not valid", str);
1940 std::vector<KeyPath>
paths;
1943 if (
extkey.key.IsValid()) {
1947 for (
auto& path :
paths) {
1958 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1963 std::span<const char> span =
sp;
1964 if (
Const(
"musig(", span,
false)) {
1965 if (ctx != ParseScriptContext::P2TR) {
1966 error =
"musig() is only allowed in tr() and rawtr()";
1972 auto split = Split(
sp,
')',
true);
1973 if (split.size() > 2) {
1974 error =
"Too many ')' in musig() expression";
1977 std::span<const char>
expr(split.at(0).begin(), split.at(0).end());
1979 error =
"Invalid musig() expression";
1986 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>>
providers;
1989 while (
expr.size()) {
1991 error =
strprintf(
"musig(): expected ',', got '%c'",
expr[0]);
1997 error =
strprintf(
"musig(): %s", error);
2010 error =
"musig(): Must contain key expressions";
2015 DeriveType
deriv_type = DeriveType::NON_RANGED;
2017 if (split.size() == 2 &&
Const(
"/", split.at(1),
false)) {
2019 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2023 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2029 if (
deriv_type == DeriveType::HARDENED_RANGED) {
2030 error =
"musig(): Cannot have hardened child derivation";
2035 error =
"musig(): " + error;
2039 error =
"musig(): cannot have hardened derivation steps";
2051 for (
size_t i = 1; i < length; ++i) {
2065 std::vector<std::unique_ptr<PubkeyProvider>>
pubs;
2074 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2078 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2088 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2105 error =
"Multiple ']' characters found for a single pubkey";
2114 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2120 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)",
slash_split[0].size());
2130 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2133 std::vector<KeyPath> path;
2135 info.
path = path.at(0);
2140 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(
prov->m_expr_index, info, std::move(
prov),
apostrophe));
2152 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2155 std::unique_ptr<PubkeyProvider>
key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2158 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(
key_provider),
false);
2165 CPubKey pubkey{
xkey.GetEvenCorrespondingCPubKey()};
2166 std::unique_ptr<PubkeyProvider>
key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2169 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(
key_provider),
false);
2185 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2187 mutable std::string m_key_parsing_error;
2197 bool KeyCompare(
const Key&
a,
const Key& b)
const {
2198 return *m_keys.at(
a).at(0) < *m_keys.at(b).at(0);
2202 switch (m_script_ctx) {
2209 std::optional<Key>
FromString(std::span<const char>& in)
const
2212 Key key = m_keys.
size();
2214 if (
pk.empty())
return {};
2215 m_keys.emplace_back(std::move(pk));
2219 std::optional<std::string> ToString(
const Key& key,
bool&)
const
2221 return m_keys.at(key).at(0)->ToString();
2224 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2227 Key key = m_keys.size();
2230 std::copy(begin, end, pubkey.
begin());
2232 m_keys.emplace_back();
2239 m_keys.emplace_back();
2247 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2249 assert(end - begin == 20);
2252 std::copy(begin, end, hash.
begin());
2257 Key key = m_keys.
size();
2258 m_keys.emplace_back();
2267 return m_script_ctx;
2276 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2277 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2281 if (pubkeys.empty()) {
2285 for (
auto& pubkey : pubkeys) {
2286 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2290 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh",
expr)) {
2292 if (pubkeys.empty()) {
2296 for (
auto& pubkey : pubkeys) {
2297 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2301 if (ctx == ParseScriptContext::TOP &&
Func(
"combo",
expr)) {
2303 if (pubkeys.empty()) {
2304 error =
strprintf(
"combo(): %s", error);
2307 for (
auto& pubkey : pubkeys) {
2308 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2312 error =
"Can only have combo() at top level";
2319 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (
multi ||
sortedmulti)) ||
2323 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>>
providers;
2327 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2332 while (
expr.size()) {
2334 error =
strprintf(
"Multi: expected ',', got '%c'",
expr[0]);
2353 }
else if (
thres < 1) {
2354 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1",
thres);
2357 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified",
thres,
providers.size());
2360 if (ctx == ParseScriptContext::TOP) {
2362 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys",
providers.size());
2366 if (ctx == ParseScriptContext::P2SH) {
2377 if (
vec.size() == 1) {
2379 vec.emplace_back(
vec.at(0)->Clone());
2382 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2390 std::vector<std::unique_ptr<PubkeyProvider>>
pubs;
2393 pubs.emplace_back(std::move(pub.at(i)));
2403 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2406 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2409 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh",
expr)) {
2411 if (pubkeys.empty()) {
2415 for (
auto& pubkey : pubkeys) {
2416 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2420 error =
"Can only have wpkh() at top level or inside sh()";
2423 if (ctx == ParseScriptContext::TOP &&
Func(
"sh",
expr)) {
2425 if (
descs.empty() ||
expr.size())
return {};
2426 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2428 for (
auto& desc :
descs) {
2429 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2433 error =
"Can only have sh() at top level";
2436 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh",
expr)) {
2438 if (
descs.empty() ||
expr.size())
return {};
2439 for (
auto& desc :
descs) {
2440 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2444 error =
"Can only have wsh() at top level or inside sh()";
2447 if (ctx == ParseScriptContext::TOP &&
Func(
"addr",
expr)) {
2450 error =
"Address is not valid";
2453 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2456 error =
"Can only have addr() at top level";
2459 if (ctx == ParseScriptContext::TOP &&
Func(
"tr",
expr)) {
2467 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>>
subscripts;
2498 error =
strprintf(
"tr(): expected '}' after script expression");
2506 error =
strprintf(
"tr(): expected ',' after script expression");
2514 error =
strprintf(
"tr(): expected ')' after script expression");
2523 if (
vec.size() == 1) {
2525 vec.emplace_back(
vec.at(0)->Clone());
2528 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2534 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2545 std::vector<std::unique_ptr<DescriptorImpl>>
this_subs;
2548 this_subs.emplace_back(std::move(subs.at(i)));
2556 error =
"Can only have tr at top level";
2559 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr",
expr)) {
2562 error =
strprintf(
"rawtr(): only one key expected.");
2567 error =
strprintf(
"rawtr(): %s", error);
2571 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2575 error =
"Can only have rawtr at top level";
2578 if (ctx == ParseScriptContext::TOP &&
Func(
"raw",
expr)) {
2579 std::string str(
expr.begin(),
expr.end());
2581 error =
"Raw script is not hex";
2585 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2588 error =
"Can only have raw() at top level";
2596 if (
parser.m_key_parsing_error !=
"") {
2597 error = std::move(
parser.m_key_parsing_error);
2601 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2602 error =
"Miniscript expressions can only be used in wsh or tr.";
2605 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2611 error +=
" is invalid";
2612 }
else if (!
node->IsSane()) {
2613 error +=
" is not sane";
2615 error +=
": malleable witnesses exist";
2617 error +=
": witnesses without signature exist";
2619 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2621 error +=
": contains duplicate public keys";
2623 error +=
": needs witnesses that may exceed resource limits";
2626 error +=
" is not satisfiable";
2636 [](
const std::vector<std::unique_ptr<PubkeyProvider>>&
a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2637 return a.size() < b.size();
2641 if (
vec.size() == 1) {
2643 vec.emplace_back(
vec.at(0)->Clone());
2646 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2654 std::vector<std::unique_ptr<PubkeyProvider>>
pubs;
2656 for (
auto& pub :
parser.m_keys) {
2657 pubs.emplace_back(std::move(pub.at(i)));
2659 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(
pubs),
node->Clone()));
2664 if (ctx == ParseScriptContext::P2SH) {
2665 error =
"A function is needed within P2SH";
2667 }
else if (ctx == ParseScriptContext::P2WSH) {
2668 error =
"A function is needed within P2WSH";
2671 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(
expr.begin(),
expr.end()));
2678 if (!
match)
return {};
2679 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2680 keys.reserve(
match->second.size());
2682 if (
keyspan.size() != 32)
return {};
2684 if (!key)
return {};
2685 keys.push_back(std::move(key));
2687 return std::make_unique<MultiADescriptor>(
match->first, std::move(keys));
2695 return std::make_unique<PKDescriptor>(
InferXOnlyPubkey(key, ctx, provider),
true);
2698 if (ctx == ParseScriptContext::P2TR) {
2703 std::vector<std::vector<unsigned char>>
data;
2706 if (
txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2712 if (
txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2732 if (
txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2734 std::vector<std::unique_ptr<PubkeyProvider>>
providers;
2735 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2744 if (
ok)
return std::make_unique<MultisigDescriptor>((
int)data[0][0], std::move(
providers));
2752 if (
sub)
return std::make_unique<SHDescriptor>(std::move(
sub));
2760 if (
sub)
return std::make_unique<WSHDescriptor>(std::move(
sub));
2766 std::copy(data[0].begin(), data[0].end(), pubkey.
begin());
2775 std::vector<std::unique_ptr<DescriptorImpl>>
subscripts;
2778 std::unique_ptr<DescriptorImpl>
subdesc;
2792 return std::make_unique<TRDescriptor>(std::move(key), std::move(
subscripts), std::move(
depths));
2800 return std::make_unique<RawTRDescriptor>(std::move(key));
2805 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2811 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2812 keys.reserve(
parser.m_keys.size());
2813 for (
auto& key :
parser.m_keys) {
2814 keys.emplace_back(std::move(key.at(0)));
2816 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(*
node));
2822 if (ctx != ParseScriptContext::TOP)
return nullptr;
2827 return std::make_unique<AddressDescriptor>(std::move(dest));
2831 return std::make_unique<RawDescriptor>(
script);
2842 error =
"Multiple '#' symbols";
2846 error =
"Missing checksum";
2857 error =
"Invalid characters in payload";
2873 std::span<const char>
sp{descriptor};
2877 if (
sp.empty() && !
ret.empty()) {
2878 std::vector<std::unique_ptr<Descriptor>>
descs;
2880 for (
auto& r :
ret) {
2881 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2892 std::span<const char>
sp{descriptor};
2959 throw std::runtime_error(std::string(
__func__) +
": New cached parent xpub does not match already cached parent xpub");
2971 throw std::runtime_error(std::string(
__func__) +
": New cached derived xpub does not match already cached derived xpub");
2983 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
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool GetKeyOriginByXOnly(const XOnlyPubKey &pubkey, KeyOriginInfo &info) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
Utility class to construct Taproot outputs from internal key and script tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
const unsigned char * begin() const
static constexpr size_t size()
bool IsFullyValid() const
Determine if this pubkey is fully valid.
constexpr unsigned char * begin()
A node in a miniscript expression.
void reserve(size_type new_capacity)
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.
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.
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(CExtPubKey &out, unsigned int nChild, uint256 *bip32_tweak_out=nullptr) const
Interface for parsed descriptor objects.
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
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
consteval auto _(util::TranslatedLiteral str)
bool IsHex(std::string_view str)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.