Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1001ToStringHelper(nullptr, ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);1002return AddChecksum(ret);1003}1005std::string ToCanonicalString() const final1006{1007std::string ret;1008ToStringHelper(nullptr, ret, StringType::CANONICAL);1009return AddChecksum(ret);1010}1012bool ToPrivateString(const SigningProvider& arg, std::string& out) const override1013{1014bool has_priv_key{ToStringHelper(&arg, out, StringType::PRIVATE)};1015out = AddChecksum(out);1016return has_priv_key;1017}1019bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override final1020{1021bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);1022out = AddChecksum(out);1023return ret;1024}1026// NOLINTNEXTLINE(misc-no-recursion)1027bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const1028{1029FlatSigningProvider subprovider;1030std::vector<CPubKey> pubkeys;1031pubkeys.reserve(m_pubkey_args.size());1033// Construct temporary data in `pubkeys`, `subscripts`, and `subprovider` to avoid producing output in case of failure.1034for (const auto& p : m_pubkey_args) {1035std::optional<CPubKey> pubkey = p->GetPubKey(pos, arg, subprovider, read_cache, write_cache);1036if (!pubkey) return false;1037pubkeys.push_back(pubkey.value());1038}1039std::vector<CScript> subscripts;1040for (const auto& subarg : m_subdescriptor_args) {1041std::vector<CScript> outscripts;1042if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache)) return false;1043assert(outscripts.size() == 1);1044subscripts.emplace_back(std::move(outscripts[0]));1045}1046out.Merge(std::move(subprovider));1048output_scripts = MakeScripts(pubkeys, std::span{subscripts}, out);1049return true;1050}1052bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const final1053{1054return ExpandHelper(pos, provider, nullptr, output_scripts, out, write_cache);1055}1057bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final1058{1059return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);1060}1062// NOLINTNEXTLINE(misc-no-recursion)1063void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final1064{1065for (const auto& p : m_pubkey_args) {1066p->GetPrivKey(pos, provider, out);1067}1068for (const auto& arg : m_subdescriptor_args) {1069arg->ExpandPrivate(pos, provider, out);1070}1071}1073std::optional<OutputType> GetOutputType() const override { return std::nullopt; }1075std::optional<int64_t> ScriptSize() const override { return {}; }1077/** A helper for MaxSatisfactionWeight.1078*1079* @param use_max_sig Whether to assume ECDSA signatures will have a high-r.1080* @return The maximum size of the satisfaction in raw bytes (with no witness meaning).1081*/1082virtual std::optional<int64_t> MaxSatSize(bool use_max_sig) const { return {}; }1084std::optional<int64_t> MaxSatisfactionWeight(bool) const override { return {}; }1086std::optional<int64_t> MaxSatisfactionElems() const override { return {}; }1088// NOLINTNEXTLINE(misc-no-recursion)1089void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs) const override1090{1091for (const auto& p : m_pubkey_args) {1092std::optional<CPubKey> pub = p->GetRootPubKey();1093if (pub) pubkeys.insert(*pub);1094std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();1095if (ext_pub) ext_pubs.insert(*ext_pub);1096}1097for (const auto& arg : m_subdescriptor_args) {1098arg->GetPubKeys(pubkeys, ext_pubs);1099}1100}1102virtual std::unique_ptr<DescriptorImpl> Clone() const = 0;1104bool HasScripts() const override { return true; }1106// NOLINTNEXTLINE(misc-no-recursion)1107std::vector<std::string> Warnings() const override {1108std::vector<std::string> all = m_warnings;1109for (const auto& sub : m_subdescriptor_args) {1110auto sub_w = sub->Warnings();1111all.insert(all.end(), sub_w.begin(), sub_w.end());1112}1113return all;1114}1116uint32_t GetMaxKeyExpr() const final1117{1118uint32_t max_key_expr{0};1119std::vector<const DescriptorImpl*> todo = {this};1120while (!todo.empty()) {1121const DescriptorImpl* desc = todo.back();1122todo.pop_back();1123for (const auto& p : desc->m_pubkey_args) {1124max_key_expr = std::max(max_key_expr, p->m_expr_index);1125}1126for (const auto& s : desc->m_subdescriptor_args) {1127todo.push_back(s.get());1128}1129}1130return max_key_expr;1131}1133size_t GetKeyCount() const final1134{1135size_t count{0};1136std::vector<const DescriptorImpl*> todo = {this};1137while (!todo.empty()) {1138const DescriptorImpl* desc = todo.back();1139todo.pop_back();1140for (const auto& p : desc->m_pubkey_args) {1141count += p->GetKeyCount();1142}1143for (const auto& s : desc->m_subdescriptor_args) {1144todo.push_back(s.get());1145}1146}1147return count;1148}1150// NOLINTNEXTLINE(misc-no-recursion)1151bool CanSelfExpand() const override1152{1153for (const auto& key : m_pubkey_args) {1154if (!key->CanSelfExpand()) return false;1155}1156for (const auto& sub : m_subdescriptor_args) {1157if (!sub->CanSelfExpand()) return false;1158}1159return true;1160}1161};1163/** A parsed addr(A) descriptor. */1164class AddressDescriptor final : public DescriptorImpl1165{1166const CTxDestination m_destination;1167protected:1168std::string ToStringExtra() const override { return EncodeDestination(m_destination); }1169std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }1170public:1171AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}1172bool IsSolvable() const final { return false; }1174std::optional<OutputType> GetOutputType() const override1175{1176return OutputTypeFromDestination(m_destination);1177}1178bool IsSingleType() const final { return true; }1179bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }1181std::optional<int64_t> ScriptSize() const override { return GetScriptForDestination(m_destination).size(); }1182std::unique_ptr<DescriptorImpl> Clone() const override1183{1184return std::make_unique<AddressDescriptor>(m_destination);1185}1186};1188/** A parsed raw(H) descriptor. */1189class RawDescriptor final : public DescriptorImpl1190{1191const CScript m_script;1192protected:1193std::string ToStringExtra() const override { return HexStr(m_script); }1194std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); }1195public:1196RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}1197bool IsSolvable() const final { return false; }1199std::optional<OutputType> GetOutputType() const override1200{1201CTxDestination dest;1202ExtractDestination(m_script, dest);1203return OutputTypeFromDestination(dest);1204}1205bool IsSingleType() const final { return true; }1206bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }1208std::optional<int64_t> ScriptSize() const override { return m_script.size(); }1210std::unique_ptr<DescriptorImpl> Clone() const override1211{1212return std::make_unique<RawDescriptor>(m_script);1213}1214};1216/** A parsed pk(P) descriptor. */1217class PKDescriptor final : public DescriptorImpl1218{1219private:1220const bool m_xonly;1221protected:1222std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override1223{1224if (m_xonly) {1225CScript script = CScript() << ToByteVector(XOnlyPubKey(keys[0])) << OP_CHECKSIG;1226return Vector(std::move(script));1227} else {1228return Vector(GetScriptForRawPubKey(keys[0]));1229}1230}1231public:1232PKDescriptor(std::unique_ptr<PubkeyProvider> prov, bool xonly = false) : DescriptorImpl(Vector(std::move(prov)), "pk"), m_xonly(xonly) {}1233bool IsSingleType() const final { return true; }1235std::optional<int64_t> ScriptSize() const override {1236return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;1237}1239std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {1240const auto ecdsa_sig_size = use_max_sig ? 72 : 71;1241return 1 + (m_xonly ? 65 : ecdsa_sig_size);1242}1244std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {1245return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;1246}1248std::optional<int64_t> MaxSatisfactionElems() const override { return 1; }1250std::unique_ptr<DescriptorImpl> Clone() const override