Commit Graph

4799 Commits

Author SHA1 Message Date
Hennadii Stepanov
91a8e9b549 Merge bitcoin-core/gui#807: refactor: interfaces, make 'createTransaction' less error-prone
4c0d4f6f93 refactor: interfaces, make 'createTransaction' less error-prone (furszy)
e2c3ec9bf4 refactor: move CreatedTransactionResult to types.h (furszy)
45372175c3 gui: remove AmountWithFeeExceedsBalance error special case (furszy)

Pull request description:

  Bundle all function's outputs inside the `util::Result` returned object.

  Removals:
  - The input-output 'change_pos' ref arg from `createTransaction`, which has been a source of bugs in the past.
  - The 'fee' ref arg from `createTransaction`, which is currently only set when the transaction creation process succeeds.
  - The no longer needed `AmountWithFeeExceedsBalance` error (more info about its re-introduction at [bitcoin#25269](https://github.com/bitcoin/bitcoin/pull/25269) and [bitcoin#34299](https://github.com/bitcoin/bitcoin/pull/34299).

  Additionally, this PR moves the `CreatedTransactionResult` struct into its own file. This change is made to avoid further expanding the GUI dependencies on `wallet.h`. Structurally, the GUI should only access the model/interfaces and never the wallet directly.

ACKs for top commit:
  stratospher:
    ACK 4c0d4f6.
  hebasto:
    ACK 4c0d4f6f93.

Tree-SHA512: 4fc61f08ca2e66e46001defb3a2e852265713e75006c98f0c465bd48afe42e7b0d626d28d578741906fdd26e907d6919f06dc640c55c44efc3dfa766fdbf38a4
2026-02-10 15:33:37 +00:00
Hennadii Stepanov
72030efd4b Merge bitcoin/bitcoin#34525: Release: Prepare "Open Transifex translations for v31.0" step
576f892027 qt: Update the `src/qt/locale/bitcoin_en.xlf` translation source file (Hennadii Stepanov)
4b9f5beafe Update Transifex slug for 31.x (Hennadii Stepanov)

Pull request description:

  This PR follows our [Release Process](46e1288df2/doc/release-process.md).

  It is required to open Transifex translations for v31.0, as scheduled in https://github.com/bitcoin/bitcoin/issues/33607.

  For reference, see the previous similar PR: https://github.com/bitcoin/bitcoin/pull/33152.

  **Note for reviewers:**

  To reproduce the diff in the last commit, run:
  ```
  cmake --preset dev-mode
  cmake --build build_dev_mode --target translate
  ```

ACKs for top commit:
  stickies-v:
    ACK 576f892027

Tree-SHA512: 9875831b8ea6ace5b6e47fe10351bc7cdd26b9c27fe275f678c7f33f6df115ce3e956f9d522905b2fda76d82fc0a4135482cfb665c4428ab2bc1164c49cf82f4
2026-02-07 13:07:18 +00:00
Ava Chow
3b39a8aeb4 Merge bitcoin/bitcoin#34483: refactor: Use SpanReader over DataStream
fa0677d131 refactor: Use SpanReader over DataStream (MarcoFalke)
fad3eb3956 refactor: Use SpanReader over DataStream (MarcoFalke)
fa06e26764 refactor: [qt] Use SpanReader to avoid two vector copies (MarcoFalke)
fabd4d2e2e refactor: Avoid UB in SpanReader::ignore (MarcoFalke)
fa20bc2ec2 refactor: Use empty() over eof() in the streams interface (MarcoFalke)
fa879db735 test: Read debug log for self-checking comment (MarcoFalke)

Pull request description:

  This changes all places, where possible, to use SpanReader over DataStream. This makes the code easier to read and reason about, because `SpanReader` can never write data. Also, the code should be minimally faster, because it avoids a full redundant copy of the whole vector of bytes.

ACKs for top commit:
  stickies-v:
    re-ACK fa0677d131
  achow101:
    ACK fa0677d131
  janb84:
    re ACK fa0677d131
  sipa:
    crACK fa0677d131

Tree-SHA512: 1d9f43fc6e71d481cf7b8f8457f479745ee331734649e9e2c2ab00ce5d317112796c77afc328612ed004e65ac5c16fc92279d760cfb012cfddce9098c4af810f
2026-02-06 18:00:18 -08:00
furszy
4c0d4f6f93 refactor: interfaces, make 'createTransaction' less error-prone
Bundle all function's outputs inside the util::Result returned object.

Reasons for the refactoring:
- The 'change_pos' ref argument has been a source of bugs in the past.
- The 'fee' ref argument is currently only set when the transaction creation process succeeds.
2026-02-06 18:15:59 -05:00
furszy
45372175c3 gui: remove AmountWithFeeExceedsBalance error special case
Since bitcoin#34299, the wallet handles the error internally
and retrieves the proper message.
2026-02-06 17:53:12 -05:00
Hennadii Stepanov
576f892027 qt: Update the src/qt/locale/bitcoin_en.xlf translation source file
Steps to reproduce the diff on Ubuntu 25.10:
```
cmake --preset dev-mode
cmake --build build_dev_mode --target translate
```
2026-02-06 13:45:34 +00:00
MarcoFalke
fa0677d131 refactor: Use SpanReader over DataStream
This refactor does not change behavior. However, it avoids a vector
copy, which can lead to a minimal speed-up of 1%-5%, depending on the
call-site. This is mostly relevant for the fuzz tests and utils that
read large blobs of data (like a full block).
2026-02-06 07:56:57 +01:00
Ava Chow
4ae00e9a71 Merge bitcoin/bitcoin#32636: Split CWallet::Create() into CreateNew and LoadExisting
db2effaca4 scripted-diff: refactor: CWallet::Create() -> CreateNew() (David Gumberg)
27e021ebc0 wallet: Correctly log stats for encrypted messages. (David Gumberg)
d8bec61be2 wallet: remove loading logic from CWallet::Create (David Gumberg)
f35acc893f refactor: wallet: Factor out `WriteVersion()` from `PopulateWalletFromDB()` (David Gumberg)
e12ff8aca0 test: wallet: Split create and load (David Gumberg)
70dbc79b09 wallet: Use CWallet::LoadExisting() for loading existing wallets. (David Gumberg)
ae66e01164 wallet: Create separate function for wallet load (David Gumberg)
bc69070416 refactor: Wallet stats logging in its own function (David Gumberg)
a9d64cd49c wallet: Remove redundant birth time update (David Gumberg)
b4a49cc727 wallet: Move argument parsing to before DB load (David Gumberg)
b15a94a618 refactor: Split out wallet argument loading (David Gumberg)
a02c4a82d8 refactor: Move -walletbroadcast setting init (David Gumberg)
411caf7281 wallet: refactor: PopulateWalletFromDB use switch statement. (David Gumberg)
a48e23f566 refactor: wallet: move error handling to PopulateWalletFromDB() (David Gumberg)
0972785fd7 wallet: Delete unnecessary PopulateWalletFromDB() calls (David Gumberg)
f0a046094e scripted-diff: refactor: CWallet::LoadWallet->PopulateWalletFromDB (David Gumberg)

Pull request description:

  This PR is mostly a refactor which splits out logic used for creating wallets and for loading wallets, both of which are presently contained in `CWallet::Create()` into `CWallet::CreateNew()` and `CWallet::LoadExisting()`

  The real win of this PR is that `CWallet::Create()` uses a very bad heuristic for trying to guess whether or not it is supposed to be creating a new wallet or loading an existing wallet:

  370c592612/src/wallet/wallet.cpp (L2882-L2885)

  This heuristic assumes that wallets with no `ScriptPubKeyMans` are being created, which sounds reasonable, but as demonstrated in #32112 and #32111, this can happen when the user tries to load a wallet file that is corrupted, both issues are fixed by this PR and any other misbehavior for wallet files which succeeded the broken heuristic's sniff test for new wallets.

  It was already the case that every caller of `CWallet::Create()` knows whether it is creating a wallet or loading one, so we can avoid replacing this bad heuristic with another one, and just shift the burden to the caller.

ACKs for top commit:
  achow101:
    ACK db2effaca4
  polespinasa:
    approach ACK db2effaca4
  w0xlt:
    reACK db2effaca4
  murchandamus:
    ACK db2effaca4
  rkrux:
    ACK db2effaca4

Tree-SHA512: c28d60e0a3001058da3fd2bdbe0726c7ebe742a4b900a1dee2e5132eccc22e49619cb747a99b4032b000eafd4aa2fdd4ec244c32be2012aba809fdc94b5f6ecd
2026-02-04 11:06:36 -08:00
MarcoFalke
fa06e26764 refactor: [qt] Use SpanReader to avoid two vector copies 2026-02-02 18:41:38 +01:00
MarcoFalke
fad042235b refactor: Remove remaining std::bind, check via clang-tidy 2026-01-28 14:44:22 +01:00
merge-script
6ae96ed607 Merge bitcoin/bitcoin#34276: Remove empty caption from user interface (noui, gui)
fad7bd9ba3 noui: Remove always empty caption while formatting (MarcoFalke)
fa8ebeb332 refactor: [gui] Document that the title is always empty for node message (MarcoFalke)
fafe71b743 refactor: Remove empty caption from ThreadSafeMessageBox (MarcoFalke)
fa8d0088e7 refactor: Remove empty caption from ThreadSafeQuestion (MarcoFalke)
fa0195499c refactor: [gui] Use lambdas over std::bind (MarcoFalke)
eeee1e341f refactor: Remove trailing semicolon after ADD_SIGNALS_DECL_WRAPPER (MarcoFalke)

Pull request description:

  Currently, the user interface (noui, gui) has a caption for each message. However, the caption has many issues:

  * It is always hard-coded to the empty string.
  * This is confusing and tedious when reading or maintaining the code.
  * It is redundant, because `noui` will ignore the caption and set the logging prefix (error, warning, info) based on the `style`.
  * The gui does prefer to set the title based on the caption, but since it the caption is always empty, the fallback will always be used.

  Fix all issues by removing it.

ACKs for top commit:
  hebasto:
    ACK fad7bd9ba3, I have reviewed the code and it looks OK. Tested on Ubuntu 25.10.
  sedited:
    ACK fad7bd9ba3

Tree-SHA512: 58ef538b9b3e1cfdcf2955f6de9b8cee335edbf6339723cb693cb4d584817904c962dac5199ee44d7e2860a5332dec1a6abf47e621eb5cf919aa1cdae271b55f
2026-01-28 13:43:56 +01:00
merge-script
27aeeff630 Merge bitcoin/bitcoin#34328: rpc: make uptime monotonic across NTP jumps
14f99cfe53 rpc: make `uptime` monotonic across NTP jumps (Lőrinc)
a9440b1595 util: add `TicksSeconds` (Lőrinc)

Pull request description:

  ### Problem
  `bitcoin-cli uptime` was derived from wall-clock time, so it could jump by large amounts when the system clock is corrected after `bitcoind` starts (e.g. on RTC-less systems syncing NTP).
  This breaks the expectation that uptime reflects process runtime.

  ### Fix
  Compute uptime from a [monotonic clock](https://en.cppreference.com/w/cpp/chrono/steady_clock.html) so it is immune to wall-clock jumps, and use that monotonic uptime for the RPC.
  GUI startup time is derived from wall clock time minus monotonic uptime so it remains sensible after clock corrections.

  ### Reproducer
  Revert the fix commit and run the `rpc_uptime` functional test (it should fail with `AssertionError: uptime should not jump with wall clock`):

  Or alternatively:

  ```bash
  cmake -B build && cmake --build build --target bitcoind bitcoin-cli -j$(nproc)
  DATA_DIR=$(mktemp -d)
  ./build/bin/bitcoind -regtest -datadir="$DATA_DIR" -connect=0 -daemon
  ./build/bin/bitcoin-cli -regtest -datadir="$DATA_DIR" -rpcwait uptime
  sleep 1
  ./build/bin/bitcoin-cli -regtest -datadir="$DATA_DIR" setmocktime $(( $(date +%s) + 20000000 ))
  ./build/bin/bitcoin-cli -regtest -datadir="$DATA_DIR" uptime
  ./build/bin/bitcoin-cli -regtest -datadir="$DATA_DIR" stop
  ```

  <details>
  <summary>Before (uptime jumps with wall clock)</summary>

  ```bash
  Bitcoin Core starting
  0
  20000001
  Bitcoin Core stopping
  ```

  </details>

  <details>
  <summary>After (uptime stays monotonic)</summary>

  ```bash
  Bitcoin Core starting
  0
  1
  Bitcoin Core stopping
  ```
  </details>

  ----------

  Issue: https://github.com/bitcoin/bitcoin/issues/34326

ACKs for top commit:
  maflcko:
    review ACK 14f99cfe53 🎦
  willcl-ark:
    tACK 14f99cfe53
  w0xlt:
    ACK 14f99cfe53
  sedited:
    ACK 14f99cfe53

Tree-SHA512: 3909973f58666ffa0b784a6df087031b9e34d2022d354900a4dbb6cbe1d36285cd92770ee71350ebf64d6e8ab212d8ff0cd851f7dca1ec46ee2f19b417f53984
2026-01-27 13:26:43 +01:00
Hennadii Stepanov
5f66fca633 Merge bitcoin-core/gui#920: Set peer version and subversion to N/A when not available or detecting
b261100e71 [qt] Set peer version and subversion to N/A when not available or detecting (WakeTrainDev)

Pull request description:

  In the debug console peer detail window, display "N/A" for the User Agent and Version when the peer is still detecting or the information is unavailable, instead of retaining the previous values.

ACKs for top commit:
  maflcko:
    lgtm ACK b261100e71
  luke-jr:
    utACK b261100e71

Tree-SHA512: ffcba716fe6173062fe00e2d428d41bbdcaebfe8c76c804519e46a448ade2785ae32efb1a30322adc19cf29e07ea8ab4d7593ef5a17b6c418c8dd77b381e4f77
2026-01-25 14:23:05 +00:00
merge-script
fa267551c4 Merge bitcoin/bitcoin#34353: refactor: Use std::bind_front over std::bind
faa18dceba refactor: Use std::bind_front over std::bind (MarcoFalke)

Pull request description:

  `std::bind` has many issues:

  * It is verbosely listing all placeholders, but in a meaningless way, because it doesn't name the args or their types.
  * It silently ignores args passed to it, when one arg is overridden. For example [1] compiles fine on current master.
  * Accidentally duplicated placeholders compile fine as well.
  * Usually the placeholders aren't even needed.
  * This makes it hard to review, understand, and maintain.

  Fix all issues by using `std::bind_front` from C++20, which allows to drop the brittle `_1, _2, ...` placeholders. The replacement should be correct, if the trailing placeholders are ordered.

  Introducing the same silent bug on top of this pull request [2] will now lead to a compile failure.

  ----

  [1]

  ```diff
  diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
  index 694fb535b5..7661dd361e 100644
  --- a/src/qt/walletmodel.cpp
  +++ b/src/qt/walletmodel.cpp
  @@ -412,3 +412,3 @@ void WalletModel::subscribeToCoreSignals()
       m_handler_status_changed = m_wallet->handleStatusChanged(std::bind(&NotifyKeyStoreStatusChanged, this));
  -    m_handler_address_book_changed = m_wallet->handleAddressBookChanged(std::bind(NotifyAddressBookChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
  +    m_handler_address_book_changed = m_wallet->handleAddressBookChanged(std::bind(NotifyAddressBookChanged, this, CTxDestination{}, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
       m_handler_transaction_changed = m_wallet->handleTransactionChanged(std::bind(NotifyTransactionChanged, this, std::placeholders::_1, std::placeholders::_2));
  ```

  [2]

  ```diff
  diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
  index 578713c0ab..84cced741c 100644
  --- a/src/qt/walletmodel.cpp
  +++ b/src/qt/walletmodel.cpp
  @@ -412,3 +412,3 @@ void WalletModel::subscribeToCoreSignals()
       m_handler_status_changed = m_wallet->handleStatusChanged(std::bind_front(&NotifyKeyStoreStatusChanged, this));
  -    m_handler_address_book_changed = m_wallet->handleAddressBookChanged(std::bind_front(NotifyAddressBookChanged, this));
  +    m_handler_address_book_changed = m_wallet->handleAddressBookChanged(std::bind_front(NotifyAddressBookChanged, this, CTxDestination{}));
       m_handler_transaction_changed = m_wallet->handleTransactionChanged(std::bind_front(NotifyTransactionChanged, this));

ACKs for top commit:
  janb84:
    cr ACK faa18dceba
  fjahr:
    Code review ACK faa18dceba
  hebasto:
    ACK faa18dceba, I have reviewed the code and it looks OK.

Tree-SHA512: 9dd13f49527e143a2beafbaae80b1358981f07a2ce20d25cffb1853089a32ff71639e6d718d1d193754522f9ac04e3e168ba017d5fc67a11a5918e79a92b3461
2026-01-21 14:59:31 +00:00
MarcoFalke
faa18dceba refactor: Use std::bind_front over std::bind 2026-01-20 15:30:46 +01:00
Lőrinc
1658b8f82b refactor: rename CTransaction::GetTotalSize to signal that it's not cached
Transaction hashes are cached, it may not be intuitive that their sizes are actually recalculated every time.
This is done before the other refactors to clarify why we want to avoid calling this method;

Co-authored-by: maflcko <6399679+maflcko@users.noreply.github.com>
2026-01-19 20:20:13 +01:00
Lőrinc
14f99cfe53 rpc: make uptime monotonic across NTP jumps
Compute `uptime` from `SteadyClock` so it is unaffected by system time changes after startup.

Derive GUI startup time by subtracting the monotonic uptime from the wall clock time.

Add a functional test covering a large `setmocktime` jump.

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
2026-01-19 17:08:08 +01:00
merge-script
c57fbbe99d Merge bitcoin/bitcoin#31650: refactor: Avoid copies by using const references or by move-construction
fa64d8424b refactor: Enforce readability-avoid-const-params-in-decls (MarcoFalke)
faf0c2d942 refactor: Avoid copies by using const references or by move-construction (MarcoFalke)

Pull request description:

  Top level `const` in declarations is problematic for many reasons:

  * It is often a typo, where one wanted to denote a const reference. For example `bool PSBTInputSignedAndVerified(const PartiallySignedTransaction psbt, ...` is missing the `&`. This will create a redundant copy of the value.
  * In constructors it prevents move construction.
  * It can incorrectly imply some data is const, like in an imaginary example `std::span<int> Shuffle(const std::span<int>);`, where the `int`s are *not* const.
  * The compiler ignores the `const` from the declaration in the implementation.
  * It isn't used consistently anyway, not even on the same line.

  Fix some issues by:

  * Using a const reference to avoid a copy, where read-only of the value is intended. This is only done for values that may be expensive to copy.
  * Using move-construction to avoid a copy
  * Applying `readability-avoid-const-params-in-decls` via clang-tidy

ACKs for top commit:
  l0rinc:
    diff reACK fa64d8424b
  hebasto:
    ACK fa64d8424b, I have reviewed the code and it looks OK.
  sedited:
    ACK fa64d8424b

Tree-SHA512: 293c000b4ebf8fdcc75259eb0283a2e4e7892c73facfb5c3182464d6cb6a868b7f4a6682d664426bf2edecd665cf839d790bef0bae43a8c3bf1ddfdd3d068d38
2026-01-19 11:44:04 +01:00
Hennadii Stepanov
22bde74d1d Merge bitcoin-core/gui#924: Show an error message if the restored wallet name is empty
dd904298c1 gui: Show an error message if the restored wallet name is empty (Ava Chow)

Pull request description:

  The Restore Wallet dialog rejects wallet names that are empty, but was doing so silently. This is confusing, we should be presenting an error message to the user.

ACKs for top commit:
  hebasto:
    ACK dd904298c1. Tested on Fedora 43.

Tree-SHA512: f4b60f32d1c2550dbce8613f25d29a92588b1ecfc8e8e5dac691a6bdb21a77508288a904539b68333d96bde5ebb993912253f4a293e4c583891f553d95762e77
2026-01-17 10:04:56 +00:00
David Gumberg
0972785fd7 wallet: Delete unnecessary PopulateWalletFromDB() calls 2026-01-15 18:04:46 -08:00
David Gumberg
f0a046094e scripted-diff: refactor: CWallet::LoadWallet->PopulateWalletFromDB
There are too many functions in CWallet with names like "Load" and
"Create", disambiguate what CWallet::LoadWallet does by renaming it to
PopulateWalletFromDB.

-BEGIN VERIFY SCRIPT-
sed -i 's|\bLoadWallet()|PopulateWalletFromDB()|g' $(git grep -l 'LoadWallet()' -- ':(exclude)src/wallet/walletdb.cpp')
-END VERIFY SCRIPT-
2026-01-15 18:04:21 -08:00
MarcoFalke
fa64d8424b refactor: Enforce readability-avoid-const-params-in-decls 2026-01-14 23:04:12 +01:00
MarcoFalke
fa8ebeb332 refactor: [gui] Document that the title is always empty for node message
This refactor does not change any behavior.
2026-01-14 19:36:22 +01:00
MarcoFalke
fafe71b743 refactor: Remove empty caption from ThreadSafeMessageBox
The caption was empty for all call-sites, so this refactor does not
change any behavior.

Note that noui_ThreadSafeMessageBoxRedirect is test-only, so no end-user
behavior is changed here.
2026-01-14 19:36:14 +01:00
MarcoFalke
fa8d0088e7 refactor: Remove empty caption from ThreadSafeQuestion
There is only one call-site, which provided an empty caption.

Note that noui_ThreadSafeQuestionRedirect is test-only and currently
entrirely unused, so the logging format string change is not a behavior
change.

This refactor does not change any behavior.
2026-01-14 19:36:02 +01:00
merge-script
377c6dbc3c Merge bitcoin/bitcoin#34224: init: Return EXIT_SUCCESS on interrupt
997e7b4d7c init: Fix non-zero code on interrupt (sedited)

Pull request description:

  Reported by dergoegge on irc.

  An interrupt does not create a failure exit code during normal operation. This should also be the case when interrupt is triggered during initialization. However a failure exit code is currently returned if an interrupt occurs during init. Fix this by making `AppInitMain` return true instead of false on interrupt, which further up the call stack currently sets the `EXIT_FAILURE` code. Also add a check for the interrupt condition during GUI startup. Returning `EXIT_SUCCESS` seems to be the usual behaviour for daemons, see the discussion on IRC for this: https://www.erisian.com.au/bitcoin-core-dev/log-2026-01-08.html#l-146 .

  Best reviewed with `--color-moved=dimmed-zebra --color-moved-ws=ignore-all-space`.

ACKs for top commit:
  maflcko:
    review ACK 997e7b4d7c 🔺
  janb84:
    ACK 997e7b4d7c
  dergoegge:
    utACK 997e7b4d7c

Tree-SHA512: c9542e95d9312567e029426a329144b5bc638d8ebc9c966e0246c1bb728d40f56ca425b00c446f5d238067e629c2337d0fe78bcc5a8760424d2ec38a5578e115
2026-01-13 15:23:12 -08:00
MarcoFalke
fa0195499c refactor: [gui] Use lambdas over std::bind
This refactor makes the code easier to read and maintain.
2026-01-13 18:08:35 +01:00
Ava Chow
dd904298c1 gui: Show an error message if the restored wallet name is empty
The Restore Wallet dialog rejects wallet names that are empty, but was
doing so silently. This is confusing, we should be presenting an error
message to the user.
2026-01-12 15:40:01 -08:00
Ryan Ofsky
796f18e559 Merge bitcoin/bitcoin#29415: Broadcast own transactions only via short-lived Tor or I2P connections
8937221304 doc: add release notes for 29415 (Vasil Dimov)
582016fa5f test: add unit test for the private broadcast storage (Vasil Dimov)
e74d54e048 test: add functional test for private broadcast (Vasil Dimov)
818b780a05 rpc: use private broadcast from sendrawtransaction RPC if -privatebroadcast is ON (Vasil Dimov)
eab595f9cf net_processing: retry private broadcast (Vasil Dimov)
37b79f9c39 net_processing: stop private broadcast of a transaction after round-trip (Vasil Dimov)
2de53eee74 net_processing: handle ConnectionType::PRIVATE_BROADCAST connections (Vasil Dimov)
30a9853ad3 net_processing: move a debug check in VERACK processing earlier (Vasil Dimov)
d1092e5d48 net_processing: modernize PushNodeVersion() (Vasil Dimov)
9937a12a2f net_processing: move the debug log about receiving VERSION earlier (Vasil Dimov)
a098f37b9e net_processing: reorder the code that handles the VERSION message (Vasil Dimov)
679ce3a0b8 net_processing: store transactions for private broadcast in PeerManager (Vasil Dimov)
a3faa6f944 node: extend node::TxBroadcast with a 3rd option (Vasil Dimov)
95c051e210 net_processing: rename RelayTransaction() to better describe what it does (Vasil Dimov)
bb49d26032 net: implement opening PRIVATE_BROADCAST connections (Vasil Dimov)
01dad4efe2 net: introduce a new connection type for private broadcast (Vasil Dimov)
94aaa5d31b init: introduce a new option to enable/disable private broadcast (Vasil Dimov)
d6ee490e0a log: introduce a new category for private broadcast (Vasil Dimov)

Pull request description:

  _Parts of this PR are isolated in independent smaller PRs to ease review:_

  * [x] _https://github.com/bitcoin/bitcoin/pull/29420_
  * [x] _https://github.com/bitcoin/bitcoin/pull/33454_
  * [x] _https://github.com/bitcoin/bitcoin/pull/33567_
  * [x] _https://github.com/bitcoin/bitcoin/pull/33793_

  ---

  To improve privacy, broadcast locally submitted transactions (from the `sendrawtransaction` RPC) to the P2P network only via Tor or I2P short-lived connections, or to IPv4/IPv6 peers but through the Tor network.

  * Introduce a new connection type for private broadcast of transactions with the following properties:
    * started whenever there are local transactions to be sent
    * opened to Tor or I2P peers or IPv4/IPv6 via the Tor proxy
    * opened regardless of max connections limits
    * after handshake is completed one local transaction is pushed to the peer, `PING` is sent and after receiving `PONG` the connection is closed
    * ignore all incoming messages after handshake is completed (except `PONG`)

  * Broadcast transactions submitted via `sendrawtransaction` using this new mechanism, to a few peers. Keep doing this until we receive back this transaction from one of our ordinary peers (this takes about 1 second on mainnet).

  * The transaction is stored in peerman and does not enter the mempool.

  * Once we get an `INV` from one of our ordinary peers, then the normal flow executes: we request the transaction with `GETDATA`, receive it with a `TX` message, put it in our mempool and broadcast it to all our existent connections (as if we see it for the first time).

  * After we receive the full transaction as a `TX` message, in reply to our `GETDATA` request, only then consider the transaction has propagated through the network and remove it from the storage in peerman, ending the private broadcast attempts.

  The messages exchange should look like this:

  ```
  tx-sender >--- connect -------> tx-recipient
  tx-sender >--- VERSION -------> tx-recipient (dummy VERSION with no revealing data)
  tx-sender <--- VERSION -------< tx-recipient
  tx-sender <--- WTXIDRELAY ----< tx-recipient (maybe)
  tx-sender <--- SENDADDRV2 ----< tx-recipient (maybe)
  tx-sender <--- SENDTXRCNCL ---< tx-recipient (maybe)
  tx-sender <--- VERACK --------< tx-recipient
  tx-sender >--- VERACK --------> tx-recipient
  tx-sender >--- INV/TX --------> tx-recipient
  tx-sender <--- GETDATA/TX ----< tx-recipient
  tx-sender >--- TX ------------> tx-recipient
  tx-sender >--- PING ----------> tx-recipient
  tx-sender <--- PONG ----------< tx-recipient
  tx-sender disconnects
  ```

  Whenever a new transaction is received from `sendrawtransaction` RPC, the node will send it to a few (`NUM_PRIVATE_BROADCAST_PER_TX`) recipients right away. If after some time we still have not heard anything about the transaction from the network, then it will be sent to 1 more peer (see `PeerManagerImpl::ReattemptPrivateBroadcast()`).

  A few considerations:
  * The short-lived private broadcast connections are very cheap and fast wrt network traffic. It is expected that some of those peers could blackhole the transaction. Just one honest/proper peer is enough for successful propagation.
  * The peers that receive the transaction could deduce that this is initial transaction broadcast from the transaction originator. This is ok, they can't identify the sender.

  ---

  <details>
  <summary>How to test this?</summary>

  Thank you, @stratospher and @andrewtoth!

  Start `bitcoind` with `-privatebroadcast=1 -debug=privatebroadcast`.

  Create a wallet and get a new address, go to the Signet faucet and request some coins to that address:
  ```bash
  build/bin/bitcoin-cli -chain="signet" createwallet test
  build/bin/bitcoin-cli -chain="signet" getnewaddress
  ```

  Get a new address for the test transaction recipient:
  ```bash
  build/bin/bitcoin-cli -chain="signet" loadwallet test
  new_address=$(build/bin/bitcoin-cli -chain="signet" getnewaddress)
  ```

  Create the transaction:
  ```bash
  # Option 1: `createrawtransaction` and `signrawtransactionwithwallet`:

  txid=$(build/bin/bitcoin-cli -chain="signet" listunspent | jq -r '.[0] | .txid')
  vout=$(build/bin/bitcoin-cli -chain="signet" listunspent | jq -r '.[0] | .vout')
  echo "txid: $txid"
  echo "vout: $vout"

  tx=$(build/bin/bitcoin-cli -chain="signet" createrawtransaction "[{\"txid\": \"$txid\", \"vout\": $vout}]" "[{\"$new_address\": 0.00001000}]" 0 false)
  echo "tx: $tx"

  signed_tx=$(build/bin/bitcoin-cli -chain="signet" signrawtransactionwithwallet "$tx" | jq -r '.hex')
  echo "signed_tx: $signed_tx"

  # OR Option 2: `walletcreatefundedpsbt` and `walletprocesspsbt`:
  # This makes it not have to worry about inputs and also automatically sends back change to the wallet.
  # Start `bitcoind` with `-fallbackfee=0.00003000` for instance for 3 sat/vbyte fee.

  psbt=$(build/bin/bitcoin-cli -chain="signet" walletcreatefundedpsbt "[]" "[{\"$new_address\": 0.00001000}]" | jq -r '.psbt')
  echo "psbt: $psbt"

  signed_tx=$(build/bin/bitcoin-cli -chain="signet" walletprocesspsbt "$psbt" | jq -r '.hex')
  echo "signed_tx: $signed_tx"
  ```

  Finally, send the transaction:
  ```bash
  raw_tx=$(build/bin/bitcoin-cli -chain="signet" sendrawtransaction "$signed_tx")
  echo "raw_tx: $raw_tx"
  ```

  </details>

  ---

  <details>
  <summary>High-level explanation of the commits</summary>

  * New logging category and config option to enable private broadcast
    * `log: introduce a new category for private broadcast`
    * `init: introduce a new option to enable/disable private broadcast`

  * Implement the private broadcast connection handling on the `CConnman` side:
    * `net: introduce a new connection type for private broadcast`
    * `net: implement opening PRIVATE_BROADCAST connections`

  * Prepare `BroadcastTransaction()` for private broadcast requests:
    * `net_processing: rename RelayTransaction to better describe what it does`
    * `node: extend node::TxBroadcast with a 3rd option`
    * `net_processing: store transactions for private broadcast in PeerManager`

  * Implement the private broadcast connection handling on the `PeerManager` side:
    * `net_processing: reorder the code that handles the VERSION message`
    * `net_processing: move the debug log about receiving VERSION earlier`
    * `net_processing: modernize PushNodeVersion()`
    * `net_processing: move a debug check in VERACK processing earlier`
    * `net_processing: handle ConnectionType::PRIVATE_BROADCAST connections`
    * `net_processing: stop private broadcast of a transaction after round-trip`
    * `net_processing: retry private broadcast`

  * Engage the new functionality from `sendrawtransaction`:
    * `rpc: use private broadcast from sendrawtransaction RPC if -privatebroadcast is ON`

  * New tests:
    * `test: add functional test for private broadcast`
    * `test: add unit test for the private broadcast storage`

  </details>

  ---

  **This PR would resolve the following issues:**
  https://github.com/bitcoin/bitcoin/issues/3828 Clients leak IPs if they are recipients of a transaction
  https://github.com/bitcoin/bitcoin/issues/14692 Can't configure bitocoind to only send tx via Tor but receive clearnet transactions
  https://github.com/bitcoin/bitcoin/issues/19042 Tor-only transaction broadcast onlynet=onion alternative
  https://github.com/bitcoin/bitcoin/issues/24557 Option for receive events with all networks, but send transactions and/or blocks only with anonymous network[s]?
  https://github.com/bitcoin/bitcoin/issues/25450 Ability to broadcast wallet transactions only via dedicated oneshot Tor connections
  https://github.com/bitcoin/bitcoin/issues/32235 Tor: TX circuit isolation

  **Issues that are related, but (maybe?) not to be resolved by this PR:**
  https://github.com/bitcoin/bitcoin/issues/21876 Broadcast a transaction to specific nodes
  https://github.com/bitcoin/bitcoin/issues/28636 new RPC: sendrawtransactiontopeer

  ---

  Further extensions:
  * Have the wallet do the private broadcast as well, https://github.com/bitcoin/bitcoin/issues/11887 would have to be resolved.
  * Have the `submitpackage` RPC do the private broadcast as well, [draft diff in the comment below](https://github.com/bitcoin/bitcoin/pull/29415#pullrequestreview-2972293733), thanks ismaelsadeeq!
  * Add some stats via RPC, so that the user can better monitor what is going on during and after the broadcast. Currently this can be done via the debug log, but that is not convenient.
  * Make the private broadcast storage, currently in peerman, persistent over node restarts.
  * Add (optional) random delay before starting to broadcast the transaction in order to avoid correlating unrelated transactions based on the time when they were broadcast. Suggested independently of this PR [here](https://github.com/bitcoin/bitcoin/issues/30471).
  * Consider periodically sending transactions that did not originate from the node as decoy, discussed [here](https://github.com/bitcoin/bitcoin/pull/29415#discussion_r2035414972).
  * Consider waiting for peer's FEEFILTER message and if the transaction that was sent to the peer is below that threshold, then assume the peer is going to drop it. Then use this knowledge to retry more aggressively with another peer, instead of the current 10 min. See [comment below](https://github.com/bitcoin/bitcoin/pull/29415#issuecomment-3258611648).
  * It may make sense to be able to override the default policy -- eg so submitrawtransaction can go straight to the mempool and relay, even if txs are normally privately relayed. See [comment below](https://github.com/bitcoin/bitcoin/pull/29415#issuecomment-3427086681).
  * As a side effect we have a new metric available - the time it takes for a transaction to reach a random node in the network (from the point of view of the private broadcast recipient the tx originator is a random node somewhere in the network). This can be useful for monitoring, unrelated to privacy characteristics of this feature.

  ---

  _A previous incarnation of this can be found at https://github.com/bitcoin/bitcoin/pull/27509. It puts the transaction in the mempool and (tries to) hide it from the outside observers. This turned out to be too error prone or maybe even impossible._

ACKs for top commit:
  l0rinc:
    code review diff ACK 8937221304
  andrewtoth:
    ACK 8937221304
  pinheadmz:
    ACK 8937221304
  w0xlt:
    ACK 8937221304 with nit https://github.com/bitcoin/bitcoin/pull/29415#discussion_r2654849875
  mzumsande:
    re-ACK 8937221304

Tree-SHA512: d51dadc865c2eb080c903cbe2f669e69a967e5f9fc64e9a20a68f39a67bf0db6ac2ad682af7fa24ef9f0942a41c89959341a16ba7b616475e1c5ab8e563b9b96
2026-01-12 15:02:14 -05:00
sedited
997e7b4d7c init: Fix non-zero code on interrupt
An interrupt does not create a failure exit code during normal
operation. This should also be the case when interrupt is triggered
during initialization. However a failure exit code is currently returned
if an interrupt occurs during init. Fix this by making `AppInitMain` return
true instead of false, which further up the call stack sets the
`EXIT_FAILURE` code. Also add a check for the interrupt condition during
GUI startup.
2026-01-08 20:08:21 +01:00
WakeTrainDev
301d9eea66 qt: Remove "Starting Block" from Peer Detail. Following Deprecation in bitcoin#34197 2026-01-06 03:08:01 +02:00
David Gumberg
11ce5cf799 scripted-diff: refactor: wallet: Delete IsCrypted
This function is a duplicate of HasEncryptionKeys().

-BEGIN VERIFY SCRIPT-
sed -i '/bool IsCrypted() const;/d' src/wallet/wallet.h
sed -i '/^bool CWallet::IsCrypted() const$/,/^}$/{/^}$/N;d;}' src/wallet/wallet.cpp
sed -i --regexp-extended 's/IsCrypted\(\)/HasEncryptionKeys()/g' $(git ls-files '*.cpp' '*.h')
-END VERIFY SCRIPT-
2025-12-24 11:09:15 -08:00
WakeTrainDev
b261100e71 [qt] Set peer version and subversion to N/A when not available or detecting 2025-12-21 13:09:08 +02:00
merge-script
7f295e1d9b Merge bitcoin/bitcoin#34084: scripted-diff: [doc] Unify stale copyright headers
fa4cb13b52 test: [doc] Manually unify stale headers (MarcoFalke)
fa5f297748 scripted-diff: [doc] Unify stale copyright headers (MarcoFalke)

Pull request description:

  Historically, the upper year range in file headers was bumped manually
  or with a script.

  This has many issues:

  * The script is causing churn. See for example commit 306ccd4, or
    drive-by first-time contributions bumping them one-by-one. (A few from
    this year: https://github.com/bitcoin/bitcoin/pull/32008,
    https://github.com/bitcoin/bitcoin/pull/31642,
    https://github.com/bitcoin/bitcoin/pull/32963, ...)
  * Some, or likely most, upper year values were wrong. Reasons for
    incorrect dates could be code moves, cherry-picks, or simply bugs in
    the script.
  * The upper range is not needed for anything.
  * Anyone who wants to find the initial file creation date, or file
    history, can use `git log` or `git blame` to get more accurate
    results.
  * Many places are already using the `-present` suffix, with the meaning
    that the upper range is omitted.

  To fix all issues, this bumps the upper range of the copyright headers
  to `-present`.

  Further notes:

  * Obviously, the yearly 4-line bump commit for the build system (c.f.
    b537a2c02a) is fine and will remain.
  * For new code, the date range can be fully omitted, as it is done
    already by some developers. Obviously, developers are free to pick
    whatever style they want. One can list the commits for each style.
  * For example, to list all commits that use `-present`:
    `git log --format='%an (%ae) [%h: %s]' -S 'present The Bitcoin'`.
  * Alternatively, to list all commits that use no range at all:
    `git log --format='%an (%ae) [%h: %s]' -S '(c) The Bitcoin'`.

  <!--
  * The lower range can be wrong as well, so it could be omitted as well,
    but this is left for a follow-up. A previous attempt was in
    https://github.com/bitcoin/bitcoin/pull/26817.

ACKs for top commit:
  l0rinc:
    ACK fa4cb13b52
  rkrux:
    re-ACK fa4cb13b52
  janb84:
    ACK fa4cb13b52

Tree-SHA512: e5132781bdc4417d1e2922809b27ef4cf0abb37ffb68c65aab8a5391d3c917b61a18928ec2ec2c75ef5184cb79a5b8c8290d63e949220dbeab3bd2c0dfbdc4c5
2025-12-19 16:56:02 +00:00
Lőrinc
1e94e562f7 refactor: enable readability-container-contains clang-tidy rule
Replace the last few instances of `.count() != 0` and `.count() == 0` and `.count()` patterns with the more expressive C++20 `.contains()` method:

* `std::set<std::string>` in `getblocktemplate` RPC;
* `std::map<std::string, ...>` in `transaction_tests`;
* other bare `std::unordered_set` and `std::map` count calls.

With no remaining violations, enable the `readability-container-contains`
clang-tidy check to prevent future regressions.
2025-12-18 22:38:02 +01:00
Ryan Ofsky
ab513103df Merge bitcoin/bitcoin#33192: refactor: unify container presence checks
d9319b06cf refactor: unify container presence checks - non-trivial counts (Lőrinc)
039307554e refactor: unify container presence checks - trivial counts (Lőrinc)
8bb9219b63 refactor: unify container presence checks - find (Lőrinc)

Pull request description:

  ### Summary
  Instead of counting occurrences in sets and maps, the C++20 `::contains` method expresses the intent unambiguously and can return early on first encounter.

  ### Context
  Applied clang‑tidy's [readability‑container‑contains](https://clang.llvm.org/extra/clang-tidy/checks/readability/container-contains.html) check, though many cases required manual changes since tidy couldn't fix them automatically.

  ### Changes
  The changes made here were:

  | From                   | To               |
  |------------------------|------------------|
  | `m.find(k) == m.end()` | `!m.contains(k)` |
  | `m.find(k) != m.end()` | `m.contains(k)`  |
  | `m.count(k)`           | `m.contains(k)`  |
  | `!m.count(k)`          | `!m.contains(k)` |
  | `m.count(k) == 0`      | `!m.contains(k)` |
  | `m.count(k) != 1`      | `!m.contains(k)` |
  | `m.count(k) == 1`      | `m.contains(k)`  |
  | `m.count(k) < 1`       | `!m.contains(k)`  |
  | `m.count(k) > 0`       | `m.contains(k)`  |
  | `m.count(k) != 0`      | `m.contains(k)`  |

  > Note that `== 1`/`!= 1`/`< 1` only apply to simple [maps](https://en.cppreference.com/w/cpp/container/map/contains)/[sets](https://en.cppreference.com/w/cpp/container/set/contains) and had to be changed manually.

  There are many other cases that could have been changed, but we've reverted most of those to reduce conflict with other open PRs.

  -----

  <details>
  <summary>clang-tidy command on Mac</summary>

  ```bash
  rm -rfd build && \
  cmake -B build \
    -DCMAKE_C_COMPILER="$(brew --prefix llvm)/bin/clang" \
    -DCMAKE_CXX_COMPILER="$(brew --prefix llvm)/bin/clang++" \
    -DCMAKE_OSX_SYSROOT="$(xcrun --show-sdk-path)" \
    -DCMAKE_C_FLAGS="-target arm64-apple-macos11" \
    -DCMAKE_CXX_FLAGS="-target arm64-apple-macos11" \
    -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_BENCH=ON -DBUILD_FUZZ_BINARY=ON -DBUILD_FOR_FUZZING=ON

   "$(brew --prefix llvm)/bin/run-clang-tidy" -quiet -p build -j$(nproc) -checks='-*,readability-container-contains' | grep -v 'clang-tidy'
  ```

  </details>

  Note: this is a take 2 of https://github.com/bitcoin/bitcoin/pull/33094 with fewer contentious changes.

ACKs for top commit:
  optout21:
    reACK d9319b06cf
  sedited:
    ACK d9319b06cf
  janb84:
    re ACK d9319b06cf
  pablomartin4btc:
    re-ACK d9319b06cf
  ryanofsky:
    Code review ACK d9319b06cf. I manually reviewed the full change, and it seems there are a lot of positive comments about this and no more very significant conflicts, so I will merge it shortly.

Tree-SHA512: e4415221676cfb88413ccc446e5f4369df7a55b6642347277667b973f515c3c8ee5bfa9ee0022479c8de945c89fbc9ff61bd8ba086e70f30298cbc1762610fe1
2025-12-17 16:17:29 -05:00
MarcoFalke
fa5ed16aa4 move-only: MAX_BLOCK_TIME_GAP to src/qt
Can be reviewed via the git option:
--color-moved=dimmed-zebra
2025-12-17 13:55:03 +01:00
MarcoFalke
fa5f297748 scripted-diff: [doc] Unify stale copyright headers
-BEGIN VERIFY SCRIPT-

 sed --in-place --regexp-extended \
   's;( 20[0-2][0-9])(-20[0-2][0-9])? The Bitcoin Core developers;\1-present The Bitcoin Core developers;g' \
   $( git grep -l 'The Bitcoin Core developers' -- ':(exclude)COPYING' ':(exclude)src/ipc/libmultiprocess' ':(exclude)src/minisketch' )

-END VERIFY SCRIPT-
2025-12-16 22:21:15 +01:00
Vasil Dimov
01dad4efe2 net: introduce a new connection type for private broadcast
We will open a short-lived connection to a random Tor or I2P peer,
send our transaction to that peer and close the connection.
2025-12-16 17:53:41 +01:00
Ava Chow
14371fd1fc gui: Add a menu item to restore then migrate a wallet file
Some users will have backups of a legacy wallet which cannot be restored
due to being a legacy wallet, and therefore cannot be migrated from the
GUI. This menu item allows such users to restore and migrate their
wallets in a single action.
2025-12-11 12:11:15 -08:00
Ava Chow
f11a7d248c gui: Add restore_and_migrate function to restore then migrate a wallet
restore_and_migrate first restores a wallet file to the wallets
directory in the expected layout, then it performs legacy to descriptor
wallet migration on the restored wallet.
2025-12-11 12:11:15 -08:00
Ava Chow
16ab6dfc10 gui: Move actual migration part of migrate() to its own function
We will need to use the same migration code in a later commit, so first
move it to a separate function.
2025-12-11 12:04:27 -08:00
Ava Chow
4ec2d18a07 wallet, interfaces, gui: Expose load_after_restore parameter
RestoreWallet has a load_after_restore parameter, expose this to callers
using it through the wallet interface as well.
2025-12-11 12:04:27 -08:00
Lőrinc
d9319b06cf refactor: unify container presence checks - non-trivial counts
The changes made here were:

| From              | To               |
|-------------------|------------------|
| `m.count(k) == 1` | `m.contains(k)`  |
| `m.count(k) == 0` | `!m.contains(k)` |
| `m.count(k) != 1` | `!m.contains(k)` |
| `m.count(k) < 1`  | `!m.contains(k)` |

* `mapInfo` is instance of `std::unordered_map` and can only contain 0 or 1 value for a given key;
* similarly, `g_enabled_filter_types` and `setClientRules` are both `std::set` instances;
* lastly, while `mapTxSpends` is `std::unordered_multimap` that could potentially hold multiple values, having a size less than 1 means that the value is missing.

`QMap<WalletModel*, WalletView*> mapWalletViews` values were also migrated manually.

Co-authored-by: pablomartin4btc <pablomartin4btc@gmail.com>
Co-authored-by: fanquake <fanquake@gmail.com>
2025-12-03 13:37:17 +01:00
Hennadii Stepanov
0672e727bf Revert "gui, qt: brintToFront workaround for Wayland"
This reverts commit 15aa7d0236.
2025-11-21 12:38:03 +00:00
Hennadii Stepanov
b126f98194 Merge bitcoin-core/gui#910: Added test coverage for qt gui#901 console history filter
310e4979b3 qt: Added test coverage for qt gui#901 console history filter (WakeTrainDev)

Pull request description:

  Add test coverage for the QT rpc console updated filtered commands in gui#901

ACKs for top commit:
  pablomartin4btc:
    ACK 310e4979b3
  hebasto:
    ACK 310e4979b3, tested on Fedora 42 by reverting 4e352efa2c.

Tree-SHA512: 45bb8583311f145353d8265d28f220d2a318c701346f147979c5d33b27811276d5e18586bf58f35e455701495d2cb87ec54dd78f4ca8631a0c7bd2c1d7fe640c
2025-11-18 23:24:31 +00:00
Hennadii Stepanov
7d7b829c36 Merge bitcoin-core/gui#908: Remove HD seed reference from blank wallet tooltip
929f69d0ff qt: Remove HD seed reference from blank wallet tooltip (John Moffett)

Pull request description:

  Blank descriptor wallets currently do not have HD seeds and none can be added (or 'set') by the user, so remove the reference in the tooltip.

  As I understand it, descriptor wallets don't have a global HD seed and don't store the HD seeds for keys they generate. Currently, no new HD seeds can be added by the user (even for old wallets since `sethdseed` was removed), though it may be possible in the future, eg -  https://github.com/bitcoin/bitcoin/pull/33043

ACKs for top commit:
  maflcko:
    lgtm ACK 929f69d0ff

Tree-SHA512: 85e9c8e18a92b3da6fd62b70570cef58e03843633300b65aee5789d38c7bcaa46738970f0aea63f4e9b3e8814abb5bf1e1aa93f568a875ad1e0443d4dafb0aab
2025-11-18 23:02:50 +00:00
WakeTrainDev
310e4979b3 qt: Added test coverage for qt gui#901 console history filter 2025-11-13 00:45:57 +02:00
Hennadii Stepanov
0dd8d5c237 cmake: Specify Windows plugin path in test_bitcoin-qt property 2025-11-12 19:02:29 +00:00
Hennadii Stepanov
d86650220a cmake: Disable -Wtrailing-whitespace warnings for RCC-generated files
See: https://bugreports.qt.io/browse/QTBUG-141858.
2025-11-11 11:12:50 +00:00