From 2ca856f7fb824205344e3c19d3e6d7cdc25a49fe Mon Sep 17 00:00:00 2001 From: merge-script Date: Mon, 18 May 2026 14:19:18 +0100 Subject: [PATCH 1/2] Merge bitcoin/bitcoin#35117: i2p: clean up SESSION CREATE error logging b6c367044288f83ab61c1a77ad34c33adf39ecf6 i2p: clean up SAM error logging (takeshikurosawaa) Pull request description: Clean up the I2P SAM error path. `SESSION CREATE` may contain the private key, so the generic SAM reply error path now reports the redacted request text instead of the full request. It also avoids echoing raw router replies in those generic error messages. No network behavior change intended. ACKs for top commit: davidgumberg: crACK https://github.com/bitcoin/bitcoin/pull/35117/commits/b6c367044288f83ab61c1a77ad34c33adf39ecf6 vasild: ACK b6c367044288f83ab61c1a77ad34c33adf39ecf6 Tree-SHA512: 204c8b64c6d3dd2f94f92cdc6d3daefd7773c42066984b9da859ebc2912c2ed38079d9e82a2d1f09d8d720750047114a80189e688929d7a0af5da2c2ee4a88da (cherry picked from commit b2a3ca3df901dcc19b07f7dcf3115d8f7835b931) --- src/i2p.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i2p.cpp b/src/i2p.cpp index 04093ea1007f..03513576c459 100644 --- a/src/i2p.cpp +++ b/src/i2p.cpp @@ -285,7 +285,7 @@ std::string Session::Reply::Get(const std::string& key) const const auto& pos = keys.find(key); if (pos == keys.end() || !pos->second.has_value()) { throw std::runtime_error( - strprintf("Missing %s= in the reply to \"%s\": \"%s\"", key, request, full)); + strprintf("Missing %s= in the reply to \"%s\"", key, request)); } return pos->second.value(); } @@ -320,7 +320,7 @@ Session::Reply Session::SendRequestAndGetReply(const Sock& sock, if (check_result_ok && reply.Get("RESULT") != "OK") { throw std::runtime_error( - strprintf("Unexpected reply to \"%s\": \"%s\"", request, reply.full)); + strprintf("Reply to \"%s\": had a RESULT not equal to OK.", reply.request)); } return reply; From 7210b7fe7b1083845c895992eec8d267a73f69bf Mon Sep 17 00:00:00 2001 From: merge-script Date: Tue, 19 May 2026 15:32:56 +0100 Subject: [PATCH 2/2] Merge bitcoin/bitcoin#34934: fuzz: exercise ForNode/ForEachNode callbacks in connman fuzz harness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 371eac8069a47f27c3c388c7cb2251f0a2a1d8e8 fuzz: exercise ForNode/ForEachNode callbacks in connman fuzz harness (frankomosh) Pull request description: Track inserted node IDs and sometimes reuse them in `ForNode()` so the successful lookup path is exercised more reliably. Replace no-op callbacks with lightweight CNode accessor calls to make `ForEachNode()` and `ForNode()` cover previously unreached callback code paths. This addresses feedback from https://github.com/bitcoin/bitcoin/pull/34830#issuecomment-4074732710 where it was noted that the callbacks had "neither the return type checked nor its side-effect”. Coverage reports from the connman fuzz corpus, before and after the change: - [Before](https://frankomosh.github.io/fuzz-coverage/connman-callback-coverage/before/index.html) - [After](https://frankomosh.github.io/fuzz-coverage/connman-callback-coverage/after/index.html) `diff cov_show_before.txt cov_show_after.txt` filtered to `ForNode`/`ForEachNode`/`IsFullOutboundConn`/`ConnectionTypeAsString`: **`IsFullOutboundConn` — `net.h:786-788`** ```diff - 786| 0| bool IsFullOutboundConn() const { - 787| 0| return m_conn_type == ConnectionType::OUTBOUND_FULL_RELAY; - 788| 0| } + 786| 1.13M| bool IsFullOutboundConn() const { + 787| 1.13M| return m_conn_type == ConnectionType::OUTBOUND_FULL_RELAY; + 788| 1.13M| } ``` **`ConnectionTypeAsString` — `net.h:967`** ```diff - 967| 0| std::string ConnectionTypeAsString() const { return ::ConnectionTypeAsString(m_conn_type); } + 967| 1.11M| std::string ConnectionTypeAsString() const { return ::ConnectionTypeAsString(m_conn_type); } ``` **`ForNode` — `net.cpp:4126-4131`** ```diff - 4126| 1.08k| if(pnode->GetId() == id) { - | Branch (4126:12): [True: 0, False: 1.08k] - 4127| 0| found = pnode; - 4131| 39| return found != nullptr && NodeFullyConnected(found) && func(found); - ^0 ^0 + 4126| 602| if(pnode->GetId() == id) { + | Branch (4126:12): [True: 1, False: 601] + 4127| 1| found = pnode; + 4131| 28| return found != nullptr && NodeFullyConnected(found) && func(found); + ^1 ^1 ``` **`ForEachNode` — `net.h:1270-1271`** ```diff - 1270| 1.13M| if (NodeFullyConnected(node)) - | Branch (1270:17): [True: 0, False: 1.13M] - 1271| 0| func(node); + 1270| 1.11M| if (NodeFullyConnected(node)) + | Branch (1270:17): [True: 1.11M, False: 0] + 1271| 1.11M| func(node); ``` Two previously uncovered functions (`IsFullOutboundConn`, `ConnectionTypeAsString`) are now exercised through the iteration callbacks. `ForNode` finds matching nodes. ACKs for top commit: nervana21: tACK 371eac8069a47f27c3c388c7cb2251f0a2a1d8e8 maflcko: lgtm ACK 371eac8069a47f27c3c388c7cb2251f0a2a1d8e8 Tree-SHA512: 3587c021b16e38ca252676a21b66c5383ab2bd3eec9073e61e9a93db7ef84a94ce5a0c037ac512483680cafabb44103b86df0893e8a9b1bf63b8383bd54f4641 (cherry picked from commit 278b9e39df2d7298fadf88f76607463005b6eb3c) --- src/test/fuzz/connman.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp index 1b0859d6ffe4..7ac4f3b8c549 100644 --- a/src/test/fuzz/connman.cpp +++ b/src/test/fuzz/connman.cpp @@ -99,12 +99,14 @@ FUZZ_TARGET(connman, .init = initialize_connman) CNode random_node = ConsumeNode(fuzzed_data_provider); CSubNet random_subnet; std::string random_string; + std::vector node_ids; LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100) { CNode& p2p_node{*ConsumeNodeAsUniquePtr(fuzzed_data_provider).release()}; // Simulate post-handshake state. p2p_node.fSuccessfullyConnected = true; connman.AddTestNode(p2p_node); + node_ids.push_back(p2p_node.GetId()); } LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) { @@ -141,10 +143,15 @@ FUZZ_TARGET(connman, .init = initialize_connman) connman.DisconnectNode(random_subnet); }, [&] { - connman.ForEachNode([](auto) {}); - }, - [&] { - (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); }); + NodeId id = node_ids.empty() || fuzzed_data_provider.ConsumeBool() + ? fuzzed_data_provider.ConsumeIntegral() + : PickValue(fuzzed_data_provider, node_ids); + (void)connman.ForNode(id, [&](CNode* pnode) { + (void)pnode->GetId(); + (void)pnode->IsInboundConn(); + (void)pnode->IsFullOutboundConn(); + return true; + }); }, [&] { auto max_addresses = fuzzed_data_provider.ConsumeIntegral(); @@ -228,6 +235,12 @@ FUZZ_TARGET(connman, .init = initialize_connman) connman.SocketHandlerPublic(); }); } + connman.ForEachNode([](CNode* pnode) { + (void)pnode->GetId(); + (void)pnode->IsInboundConn(); + (void)pnode->IsFullOutboundConn(); + (void)pnode->ConnectionTypeAsString(); + }); (void)connman.GetAddedNodeInfo(fuzzed_data_provider.ConsumeBool()); (void)connman.GetExtraFullOutboundCount(); (void)connman.GetLocalServices();