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.
502def tor_port(n):503return p2p_port(n) + PORT_RANGE * 2506# Node functions507################510def initialize_datadir(dirname, n, chain, disable_autoconnect=True):511datadir = get_datadir_path(dirname, n)512if not os.path.isdir(datadir):513os.makedirs(datadir)514write_config(os.path.join(datadir, "bitcoin.conf"), n=n, chain=chain, disable_autoconnect=disable_autoconnect)515os.makedirs(os.path.join(datadir, 'stderr'), exist_ok=True)516os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True)517return datadir520def write_config(config_path, *, n, chain, extra_config="", disable_autoconnect=True):521# Translate chain subdirectory name to config name522if chain == 'testnet3':523chain_name_conf_arg = 'testnet'524chain_name_conf_section = 'test'525else:526chain_name_conf_arg = chain527chain_name_conf_section = chain528with open(config_path, 'w') as f:529if chain_name_conf_arg:530f.write("{}=1\n".format(chain_name_conf_arg))531if chain_name_conf_section:532f.write("[{}]\n".format(chain_name_conf_section))533f.write("port=" + str(p2p_port(n)) + "\n")534f.write("rpcport=" + str(rpc_port(n)) + "\n")535# Disable server-side timeouts to avoid intermittent issues536f.write("rpcservertimeout=99000\n")537f.write("rpcdoccheck=1\n")538f.write("rpcthreads=2\n")539f.write("fallbackfee=0.0002\n")540f.write("server=1\n")541f.write("keypool=1\n")542f.write("discover=0\n")543f.write("dnsseed=0\n")544f.write("fixedseeds=0\n")545f.write("listenonion=0\n")546# Increase peertimeout to avoid disconnects while using mocktime.547# peertimeout is measured in mock time, so setting it large enough to548# cover any duration in mock time is sufficient. It can be overridden549# in tests.550f.write("peertimeout=999999999\n")551f.write("printtoconsole=0\n")552f.write("natpmp=0\n") # Avoid non-loopback network traffic during tests.553f.write("shrinkdebugfile=0\n")554# To improve SQLite wallet performance so that the tests don't timeout, use -unsafesqlitesync555f.write("unsafesqlitesync=1\n")556if disable_autoconnect:557f.write("connect=0\n")558# Limit max connections to mitigate test failures on some systems caused by the warning:559# "Warning: Reducing -maxconnections from <...> to <...> due to system limitations".560# For details, consult the `AppInitParameterInteraction` function in src/init.cpp.561# available_fds = 256 // Same as FD_SETSIZE on NetBSD.562# MIN_CORE_FDS = 151 // Number of file descriptors required for core functionality.563# MAX_ADDNODE_CONNECTIONS = 8 // Maximum number of -addnode outgoing nodes.564# num_p2p_bind = 3 // Maximum number of bound P2P interfaces (-bind and -whitebind) used in a test.565# num_rpc_bind = 2 // Maximum number of HTTP sockets used in a test.566# DEFAULT_MAX_HTTP_CONNECTIONS = 16 // Reserved for connected HTTP clients.567#568# min_required_fds = MIN_CORE_FDS + MAX_ADDNODE_CONNECTIONS + num_p2p_bind + num_rpc_bind + DEFAULT_MAX_HTTP_CONNECTIONS =569# = 151 + 8 + 3 + 2 + 16 = 180;570# num_p2p_max_connections = available_fds - min_required_fds = 256 - 180 = 76;571f.write("maxconnections=76\n")572f.write("par=" + str(min(2, os.cpu_count())) + "\n")573# Use a single prevoutfetch worker thread to keep per-node resource usage low.574f.write("prevoutfetchthreads=1\n")575f.write(extra_config)578def get_datadir_path(dirname, n):579return pathlib.Path(dirname) / f"node{n}"582def get_temp_default_datadir(temp_dir: pathlib.Path) -> tuple[dict, pathlib.Path]:583"""Return os-specific environment variables that can be set to make the584GetDefaultDataDir() function return a datadir path under the provided585temp_dir, as well as the complete path it would return."""586if platform.system() == "Windows":587env = dict(APPDATA=str(temp_dir))588datadir = temp_dir / "Bitcoin"589else:590env = dict(HOME=str(temp_dir))591if platform.system() == "Darwin":592datadir = temp_dir / "Library/Application Support/Bitcoin"593else:594datadir = temp_dir / ".bitcoin"595return env, datadir598def append_config(datadir, options):599with open(os.path.join(datadir, "bitcoin.conf"), 'a') as f:600for option in options:601f.write(option + "\n")604def get_auth_cookie(datadir, chain):605user = None606password = None607if os.path.isfile(os.path.join(datadir, "bitcoin.conf")):608with open(os.path.join(datadir, "bitcoin.conf"), 'r') as f:609for line in f:610if line.startswith("rpcuser="):611assert user is None # Ensure that there is only one rpcuser line612user = line.split("=")[1].strip("\n")613if line.startswith("rpcpassword="):614assert password is None # Ensure that there is only one rpcpassword line615password = line.split("=")[1].strip("\n")616try:617with open(os.path.join(datadir, chain, ".cookie"), 'r') as f:618userpass = f.read()619split_userpass = userpass.split(':')620user = split_userpass[0]621password = split_userpass[1]622except OSError:623pass624if user is None or password is None:625raise ValueError("No RPC credentials")626return user, password629# If a cookie file exists in the given datadir, delete it.630def delete_cookie_file(datadir, chain):631if os.path.isfile(os.path.join(datadir, chain, ".cookie")):632logger.debug("Deleting leftover cookie file")633os.remove(os.path.join(datadir, chain, ".cookie"))636def softfork_active(node, key):637"""Return whether a softfork is active."""638return node.getdeploymentinfo()['deployments'][key]['active']641def set_node_times(nodes, t):642for node in nodes:643node.setmocktime(t)646def check_node_connections(*, node, num_in, num_out):647info = node.getnetworkinfo()648assert_equal(info["connections_in"], num_in)649assert_equal(info["connections_out"], num_out)652# Transaction/Block functions653#############################656# Create large OP_RETURN txouts that can be appended to a transaction657# to make it large (helper for constructing large transactions). The658# total serialized size of the txouts is about 66k vbytes.659def gen_return_txouts():660from .messages import CTxOut661from .script import CScript, OP_RETURN662txouts = [CTxOut(nValue=0, scriptPubKey=CScript([OP_RETURN, b'\x01'*67437]))]663assert_equal(sum([len(txout.serialize()) for txout in txouts]), 67456)664return txouts667# Create a spend of each passed-in utxo, splicing in "txouts" to each raw668# transaction to make it large. See gen_return_txouts() above.669def create_lots_of_big_transactions(mini_wallet, node, fee, tx_batch_size, txouts, utxos=None):670txids = []671use_internal_utxos = utxos is None672for _ in range(tx_batch_size):673tx = mini_wallet.create_self_transfer(674utxo_to_spend=None if use_internal_utxos else utxos.pop(),675fee=fee,676)["tx"]677tx.vout.extend(txouts)678res = node.testmempoolaccept([tx.serialize().hex()])[0]679assert_equal(res['fees']['base'], fee)680txids.append(node.sendrawtransaction(tx.serialize().hex()))681return txids684def mine_large_block(test_framework, mini_wallet, node):685# generate a 66k transaction,686# and 14 of them is close to the 1MB block limit687txouts = gen_return_txouts()688fee = 100 * node.getnetworkinfo()["relayfee"]689create_lots_of_big_transactions(mini_wallet, node, fee, 14, txouts)690test_framework.generate(node, 1)693def find_vout_for_address(node, txid, addr):694"""695Locate the vout index of the given transaction sending to the696given address. Raises runtime error exception if not found.697"""698tx = node.getrawtransaction(txid, True)699for i in range(len(tx["vout"])):700if addr == tx["vout"][i]["scriptPubKey"]["address"]:701return i702raise RuntimeError("Vout not found for address: txid=%s, addr=%s" % (txid, addr))705def dumb_sync_blocks(*, src, dst, height=None):706"""Sync blocks between `src` and `dst` nodes via RPC submitblock up to height."""707height = height or src.getblockcount()708for i in range(dst.getblockcount() + 1, height + 1):709block_hash = src.getblockhash(i)710# Use boolean verbosity for v0.14.x compatibility.711block = src.getblock(blockhash=block_hash, verbose=False)712dst.submitblock(block)713assert_equal(dst.getblockcount(), height)716def sync_txindex(test_framework, node):717test_framework.log.debug("Waiting for node txindex to sync")718sync_start = int(time.time())719test_framework.wait_until(lambda: node.getindexinfo("txindex")["txindex"]["synced"])720test_framework.log.debug(f"Synced in {time.time() - sync_start} seconds")722def wallet_importprivkey(wallet_rpc, privkey, timestamp, *, label=""):723desc = descsum_create("combo(" + privkey + ")")724req = [{725"desc": desc,726"timestamp": timestamp,727"label": label,728}]729import_res = wallet_rpc.importdescriptors(req)730assert_equal(import_res[0]["success"], True)732def is_dir_writable(dir_path: pathlib.Path) -> bool:733"""Return True if we can create a file in the directory, False otherwise"""734try:735tmp = dir_path / f".tmp_{random.randrange(1 << 32)}"736tmp.touch()737tmp.unlink()738return True739except OSError:740return False742def bitflipper(input):743assert isinstance(input, bytes)744return (int.from_bytes(input, "little") ^ (1 << random.randrange(len(input) * 8))).to_bytes(len(input), "little")
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.