Skip to content

[KLC-2418] seednode: reduce log noise + expose /peers, /node/status, /node/metrics#56

Merged
fbsobreira merged 3 commits into
developfrom
chore/KLC-2418-seednode-noise-and-endpoints
May 21, 2026
Merged

[KLC-2418] seednode: reduce log noise + expose /peers, /node/status, /node/metrics#56
fbsobreira merged 3 commits into
developfrom
chore/KLC-2418-seednode-noise-and-endpoints

Conversation

@fbsobreira
Copy link
Copy Markdown
Member

@fbsobreira fbsobreira commented May 21, 2026

Summary

  • Replaces the 5 s INFO peer-table dump (~190 lines/tick at production peer counts) with a single-line summary every 30 s; full table preserved at DEBUG; the "Seednode addresses:" table prints once at startup.
  • Adds GET /peers, GET /node/status, GET /node/metrics (Prometheus). The latter clears the 404 that operator tooling has been hitting in the logs.
  • Refactors cmd/seednode/api into a server struct behind exported Start; /log websocket unchanged. Adds httptest coverage for the new handlers.

INFO output, before / after

Before — every 5 s, ~190 lines at production peer count:

INFO  \n+-- Seednode addresses table (3-5 lines) ----+
INFO  known peers  num peers = 218
INFO  \n+-- Seednode is connected to 187 peers ------+  (187 lines)

After — once at startup + 1 line per 30 s:

INFO  \n+-- Seednode addresses table -------+         (startup only)
INFO  seednode status  connected=187  known=218  gained=3  lost=1  listen=/ip4/.../tcp/.../p2p/...

--log-level '*:DEBUG' still produces the full connected-peers table — no information loss.

New HTTP surface

GET /node/status

{
  "version": "v…",
  "uptimeSeconds": 64,
  "connectedPeers": 187,
  "knownPeers": 218,
  "listenAddresses": ["/ip4/…", "/ip4/127.0.0.1/…", ]
}

GET /peers

{
  "connectedPeers": 187,
  "knownPeers": 218,
  "listenAddresses": [...],
  "connectedAddresses": [...sorted multiaddrs...]
}

GET /node/metrics

seednode_connected_peers 187
seednode_known_peers 218
seednode_uptime_seconds 64
klv_build_info{version="v…",node_type="seednode"} 1

Behavior notes

  • The API now starts after messenger.Bootstrap() (was before) because the new endpoints query the messenger. External scrapers will see a brief connection refused during the bootstrap window instead of a /log-only gin server.
  • uptimeSeconds is "since process start" (captured at the top of startNode), not "since API listener bound".
  • pickReportableListenAddress skips /ip4/127., /ip6/::1/ and the Docker default bridge /ip4/172.17. for the log line only; JSON/Prometheus surfaces report messenger.Addresses() raw (ground truth for monitoring).

Test plan

  • go build ./cmd/seednode/...
  • go vet ./cmd/seednode/...
  • go test ./cmd/seednode/... — 5 new tests passing
  • Local smoke test: seednode emits one seednode status INFO line per 30 s tick, uptimeSeconds advances across ticks, --log-level '*:DEBUG' reinstates the verbose table, /peers /node/status /node/metrics all return expected payloads.
  • Verify against the live network once deployed on a real seed (isolated test seed has no peers to bootstrap with so connected/known stay at 0/1).

References

  • KLC-2358 — the Prometheus pattern already established for regular nodes
  • KLC-2416 — surfacing change that exposed this log-noise issue

Blockchain-Critical Impact Assessment

This PR has minimal blockchain-critical impact — it only touches the seednode (peer discovery/observability) and does not modify consensus, transaction processing, state management, or the KVM.

Affected Components

  • Seednode networking / observability only:
    • Replaces noisy 5s full peer-table INFO dumps with a 30s single-line status log; full peer table remains available at DEBUG and is printed once at startup.
    • Adds HTTP endpoints: GET /peers, GET /node/status, GET /node/metrics (Prometheus).
    • Prometheus metrics: seednode_connected_peers, seednode_known_peers, seednode_uptime_seconds, and optional klv_build_info{version,node_type}.
    • API refactor: Gin-based server moved into a server struct with an exported Start; routes are wired to a messenger-providing interface; the /log websocket is preserved.
    • Human-readable listen-address selection (pickReportableListenAddress) omits loopback and Docker-bridge addresses for the single-line log only; JSON and Prometheus return messenger.Addresses() raw.

