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.
2514. The position of the change output as an `int32`253#### Tracepoint `coin_selection:attempting_aps_create_tx`255Is called when `CreateTransactionInternal` is called the second time for the optimistic256Avoid Partial Spends selection attempt. This is used to determine whether the next257tracepoints called are for the Avoid Partial Spends solution, or a different transaction.259Arguments passed:2601. Wallet name as `pointer to C-style string`262#### Tracepoint `coin_selection:aps_create_tx_internal`264Is called when the second `CreateTransactionInternal` with Avoid Partial Spends enabled completes.266Arguments passed:2671. Wallet name as `pointer to C-style string`2682. Whether the Avoid Partial Spends solution will be used as `bool`2693. Whether `CreateTransactionInternal` succeeded as` bool`2704. The expected transaction fee as an `int64`2715. The position of the change output as an `int32`273### Context `mempool`275#### Tracepoint `mempool:added`277Is called when a transaction is added to the node's mempool. Passes information278about the transaction.280Arguments passed:2811. Transaction ID (hash) as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)2822. Transaction virtual size as `int32`2833. Transaction fee as `int64`285#### Tracepoint `mempool:removed`287Is called when a transaction is removed from the node's mempool. Passes information288about the transaction.290Arguments passed:2911. Transaction ID (hash) as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)2922. Removal reason as `pointer to C-style String` (max. length 9 characters)2933. Transaction virtual size as `int32`2944. Transaction fee as `int64`2955. Transaction mempool entry time (epoch) as `uint64`297#### Tracepoint `mempool:replaced`299Is called when a transaction in the node's mempool is getting replaced by another.300Passes information about the replaced and replacement transactions.302Arguments passed:3031. Replaced transaction ID (hash) as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)3042. Replaced transaction virtual size as `int32`3053. Replaced transaction fee as `int64`3064. Replaced transaction mempool entry time (epoch) as `uint64`3075. Replacement transaction ID or package hash as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)3086. Replacement transaction virtual size as `int32`3097. Replacement transaction fee as `int64`3108. `bool` indicating if the argument 5. is a transaction ID or package hash (true if it's a transaction ID)312Note: In cases where a replacement transaction or package replaces multiple313existing transactions in the mempool, the tracepoint is called once for each314replaced transaction, with data of the replacement transaction or package315being the same in each call.317#### Tracepoint `mempool:rejected`319Is called when a transaction is not permitted to enter the mempool. Passes320information about the rejected transaction.322Arguments passed:3231. Transaction ID (hash) as `pointer to unsigned chars` (i.e. 32 bytes in little-endian)3242. Reject reason as `pointer to C-style String` (max. length 118 characters)326## Adding tracepoints to Bitcoin Core328Use the `TRACEPOINT` macro to add a new tracepoint. If not yet included, include329`util/trace.h` (defines the tracepoint macros) with `#include <util/trace.h>`.330Each tracepoint needs a `context` and an `event`. Please use `snake_case` and331try to make sure that the tracepoint names make sense even without detailed332knowledge of the implementation details. You can pass zero to twelve arguments333to the tracepoint. Each tracepoint also needs a global semaphore. The semaphore334gates the tracepoint arguments from being processed if we are not attached to335the tracepoint. Add a `TRACEPOINT_SEMAPHORE(context, event)` with the `context`336and `event` of your tracepoint in the top-level namespace at the beginning of337the file. Do not forget to update the tracepoint list in this document.339For example, the `net:outbound_message` tracepoint in `src/net.cpp` with six340arguments.342```C++343// src/net.cpp344TRACEPOINT_SEMAPHORE(net, outbound_message);345…346void CConnman::PushMessage(…) {347…348TRACEPOINT(net, outbound_message,349pnode->GetId(),350pnode->m_addr_name.c_str(),351pnode->ConnectionTypeAsString().c_str(),352sanitizedType.c_str(),353msg.data.size(),354msg.data.data()355);356…357}358```359If needed, an extra `if (TRACEPOINT_ACTIVE(context, event)) {...}` check can be360used to prepare somewhat expensive arguments right before the tracepoint. While361the tracepoint arguments are only prepared when we attach something to the362tracepoint, an argument preparation should never hang the process. Hashing and363serialization of data structures is probably fine, a `sleep(10s)` not.365```C++366// An example tracepoint with an expensive argument.368TRACEPOINT_SEMAPHORE(example, gated_expensive_argument);369…370if (TRACEPOINT_ACTIVE(example, gated_expensive_argument)) {371expensive_argument = expensive_calculation();372TRACEPOINT(example, gated_expensive_argument, expensive_argument);373}374```376### Guidelines and best practices378#### Clear motivation and use case379Tracepoints need a clear motivation and use case. The motivation should380outweigh the impact on, for example, code readability. There is no point in381adding tracepoints that don't end up being used.383#### Provide an example384When adding a new tracepoint, provide an example. Examples can show the use case385and help reviewers testing that the tracepoint works as intended. The examples386can be kept simple but should give others a starting point when working with387the tracepoint. See existing examples in [contrib/tracing/].389[contrib/tracing/]: ../contrib/tracing/391#### Semi-stable API392Tracepoints should have a semi-stable API. Users should be able to rely on the393tracepoints for scripting. This means tracepoints need to be documented, and the394argument order ideally should not change. If there is an important reason to395change argument order, make sure to document the change and update the examples396using the tracepoint.398#### eBPF Virtual Machine limits399Keep the eBPF Virtual Machine limits in mind. eBPF programs receiving data from400the tracepoints run in a sandboxed Linux kernel VM. This VM has a limited stack401size of 512 bytes. Check if it makes sense to pass larger amounts of data, for402example, with a tracing script that can handle the passed data.404#### `bpftrace` argument limit405While tracepoints can have up to 12 arguments, bpftrace scripts currently only406support reading from the first six arguments (`arg0` till `arg5`) on `x86_64`.407bpftrace currently lacks real support for handling and printing binary data,408like block header hashes and txids. When a tracepoint passes more than six409arguments, then string and integer arguments should preferably be placed in the410first six argument fields. Binary data can be placed in later arguments. The BCC411supports reading from all 12 arguments.413#### Strings as C-style String414Generally, strings should be passed into the `TRACEPOINT` macros as pointers to415C-style strings (a null-terminated sequence of characters). For C++416`std::strings`, [`c_str()`] can be used. It's recommended to document the417maximum expected string size if known.420[`c_str()`]: https://www.cplusplus.com/reference/string/string/c_str/423## Listing available tracepoints425Multiple tools can list the available tracepoints in a `bitcoind` binary with426USDT support.428### GDB - GNU Project Debugger430To list probes in Bitcoin Core, use `info probes` in `gdb`:432```433$ gdb ./build/bin/bitcoind434…435(gdb) info probes436Type Provider Name Where Semaphore Object437stap net inbound_message 0x000000000014419e 0x0000000000d29bd2 /build/bin/bitcoind438stap net outbound_message 0x0000000000107c05 0x0000000000d29bd0 /build/bin/bitcoind439stap validation block_connected 0x00000000002fb10c 0x0000000000d29bd8 /build/bin/bitcoind440…441```443### With `readelf`445The `readelf` tool can be used to display the USDT tracepoints in Bitcoin Core.446Look for the notes with the description `NT_STAPSDT`.448```449$ readelf -n ./build/bin/bitcoind | grep NT_STAPSDT -A 4 -B 2450Displaying notes found in: .note.stapsdt451Owner Data size Description452stapsdt 0x0000005d NT_STAPSDT (SystemTap probe descriptors)453Provider: net454Name: outbound_message455Location: 0x0000000000107c05, Base: 0x0000000000579c90, Semaphore: 0x0000000000d29bd0456Arguments: -8@%r12 8@%rbx 8@%rdi 8@192(%rsp) 8@%rax 8@%rdx457…458```460### With `tplist`462The `tplist` tool is provided by BCC (see [Installing BCC]). It displays kernel463tracepoints or USDT probes and their formats (for more information, see the464[`tplist` usage demonstration]). There are slight binary naming differences465between distributions. For example, on466[Ubuntu the binary is called `tplist-bpfcc`][ubuntu binary].468[Installing BCC]: https://github.com/iovisor/bcc/blob/master/INSTALL.md469[`tplist` usage demonstration]: https://github.com/iovisor/bcc/blob/master/tools/tplist_example.txt470[ubuntu binary]: https://github.com/iovisor/bcc/blob/master/INSTALL.md#ubuntu---binary472```473$ tplist -l ./build/bin/bitcoind -v474b'net':b'outbound_message' [sema 0xd29bd0]4751 location(s)4766 argument(s)477…478```
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.