Inside Bitcoin
Opening the selected file…
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.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#include <bitcoin-build-config.h> // IWYU pragma: keep8#include <chainparamsbase.h>9#include <clientversion.h>10#include <common/args.h>11#include <common/license_info.h>12#include <common/system.h>13#include <common/url.h>14#include <compat/compat.h>15#include <compat/stdin.h>16#include <interfaces/init.h>17#include <interfaces/ipc.h>18#include <interfaces/rpc.h>19#include <netbase.h>20#include <policy/feerate.h>21#include <rpc/client.h>22#include <rpc/mining.h>23#include <rpc/protocol.h>24#include <rpc/request.h>25#include <tinyformat.h>26#include <univalue.h>27#include <util/chaintype.h>28#include <util/exception.h>29#include <util/sock.h>30#include <util/strencodings.h>31#include <util/string.h>32#include <util/time.h>33#include <util/translation.h>35#include <algorithm>36#include <chrono>37#include <cmath>38#include <cstdio>39#include <functional>40#include <limits>41#include <memory>42#include <optional>43#include <span>44#include <string>45#include <string_view>46#include <thread>47#include <tuple>49#ifndef WIN3250#include <unistd.h>51#endif53using util::Join;54using util::ToString;56// The server returns time values from a mockable system clock, but it is not57// trivial to get the mocked time from the server, nor is it needed for now, so58// just use a plain system_clock.59using CliClock = std::chrono::system_clock;61const TranslateFn G_TRANSLATION_FUN{nullptr};63static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";64static constexpr const char* DEFAULT_RPC_REQ_ID{"1"};65static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;66static constexpr int DEFAULT_WAIT_CLIENT_TIMEOUT = 0;67static const bool DEFAULT_NAMED=false;68static const int CONTINUE_EXECUTION=-1;69static constexpr uint8_t NETINFO_MAX_LEVEL{4};70static constexpr int8_t UNKNOWN_NETWORK{-1};71// See GetNetworkName() in netbase.cpp72static constexpr std::array NETWORKS{"not_publicly_routable", "ipv4", "ipv6", "onion", "i2p", "cjdns", "internal"};73static constexpr std::array NETWORK_SHORT_NAMES{"npr", "ipv4", "ipv6", "onion", "i2p", "cjdns", "int"};74static constexpr std::array UNREACHABLE_NETWORK_IDS{/*not_publicly_routable*/0, /*internal*/6};76/** Default number of blocks to generate for RPC generatetoaddress. */77static const std::string DEFAULT_NBLOCKS = "1";79/** Default -color setting. */80static const std::string DEFAULT_COLOR_SETTING{"auto"};82struct HTTPError : std::runtime_error {83explicit inline HTTPError(const std::string& msg) : std::runtime_error(msg) {}84};86/** Parses the headers of an HTTP response.87*88* May be replaced by the corresponding methods in HTTPHeaders from89* https://github.com/bitcoin/bitcoin/pull/35182 once that class is in a90* shared location.91*/92class HTTPResponseHeaders93{94std::vector<std::pair<std::string, std::string>> m_headers;96public:97void Read(util::LineReader& reader);98std::optional<std::string> FindFirst(std::string_view key) const;99};101// Named Read() in HTTPHeaders (see PR #35182).102void HTTPResponseHeaders::Read(util::LineReader& reader)103{104// Headers https://httpwg.org/specs/rfc9110.html#rfc.section.6.3105// A sequence of Field Lines https://httpwg.org/specs/rfc9110.html#rfc.section.5.2106while (auto maybe_line = reader.ReadLine()) {107const std::string_view line = *maybe_line;109// An empty line indicates end of the headers section https://www.rfc-editor.org/rfc/rfc2616#section-4110if (line.empty()) return;112// Header line must have at least one ":"113// keys are not allowed to have delimiters like ":" but values are114// https://httpwg.org/specs/rfc9110.html#rfc.section.5.6.2115const size_t pos{line.find(':')};116if (pos == std::string::npos) throw HTTPError{"Header missing colon (:)"};118// Whitespace is optional119std::string key = util::TrimString(std::string_view(line).substr(0, pos));120std::string value = util::TrimString(std::string_view(line).substr(pos + 1));122// Header keys are Field Names: https://httpwg.org/specs/rfc9110.html#fields.names123// which consist of "tokens": https://httpwg.org/specs/rfc9110.html#rfc.section.5.6.2124// that can not be empty.125if (key.empty()) throw HTTPError{"Empty header name"};127m_headers.emplace_back(std::move(key), std::move(value));128}129}131std::optional<std::string> HTTPResponseHeaders::FindFirst(std::string_view key) const132{133for (const auto& item : m_headers) {134if (CaseInsensitiveEqual(key, item.first)) {135return item.second;136}137}138return std::nullopt;139}141static void SetupCliArgs(ArgsManager& argsman)142{143SetupHelpOptions(argsman);145const auto defaultBaseParams = CreateBaseChainParams(ChainType::MAIN);146const auto testnetBaseParams = CreateBaseChainParams(ChainType::TESTNET);147const auto testnet4BaseParams = CreateBaseChainParams(ChainType::TESTNET4);148const auto signetBaseParams = CreateBaseChainParams(ChainType::SIGNET);149const auto regtestBaseParams = CreateBaseChainParams(ChainType::REGTEST);151argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);152argsman.AddArg("-conf=<file>", strprintf("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);153argsman.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);154argsman.AddArg("-generate",155strprintf("Generate blocks, equivalent to RPC getnewaddress followed by RPC generatetoaddress. Optional positional integer "156"arguments are number of blocks to generate (default: %s) and maximum iterations to try (default: %s), equivalent to "157"RPC generatetoaddress nblocks and maxtries arguments. Example: bitcoin-cli -generate 4 1000",158DEFAULT_NBLOCKS, DEFAULT_MAX_TRIES),159ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);160argsman.AddArg("-addrinfo", "Get the number of addresses known to the node, per network and total.", ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);161argsman.AddArg("-getinfo", "Get general information from the remote server. Note that unlike server-side RPC calls, the output of -getinfo is the result of multiple non-atomic requests. Some entries in the output may represent results from different states (e.g. wallet balance may be as of a different block from the chain state reported)", ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);162argsman.AddArg("-netinfo", strprintf("Get network peer connection information from the remote server. An optional argument from 0 to %d can be passed for different peers listings (default: 0). If a non-zero value is passed, an additional \"outonly\" (or \"o\") argument can be passed to see outbound peers only. Pass \"help\" (or \"h\") for detailed help documentation.", NETINFO_MAX_LEVEL), ArgsManager::ALLOW_ANY, OptionsCategory::CLI_COMMANDS);164SetupChainParamsBaseOptions(argsman);165argsman.AddArg("-color=<when>", strprintf("Color setting for CLI output (default: %s). Valid values: always, auto (add color codes when standard output is connected to a terminal and OS is not WIN32), never. Only applies to the output of -getinfo.", DEFAULT_COLOR_SETTING), ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);166argsman.AddArg("-named", strprintf("Pass named instead of positional arguments (default: %s)", DEFAULT_NAMED), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);167argsman.AddArg("-rpcid=<id>", strprintf("Set a custom JSON-RPC request ID string (default: %s)", DEFAULT_RPC_REQ_ID), ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION | ArgsManager::DISALLOW_ELISION, OptionsCategory::OPTIONS);168argsman.AddArg("-rpcclienttimeout=<n>", strprintf("Timeout in seconds during HTTP requests, or 0 for no timeout. Not implemented for IPC connections (see -ipcconnect). (default: %d)", DEFAULT_HTTP_CLIENT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);169argsman.AddArg("-rpcconnect=<ip>", strprintf("Send commands to node running on <ip> (default: %s)", DEFAULT_RPCCONNECT), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);170argsman.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);171argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);172argsman.AddArg("-rpcport=<port>", strprintf("Connect to JSON-RPC on <port> (default: %u, testnet: %u, testnet4: %u, signet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), testnet4BaseParams->RPCPort(), signetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::OPTIONS);173argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);174argsman.AddArg("-rpcwait", "Wait for RPC server to start", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);175argsman.AddArg("-rpcwaittimeout=<n>", strprintf("Timeout in seconds to wait for the RPC server to start, or 0 for no timeout. (default: %d)", DEFAULT_WAIT_CLIENT_TIMEOUT), ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);176argsman.AddArg("-rpcwallet=<walletname>", "Send RPC for non-default wallet on RPC server (needs to exactly match corresponding -wallet option passed to bitcoind). This changes the RPC endpoint used, e.g. http://127.0.0.1:8332/wallet/<walletname>", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);177argsman.AddArg("-stdin", "Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). When combined with -stdinrpcpass, the first line from standard input is used for the RPC password.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);178argsman.AddArg("-stdinrpcpass", "Read RPC password from standard input as a single line. When combined with -stdin, the first line from standard input is used for the RPC password. When combined with -stdinwalletpassphrase, -stdinrpcpass consumes the first line, and -stdinwalletpassphrase consumes the second.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);179argsman.AddArg("-stdinwalletpassphrase", "Read wallet passphrase from standard input as a single line. When combined with -stdin, the first line from standard input is used for the wallet passphrase.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);180argsman.AddArg("-ipcconnect=<address>", "Connect to bitcoin-node through IPC socket instead of TCP socket to execute requests. Valid <address> values are 'auto' to try to connect to default socket path at <datadir>/node.sock but fall back to TCP if it is not available, 'unix' to connect to the default socket and fail if it isn't available, or 'unix:<socket path>' to connect to a socket at a nonstandard path. -noipcconnect can be specified to avoid attempting to use IPC at all. Default value: auto", ArgsManager::ALLOW_ANY, OptionsCategory::IPC);181}183std::optional<std::string> RpcWalletName(const ArgsManager& args)184{185// Check IsArgNegated to return nullopt instead of "0" if -norpcwallet is specified186if (args.IsArgNegated("-rpcwallet")) return std::nullopt;187return args.GetArg("-rpcwallet");188}190//191// Exception thrown on connection error. This error is used to determine192// when to wait if -rpcwait is given.193//194struct CConnectionFailed : std::runtime_error {195explicit inline CConnectionFailed(const std::string& msg) :196std::runtime_error(msg)197{}198};200//201// This function returns either one of EXIT_ codes when it's expected to stop the process or202// CONTINUE_EXECUTION when it's expected to continue further.203//204static int AppInitRPC(int argc, char* argv[])205{206SetupCliArgs(gArgs);207std::string error;208if (!gArgs.ParseParameters(argc, argv, error)) {209tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error);210return EXIT_FAILURE;211}212if (argc < 2 || HelpRequested(gArgs) || gArgs.GetBoolArg("-version", false)) {213std::string strUsage = CLIENT_NAME " RPC client version " + FormatFullVersion() + "\n";215if (gArgs.GetBoolArg("-version", false)) {216strUsage += FormatParagraph(LicenseInfo());217} else {218strUsage += "\n"219"The bitcoin-cli utility provides a command line interface to interact with a " CLIENT_NAME " RPC server.\n"220"\nIt can be used to query network information, manage wallets, create or broadcast transactions, and control the " CLIENT_NAME " server.\n"221"\nUse the \"help\" command to list all commands. Use \"help <command>\" to show help for that command.\n"222"The -named option allows you to specify parameters using the key=value format, eliminating the need to pass unused positional parameters.\n"223"\n"224"Usage: bitcoin-cli [options] <command> [params]\n"225"or: bitcoin-cli [options] -named <command> [name=value]...\n"226"or: bitcoin-cli [options] help\n"227"or: bitcoin-cli [options] help <command>\n"228"\n";229strUsage += "\n" + gArgs.GetHelpMessage();230}232tfm::format(std::cout, "%s", strUsage);233if (argc < 2) {234tfm::format(std::cerr, "Error: too few parameters\n");235return EXIT_FAILURE;236}237return EXIT_SUCCESS;238}239if (!CheckDataDirOption(gArgs)) {240tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""));241return EXIT_FAILURE;242}243if (!gArgs.ReadConfigFiles(error, true)) {244tfm::format(std::cerr, "Error reading configuration file: %s\n", error);245return EXIT_FAILURE;246}247// Check for chain settings (BaseParams() calls are only valid after this clause)248try {249SelectBaseParams(gArgs.GetChainType());250} catch (const std::exception& e) {