Stability and Safety Considerations

  • Minimal risk to node stability or data integrity:
    • No changes to P2P protocol, peer discovery algorithms, message handling, consensus, transaction processing, or persistent state.
    • Peer-visibility changes are observational only; the peer diffing (prevConnected) and emitted status affect only logging/metrics.
    • A defensive copy is now made before sorting ConnectedAddresses in snapshot()/emitPeerStatus to avoid mutating messenger-owned backing slices — this fixes a reported regression and prevents accidental mutation of messenger state visible to other code paths.

Concurrency and Startup Behaviour

  • API startup moved to after messenger.Bootstrap():
    • The REST server now starts after bootstrap, so scrapers may observe a brief connection refusal during startup (short-lived) instead of the previous /log-only gin server behavior.
    • startRestServices launches the API in a goroutine when enabled; Start runs the Gin server.
  • No new synchronization primitives introduced; handlers read messenger state on-demand. snapshot() sorts a defensive copy and may observe transient state under churn (documented).

Error Handling and Metrics

  • Metrics:
    • Version label values are escaped for Prometheus safety (quotes, backslashes, newlines).
    • If version is empty, klv_build_info is omitted.
  • No broad changes to error-handling semantics; handlers return HTTP 200 for successful snapshots/metrics.

Tests and Build

  • Five new httptest cases added validating endpoints, sorting, uptime ranges, metrics formatting, and label escaping.
  • go build and go vet pass for cmd/seednode locally; a regression test (TestSnapshot_doesNotMutateMessengerSlices) verifies the defensive-copy fix.

Data Integrity

  • No impact to blockchain data integrity or consensus. Changes are limited to observability and logging; no code path modifies persisted state or peer-management semantics.

Review Change Stack

…/node/metrics

The seednode was dumping its full connected-peer table at INFO every 5 s
(~190 lines per tick at production peer counts) on top of the concise
single-line summary already emitted at DEBUG by the libp2p messenger.
This drowned out actionable events and consumed disk fast under
--log-save, with no machine-readable surface for monitoring.

Logging (cmd/seednode/main.go):
- Print the "Seednode addresses:" table once at startup, not on every tick.
- Move the full connected-peers table to DEBUG.
- At INFO emit a single summary line per tick:
    seednode status  connected=N  known=M  gained=G  lost=L  listen=...
- Track the peer set across ticks so gained/lost report churn.
- Bump the tick interval from 5 s to 30 s.
- pickReportableListenAddress skips loopback and the Docker default
  bridge (172.17.x) so the log line's listen= field shows the address
  operators can actually use.

HTTP endpoints (cmd/seednode/api/api.go):
- GET /peers           JSON: connectedPeers, knownPeers,
                       listenAddresses, connectedAddresses (raw).
- GET /node/status     JSON: version, uptimeSeconds, connectedPeers,
                       knownPeers, listenAddresses.
- GET /node/metrics    Prometheus exposition:
                         seednode_connected_peers
                         seednode_known_peers
                         seednode_uptime_seconds
                         klv_build_info{version,node_type}
- Refactor the package into a server struct hidden behind exported
  Start(); /log websocket behavior unchanged.
- snapshot() reads the peer view once per handler so connected count
  and connected-addresses slice stay consistent across the response.
- startTime captured at top of startNode so uptimeSeconds reflects
  process start, not the post-bootstrap API listener.

API now starts after messenger.Bootstrap() since the new endpoints
query the messenger; external scrapers see a brief connection refused
during the bootstrap window instead of a /log-only gin server.

Tests (cmd/seednode/api/api_test.go): 5 httptest cases against a stub
peerInfoProvider cover the three handlers, empty-version build_info
omission, and Prometheus label escaping.
Copilot AI review requested due to automatic review settings May 21, 2026 00:08
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: dd7aed8c-8d48-45c5-8290-f7d6a9b6e040

📥 Commits

Reviewing files that changed from the base of the PR and between 2209b33 and b4b4091.

📒 Files selected for processing (3)
  • cmd/seednode/api/api.go
  • cmd/seednode/api/api_test.go
  • cmd/seednode/main.go
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (go)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (Custom checks)

