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.
1002- Prefer locks that are in a class rather than global, and that are1003internal to a class (private or protected) rather than public.1005- Combine annotations in function declarations with run-time asserts in1006function definitions (`AssertLockNotHeld()` can be omitted if `LOCK()` is1007called unconditionally after it because `LOCK()` does the same check as1008`AssertLockNotHeld()` internally, for non-recursive mutexes):1010```C++1011// txmempool.h1012class CTxMemPool1013{1014public:1015...1016mutable RecursiveMutex cs;1017...1018void UpdateTransactionsFromBlock(...) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, cs);1019...1020}1022// txmempool.cpp1023void CTxMemPool::UpdateTransactionsFromBlock(...)1024{1025AssertLockHeld(::cs_main);1026AssertLockHeld(cs);1027...1028}1029```1031```C++1032// validation.h1033class Chainstate1034{1035protected:1036...1037Mutex m_chainstate_mutex;1038...1039public:1040...1041bool ActivateBestChain(1042BlockValidationState& state,1043std::shared_ptr<const CBlock> pblock = nullptr)1044EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex)1045LOCKS_EXCLUDED(::cs_main);1046...1047bool PreciousBlock(BlockValidationState& state, CBlockIndex* pindex)1048EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex)1049LOCKS_EXCLUDED(::cs_main);1050...1051}1053// validation.cpp1054bool Chainstate::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex)1055{1056AssertLockNotHeld(m_chainstate_mutex);1057AssertLockNotHeld(::cs_main);1058{1059LOCK(cs_main);1060...1061}1063return ActivateBestChain(state, std::shared_ptr<const CBlock>());1064}1065```1067- Build and run tests with `-DDEBUG_LOCKORDER` to verify that no potential1068deadlocks are introduced. This is defined by default when1069building with `-DCMAKE_BUILD_TYPE=Debug`.1071- When using `LOCK`/`TRY_LOCK` be aware that the lock exists in the context of1072the current scope, so surround the statement and the code that needs the lock1073with braces.1075OK:1076```c++1077{1078TRY_LOCK(cs_vNodes, lockNodes);1079...1080}1081```1083Wrong:1084```c++1085TRY_LOCK(cs_vNodes, lockNodes);1086{1087...1088}1089```1091## Scripts1093Write scripts in Python or Rust rather than bash, when possible.1095## Source code organization1097- Implementation code should go into the `.cpp` file and not the `.h`, unless necessary due to template usage or1098when performance due to inlining is critical.1100- *Rationale*: Shorter and simpler header files are easier to read and reduce compile time.1102- Every `.cpp` and `.h` file should `#include` every header file it directly uses classes, functions or other1103definitions from, even if those headers are already included indirectly through other headers.1105- *Rationale*: Excluding headers because they are already indirectly included results in compilation1106failures when those indirect dependencies change. Furthermore, it obscures what the real code1107dependencies are. The [Using IWYU](#using-iwyu) section describes a tool to help enforce this.1109- Don't import anything into the global namespace (`using namespace ...`). Use1110fully specified types such as `std::string`.1112- *Rationale*: Avoids symbol conflicts.1114- Terminate namespaces with a comment (`// namespace mynamespace`). The comment1115should be placed on the same line as the brace closing the namespace, e.g.1117```c++1118namespace mynamespace {1119...1120} // namespace mynamespace1122namespace {1123...1124} // namespace1125```1127- *Rationale*: Avoids confusion about the namespace context.1129## GUI1131- Do not display or manipulate dialogs in model code (classes `*Model`).1133- *Rationale*: Model classes pass through events and data from the core, they1134should not interact with the user. That's where View classes come in. The converse also1135holds: try to not directly access core data structures from Views.1137- Avoid adding slow or blocking code in the GUI thread. In particular, do not1138add new `interfaces::Node` and `interfaces::Wallet` method calls, even if they1139may be fast now, in case they are changed to lock or communicate across1140processes in the future.1142Prefer to offload work from the GUI thread to worker threads (see1143`RPCExecutor` in console code as an example) or take other steps (see1144https://doc.qt.io/archives/qq/qq27-responsive-guis.html) to keep the GUI1145responsive.1147- *Rationale*: Blocking the GUI thread can increase latency, and lead to1148hangs and deadlocks.1150## Subtrees1152Several parts of the repository are subtrees of software maintained elsewhere.1154Normally, these are maintained by active developers of Bitcoin Core, in which case1155changes should go directly upstream without being PRed directly against the project.1156They will be merged back in the next subtree merge.1158Others are external projects without a tight relationship with our project. Changes1159to these should also be sent upstream, but bugfixes may also be prudent to PR against1160a Bitcoin Core subtree, so that they can be integrated quickly. Cosmetic changes1161should be taken upstream.1163There is a tool in `test/lint/git-subtree-check.sh` ([instructions](../test/lint#git-subtree-checksh))1164to check a subtree directory for consistency with its upstream repository.1166The tool instructions also include a list of the subtrees managed by Bitcoin Core.1168To fully verify or update a subtree, add it as a remote:1170```sh1171git remote add libmultiprocess https://github.com/bitcoin-core/libmultiprocess.git1172```1174To update the subtree:1176```sh1177git fetch libmultiprocess1178git subtree pull --prefix=src/ipc/libmultiprocess libmultiprocess master --squash1179```1181The ultimate upstream of the few externally managed subtrees are:1183- src/leveldb1184- Upstream at https://github.com/google/leveldb ; maintained by Google. Open1185important PRs to the Bitcoin Core subtree to avoid delay.1186- **Note**: Follow the instructions in [Upgrading LevelDB](#upgrading-leveldb) when1187merging upstream changes to the LevelDB subtree.1189- src/crc32c1190- Used by leveldb for hardware acceleration of CRC32C checksums for data integrity.1191- Upstream at https://github.com/google/crc32c ; maintained by Google.1193## Upgrading LevelDB1195Extra care must be taken when upgrading LevelDB. This section explains issues1196you must be aware of.1198### File Descriptor Counts1200In most configurations, we use the default LevelDB value for `max_open_files`,1201which is 1000 at the time of this writing. If LevelDB actually uses this many1202file descriptors, it will cause problems with Bitcoin's `select()` loop, because1203it may cause new sockets to be created where the fd value is >= 1024. For this1204reason, on 64-bit Unix systems, we rely on an internal LevelDB optimization that1205uses `mmap()` + `close()` to open table files without actually retaining1206references to the table file descriptors. If you are upgrading LevelDB, you must1207sanity check the changes to make sure that this assumption remains valid.1209In addition to reviewing the upstream changes in `env_posix.cc`, you can use `lsof` to1210check this. For example, on Linux this command will show open `.ldb` file counts:1212```bash1213$ lsof -p $(pidof bitcoind) |\1214awk 'BEGIN { fd=0; mem=0; } /ldb$/ { if ($4 == "mem") mem++; else fd++ } END { printf "mem = %s, fd = %s\n", mem, fd}'1215mem = 119, fd = 01216```1218The `mem` value shows how many files are mmap'ed, and the `fd` value shows how1219many file descriptors these files are using. You should check that `fd` is a1220small number (usually 0 on 64-bit hosts).1222See the notes in the `SetMaxOpenFiles()` function in `dbwrapper.cc` for more1223details.1225### Consensus Compatibility1227It is possible for LevelDB changes to inadvertently change consensus1228compatibility between nodes. This happened in Bitcoin 0.8 (when LevelDB was1229first introduced). When upgrading LevelDB, you should review the upstream changes1230to check for issues affecting consensus compatibility.1232For example, if LevelDB had a bug that accidentally prevented a key from being1233returned in an edge case, and that bug was fixed upstream, the bug "fix" would1234be an incompatible consensus change. In this situation, the correct behavior1235would be to revert the upstream fix before applying the updates to Bitcoin's1236copy of LevelDB. In general, you should be wary of any upstream changes affecting1237what data is returned from LevelDB queries.1239## Scripted diffs1241For reformatting and refactoring commits where the changes can be easily automated using a bash script, we use1242scripted-diff commits. The bash script is included in the commit message and our CI job checks that1243the result of the script is identical to the commit. This aids reviewers since they can verify that the script1244does exactly what it is supposed to do. It is also helpful for rebasing (since the same script can just be re-run1245on the new master commit).1247To create a scripted-diff:1249- start the commit message with `scripted-diff:` (and then a description of the diff on the same line)1250- in the commit message include the bash script between lines containing just the following text:
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.