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.
752- [ThreadMessageHandler (`b-msghand`)](https://doxygen.bitcoincore.org/class_c_connman.html#msghand)753: Application level message handling (sending and receiving). Almost754all net_processing and validation logic runs on this thread.756- [ThreadDNSAddressSeed (`b-dnsseed`)](https://doxygen.bitcoincore.org/class_c_connman.html#dnsseed)757: Loads addresses of peers from the DNS.759- [ThreadMapPort (`b-mapport`)](https://doxygen.bitcoincore.org/mapport_8cpp.html#mapport)760: Universal plug-and-play startup/shutdown.762- [ThreadSocketHandler (`b-net`)](https://doxygen.bitcoincore.org/class_c_connman.html#net)763: Sends/Receives data from peers on port 8333.765- [ThreadOpenAddedConnections (`b-addcon`)](https://doxygen.bitcoincore.org/class_c_connman.html#addcon)766: Opens network connections to added nodes.768- [ThreadOpenConnections (`b-opencon`)](https://doxygen.bitcoincore.org/class_c_connman.html#opencon)769: Initiates new connections to peers.771- [ThreadI2PAcceptIncoming (`b-i2paccept`)](https://doxygen.bitcoincore.org/class_c_connman.html#i2paccept)772: Listens for and accepts incoming I2P connections through the I2P SAM proxy.774## General Bitcoin Core776- New features should be exposed on RPC first, then can be made available in the GUI.778- *Rationale*: RPC allows for better automatic testing. The test suite for779the GUI is very limited.781## Logging783The macros `LogInfo`, `LogDebug`, `LogTrace`, `LogWarning` and `LogError` are available for784logging messages. They should be used as follows:786- `LogDebug(BCLog::CATEGORY, fmt, params...)` is what you want787most of the time, and it should be used for log messages that are788useful for debugging and can reasonably be enabled on a production789system (that has sufficient free storage space). They will be logged790if the program is started with `-debug=category` or `-debug=1`, or791the category is enabled through the `logging` RPC.793- `LogInfo(fmt, params...)` should only be used rarely, e.g. for startup794messages or for infrequent and important events such as a new block tip795being found or a new outbound connection being made.797- `LogError(fmt, params...)` should be used in place of `LogInfo` for798severe problems that require the node (or a subsystem) to shut down799entirely (e.g., insufficient storage space).801- `LogWarning(fmt, params...)` should be used in place of `LogInfo` for802severe problems that the node admin should address, but are not803severe enough to warrant shutting down the node (e.g., system time804appears to be wrong, unknown soft fork appears to have activated).806- `LogTrace(BCLog::CATEGORY, fmt, params...)` should be used in place of807`LogDebug` for log messages that would be unusable on a production808system, e.g. due to being too noisy in normal use, or too resource809intensive to process. These will be logged if the startup810options `-debug=category -loglevel=category:trace` or `-debug=1811-loglevel=trace` are selected.813Note that the format strings and parameters of `LogDebug` and `LogTrace`814are only evaluated if the logging category is enabled, so you must be815careful to avoid side-effects in those expressions.817While `LogInfo`, `LogWarning` and `LogError` messages should be rare,818in case there are circumstances where they are not, those messages819are automatically rate-limited to prevent potential disk-filling820attacks. For the cases where this protection is undesirable,821rate-limiting can be avoided with the `util::log::NO_RATE_LIMIT` tag, eg822`LogInfo(util::log::NO_RATE_LIMIT, "UpdateTip: new best=%s ...",...)`.824## General C++826For general C++ guidelines, you may refer to the [C++ Core827Guidelines](https://isocpp.github.io/CppCoreGuidelines/).829Common misconceptions are clarified in those sections:831- Passing (non-)fundamental types in the [C++ Core832Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rf-conventional).834- If you use the `.h`, you must link the `.cpp`.836- *Rationale*: Include files define the interface for the code in implementation files. Including one but837not linking the other is confusing. Please avoid that. Moving functions from838the `.h` to the `.cpp` should not result in build errors.840- Use the RAII (Resource Acquisition Is Initialization) paradigm where possible. For example, by using841`unique_ptr` for allocations in a function.843- *Rationale*: This avoids memory and resource leaks, and ensures exception safety.845## C++ data structures847- Never use the `std::map []` syntax when reading from a map, but instead use `.find()`.849- *Rationale*: `[]` does an insert (of the default element) if the item doesn't850exist in the map yet. This has resulted in memory leaks in the past, as well as851race conditions (expecting read-read behavior). Using `[]` is fine for *writing* to a map.853- Do not compare an iterator from one data structure with an iterator of854another data structure (even if of the same type).856- *Rationale*: Behavior is undefined. In C++ parlance this means "may reformat857the universe", in practice this has resulted in at least one hard-to-debug crash bug.859- Watch out for out-of-bounds vector access. `&vch[vch.size()]` is illegal,860including `&vch[0]` for an empty vector. Use `vch.data()` and `vch.data() +861vch.size()` instead.863- Vector bounds checking is only enabled in debug mode. Do not rely on it.865- Initialize all non-static class members where they are defined.866If this is skipped for a good reason (i.e., optimization on the critical867path), add an explicit comment about this.869- *Rationale*: Ensure determinism by avoiding accidental use of uninitialized870values. Also, static analyzers balk about this.871Initializing the members in the declaration makes it easy to872spot uninitialized ones.874```cpp875class A876{877uint32_t m_count{0};878}879```881- By default, declare constructors `explicit`.883- *Rationale*: This is a precaution to avoid unintended884[conversions](https://en.cppreference.com/w/cpp/language/converting_constructor).886- Use explicitly signed or unsigned `char`s, or even better `uint8_t` and887`int8_t`. Do not use bare `char` unless it is to pass to a third-party API.888This type can be signed or unsigned depending on the architecture, which can889lead to interoperability problems or dangerous conditions such as890out-of-bounds array accesses.892- Prefer explicit constructions over implicit ones that rely on 'magical' C++ behavior.894- *Rationale*: Easier to understand what is happening, thus easier to spot mistakes, even for those895that are not language lawyers.897- Use `std::span` as function argument when it can operate on any range-like container.899- *Rationale*: Compared to `Foo(const vector<int>&)` this avoids the need for a (potentially expensive)900conversion to vector if the caller happens to have the input stored in another type of container.901However, be aware of the pitfalls documented in [span.h](../src/span.h).903```cpp904void Foo(std::span<const int> data);906std::vector<int> vec{1,2,3};907Foo(vec);908```910- Prefer `enum class` (scoped enumerations) over `enum` (traditional enumerations) where possible.912- *Rationale*: Scoped enumerations avoid two potential pitfalls/problems with traditional C++ enumerations: implicit conversions to `int`, and name clashes due to enumerators being exported to the surrounding scope.914- `switch` statement on an enumeration example:916```cpp917enum class Tabs {918info,919console,920};922int GetInt(Tabs tab)923{924int ret = [&]() {925switch (tab) {926case Tabs::info: return 0;927case Tabs::console: return 1;928} // no default case, so the compiler can warn about missing cases929assert(false);930}();931LogInfo("Tab %s", ret);932return ret;933}934```936*Rationale*: The comment documents skipping `default:` label, and it complies with `clang-format` rules. The assertion prevents firing of `-Wreturn-type` warning on some compilers.938## Strings and formatting940- Use `std::string`, avoid C string manipulation functions.942- *Rationale*: C++ string handling is marginally safer, less scope for943buffer overflows, and surprises with `\0` characters. Also, some C string manipulations944tend to act differently depending on platform, or even the user locale.946- For `strprintf`, `LogInfo`, `LogDebug`, etc formatting characters don't need size specifiers (hh, h, l, ll, j, z, t, L) for arithmetic types.948- *Rationale*: Bitcoin Core uses tinyformat, which is type safe. Leave them out to avoid confusion.950- Use `.c_str()` sparingly. Its only valid use is to pass C++ strings to C functions that take NULL-terminated951strings.953- Do not use it when passing a sized array (so along with `.size()`). Use `.data()` instead to get a pointer954to the raw data.956- *Rationale*: Although this is guaranteed to be safe starting with C++11, `.data()` communicates the intent better.958- Do not use it when passing strings to `tfm::format`, `strprintf`, `LogInfo`, `LogDebug`, etc.960- *Rationale*: This is redundant. Tinyformat handles strings.962- Do not use it to convert to `QString`. Use `QString::fromStdString()`.964- *Rationale*: Qt has built-in functionality for converting their string965type from/to C++. No need to roll your own.967- In cases where you do call `.c_str()`, you might want to additionally check that the string does not contain embedded '\0' characters, because968it will (necessarily) truncate the string. This might be used to hide parts of the string from logging or to circumvent969checks. If a use of strings is sensitive to this, take care to check the string for embedded NULL characters first970and reject it if there are any.972## Shadowing974Although the shadowing warning (`-Wshadow`) is not enabled by default (it prevents issues arising975from using a different variable with the same name),976please name variables so that their names do not shadow variables defined in the source code.978When using nested cycles, do not name the inner cycle variable the same as in979the outer cycle, etc.981## Lifetimebound983The [Clang `lifetimebound`984attribute](https://clang.llvm.org/docs/AttributeReference.html#lifetimebound)985can be used to tell the compiler that a lifetime is bound to an object and986potentially see a compile-time warning if the object has a shorter lifetime from987the invalid use of a temporary. You can use the attribute by adding a `LIFETIMEBOUND`988annotation defined in `src/attributes.h`; please grep the codebase for examples.990## Threads and synchronization992- Prefer `Mutex` type to `RecursiveMutex` one.994- Consistently use [Clang Thread Safety Analysis](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html) annotations to995get compile-time warnings about potential race conditions or deadlocks in code.997- In functions that are declared separately from where they are defined, the998thread safety annotations should be added exclusively to the function999declaration. Annotations on the definition could lead to false positives1000(lack of compile failure) at call sites between the two.
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.