**/*.go: Verify that any new or modified concurrent code (goroutines, channels, mutexes, sync primitives) is free of race conditions. Check for: proper lock/unlock pairing, no goroutine leaks, correct channel lifecycle management, and proper context cancellation propagation.
Verify that errors are not silently discarded. Check for: unchecked error returns, error wrapping with context, proper error propagation up the call chain, and no bare panic() calls outside of init() functions.

Files:

  • cmd/seednode/main.go
  • cmd/seednode/api/api.go
  • cmd/seednode/api/api_test.go
**/*_test.go

⚙️ CodeRabbit configuration file

**/*_test.go: Test files. Review for: - Adequate coverage of edge cases and error paths - Proper use of test helpers and assertions - Race condition coverage (tests should use -race flag patterns) - No hardcoded sleep for synchronization (use channels or sync primitives) - Test isolation (no shared mutable state between tests)

Files:

  • cmd/seednode/api/api_test.go
🧠 Learnings (1)
📚 Learning: 2026-04-21T20:12:22.959Z
Learnt from: phcarneirobc
Repo: klever-io/klever-go PR: 38
File: indexer/eventsProcessor.go:188-211
Timestamp: 2026-04-21T20:12:22.959Z
Learning: In Go structs that are JSON-marshaled, if a field is a `bool` and has the `json:"...,omitempty"` tag, then leaving that field at its zero value (`false`) is functionally equivalent (in the resulting JSON) to explicitly setting `Foundation: false`. Reviewers should not flag struct literals that omit such `bool` fields as an inconsistency; they will serialize identically because `omitempty` suppresses `false` values.

Applied to files:

  • cmd/seednode/main.go
  • cmd/seednode/api/api.go
  • cmd/seednode/api/api_test.go
🔇 Additional comments (3)
cmd/seednode/main.go (1)

253-254: LGTM!

cmd/seednode/api/api.go (1)

101-107: LGTM!

cmd/seednode/api/api_test.go (1)

185-187: ⚡ Quick win

Send the original <review_comment> content so I can rewrite it according to the required format.


Walkthrough

Refactors the seednode HTTP API into a stateful server wired with runtime messenger, version, and startTime. Adds shared snapshot-backed /peers and /node/status, Prometheus /node/metrics with escaped build info, comprehensive API tests, delays REST startup until after messenger bootstrap, and moves periodic peer-status logging to a 30s ticker.

Changes

Seednode API Refactoring

Layer / File(s) Summary
API Server Struct and Route Registration
cmd/seednode/api/api.go
Introduces peerInfoProvider and server to hold marshalizer, messenger, version, and startTime. Start signature now accepts messenger, version, and startTime; routes are registered via server methods and /log websocket uses s.marshalizer.
Endpoint Implementations and Prometheus Metrics
cmd/seednode/api/api.go
Adds server.snapshot() used by /peers and /node/status (sorted connected addresses, known peer count, listen addresses). Adds /node/metrics returning Prometheus metrics: connected/known peer counts, uptime (seconds), and conditional klv_build_info with properly escaped version labels.
API Endpoint Test Suite
cmd/seednode/api/api_test.go
Adds stubMessenger, test helpers, and tests validating /peers (sorted addresses, counts), /node/status (version, uptime, counts), /node/metrics (Prometheus lines, build info presence/omission), snapshot regression, and label-escaping behavior for versions containing quotes/backslashes/newlines.
Startup Initialization and REST Service Wiring
cmd/seednode/main.go
Capture startTime at startup and apply CLI log-level; delay REST service startup until messenger exists and is bootstrapped; update startRestServices/startGinServer to pass messenger and startTime into api.Start.
Peer Status Reporting and Logging Loop
cmd/seednode/main.go
Refactors main loop to show startup addresses once and emit peer status on a 30s ticker. Adds displayStartupAddresses, emitPeerStatus, prevConnected bookkeeping for gained/lost counts, and pickReportableListenAddress to prefer non-loopback/non-Docker-bridge addresses for logs.

Sequence Diagram(s)

sequenceDiagram
  participant Node as startNode
  participant Logger as logger
  participant Messenger as P2P_Messenger
  participant REST as REST_Services
  Node->>Node: Capture startTime
  Node->>Logger: SetLogLevel(cli)
  Node->>Messenger: Create and bootstrap messenger
  Node->>REST: startRestServices(ctx, marshalizer, messenger, startTime)
  REST->>REST: startGinServer -> api.Start(interface, marshalizer, messenger, version, startTime)
  REST->>REST: Register routes using server state
  REST->>Messenger: server.snapshot() reads connected peers / listen addrs
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • RomuloSiebra
🚥 Pre-merge checks | ✅ 6 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Error Handling ⚠️ Warning API startup error silently discarded: api.Start() called in goroutine with error only logged, not propagated. WebSocket handler errors logged but not returned to caller. Use error channel to signal API startup completion or make startGinServer synchronous. Return errors from /log handler to HTTP response. Ensure API bind failure blocks process.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title follows the required [KLC-XXXX] type: description format with 'chore' type and clearly describes the main changes: reducing log noise and exposing new HTTP endpoints.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Concurrency Safety ✅ Passed No race conditions found. prevConnected map is local to mainLoop; defensive copies prevent snapshot mutation; ticker cleanup is correct; signal handling follows standard patterns.
State Consistency ✅ Passed PR modifies only seednode HTTP API and metrics reporting—no blockchain state (accounts, balances, storage) operations. Check is not applicable.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/KLC-2418-seednode-noise-and-endpoints

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reduces operational log volume from the seednode by switching periodic peer logging from verbose tables to a concise status line, and it exposes additional HTTP endpoints (/peers, /node/status, /node/metrics) to support operator tooling and Prometheus scraping.

Changes:

  • Replaces the 5s peer-table INFO log with a 30s single-line “seednode status” log, while keeping the full connected-peers table at DEBUG.
  • Refactors cmd/seednode/api to a stateful server with exported Start(...), adding JSON status/peer endpoints and a Prometheus metrics endpoint.
  • Adds httptest coverage for the new HTTP handlers.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
cmd/seednode/main.go Delays API start until after bootstrap; introduces 30s status ticker and debug-only peer table; adds listen-address selection helper for log output.
cmd/seednode/api/api.go Refactors API into a server struct and adds /peers, /node/status, /node/metrics handlers.
cmd/seednode/api/api_test.go Adds handler-level tests for the new JSON and Prometheus endpoints, including label escaping behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/seednode/api/api.go Outdated
Comment thread cmd/seednode/api/api.go Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/seednode/api/api_test.go`:
- Around line 132-168: Both tests (TestNodeMetrics_emptyVersionOmitsBuildInfo
and TestNodeMetrics_versionLabelEscaped) lack assertions on the HTTP response
status which can mask handler failures; after calling r.ServeHTTP(w, req) assert
that w.Code == http.StatusOK (or use http.StatusOK constant) and fail the test
if not before performing body checks so that a 4xx/5xx response cannot produce a
false positive; update both tests to check the status using the existing
recorder variable w immediately after ServeHTTP.

In `@cmd/seednode/main.go`:
- Around line 254-256: Replace the custom comparator sort.Slice call that uses
strings.Compare on the slice named connected with the idiomatic
sort.Strings(connected) call; specifically find the sort.Slice(connected,
func(i, j int) bool { return strings.Compare(connected[i], connected[j]) < 0 })
usage and swap it to sort.Strings(connected) to match the style used in api.go
and simplify the code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 54a0e402-649b-41dc-bd16-9a3a20caef05

📥 Commits

Reviewing files that changed from the base of the PR and between a4ba64e and 03bf6ef.

📒 Files selected for processing (3)
  • cmd/seednode/api/api.go
  • cmd/seednode/api/api_test.go
  • cmd/seednode/main.go
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Agent
  • GitHub Check: setup-and-lint / setup-and-lint
  • GitHub Check: Analyze (go)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (Custom checks)

**/*.go: Verify that any new or modified concurrent code (goroutines, channels, mutexes, sync primitives) is free of race conditions. Check for: proper lock/unlock pairing, no goroutine leaks, correct channel lifecycle management, and proper context cancellation propagation.
Verify that errors are not silently discarded. Check for: unchecked error returns, error wrapping with context, proper error propagation up the call chain, and no bare panic() calls outside of init() functions.

