Skip to content

fix: Bound the per-connection peer state cache - #118

Open
giaki3003 wants to merge 5 commits into
LayerTwo-Labs:masterfrom
giaki3003:fix/w3-20260618-1609-kimiclaw-confirm-openclaw--thunder-peer-state-heartbeat-churn-grows-per-con
Open

fix: Bound the per-connection peer state cache#118
giaki3003 wants to merge 5 commits into
LayerTwo-Labs:masterfrom
giaki3003:fix/w3-20260618-1609-kimiclaw-confirm-openclaw--thunder-peer-state-heartbeat-churn-grows-per-con

Conversation

@giaki3003

Copy link
Copy Markdown
Contributor

What's wrong

ConnectionTask::handle_peer_request (lib/net/peer/task.rs) inserts every heartbeat's PeerState into a per-connection HashMap<PeerStateId, PeerState>, and nothing ever removes entries. The peer composes its own heartbeats, so it can produce an unlimited number of distinct states (varying version or tip_info is enough) on a single connection. The map then grows for the lifetime of that connection, at whatever rate the peer is willing to send heartbeats.

The fix

The map becomes a hashlink::LinkedHashMap (already a dependency), and all inserts go through a new insert_peer_state helper that appends at the back and pops from the front once the map exceeds MAX_PEER_STATES (256), so the most recently received states are the ones retained.

Because a state can now be evicted, the two Error::MissingPeerState returns in handle_internal_message would otherwise tear down an otherwise healthy connection; they now log a warning and drop the message instead. 256 is a judgement call — happy to change it, or to make it configurable.

Tests

Adds peer_state_cache_is_bounded, which inserts 2 * MAX_PEER_STATES distinct states and checks that the cache stays at MAX_PEER_STATES and holds exactly the most recent ones.

Finding report (access-controlled): https://giaki3003.tech/#/findings/20260618-1609-kimiclaw-confirm-openclaw-thunder-rust-peer-state-heartbeat-churn


Part of a short series for this repo (fix 2 of 3); builds on #117, so it reads best merged after that one. Happy to rebase or split if you'd prefer them independent.

Ash-L2L and others added 5 commits July 24, 2026 01:39
…ers` response read budget (memory-exhaustion sync DoS)

Bug: w3-20260618-1639-kimiclaw-confirm-glmclaw-t (primary)
Finding: findings/20260618-1639-kimiclaw-confirm-glmclaw-thunder-rust-getheaders-response-limit-inflation.md
Severity: R3-T2

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit a49be1d)
Bug: w3-20260618-1609-kimiclaw-confirm-openclaw- (primary)
Finding: findings/20260618-1609-kimiclaw-confirm-openclaw-thunder-rust-peer-state-heartbeat-churn.md
Severity: R3-T3

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit bbb6c55)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants