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.
1251case Type::BOOL:1252return res + "bool";1253case Type::ARR:1254res += "[";1255for (const auto& i : m_inner) {1256res += i.ToString(oneline) + ",";1257}1258return res + "...]";1259case Type::OBJ:1260case Type::OBJ_NAMED_PARAMS:1261case Type::OBJ_USER_KEYS:1262// Currently unused, so avoid writing dead code1263NONFATAL_UNREACHABLE();1264} // no default case, so the compiler can warn about missing cases1265NONFATAL_UNREACHABLE();1266}1268// NOLINTNEXTLINE(misc-no-recursion)1269std::string RPCArg::ToString(const bool oneline) const1270{1271if (oneline && !m_opts.oneline_description.empty()) {1272if (m_opts.oneline_description[0] == '\"' && m_type != Type::STR_HEX && m_type != Type::STR && gArgs.GetBoolArg("-rpcdoccheck", DEFAULT_RPC_DOC_CHECK)) {1273throw std::runtime_error{1274STR_INTERNAL_BUG(strprintf("non-string RPC arg \"%s\" quotes oneline_description:\n%s",1275m_names, m_opts.oneline_description)1276)};1277}1278return m_opts.oneline_description;1279}1281switch (m_type) {1282case Type::STR_HEX:1283case Type::STR: {1284return "\"" + GetFirstName() + "\"";1285}1286case Type::NUM:1287case Type::RANGE:1288case Type::AMOUNT:1289case Type::BOOL: {1290return GetFirstName();1291}1292case Type::OBJ:1293case Type::OBJ_NAMED_PARAMS:1294case Type::OBJ_USER_KEYS: {1295// NOLINTNEXTLINE(misc-no-recursion)1296const std::string res = Join(m_inner, ",", [&](const RPCArg& i) { return i.ToStringObj(oneline); });1297if (m_type == Type::OBJ) {1298return "{" + res + "}";1299} else {1300return "{" + res + ",...}";1301}1302}1303case Type::ARR: {1304std::string res;1305for (const auto& i : m_inner) {1306res += i.ToString(oneline) + ",";1307}1308return "[" + res + "...]";1309}1310} // no default case, so the compiler can warn about missing cases1311NONFATAL_UNREACHABLE();1312}1314static std::pair<int64_t, int64_t> ParseRange(const UniValue& value)1315{1316if (value.isNum()) {1317return {0, value.getInt<int64_t>()};1318}1319if (value.isArray() && value.size() == 2 && value[0].isNum() && value[1].isNum()) {1320int64_t low = value[0].getInt<int64_t>();1321int64_t high = value[1].getInt<int64_t>();1322if (low > high) throw JSONRPCError(RPC_INVALID_PARAMETER, "Range specified as [begin,end] must not have begin after end");1323return {low, high};1324}1325throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified as end or as [begin,end]");1326}1328std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value)1329{1330int64_t low, high;1331std::tie(low, high) = ParseRange(value);1332if (low < 0) {1333throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should be greater or equal than 0");1334}1335if ((high >> 31) != 0) {1336throw JSONRPCError(RPC_INVALID_PARAMETER, "End of range is too high");1337}1338if (high >= low + 1000000) {1339throw JSONRPCError(RPC_INVALID_PARAMETER, "Range is too large");1340}1341return {low, high};1342}1344std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider, const bool expand_priv)1345{1346std::string desc_str;1347std::pair<int64_t, int64_t> range = {0, 1000};1348if (scanobject.isStr()) {1349desc_str = scanobject.get_str();1350} else if (scanobject.isObject()) {1351const UniValue& desc_uni{scanobject.find_value("desc")};1352if (desc_uni.isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor needs to be provided in scan object");1353desc_str = desc_uni.get_str();1354const UniValue& range_uni{scanobject.find_value("range")};1355if (!range_uni.isNull()) {1356range = ParseDescriptorRange(range_uni);1357}1358} else {1359throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan object needs to be either a string or an object");1360}1362std::string error;1363auto descs = Parse(desc_str, provider, error);1364if (descs.empty()) {1365throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);1366}1367if (!descs.at(0)->IsRange()) {1368range.first = 0;1369range.second = 0;1370}1371std::vector<CScript> ret;1372for (int64_t i = range.first; i <= range.second; ++i) {1373for (const auto& desc : descs) {1374std::vector<CScript> scripts;1375if (!desc->Expand(i, provider, scripts, provider)) {1376throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys: '%s'", desc_str));1377}1378if (expand_priv) {1379desc->ExpandPrivate(/*pos=*/i, provider, /*out=*/provider);1380}1381std::move(scripts.begin(), scripts.end(), std::back_inserter(ret));1382}1383}1384return ret;1385}1387std::vector<uint32_t> ParsePathBIP32(const std::string& path)1388{1389std::vector<uint32_t> out;1390if (!ParseHDKeypath(path, out)) {1391throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid BIP32 keypath");1392}1393return out;1394}1396/** Convert a vector of bilingual strings to a UniValue::VARR containing their original untranslated values. */1397[[nodiscard]] static UniValue BilingualStringsToUniValue(const std::vector<bilingual_str>& bilingual_strings)1398{1399CHECK_NONFATAL(!bilingual_strings.empty());1400UniValue result{UniValue::VARR};1401for (const auto& s : bilingual_strings) {1402result.push_back(s.original);1403}1404return result;1405}1407void PushWarnings(const UniValue& warnings, UniValue& obj)1408{1409if (warnings.empty()) return;1410obj.pushKV("warnings", warnings);1411}1413void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj)1414{1415if (warnings.empty()) return;1416obj.pushKV("warnings", BilingualStringsToUniValue(warnings));1417}1419std::vector<RPCResult> ScriptPubKeyDoc() {1420return1421{1422{RPCResult::Type::STR, "asm", "Disassembly of the output script"},1423{RPCResult::Type::STR, "desc", "Inferred descriptor for the output"},1424{RPCResult::Type::STR_HEX, "hex", "The raw output script bytes, hex-encoded"},1425{RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},1426{RPCResult::Type::STR, "type", "The type (one of: " + GetAllOutputTypes() + ")"},1427};1428}1430uint256 GetTarget(const CBlockIndex& blockindex, const uint256 pow_limit)1431{1432arith_uint256 target{*CHECK_NONFATAL(DeriveTarget(blockindex.nBits, pow_limit))};1433return ArithToUint256(target);1434}1436std::vector<RPCResult> ElideGroup(std::vector<RPCResult> fields, std::string summary)1437{1438if (fields.empty()) return fields;1439std::vector<RPCResult> result;1440result.reserve(fields.size());1441for (size_t i = 0; i < fields.size(); ++i) {1442RPCResultOptions opts = fields[i].m_opts;1443if (i == 0) {1444opts.print_elision = summary;1445} else {1446opts.print_elision = HelpElisionSkip{};1447}1448result.emplace_back(fields[i], std::move(opts));1449}1450return result;1451}