Changeset View
Changeset View
Standalone View
Standalone View
doc/developer-notes.md
Developer Notes | Developer Notes | ||||
=============== | =============== | ||||
<!-- markdown-toc start --> | |||||
**Table of Contents** | |||||
- [Developer Notes](#developer-notes) | |||||
- [Coding Style](#coding-style) | |||||
- [Doxygen comments](#doxygen-comments) | |||||
- [Development tips and tricks](#development-tips-and-tricks) | |||||
- [Compiling for debugging](#compiling-for-debugging) | |||||
- [Compiling for gprof profiling](#compiling-for-gprof-profiling) | |||||
- [debug.log](#debuglog) | |||||
- [Writing tests](#writing-tests) | |||||
- [Writing script integration tests](#writing-script-integration-tests) | |||||
- [Testnet and Regtest modes](#testnet-and-regtest-modes) | |||||
- [DEBUG_LOCKORDER](#debug_lockorder) | |||||
- [Valgrind suppressions file](#valgrind-suppressions-file) | |||||
- [Compiling for test coverage](#compiling-for-test-coverage) | |||||
- [Sanitizers](#sanitizers) | |||||
- [Locking/mutex usage notes](#lockingmutex-usage-notes) | |||||
- [Threads](#threads) | |||||
- [Ignoring IDE/editor files](#ignoring-ideeditor-files) | |||||
- [Development guidelines](#development-guidelines) | |||||
- [Wallet](#wallet) | |||||
- [General C++](#general-c) | |||||
- [C++ data structures](#c-data-structures) | |||||
- [Strings and formatting](#strings-and-formatting) | |||||
- [Variable names](#variable-names) | |||||
- [Threads and synchronization](#threads-and-synchronization) | |||||
- [Source code organization](#source-code-organization) | |||||
- [GUI](#gui) | |||||
- [Unit tests](#unit-tests) | |||||
- [Subtrees](#subtrees) | |||||
- [Git and GitHub tips](#git-and-github-tips) | |||||
- [RPC interface guidelines](#rpc-interface-guidelines) | |||||
<!-- markdown-toc end --> | |||||
Coding Style | |||||
--------------- | |||||
Various coding styles have been used during the history of the codebase, | Various coding styles have been used during the history of the codebase, | ||||
and the result is not very consistent. However, we're now trying to converge to | and the result is not very consistent. However, we're now trying to converge to | ||||
a single style, so please use it in new code. Old code will be converted | a single style, so please use it in new code. Old code will be converted | ||||
gradually and you are encouraged to use the provided | gradually and you are encouraged to use the provided | ||||
[clang-format-diff script](/contrib/devtools/README.md#clang-format-diffpy) | [clang-format-diff script](/contrib/devtools/README.md#clang-format-diffpy) | ||||
to clean up the patch automatically before submitting a pull request. | to clean up the patch automatically before submitting a pull request. | ||||
- Basic rules specified in [src/.clang-format](/src/.clang-format). | - Basic rules specified in [src/.clang-format](/src/.clang-format). | ||||
▲ Show 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | |||||
# In the build directory, call: | # In the build directory, call: | ||||
doxygen doc/Doxyfile | doxygen doc/Doxyfile | ||||
# output goes to doc/doxygen/html/ | # output goes to doc/doxygen/html/ | ||||
``` | ``` | ||||
Development tips and tricks | Development tips and tricks | ||||
--------------------------- | --------------------------- | ||||
**compiling for debugging** | ### Compiling for debugging | ||||
Run configure with `--enable-debug` to add additional compiler flags that | |||||
produce better debugging builds. | |||||
### Compiling for gprof profiling | |||||
Run configure with the --enable-debug option, then make. Or run configure with | Run configure with the `--enable-gprof` option, then make. | ||||
CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need. | |||||
**debug.log** | ### debug.log | ||||
If the code is behaving strangely, take a look in the debug.log file in the data directory; | If the code is behaving strangely, take a look in the debug.log file in the data directory; | ||||
error and debugging messages are written there. | error and debugging messages are written there. | ||||
The -debug=... command-line option controls debugging; running with just -debug or -debug=1 will turn | The `-debug=...` command-line option controls debugging; running with just `-debug` or `-debug=1` will turn | ||||
on all categories (and give you a very large debug.log file). | on all categories (and give you a very large debug.log file). | ||||
The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt | The Qt code routes `qDebug()` output to debug.log under category "qt": run with `-debug=qt` | ||||
to see it. | to see it. | ||||
**writing tests** | ### Writing tests | ||||
For details on unit tests, see `unit-tests.md` | For details on unit tests, see `unit-tests.md` | ||||
For details on functional tests, see `functional-tests.md` | For details on functional tests, see `functional-tests.md` | ||||
**writing script integration tests** | ### Writing script integration tests | ||||
Script integration tests are built using `src/test/script_tests.cpp`: | Script integration tests are built using `src/test/script_tests.cpp`: | ||||
1. Uncomment the line with `#define UPDATE_JSON_TESTS` | 1. Uncomment the line with `#define UPDATE_JSON_TESTS` | ||||
2. Add a new TestBuilder to the `script_build` test to cover your test case. | 2. Add a new TestBuilder to the `script_build` test to cover your test case. | ||||
3. `make && ./src/test/test_bitcoin --run_test=script_tests` | 3. `make && ./src/test/test_bitcoin --run_test=script_tests` | ||||
4. Copy your newly generated test JSON from `<build-dir>/src/script_tests.json.gen` to `src/test/data/script_tests.json`. | 4. Copy your newly generated test JSON from `<build-dir>/src/script_tests.json.gen` to `src/test/data/script_tests.json`. | ||||
Please commit your TestBuilder along with your generated test JSON and cleanup the uncommented #define before code review. | Please commit your TestBuilder along with your generated test JSON and cleanup the uncommented #define before code review. | ||||
**testnet and regtest modes** | ### Testnet and Regtest modes | ||||
Run with the -testnet option to run with "play bitcoins" on the test network, if you | Run with the `-testnet` option to run with "play bitcoins" on the test network, if you | ||||
are testing multi-machine code that needs to operate across the internet. | are testing multi-machine code that needs to operate across the internet. | ||||
If you are testing something that can run on one machine, run with the -regtest option. | If you are testing something that can run on one machine, run with the `-regtest` option. | ||||
In regression test mode, blocks can be created on-demand; see test/functional/ for tests | In regression test mode, blocks can be created on-demand; see [test/functional/](/test/functional) for tests | ||||
that run in -regtest mode. | that run in `-regtest` mode. | ||||
**DEBUG_LOCKORDER** | ### DEBUG_LOCKORDER | ||||
Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs | Bitcoin ABC is a multi-threaded application, and deadlocks or other | ||||
can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure | multi-threading bugs can be very difficult to track down. The `--enable-debug` | ||||
CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks | configure option adds `-DDEBUG_LOCKORDER` to the compiler flags. This inserts | ||||
are held, and adds warnings to the debug.log file if inconsistencies are detected. | run-time checks to keep track of which locks are held, and adds warnings to the | ||||
debug.log file if inconsistencies are detected. | |||||
**Valgrind suppressions file** | ### Valgrind suppressions file | ||||
Valgrind is a programming tool for memory debugging, memory leak detection, and | Valgrind is a programming tool for memory debugging, memory leak detection, and | ||||
profiling. The repo contains a Valgrind suppressions file | profiling. The repo contains a Valgrind suppressions file | ||||
([`valgrind.supp`](contrib/valgrind.supp)) | ([`valgrind.supp`](contrib/valgrind.supp)) | ||||
which includes known Valgrind warnings in our dependencies that cannot be fixed | which includes known Valgrind warnings in our dependencies that cannot be fixed | ||||
in-tree. Example use: | in-tree. Example use: | ||||
```shell | ```shell | ||||
$ valgrind --suppressions=contrib/valgrind.supp src/test/test_bitcoin | $ valgrind --suppressions=contrib/valgrind.supp src/test/test_bitcoin | ||||
$ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ | $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ | ||||
--show-leak-kinds=all src/test/test_bitcoin --log_level=test_suite | --show-leak-kinds=all src/test/test_bitcoin --log_level=test_suite | ||||
$ valgrind -v --leak-check=full src/bitcoind -printtoconsole | $ valgrind -v --leak-check=full src/bitcoind -printtoconsole | ||||
``` | ``` | ||||
**compiling for test coverage** | ### Compiling for test coverage | ||||
LCOV can be used to generate a test coverage report based upon `make check` | LCOV can be used to generate a test coverage report based upon `make check` | ||||
execution. LCOV must be installed on your system (e.g. the `lcov` package | execution. LCOV must be installed on your system (e.g. the `lcov` package | ||||
on Debian/Ubuntu). | on Debian/Ubuntu). | ||||
To enable LCOV report generation during test runs: | To enable LCOV report generation during test runs: | ||||
```shell | ```shell | ||||
./configure --enable-lcov | ./configure --enable-lcov | ||||
make | make | ||||
make cov | make cov | ||||
# A coverage report will now be accessible at `./test_bitcoin.coverage/index.html`. | # A coverage report will now be accessible at `./test_bitcoin.coverage/index.html`. | ||||
``` | ``` | ||||
**Sanitizers** | ### Sanitizers | ||||
Bitcoin ABC can be compiled with various "sanitizers" enabled, which add | Bitcoin ABC can be compiled with various "sanitizers" enabled, which add | ||||
instrumentation for issues regarding things like memory safety, thread race | instrumentation for issues regarding things like memory safety, thread race | ||||
conditions, or undefined behavior. This is controlled with the | conditions, or undefined behavior. This is controlled with the | ||||
`--with-sanitizers` configure flag, which should be a comma separated list of | `--with-sanitizers` configure flag, which should be a comma separated list of | ||||
sanitizers to enable. The sanitizer list should correspond to supported | sanitizers to enable. The sanitizer list should correspond to supported | ||||
`-fsanitize=` options in your compiler. These sanitizers have runtime overhead, | `-fsanitize=` options in your compiler. These sanitizers have runtime overhead, | ||||
so they are most useful when testing changes or producing debugging builds. | so they are most useful when testing changes or producing debugging builds. | ||||
Show All 38 Lines | |||||
* [GCC Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html) | * [GCC Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html) | ||||
* [Google Sanitizers Wiki](https://github.com/google/sanitizers/wiki) | * [Google Sanitizers Wiki](https://github.com/google/sanitizers/wiki) | ||||
* [Issue #12691: Enable -fsanitize flags in Travis](https://github.com/bitcoin/bitcoin/issues/12691) | * [Issue #12691: Enable -fsanitize flags in Travis](https://github.com/bitcoin/bitcoin/issues/12691) | ||||
Locking/mutex usage notes | Locking/mutex usage notes | ||||
------------------------- | ------------------------- | ||||
The code is multi-threaded, and uses mutexes and the | The code is multi-threaded, and uses mutexes and the | ||||
LOCK/TRY_LOCK macros to protect data structures. | `LOCK` and `TRY_LOCK` macros to protect data structures. | ||||
Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main | Deadlocks due to inconsistent lock ordering (thread 1 locks `cs_main` and then | ||||
and then cs_wallet, while thread 2 locks them in the opposite order: | `cs_wallet`, while thread 2 locks them in the opposite order: result, deadlock | ||||
result, deadlock as each waits for the other to release its lock) are | as each waits for the other to release its lock) are a problem. Compile with | ||||
a problem. Compile with -DDEBUG_LOCKORDER to get lock order | `-DDEBUG_LOCKORDER` (or use `--enable-debug`) to get lock order inconsistencies | ||||
inconsistencies reported in the debug.log file. | reported in the debug.log file. | ||||
Re-architecting the core code so there are better-defined interfaces | Re-architecting the core code so there are better-defined interfaces | ||||
between the various components is a goal, with any necessary locking | between the various components is a goal, with any necessary locking | ||||
done by the components (e.g. see the self-contained CBasicKeyStore class | done by the components (e.g. see the self-contained `CBasicKeyStore` class | ||||
and its cs_KeyStore lock for example). | and its `cs_KeyStore` lock for example). | ||||
Threads | Threads | ||||
------- | ------- | ||||
- ThreadScriptCheck : Verifies block scripts. | - ThreadScriptCheck : Verifies block scripts. | ||||
- ThreadImport : Loads blocks from blk*.dat files or bootstrap.dat. | - ThreadImport : Loads blocks from blk*.dat files or bootstrap.dat. | ||||
▲ Show 20 Lines • Show All 475 Lines • Show Last 20 Lines |