From 31b771a9425dace38582e0de0fb468f388df170c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Tue, 13 Jan 2026 12:01:28 +0100 Subject: [PATCH 1/3] 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 --- src/net.cpp | 2 +- src/net_processing.cpp | 38 +++++++++++++++++++------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index d92cb72ccc3..339a32dc982 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3239,7 +3239,7 @@ void CConnman::ThreadPrivateBroadcast() std::optional proxy; const std::optional net{m_private_broadcast.PickNetwork(proxy)}; if (!net.has_value()) { - LogWarning("[privatebroadcast] Connections needed but none of the Tor or I2P networks is reachable"); + LogWarning("Unable to open -privatebroadcast connections: neither Tor nor I2P is reachable"); m_interrupt_net->sleep_for(5s); continue; } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 84c0ba9c41b..e23e2fc73b7 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1653,9 +1653,9 @@ void PeerManagerImpl::ReattemptPrivateBroadcast(CScheduler& scheduler) stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString()); ++num_for_rebroadcast; } else { - LogInfo("[privatebroadcast] Giving up broadcast attempts for txid=%s wtxid=%s: %s", - stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString(), - mempool_acceptable.m_state.ToString()); + LogDebug(BCLog::PRIVBROADCAST, "Giving up broadcast attempts for txid=%s wtxid=%s: %s", + stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString(), + mempool_acceptable.m_state.ToString()); m_tx_for_private_broadcast.Remove(stale_tx); } } @@ -3536,9 +3536,9 @@ void PeerManagerImpl::PushPrivateBroadcastTx(CNode& node) } const CTransactionRef& tx{*opt_tx}; - LogInfo("[privatebroadcast] P2P handshake completed, sending INV for txid=%s%s, peer=%d%s", - tx->GetHash().ToString(), tx->HasWitness() ? strprintf(", wtxid=%s", tx->GetWitnessHash().ToString()) : "", - node.GetId(), node.LogIP(fLogIPs)); + LogDebug(BCLog::PRIVBROADCAST, "P2P handshake completed, sending INV for txid=%s%s, peer=%d%s", + tx->GetHash().ToString(), tx->HasWitness() ? strprintf(", wtxid=%s", tx->GetWitnessHash().ToString()) : "", + node.GetId(), node.LogIP(fLogIPs)); MakeAndPushMessage(node, NetMsgType::INV, std::vector{{CInv{MSG_TX, tx->GetHash().ToUint256()}}}); } @@ -3677,8 +3677,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, if (fRelay) { MakeAndPushMessage(pfrom, NetMsgType::VERACK); } else { - LogInfo("[privatebroadcast] Disconnecting: does not support transactions relay (connected in vain), peer=%d%s", - pfrom.GetId(), pfrom.LogIP(fLogIPs)); + LogDebug(BCLog::PRIVBROADCAST, "Disconnecting: does not support transaction relay (connected in vain), peer=%d%s", + pfrom.GetId(), pfrom.LogIP(fLogIPs)); pfrom.fDisconnect = true; } return; @@ -4203,8 +4203,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, if (pfrom.IsPrivateBroadcastConn()) { const auto pushed_tx_opt{m_tx_for_private_broadcast.GetTxForNode(pfrom.GetId())}; if (!pushed_tx_opt) { - LogInfo("[privatebroadcast] Disconnecting: got GETDATA without sending an INV, peer=%d%s", - pfrom.GetId(), fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToStringAddrPort()) : ""); + LogDebug(BCLog::PRIVBROADCAST, "Disconnecting: got GETDATA without sending an INV, peer=%d%s", + pfrom.GetId(), fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToStringAddrPort()) : ""); pfrom.fDisconnect = true; return; } @@ -4220,8 +4220,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, peer->m_ping_queued = true; // Ensure a ping will be sent: mimic a request via RPC. MaybeSendPing(pfrom, *peer, GetTime()); } else { - LogInfo("[privatebroadcast] Disconnecting: got an unexpected GETDATA message, peer=%d%s", - pfrom.GetId(), fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToStringAddrPort()) : ""); + LogDebug(BCLog::PRIVBROADCAST, "Disconnecting: got an unexpected GETDATA message, peer=%d%s", + pfrom.GetId(), fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToStringAddrPort()) : ""); pfrom.fDisconnect = true; } return; @@ -4465,9 +4465,9 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, AddKnownTx(*peer, hash); if (const auto num_broadcasted{m_tx_for_private_broadcast.Remove(ptx)}) { - LogInfo("[privatebroadcast] Received our privately broadcast transaction (txid=%s) from the " - "network from peer=%d%s; stopping private broadcast attempts", - txid.ToString(), pfrom.GetId(), pfrom.LogIP(fLogIPs)); + LogDebug(BCLog::PRIVBROADCAST, "Received our privately broadcast transaction (txid=%s) from the " + "network from peer=%d%s; stopping private broadcast attempts", + txid.ToString(), pfrom.GetId(), pfrom.LogIP(fLogIPs)); if (NUM_PRIVATE_BROADCAST_PER_TX > num_broadcasted.value()) { // Not all of the initial NUM_PRIVATE_BROADCAST_PER_TX connections were needed. // Tell CConnman it does not need to start the remaining ones. @@ -4981,8 +4981,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, pfrom.PongReceived(ping_time); if (pfrom.IsPrivateBroadcastConn()) { m_tx_for_private_broadcast.NodeConfirmedReception(pfrom.GetId()); - LogInfo("[privatebroadcast] Got a PONG (the transaction will probably reach the network), marking for disconnect, peer=%d%s", - pfrom.GetId(), pfrom.LogIP(fLogIPs)); + LogDebug(BCLog::PRIVBROADCAST, "Got a PONG (the transaction will probably reach the network), marking for disconnect, peer=%d%s", + pfrom.GetId(), pfrom.LogIP(fLogIPs)); pfrom.fDisconnect = true; } } else { @@ -5697,8 +5697,8 @@ bool PeerManagerImpl::SendMessages(CNode* pto) // not sent. This here is just an optimization. if (pto->IsPrivateBroadcastConn()) { if (pto->m_connected + PRIVATE_BROADCAST_MAX_CONNECTION_LIFETIME < current_time) { - LogInfo("[privatebroadcast] Disconnecting: did not complete the transaction send within %d seconds, peer=%d%s", - count_seconds(PRIVATE_BROADCAST_MAX_CONNECTION_LIFETIME), pto->GetId(), pto->LogIP(fLogIPs)); + LogDebug(BCLog::PRIVBROADCAST, "Disconnecting: did not complete the transaction send within %d seconds, peer=%d%s", + count_seconds(PRIVATE_BROADCAST_MAX_CONNECTION_LIFETIME), pto->GetId(), pto->LogIP(fLogIPs)); pto->fDisconnect = true; } return true; From c7028d3368e90fef2dd2a7ae68877767d602eff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Tue, 13 Jan 2026 12:01:41 +0100 Subject: [PATCH 2/3] 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 Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> --- src/init/common.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/init/common.cpp b/src/init/common.cpp index d1926d04940..5436cba59c2 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -98,6 +98,11 @@ util::Result SetLoggingCategories(const ArgsManager& args) return util::Error{strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)}; } } + + if (LogInstance().GetCategoryMask() != BCLog::NONE) { + LogInfo("Debug logging is enabled (-debug). Additional log output may contain privacy-sensitive information. Be cautious when sharing logs."); + } + return {}; } From b39291f4cde03d5aa7936bf5aa7cc4fa18f65cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Tue, 13 Jan 2026 22:36:59 +0100 Subject: [PATCH 3/3] doc: fix `-logips` description to clarify that non-debug logs can also contain IP addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/init/common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init/common.cpp b/src/init/common.cpp index 5436cba59c2..c0695e52faa 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -31,7 +31,7 @@ void AddLoggingArgs(ArgsManager& argsman) "If is not supplied or if is 1 or \"all\", output all debug logging. If is 0 or \"none\", any other categories are ignored. Other valid values for are: " + LogInstance().LogCategoriesString() + ". This option can be specified multiple times to output multiple categories.", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-debugexclude=", "Exclude debug and trace logging for a category. Can be used in conjunction with -debug=1 to output debug and trace logging for all categories except the specified category. This option can be specified multiple times to exclude multiple categories. This takes priority over \"-debug\"", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); - argsman.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + argsman.AddArg("-logips", strprintf("Include IP addresses in log output (default: %u)", DEFAULT_LOGIPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-loglevel=|:", strprintf("Set the global or per-category severity level for logging categories enabled with the -debug configuration option or the logging RPC. Possible values are %s (default=%s). The following levels are always logged: error, warning, info. If : is supplied, the setting will override the global one and may be specified multiple times to set multiple category-specific levels. can be: %s.", LogInstance().LogLevelsString(), LogInstance().LogLevelToStr(BCLog::DEFAULT_LOG_LEVEL), LogInstance().LogCategoriesString()), ArgsManager::DISALLOW_NEGATION | ArgsManager::DISALLOW_ELISION | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logthreadnames", strprintf("Prepend debug output with name of the originating thread (default: %u)", DEFAULT_LOGTHREADNAMES), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);