Files:

  • cmd/seednode/api/api_test.go
  • cmd/seednode/main.go
  • cmd/seednode/api/api.go
**/*_test.go

⚙️ CodeRabbit configuration file

**/*_test.go: Test files. Review for: - Adequate coverage of edge cases and error paths - Proper use of test helpers and assertions - Race condition coverage (tests should use -race flag patterns) - No hardcoded sleep for synchronization (use channels or sync primitives) - Test isolation (no shared mutable state between tests)

Files:

  • cmd/seednode/api/api_test.go
🧠 Learnings (1)
📚 Learning: 2026-04-21T20:12:22.959Z
Learnt from: phcarneirobc
Repo: klever-io/klever-go PR: 38
File: indexer/eventsProcessor.go:188-211
Timestamp: 2026-04-21T20:12:22.959Z
Learning: In Go structs that are JSON-marshaled, if a field is a `bool` and has the `json:"...,omitempty"` tag, then leaving that field at its zero value (`false`) is functionally equivalent (in the resulting JSON) to explicitly setting `Foundation: false`. Reviewers should not flag struct literals that omit such `bool` fields as an inconsistency; they will serialize identically because `omitempty` suppresses `false` values.

Applied to files:

  • cmd/seednode/api/api_test.go
  • cmd/seednode/main.go
  • cmd/seednode/api/api.go
🔇 Additional comments (16)
cmd/seednode/api/api_test.go (1)

15-130: LGTM!

Also applies to: 170-178

cmd/seednode/api/api.go (8)

21-28: LGTM!


30-36: LGTM!


38-56: LGTM!


58-63: LGTM!


65-87: LGTM!


89-105: LGTM!


107-122: LGTM!

Also applies to: 124-141


143-160: LGTM!

cmd/seednode/main.go (7)

130-136: LGTM!


194-195: LGTM!


208-228: LGTM!


242-250: LGTM!


258-303: LGTM!


305-324: LGTM!


360-374: LGTM!

Comment thread cmd/seednode/api/api_test.go
Comment thread cmd/seednode/main.go Outdated
- api: gin.Default() -> gin.New() + Recovery in ReleaseMode so
  /node/metrics scrapes no longer emit a [GIN] access-log line per hit.
  Skip the network/api ginWriter redirect; routing
  gin.DefaultErrorWriter to log.Trace would have silenced panic stacks
  at production log levels, leaving them visible on stderr is better.
- api: rewrite peerSnapshot doc to honestly describe what the helper
  guarantees (connected count == its slice; knownPeers may drift).
- api_test: assert w.Code == http.StatusOK in the two metrics tests so
  a 4xx/5xx cannot pass them silently. Use strings.SplitSeq (Go 1.25).
- main: sort.Slice(strings.Compare) -> sort.Strings for consistency
  with api.go.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/seednode/api/api.go (1)

100-107: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Adjust concurrency/mutation concern based on messenger implementations

network/p2p/libp2p/netMessenger.go’s ConnectedAddresses() and Addresses() both build and return fresh []string slices (via make(...)/append), so snapshot()’s sort.Strings(connected) shouldn’t mutate provider-owned memory or race with the live messenger for that implementation.

The “copy before sorting” suggestion is only necessary if other messenger implementations can return internal/shared slices—current evidence shows the test stubMessenger returns backing slices directly (cmd/seednode/api/api_test.go), so sorting would mutate the stub during tests, but that’s not a production race.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/seednode/api/api.go` around lines 100 - 107, snapshot() currently sorts
the slice returned by s.messenger.ConnectedAddresses(), which can mutate
caller-owned slices in tests (stubMessenger) — make a defensive copy of the
slice returned by ConnectedAddresses() before calling sort.Strings to avoid
mutating provider-owned memory; similarly, ensure any use of
s.messenger.Addresses() that gets sorted or mutated is copied first. Locate the
snapshot() function and the variables connected/listenAddrs and perform a copy
(e.g., via append to a nil slice or make+copy) of the returned slices before any
in-place modifications.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@cmd/seednode/api/api.go`:
- Around line 100-107: snapshot() currently sorts the slice returned by
s.messenger.ConnectedAddresses(), which can mutate caller-owned slices in tests
(stubMessenger) — make a defensive copy of the slice returned by
ConnectedAddresses() before calling sort.Strings to avoid mutating
provider-owned memory; similarly, ensure any use of s.messenger.Addresses() that
gets sorted or mutated is copied first. Locate the snapshot() function and the
variables connected/listenAddrs and perform a copy (e.g., via append to a nil
slice or make+copy) of the returned slices before any in-place modifications.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9e838833-b95f-4866-9b5e-6ab816d3f44a

