@@ -33,16 +33,18 @@ This audit found **4 bugs**, **2 security issues**, **5 performance issues**,
3333test-quality weaknesses** that reduce confidence in the test suite.
3434
3535All 4 bugs, both security issues, and 1 performance issue were resolved in
36- ** 018-audit-bug-security-fixes** . Remaining items are tracked below.
36+ ** 018-audit-bug-security-fixes** . Three more performance issues, both
37+ duplication clusters, and 1 test-quality issue were resolved in
38+ ** 019-perf-dedup-cleanup** . Remaining items are tracked below.
3739
3840| Category | Found | Resolved | Remaining | Highest Open Severity |
3941| -----------------------| ------:| ---------:| ----------:| ----------------------:|
4042| Bugs | 4 | 4 | 0 | — |
4143| Security issues | 2 | 2 | 0 | — |
42- | Performance issues | 5 | 1 | 4 | Medium |
43- | Code duplication | 2 | 0 | 2 | Medium |
44+ | Performance issues | 5 | 4 | 1 | Low |
45+ | Code duplication | 2 | 2 | 0 | — |
4446| Architecture concerns | 3 | 0 | 3 | Medium |
45- | Test quality issues | 6 | 0 | 6 | High |
47+ | Test quality issues | 6 | 1 | 5 | High |
4648
4749---
4850
@@ -91,39 +93,29 @@ returns JSON-RPC error -32001 "Block not found" for out-of-range indices.
9193
9294## 4. Performance Issues
9395
94- ### 4.1 O(n) peer lookups — MEDIUM
96+ ### 4.1 ~~ O(n) peer lookups — MEDIUM~~ ✅ RESOLVED (019)
9597
96- ` find_peer() ` , ` add_peer() ` , ` remove_peer() ` , ` is_banned() ` , and
97- ` get_non_banned_peer_addresses() ` all perform linear scans over
98- ` std::vector<PeerEntry> ` and ` std::vector<BanRecord> ` .
98+ ` peers_ ` and ` bans_ ` are now ` std::unordered_map<std::string, PeerEntry/BanRecord> `
99+ keyed by ` host:port ` , giving O(1) lookups in ` find_peer() ` , ` add_peer() ` ,
100+ ` remove_peer() ` , ` is_banned() ` , ` ban_peer() ` , ` unban_peer() ` , and
101+ ` get_non_banned_peer_addresses() ` .
99102
100- With a configured maximum of 256 stored peers and ` is_banned() ` called on
101- every peer exchange, connection attempt, and block reception, switching to
102- ` std::unordered_map<std::string, PeerEntry> ` keyed by ` host:port ` would drop
103- lookups from O(n) to O(1).
103+ ### 4.2 ~~ RPC dispatch is a 21-branch ` if ` /` else ` chain — MEDIUM~~ ✅ RESOLVED (019)
104104
105- ### 4.2 RPC dispatch is a 21-branch ` if ` /` else ` chain — MEDIUM
106-
107- [ RpcServer.cpp] ( ../src/network/RpcServer.cpp#L74-L704 )
108-
109- Every request walks up to 21 string comparisons. A
110- ` std::unordered_map<std::string, Handler> ` dispatch table would be O(1) and
111- reduce the 700-line ` do_read() ` callback into individually testable handler
112- functions.
105+ ` do_read() ` now performs a single ` dispatch_.find(method) ` lookup into an
106+ ` std::unordered_map<std::string, RpcHandler> ` initialized in ` init_dispatch() ` .
107+ All 20 handlers are private methods returning ` nlohmann::json ` .
113108
114109### 4.3 ~~ ` recoverChain() ` loads each chunk multiple times — MEDIUM~~ ✅ RESOLVED (018)
115110
116111Resolved together with §2.2. Single-pass recovery loads each chunk once.
117112
118- ### 4.4 String construction in log calls — LOW
119-
120- Throughout the codebase, ` logMessage("INFO", "Block #" + std::to_string(...) + ...) `
121- constructs the string even when the log level would suppress it. The
122- ` logMessage() ` function already filters by level, but the string allocation
123- happens at the call site.
113+ ### 4.4 ~~ String construction in log calls — LOW~~ ✅ RESOLVED (019)
124114
125- ** Fix:** A level-check macro or a lazy-evaluation wrapper would eliminate
126- unnecessary allocations.
115+ Hot-path ` logMessage() ` calls in ` PeerManager.cpp ` , ` BlockPropagation.cpp ` ,
116+ ` PeerClient.cpp ` , and ` PeerServer.cpp ` have been replaced with lazy
117+ ` LOG_INFO ` /` LOG_WARN ` /` LOG_ERROR ` /` LOG_DEBUG ` macros that check ` getLogLevel() `
118+ before evaluating the message expression.
127119
128120### 4.5 ` replaceChain() ` loads entire candidate into memory — LOW
129121
@@ -137,19 +129,18 @@ simultaneously. A streaming/chunked replacement would bound memory usage.
137129
138130## 5. Code Duplication
139131
140- ### 5.1 Packet serialization in PeerClient and PeerServer — MEDIUM
132+ ### 5.1 ~~ Packet serialization in PeerClient and PeerServer — MEDIUM~~ ✅ RESOLVED (019)
141133
142- ` PeerClient::send<T>() ` ( [ PeerClient.cpp ] ( ../src/network/PeerClient.cpp#L352-L375 ) ) and
143- ` PeerServer::send_packet <T>()` ( [ PeerServer.cpp ] ( ../src/network/PeerServer.cpp#L271-L300 ) )
144- share the same serialize → ` PacketHeader ` → ` memcpy ` → ` async_write ` pattern.
145- This could live in a shared utility or base class .
134+ Both ` PeerClient::send<T>() ` and ` PeerServer::send_packet<T>() ` now call the
135+ shared ` serialize_packet <T>()` template from ` PacketSerializer.hpp ` , which
136+ returns header bytes + serialized payload. Each caller retains its own
137+ ` async_write ` logic .
146138
147- ### 5.2 Test files still duplicate ` mineTestBlock() ` / ` buildValidChain() ` — LOW
139+ ### 5.2 ~~ Test files still duplicate ` mineTestBlock() ` / ` buildValidChain() ` — LOW~~ ✅ RESOLVED (019)
148140
149- Despite ` TestHelpers.hpp ` existing, ` sync_tests.cpp ` ,
150- ` block_propagation_tests.cpp ` , ` consensus_tests.cpp ` , and
151- ` chunk_persistence_tests.cpp ` still define their own local versions of
152- ` mineTestBlock() ` , ` buildValidChain() ` , and temporary-directory helpers.
141+ Local helper definitions in ` sync_tests.cpp ` , ` consensus_tests.cpp ` , and
142+ ` chunk_persistence_tests.cpp ` have been removed. All test files now use the
143+ shared ` TestHelpers:: ` namespace.
153144
154145---
155146
@@ -263,13 +254,12 @@ The following behaviors have no test coverage:
263254| Block propagation relay excludes sender correctly | Medium | Open |
264255| ` recoverChain() ` with corrupted index files (fallback to chunk rebuild) | Medium | Open |
265256
266- ### 7.6 Duplicated test setup persists in 4 files — LOW
257+ ### 7.6 ~~ Duplicated test setup persists in 4 files — LOW~~ ✅ RESOLVED (019)
267258
268- Despite ` TestHelpers.hpp ` existing, ` sync_tests.cpp ` ,
269- ` block_propagation_tests.cpp ` , ` consensus_tests.cpp ` , and
270- ` chunk_persistence_tests.cpp ` still define local ` mineTestBlock() ` /
271- ` buildValidChain() ` / temp directory helpers instead of using the shared
272- utilities.
259+ All local test helper definitions have been removed. Test files now use
260+ ` TestHelpers::mineTestBlock() ` , ` TestHelpers::buildValidChain() ` ,
261+ ` TestHelpers::createTestDir() ` , ` TestHelpers::cleanupTestDir() ` , and
262+ ` TestHelpers::make_block() ` exclusively.
273263
274264---
275265
@@ -288,8 +278,8 @@ Ordered by impact and effort:
288278| 5 | Rewrite ` rpc_expansion_tests.cpp ` to test real RPC handlers (§7.3) | False confidence → real coverage | Medium | Open |
289279| 6 | Replace trivial assertions with meaningful ones (§7.1, §7.2) | Catches actual regressions | Medium | Open |
290280| 7 | Cache chunk during ` recoverChain() ` validation (§2.2, §4.3) | 3× faster startup | Low | ✅ Done (018) |
291- | 8 | Replace O(n) peer lookups with ` unordered_map ` (§4.1) | O(1) peer operations | Medium | Open |
292- | 9 | Extract RPC dispatch table from ` do_read() ` (§4.2) | Maintainability, testability | Medium | Open |
281+ | 8 | Replace O(n) peer lookups with ` unordered_map ` (§4.1) | O(1) peer operations | Medium | ✅ Done (019) |
282+ | 9 | Extract RPC dispatch table from ` do_read() ` (§4.2) | Maintainability, testability | Medium | ✅ Done (019) |
293283| 10 | Narrow ` IBlockchain ` into reader/writer interfaces (§6.1) | Reduces coupling | Medium | Open |
294- | 11 | Remove local test helpers in favor of ` TestHelpers.hpp ` (§7.6) | Consistency | Low | Open |
284+ | 11 | Remove local test helpers in favor of ` TestHelpers.hpp ` (§7.6) | Consistency | Low | ✅ Done (019) |
295285| 12 | Make integration tests deterministic (§7.4) | Reduces CI flakiness | Medium | Open |
0 commit comments