What changed, and why it matters
This change makes the ListPeers RPC more reliable. Previously, if the system couldn't retrieve a peer's 'flap count' (a count of connection up/down events), the entire ListPeers request would fail. Now it logs the error and continues, returning the rest of the peer information. This is a robustness improvement rather than a typical security vulnerability, but the original behavior could have been used to deny access to peer information.
No immediate action required. This is a low-risk hardening patch. Operators should ensure debug logs are collected so FlapCount retrieval failures remain observable. Reviewers may want to confirm that silently omitting flap-count data is acceptable for downstream consumers.
Security signals we found
RPC failure mode removed: error from FlapCount no longer aborts ListPeers
Potential denial-of-service vector reduced: malformed or missing flap-count state cannot block peer listing
Debug logging added for error visibility
Integration test coverage added for FlapCount field
Evidence from the diff
In rpcserver.go’s ListPeers handler, the call to r.server.chanEventStore.FlapCount(vertex) previously returned any error directly, causing the RPC to fail. The patch changes this to log the error at debug level and continue execution. The integration test is updated to verify that FlapCount is populated correctly after a channel open event. This is a defensive hardening change that removes a single point of failure in the RPC path.
Changed components
rpcserver.go ListPeers RPC handleritest/lnd_misc_test.go integration testInspect captured patch +16 / −1
diff --git a/itest/lnd_misc_test.go b/itest/lnd_misc_test.go
index 1382327..f625213 100644
--- a/itest/lnd_misc_test.go
+++ b/itest/lnd_misc_test.go
@@ -257,6 +257,17 @@ func testListChannels(ht *lntest.HarnessTest) {
assertChannelConstraintsEqual(
ht, aliceChannel.RemoteConstraints, bobChannel.LocalConstraints,
)
+
+ // Finally we assert that the flap count is updated as expected.
+ resp := alice.RPC.ListPeers()
+
+ // Assert Alice only have one peer.
+ require.Len(ht, resp.Peers, 1)
+ for _, p := range resp.Peers {
+ // The channel open event resulted in an online event, so we
+ // expect the flap count to be 1.
+ require.EqualValues(ht, 1, p.FlapCount)
+ }
}
// testMaxPendingChannels checks that error is returned from remote peer if
diff --git a/rpcserver.go b/rpcserver.go
index 6fb0507..d3d3c51 100644
--- a/rpcserver.go
+++ b/rpcserver.go
@@ -3561,8 +3561,12 @@ func (r *rpcServer) ListPeers(ctx context.Context,
flap, ts, err := r.server.chanEventStore.FlapCount(
vertex,
)
+
+ // Log the error if we cannot get the flap count instead
+ // of failing this RPC call.
if err != nil {
- return nil, err
+ rpcsLog.Debugf("Failed to get flap count for "+
+ "peer %v", vertex)
}
// If our timestamp is non-nil, we have values for our
Why this scored 25/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.