📥 Commits

Reviewing files that changed from the base of the PR and between 03bf6ef and 2209b33.

📒 Files selected for processing (3)
  • cmd/seednode/api/api.go
  • cmd/seednode/api/api_test.go
  • cmd/seednode/main.go
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: setup-and-lint / setup-and-lint
  • GitHub Check: Analyze (go)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (Custom checks)

**/*.go: Verify that any new or modified concurrent code (goroutines, channels, mutexes, sync primitives) is free of race conditions. Check for: proper lock/unlock pairing, no goroutine leaks, correct channel lifecycle management, and proper context cancellation propagation.
Verify that errors are not silently discarded. Check for: unchecked error returns, error wrapping with context, proper error propagation up the call chain, and no bare panic() calls outside of init() functions.

Files:

  • cmd/seednode/api/api.go
  • cmd/seednode/main.go
  • cmd/seednode/api/api_test.go
**/*_test.go

⚙️ CodeRabbit configuration file

**/*_test.go: Test files. Review for: - Adequate coverage of edge cases and error paths - Proper use of test helpers and assertions - Race condition coverage (tests should use -race flag patterns) - No hardcoded sleep for synchronization (use channels or sync primitives) - Test isolation (no shared mutable state between tests)

Files:

  • cmd/seednode/api/api_test.go
🧠 Learnings (1)
📚 Learning: 2026-04-21T20:12:22.959Z
Learnt from: phcarneirobc
Repo: klever-io/klever-go PR: 38
File: indexer/eventsProcessor.go:188-211
Timestamp: 2026-04-21T20:12:22.959Z
Learning: In Go structs that are JSON-marshaled, if a field is a `bool` and has the `json:"...,omitempty"` tag, then leaving that field at its zero value (`false`) is functionally equivalent (in the resulting JSON) to explicitly setting `Foundation: false`. Reviewers should not flag struct literals that omit such `bool` fields as an inconsistency; they will serialize identically because `omitempty` suppresses `false` values.

Applied to files:

  • cmd/seednode/api/api.go
  • cmd/seednode/main.go
  • cmd/seednode/api/api_test.go
🔇 Additional comments (5)
cmd/seednode/api/api_test.go (3)

143-145: LGTM!


162-164: LGTM!


178-178: LGTM!

cmd/seednode/api/api.go (1)

50-54: LGTM!

Also applies to: 93-93

cmd/seednode/main.go (1)

252-254: LGTM!

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 21, 2026
The messenger interface does not document whether ConnectedAddresses
returns a fresh slice or a view over internal state, and the test stub
returns its backing slice directly. sort.Strings then mutates whatever
it gets, so in tests the stub.connected field was being reordered in
place and a future second call would have seen a tainted view.

- api.go: copy before sort in server.snapshot.
- main.go: same in emitPeerStatus.
- api_test: regression test TestSnapshot_doesNotMutateMessengerSlices,
  verified failing before the fix.
@fbsobreira
Copy link
Copy Markdown
Member Author

Addressed the CodeRabbit outside-diff finding in b4b4091: snapshot() and emitPeerStatus now copy the slice returned by ConnectedAddresses() before sorting, so we no longer mutate provider-owned memory. Addresses() is read-only on our side (passed straight to JSON / the log line), no copy needed there. Added TestSnapshot_doesNotMutateMessengerSlices as a regression guard — verified it fails against the un-fixed code before reinstating the copy.

Copy link
Copy Markdown
Contributor

@nickgs1337 nickgs1337 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big fan of manually manipulating strings to return the metrics. But, not a deal breaker

Lgtm

@fbsobreira fbsobreira merged commit 9c6c33b into develop May 21, 2026
7 checks passed
@fbsobreira fbsobreira deleted the chore/KLC-2418-seednode-noise-and-endpoints branch May 21, 2026 11:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants