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 <randomenv.h>10#include <clientversion.h>11#include <compat/compat.h>12#include <compat/cpuid.h>13#include <crypto/sha512.h>14#include <span.h>15#include <support/cleanse.h>16#include <util/byte_units.h>17#include <util/time.h>19#include <algorithm>20#include <atomic>21#include <cstdint>22#include <cstring>23#include <chrono>24#include <climits>25#include <thread>26#include <vector>28#include <sys/types.h> // must go before a number of other headers30#ifdef WIN3231#include <windows.h>32#else33#include <fcntl.h>34#include <netinet/in.h>35#include <sys/resource.h>36#include <sys/socket.h>37#include <sys/stat.h>38#include <sys/time.h>39#include <sys/utsname.h>40#include <unistd.h>41#endif42#ifdef HAVE_IFADDRS43#include <ifaddrs.h>44#endif45#ifdef HAVE_SYSCTL46#include <sys/sysctl.h>47#if __has_include(<vm/vm_param.h>)48#include <vm/vm_param.h>49#endif50#if __has_include(<sys/resources.h>)51#include <sys/resources.h>52#endif53#if __has_include(<sys/vmmeter.h>)54#include <sys/vmmeter.h>55#endif56#endif57#if defined(HAVE_STRONG_GETAUXVAL)58#include <sys/auxv.h>59#endif61#if defined(__APPLE__) || \62defined(__FreeBSD__) || \63defined(__NetBSD__) || \64defined(__OpenBSD__) || \65defined(__illumos__)66extern char** environ; // Necessary on the above platforms67#endif69namespace {71/** Helper to easily feed data into a CSHA512.72*73* Note that this does not serialize the passed object (like stream.h's << operators do).74* Its raw memory representation is used directly.75*/76template<typename T>77CSHA512& operator<<(CSHA512& hasher, const T& data) {78static_assert(!std::is_same_v<std::decay_t<T>, char*>, "Calling operator<<(CSHA512, char*) is probably not what you want");79static_assert(!std::is_same_v<std::decay_t<T>, unsigned char*>, "Calling operator<<(CSHA512, unsigned char*) is probably not what you want");80static_assert(!std::is_same_v<std::decay_t<T>, const char*>, "Calling operator<<(CSHA512, const char*) is probably not what you want");81static_assert(!std::is_same_v<std::decay_t<T>, const unsigned char*>, "Calling operator<<(CSHA512, const unsigned char*) is probably not what you want");82hasher.Write((const unsigned char*)&data, sizeof(data));83return hasher;84}86#ifndef WIN3287void AddSockaddr(CSHA512& hasher, const struct sockaddr *addr)88{89if (addr == nullptr) return;90switch (addr->sa_family) {91case AF_INET:92hasher.Write((const unsigned char*)addr, sizeof(sockaddr_in));93break;94case AF_INET6:95hasher.Write((const unsigned char*)addr, sizeof(sockaddr_in6));96break;97default:98hasher.Write((const unsigned char*)&addr->sa_family, sizeof(addr->sa_family));99}100}102void AddFile(CSHA512& hasher, const char *path)103{104struct stat sb = {};105int f = open(path, O_RDONLY);106size_t total = 0;107if (f != -1) {108unsigned char fbuf[4096];109int n;110hasher.Write((const unsigned char*)&f, sizeof(f));111if (fstat(f, &sb) == 0) hasher << sb;112do {113n = read(f, fbuf, sizeof(fbuf));114if (n > 0) hasher.Write(fbuf, n);115total += n;116/* not bothering with EINTR handling. */117} while (n == sizeof(fbuf) && total < 1_MiB); // Read only the first 1 Mbyte118close(f);119}120}122void AddPath(CSHA512& hasher, const char *path)123{124struct stat sb = {};125if (stat(path, &sb) == 0) {126hasher.Write((const unsigned char*)path, strlen(path) + 1);127hasher << sb;128}129}130#endif132#ifdef HAVE_SYSCTL133template<int... S>134void AddSysctl(CSHA512& hasher)135{136int CTL[sizeof...(S)] = {S...};137unsigned char buffer[65536];138size_t siz = 65536;139int ret = sysctl(CTL, sizeof...(S), buffer, &siz, nullptr, 0);140if (ret == 0 || (ret == -1 && errno == ENOMEM)) {141hasher << sizeof(CTL);142hasher.Write((const unsigned char*)CTL, sizeof(CTL));143if (siz > sizeof(buffer)) siz = sizeof(buffer);144hasher << siz;145hasher.Write(buffer, siz);146}147}148#endif150#ifdef HAVE_GETCPUID151void inline AddCPUID(CSHA512& hasher, uint32_t leaf, uint32_t subleaf, uint32_t& ax, uint32_t& bx, uint32_t& cx, uint32_t& dx)152{153GetCPUID(leaf, subleaf, ax, bx, cx, dx);154hasher << leaf << subleaf << ax << bx << cx << dx;155}157void AddAllCPUID(CSHA512& hasher)158{159uint32_t ax, bx, cx, dx;160// Iterate over all standard leaves161AddCPUID(hasher, 0, 0, ax, bx, cx, dx); // Returns max leaf in ax162uint32_t max = ax;163for (uint32_t leaf = 1; leaf <= max && leaf <= 0xFF; ++leaf) {164uint32_t maxsub = 0;165for (uint32_t subleaf = 0; subleaf <= 0xFF; ++subleaf) {166AddCPUID(hasher, leaf, subleaf, ax, bx, cx, dx);167// Iterate subleafs for leaf values 4, 7, 11, 13168if (leaf == 4) {169if ((ax & 0x1f) == 0) break;170} else if (leaf == 7) {171if (subleaf == 0) maxsub = ax;172if (subleaf == maxsub) break;173} else if (leaf == 11) {174if ((cx & 0xff00) == 0) break;175} else if (leaf == 13) {176if (ax == 0 && bx == 0 && cx == 0 && dx == 0) break;177} else {178// For any other leaf, stop after subleaf 0.179break;180}181}182}183// Iterate over all extended leaves184AddCPUID(hasher, 0x80000000, 0, ax, bx, cx, dx); // Returns max extended leaf in ax185uint32_t ext_max = ax;186for (uint32_t leaf = 0x80000001; leaf <= ext_max && leaf <= 0x800000FF; ++leaf) {187AddCPUID(hasher, leaf, 0, ax, bx, cx, dx);188}189}190#endif191} // namespace193void RandAddDynamicEnv(CSHA512& hasher)194{195// Various clocks196#ifdef WIN32197FILETIME ftime;198GetSystemTimeAsFileTime(&ftime);199hasher << ftime;200#else201struct timespec ts = {};202# ifdef CLOCK_MONOTONIC203clock_gettime(CLOCK_MONOTONIC, &ts);204hasher << ts;205# endif206# ifdef CLOCK_REALTIME207clock_gettime(CLOCK_REALTIME, &ts);208hasher << ts;209# endif210# ifdef CLOCK_BOOTTIME211clock_gettime(CLOCK_BOOTTIME, &ts);212hasher << ts;213# endif214// gettimeofday is available on all UNIX systems, but only has microsecond precision.215struct timeval tv = {};216gettimeofday(&tv, nullptr);217hasher << tv;218#endif219// Probably redundant, but also use all the standard library clocks:220hasher << std::chrono::system_clock::now().time_since_epoch().count();221hasher << std::chrono::steady_clock::now().time_since_epoch().count();222hasher << std::chrono::high_resolution_clock::now().time_since_epoch().count();224#ifndef WIN32225// Current resource usage.226struct rusage usage = {};227if (getrusage(RUSAGE_SELF, &usage) == 0) hasher << usage;228#endif230#ifdef __linux__231AddFile(hasher, "/proc/diskstats");232AddFile(hasher, "/proc/vmstat");233AddFile(hasher, "/proc/schedstat");234AddFile(hasher, "/proc/zoneinfo");235AddFile(hasher, "/proc/meminfo");236AddFile(hasher, "/proc/softirqs");237AddFile(hasher, "/proc/stat");238AddFile(hasher, "/proc/self/schedstat");239AddFile(hasher, "/proc/self/status");240#endif242#ifdef HAVE_SYSCTL243# ifdef CTL_KERN244# if defined(KERN_PROC) && defined(KERN_PROC_ALL)245AddSysctl<CTL_KERN, KERN_PROC, KERN_PROC_ALL>(hasher);246# endif247# endif248# ifdef CTL_HW249# ifdef HW_DISKSTATS250AddSysctl<CTL_HW, HW_DISKSTATS>(hasher);
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.