net: avoid unconditional privatebroadcast logging (+ warn for debug logs) #34267

pull l0rinc wants to merge 3 commits into bitcoin:master from l0rinc:l0rinc/privatebroadcast-logdebug changing 3 files +26 −21
  1. l0rinc commented at 9:25 pm on January 12, 2026: contributor

    Motivation

    The recently merged private broadcast is a privacy feature, and users may share debug.log with support. Unconditional LogInfo() messages that mention private broadcast and/or include (w)txids can leak sensitive context (e.g. which transactions a user originated). Since it’s meant to be a private broadcast, we should minimize leaks. It’s a best effort, it’s not invalidated by other logs possibly leaking identifiable information, those can be addressed separately. We’re not promising that the logs won’t ever contain data that could be used against the user, but we should still try to minimize that data, especially for a feature that’s advertised as privacy-focused.

    Follow up to #29415 (comment)

    Changes

    • Move private-broadcast event logs from LogInfo() to LogDebug(BCLog::PRIVBROADCAST, ...), so they are only emitted when -debug=privatebroadcast was explicitly provided.
    • Remove hardcoded "[privatebroadcast]" log-string prefixes (category logging already adds the prefix).
    • Keep warning at the default log level for startup failures.
    • Add an init log (not a warning since that would require excessive test framework updates) when any -debug categories are enabled that additional logs may contain privacy-sensitive information and should not be shared publicly.
    • Update a related startup arg (-logips) to clarify that clarify that non-debug logs can also contain IP addresses.

    Reproducer

    The new warning can be checked with:

    0./build/bin/bitcoind -printtoconsole=1 -stopatheight=1 -listen=0 -connect=0 | grep 'Debug logging is enabled' | wc -l
    1       0
    2./build/bin/bitcoind -printtoconsole=1 -stopatheight=1 -listen=0 -connect=0 -debug | grep 'Debug logging is enabled' | wc  -l
    3       1
    
  2. DrahtBot added the label P2P on Jan 12, 2026
  3. DrahtBot commented at 9:25 pm on January 12, 2026: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34267.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK janb84, vasild

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #34271 (net_processing: make m_tx_for_private_broadcast optional by vasild)
    • #34181 (refactor: [p2p] Make ProcessMessage private again, Use references when non-null by maflcko)
    • #34038 (logging: API improvements by ajtowns)
    • #31260 (scripted-diff: Type-safe settings retrieval by ryanofsky)
    • #17783 (common: Disallow calling IsArgSet() on ALLOW_LIST options by ryanofsky)
    • #17581 (refactor: Remove settings merge reverse precedence code by ryanofsky)
    • #17580 (refactor: Add ALLOW_LIST flags and enforce usage in CheckArgFlags by ryanofsky)
    • #17493 (util: Forbid ambiguous multiple assignments in config file by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  4. fanquake requested review from vasild on Jan 12, 2026
  5. in src/net.cpp:3239 in 4666a55105 outdated
    3238@@ -3239,7 +3239,7 @@ void CConnman::ThreadPrivateBroadcast()
    3239         std::optional<Proxy> proxy;
    


    vasild commented at 10:10 am on January 13, 2026:

    Agree that local (our own) transaction IDs are somewhat sensitive and maybe should not be logged by default. At least I could not find any place that already logs them (before #29415).

    The mere usage of -privatebroadcast=1 IMO shouldn’t be considered sensitive to the point that we do not log about it by default.


    l0rinc commented at 11:53 am on January 13, 2026:
    Do you need me to anything here?

    vasild commented at 5:16 pm on January 13, 2026:
    Why were some logs that do not contain sensitive information (txid) were changed from info to debug?

    andrewtoth commented at 9:11 pm on January 13, 2026:
    What about timing analysis that could be conducted with these log lines?

    l0rinc commented at 9:25 pm on January 13, 2026:

    Yes, as described in the PR:

    LogInfo() messages that mention private broadcast and/or include (w)txids can leak sensitive context

    I considered all indication that a private broadcast has happened as a leak, unless the user explicitly decided to use debug logging - which even warns now.


    andrewtoth commented at 9:34 pm on January 13, 2026:

    I agree, and think we should not log here either #34267 (review).

    Startup logs should be the only non-debug logs we make for private broadcast. Info should be retrieved via new RPCs.


    l0rinc commented at 10:07 pm on January 13, 2026:

    we should not log here either #34267 (comment).

    That’s a valid point actually - what do you think @vasild? Please see https://github.com/bitcoin/bitcoin/compare/b0edff013c24cd05eda86156c720ff52d3f187f0..c5ec0e5317118d84182dd92c1c01c2422d0abc5d


    vasild commented at 8:06 am on January 14, 2026:

    timing analysis

    Info should be retrieved via new RPCs

    Ok, makes sense.

    we should not log here either #34267 (review).

    That’s a valid point actually - what do you think @vasild? Please see https://github.com/bitcoin/bitcoin/compare/b0edff013c24cd05eda86156c720ff52d3f187f0..c5ec0e5317118d84182dd92c1c01c2422d0abc5d

    +1

  6. in src/net.cpp:3240 in 4666a55105 outdated
    3238@@ -3239,7 +3239,7 @@ void CConnman::ThreadPrivateBroadcast()
    3239         std::optional<Proxy> proxy;
    3240         const std::optional<Network> net{m_private_broadcast.PickNetwork(proxy)};
    


    vasild commented at 10:17 am on January 13, 2026:

    Is it documented somewhere that:

    1. logs by default are fine to share online
    2. debug logs (e.g. when some -debug=... is enabled) might contain sensitive information and should not be shared online.

    If not, then maybe this should be documented. Otherwise there might be oblivious people running -debug=... and sharing their logs online and this PR will not help them.


    l0rinc commented at 11:51 am on January 13, 2026:

    Added a warning when we’re logging extra data, it’s in a separate commit, added you as coauthor, extended the PR description with reproducer, see: https://github.com/bitcoin/bitcoin/compare/4666a551051f7462b02babf42bfb26ec173619b0..b0edff013c24cd05eda86156c720ff52d3f187f0

    Edit: changed the warning to LogInfo to avoid having to touch the test framework



    l0rinc commented at 1:18 pm on January 13, 2026:
    Yeah, changed the warning to LogInfo to avoid having to touch the test framework: https://github.com/bitcoin/bitcoin/compare/b694f26872fa7a3858b1d22ffe8992023bffffd0..b0edff013c24cd05eda86156c720ff52d3f187f0
  7. in src/net_processing.cpp:1658 in 4666a55105
    1652@@ -1653,9 +1653,9 @@ void PeerManagerImpl::ReattemptPrivateBroadcast(CScheduler& scheduler)
    1653                          stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString());
    1654                 ++num_for_rebroadcast;
    1655             } else {
    1656-                LogInfo("[privatebroadcast] Giving up broadcast attempts for txid=%s wtxid=%s: %s",
    1657-                        stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString(),
    1658-                        mempool_acceptable.m_state.ToString());
    1659+                LogDebug(BCLog::PRIVBROADCAST, "Giving up broadcast attempts for txid=%s wtxid=%s: %s",
    1660+                         stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString(),
    1661+                         mempool_acceptable.m_state.ToString());
    


    vasild commented at 10:25 am on January 13, 2026:

    IMO this deserves the INFO severity (or maybe even a WARNING).

    What about having two log messages here - one INFO without txid and one DEBUG with the txid? Or maybe log the txid conditionally on LogAcceptCategory(BCLog::PRIVBROADCAST, BCLog::Debug)?


    l0rinc commented at 11:52 am on January 13, 2026:

    Added a warning, see: https://github.com/bitcoin/bitcoin/compare/4666a551051f7462b02babf42bfb26ec173619b0..b0edff013c24cd05eda86156c720ff52d3f187f0

    Edit: changed the warning to LogInfo to avoid having to touch the test framework

  8. vasild commented at 10:39 am on January 13, 2026: contributor

    Approach ACK 4666a551051f7462b02babf42bfb26ec173619b0

    I verified that this did not miss any logs added in #29415

  9. janb84 commented at 10:59 am on January 13, 2026: contributor

    concept ACK 4666a551051f7462b02babf42bfb26ec173619b0

    Given the nature of the (possible) PII (or in this case TII) in the loglines of the privatebroadcast feature, I agree with the author to move the loglines from info to debug level with the additional -debug=privatebroadcast filter so that they only show up when explicitly asked.

    cross checked if messages where missed with #29415 Would like to see #34267 (review) resolved. (I agree with Vasild) Failing broadcasts need to show-up in more than only debug with flag.

  10. l0rinc force-pushed on Jan 13, 2026
  11. l0rinc renamed this:
    net: avoid unconditional `privatebroadcast` logging
    net: avoid unconditional `privatebroadcast` logging (+ warn for debug logs)
    on Jan 13, 2026
  12. l0rinc force-pushed on Jan 13, 2026
  13. DrahtBot added the label CI failed on Jan 13, 2026
  14. DrahtBot commented at 1:15 pm on January 13, 2026: contributor

    🚧 At least one of the CI tasks failed. Task Windows native, VS 2022: https://github.com/bitcoin/bitcoin/actions/runs/20955633543/job/60219432981 LLM reason (✨ experimental): test_bitcoin-qt failed/crashed (exit code 0xc0000409) during CTest, causing overall CI failure.

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  15. in src/init/common.cpp:103 in b0edff013c
     97@@ -98,6 +98,11 @@ util::Result<void> SetLoggingCategories(const ArgsManager& args)
     98             return util::Error{strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)};
     99         }
    100     }
    101+
    102+    if (LogInstance().GetCategoryMask() != BCLog::NONE) {
    103+        LogInfo("Debug logging is enabled (-debug). Debug logs may contain privacy-sensitive information (e.g., transaction IDs, network addresses) and should not be shared publicly.");
    


    vasild commented at 1:31 pm on January 13, 2026:

    … network addresses …

    Those are controlled by -logips. So, maybe remove “network addresses”.

    Offtopic, the description of -logips reads:

    Include IP addresses in debug output

    however in some places we would log the addresses if -logips=1 even in non-debug output (LogInfo() or LogError()). So, I guess the part “in debug output” is outdated.


    l0rinc commented at 10:19 pm on January 13, 2026:
    Good point, reverted the network addresses from the commit and the log message and added a new commit on top which clarifies that non-debug logs can also contain IP addresses.
  16. l0rinc force-pushed on Jan 13, 2026
  17. DrahtBot removed the label CI failed on Jan 13, 2026
  18. vasild approved
  19. vasild commented at 8:15 am on January 14, 2026: contributor
    ACK c5ec0e5317118d84182dd92c1c01c2422d0abc5d
  20. DrahtBot requested review from janb84 on Jan 14, 2026
  21. janb84 commented at 8:34 am on January 14, 2026: contributor

    ACK c5ec0e5317118d84182dd92c1c01c2422d0abc5d

    Unlike my earlier judgement that getting some information about failed broadcasts in the (normal) logging would be nice, It makes much more sense to retrieve that information via an RPC call.

  22. in src/net_processing.cpp:3680 in c5ec0e5317
    3676@@ -3677,8 +3677,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
    3677             if (fRelay) {
    3678                 MakeAndPushMessage(pfrom, NetMsgType::VERACK);
    3679             } else {
    3680-                LogInfo("[privatebroadcast] Disconnecting: does not support transactions relay (connected in vain), peer=%d%s",
    3681-                        pfrom.GetId(), pfrom.LogIP(fLogIPs));
    3682+                LogDebug(BCLog::PRIVBROADCAST, "Disconnecting: does not support transactions relay (connected in vain), peer=%d%s",
    


    maflcko commented at 8:57 am on January 14, 2026:
    transactions relay -> transaction relay [“transactions relay” is ungrammatical; use the singular “transaction relay” for correct phrasing]
    

    nit in the first commit: I think the LLM is right here


    l0rinc commented at 9:34 am on January 14, 2026:
  23. in src/init/common.cpp:103 in e70198fc7e outdated
     97@@ -98,6 +98,11 @@ util::Result<void> SetLoggingCategories(const ArgsManager& args)
     98             return util::Error{strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)};
     99         }
    100     }
    101+
    102+    if (LogInstance().GetCategoryMask() != BCLog::NONE) {
    103+        LogInfo("Debug logging is enabled (-debug). These logs may contain privacy-sensitive information (e.g., transaction IDs) and should not be shared publicly.");
    


    maflcko commented at 9:03 am on January 14, 2026:

    nit in e70198fc7e3ebd19ef19847fa4ee2f8ba7f109ac:

    Even without debug logging, the log may contain the user name (datadir path), the wallet name (if one exists), the system specs, …

    So I think this can be dropped or made more general?


    l0rinc commented at 9:31 am on January 14, 2026:
    Is it not generally true that debug logs can contain more private info? I don’t see how the above is private (except wallet name maybe). What do you suggest?

    maflcko commented at 10:06 am on January 14, 2026:

    It is just a nit, because I think the user name could be first_name_last_name, which seems private. Also, even the timestamps of when the node was started/stopped could be privacy-sensitive, because they could allow a rough geo-location and transaction-pre-sampling. If someone were to use Bitcoin Core in sufficiently short bursts (e.g. a few minutes to send a transaction every few days) , I’d expect that after a few months, transactions could be uniquely identified and tied to the users wallet, just based on the timestamps when Bitcoin Core was started and shut down.

    So I think implying that only -debug logs can leak sensitive information doesn’t seem ideal. But again, this is just a nit.


    l0rinc commented at 11:18 am on January 14, 2026:

    I still think we should inform the user that -debug leaks more information - do you disagree? I have reworded the -debug warning to be more general, does that align with your view? https://github.com/bitcoin/bitcoin/compare/ae41ffc90f91f5f6ed685041eed17f1969c454d8..b39291f4cde03d5aa7936bf5aa7cc4fa18f65cad


    Additionally we could of course extend this to avoid printing other private stuff, e.g.

     0diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp
     1--- a/src/torcontrol.cpp	(revision ae41ffc90f91f5f6ed685041eed17f1969c454d8)
     2+++ b/src/torcontrol.cpp	(revision 5ba7f3080171f86b483ef1d3e7acb1bb2ab6a50c)
     3@@ -446,7 +446,7 @@
     4             return;
     5         }
     6         service = LookupNumeric(std::string(service_id+".onion"), Params().GetDefaultPort());
     7-        LogInfo("Got tor service ID %s, advertising service %s\n", service_id, service.ToStringAddrPort());
     8+        LogDebug(BCLog::TOR, "Got tor service ID %s, advertising service %s\n", service_id, service.ToStringAddrPort());
     9         if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) {
    10             LogDebug(BCLog::TOR, "Cached service private key to %s\n", fs::PathToString(GetPrivateKeyFile()));
    11         } else {
    

    but that’s slightly outside the scope of this PR.


    maflcko commented at 12:50 pm on January 14, 2026:

    I still think we should inform the user that -debug leaks more information - do you disagree?

    No, it seems fine. It is just that the warning will go away as soon as the user removes -debug. So they may think that the logs are now stripped and good to share. However, there are many leaks on the info level (apart from the above, the simplest being the wallet logging all txids belonging to you).

    So I think either users are assumed to know this, and then the whole log can be removed. Or, users should be warned about this, and then the if (LogInstance().GetCategoryMask() != BCLog::NONE) should be removed and the warning be printed always.


    l0rinc commented at 12:56 pm on January 14, 2026:
    aren’t we deliberately trying to avoid logging sensitive information by default? The current warning just notes that the user would be sharing more sensitive info. What do others think?

    vasild commented at 3:13 pm on January 14, 2026:

    However, there are many leaks on the info level (apart from the above, the simplest being the wallet logging all txids belonging to you).

    If the wallet is logging our txids at info level, then this PR will help nothing.


    andrewtoth commented at 3:15 pm on January 14, 2026:

    If the wallet is logging our txids at info level, then this PR will help nothing.

    Private broadcasting txs is orthogonal to using a wallet in bitcoind.


    vasild commented at 3:26 pm on January 14, 2026:

    Why? I plan to have the wallet broadcast its transactions using the private broadcast mechanism as well.

    Anyway, generally, I meant – if there is any part of the code (wallet or whatever) already logging our txids at info level, then this PR will help nothing, unless we change that one as well.


    l0rinc commented at 3:27 pm on January 14, 2026:
    I will look into that, was hoping we can tackle the leak more broadly in this PR

    andrewtoth commented at 4:30 pm on January 14, 2026:

    Using an external wallet and using the bitcoind node just to broadcast your txs does not require the internal wallet, and this PR helps by not leaking any information about that in the logs.

    Using this with the internal wallet is a great next step, and you are right that this PR does not help not leak anything in the logs if you are using private broadcast along with the internal wallet.


    vasild commented at 8:06 am on January 15, 2026:

    If the wallet is logging our txids at info level

    It is:

    02025-12-...Z [privatebroadcast:info] Received our privately broadcast transaction (txid=xyz) from the network from peer=1706 peeraddr=...; stopping private broadcast attempts
    12025-12-...Z [walletname] AddToWallet xyz  new InMempool
    

    https://github.com/bitcoin/bitcoin/blob/9d2b8fddad463f70171906dbe68dbd4681ea1aca/src/wallet/wallet.h#L938


    l0rinc commented at 10:02 am on January 15, 2026:
    I’m handling the wallet logs in a separate PR - will push soon

    l0rinc commented at 1:17 pm on January 19, 2026:
  24. net: move `privatebroadcast` logs to debug category
    Private broadcast is a privacy feature, and users may share `debug.log` with support.
    Unconditional log messages that mention private broadcast and/or include (w)txids can leak which transactions a user originated.
    
    Move private broadcast event logging from `LogInfo()` to `LogDebug(BCLog::PRIVBROADCAST, ...)` so it is only emitted when debug logging is enabled, and drop the hardcoded "[privatebroadcast]" prefixes.
    Keep warnings at the default log level without (w)txids, detailed context remains available under `-debug=privatebroadcast`.
    
    Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
    31b771a942
  25. l0rinc force-pushed on Jan 14, 2026
  26. init: log that additional logs may contain privacy-sensitive information
    Log an info message when any `-debug` categories are enabled, noting they may contain privacy-sensitive information (e.g. transaction IDs) and should not be shared publicly.
    
    Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
    Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
    c7028d3368
  27. doc: fix `-logips` description to clarify that non-debug logs can also contain IP addresses
    IP addresses controlled by `-logips` are also logged in non-debug outputs:
    * LogInfo "outbound peer headers chain has insufficient work" -> src/net_processing.cpp:2909
    * LogInfo "Outbound peer has old chain" -> src/net_processing.cpp:5301
    * LogInfo "Peer is stalling block download" -> src/net_processing.cpp:6057
    * LogInfo "Timeout downloading block" -> src/net_processing.cpp:6076
    * LogInfo "Timeout downloading headers" -> src/net_processing.cpp:6092
    * LogInfo "Timeout downloading headers from noban peer, not …" -> src/net_processing.cpp:6096
    * LogError "Cannot load block from disk" -> src/net_processing.cpp:2386 and src/net_processing.cpp:2399
    
    Co-authored-by: Vasil Dimov <vd@freebsd.org>
    b39291f4cd
  28. l0rinc force-pushed on Jan 14, 2026
  29. DrahtBot added the label CI failed on Jan 14, 2026
  30. DrahtBot removed the label CI failed on Jan 14, 2026
  31. janb84 commented at 11:50 am on January 19, 2026: contributor

    re ACK b39291f4cde03d5aa7936bf5aa7cc4fa18f65cad

    This PR is a good start to not log privacy sensitive information in the log. It’s not resolving everything but it makes an effort to reduce the problem. This will fix the logging of PII when using the new feature Private Broadcast. (will only log in debug with flag)

  32. DrahtBot requested review from vasild on Jan 19, 2026
  33. l0rinc requested review from maflcko on Jan 20, 2026
  34. l0rinc requested review from andrewtoth on Jan 20, 2026
  35. maflcko commented at 3:17 pm on January 20, 2026: member

    No objection. I just don’t understand what the greater goal here is.

    I think it is generally impossible to assume the debug log does not leak any private (transaction) details. See #34267 (review). Even if the wallet logging is turned into debug, simply the timestamp when a transaction is created is enough to recover the txid (or a set of txids) based on the anti-fee-sniping fingerprint. Possibly also the coin selection may print a unique tx fingerprint.

    Personally I think it is fine to leave this as-is, or add a log: LogInfo("These logs may contain privacy-sensitive information (e.g., transaction IDs) and should not be shared publicly.");

  36. l0rinc commented at 3:28 pm on January 20, 2026: contributor

    I just don’t understand what the greater goal here is.

    The purpose of this change is that this is meant to be a private broadcast so we should minimize leaks. It’s a best effort, it’s not invalidated by other logs possibly leaking identifiable information, those can be addressed separately. We’re not promising that the logs won’t contain data that could be used against you, but I think we should still try to minimize that data, especially for a feature that’s advertised as privacy focused.

    simply the timestamp when a transaction is created is enough to recover the txid

    This is an independent concern, can be tackled either by #34118 or as also described in the original PR:

    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.

    See @andrewtoth’s PR and a related comment by @tankyleo in #34322 (comment).

  37. maflcko commented at 4:24 pm on January 20, 2026: member

    So the scope here is just logging which by itself directly identifies a transaction?

    Otherwise, i am pretty confident that trying to avoid indirectly identifying logging is only possible via -nodebuglogfile and -noprinttoconsole.

  38. l0rinc commented at 4:27 pm on January 20, 2026: contributor
    I’m not trying to eliminate the possibility of identification here, just reduce the likelihood.
  39. vasild approved
  40. vasild commented at 8:30 am on January 21, 2026: contributor

    ACK b39291f4cde03d5aa7936bf5aa7cc4fa18f65cad

    I agree with @maflcko. IMO the PR looks good, but I think it is fine if the code is left as it is. This PR also changes some logs from info to debug that do not contain txid, like Disconnecting: does not support transactions relay (connected in vain) I think those were too noisy anyway so a change to debug seems welcome regardless of privacy concerns.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-01-22 09:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me