Skip to content

Conversation

@galt-tr
Copy link
Contributor

@galt-tr galt-tr commented Oct 22, 2025

This pull request adds an automatic health check for the asset HTTP address during server initialization in the P2P service. If the asset address is unreachable and the node is in full mode, the server now switches to listen-only mode to prevent other peers from attempting to fetch data from an unavailable node. The implementation includes robust detection of various failure scenarios and is thoroughly covered by new unit tests.

Asset address health check logic

  • Added a health check in the Init method of Server to verify the reachability of the configured asset HTTP address. If unreachable and the node is in full mode, the server switches to listen-only mode. [1] [2]
  • Implemented the isAssetAddressReachable method, which attempts to fetch the genesis block from the asset server with a timeout, and considers various HTTP status codes and offline indicators.
  • Updated import statements to include io for reading HTTP response bodies.

Test coverage for health check

  • Added comprehensive unit tests in Server_test.go to cover scenarios including reachable/unreachable asset addresses, server errors, offline detection, normal 404 responses, skipping health checks in listen-only mode, and empty asset addresses.

Fixes #2

@galt-tr
Copy link
Contributor Author

galt-tr commented Oct 22, 2025

/claude-review

@claude
Copy link
Contributor

claude bot commented Oct 22, 2025

Claude finished @galt-tr's task —— View job


Code Review Complete

  • Read and analyze changed files
  • Review health check implementation logic
  • Review test coverage
  • Identify any issues or concerns
  • Post review feedback

Summary

The PR adds a sensible health check for the asset HTTP address during P2P server initialization. The test coverage is comprehensive and handles various edge cases well.

Issues to Address:

  1. Settings mutation concern (services/p2p/Server.go:477): Modifying s.settings.P2P.ListenMode directly can cause configuration inconsistencies. Consider using a separate field for the effective mode.

  2. Hardcoded genesis fallback (services/p2p/Server.go:501): The fallback to a hardcoded regtest genesis hash could mask configuration problems. Failing fast would be safer.

  3. Limited body read size (services/p2p/Server.go:541): Reading only 1024 bytes for offline detection might miss keywords in larger responses.

Positive aspects:

  • Well-structured implementation with clear separation of concerns
  • Excellent test coverage including edge cases (offline detection, 404 handling, different modes)
  • Good timeout handling (5 seconds) to prevent initialization hangs
  • Appropriate logging at debug/warn/info levels

Minor observations:

  • The unrelated changes to handleNodeStatusTopic (lines 1015-1016) add TxCount and SubtreeCount fields - these appear correct but weren't mentioned in the PR description
  • HTTP client could potentially be reused rather than created each time, but for an init-time check this is fine

⚠️ Note: Due to fork PR security constraints, I cannot execute tests or linters. The review is based on static code analysis only.


Job Run | Branch: sanity

// If the address is not reachable, automatically switch to listen-only mode
if s.settings.P2P.ListenMode == settings.ListenModeFull {
if !s.isAssetAddressReachable(ctx, s.AssetHTTPAddressURL) {
s.logger.Warnf("[Init] Asset HTTP address %s is not reachable. Automatically switching to listen-only mode to prevent peers from attempting to fetch data from this node. Please check your asset_httpPublicAddress configuration and ensure the endpoint is publicly accessible.", s.AssetHTTPAddressURL)
Copy link
Contributor

Choose a reason for hiding this comment

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

Issue: Modifying s.settings.P2P.ListenMode after server initialization can cause inconsistencies. Settings should generally be immutable after configuration.

Suggestion: Consider storing the effective listen mode in a separate field (e.g., s.effectiveListenMode) rather than mutating the original settings. This preserves the user's intended configuration and makes debugging easier.

// Get genesis hash for the health check
var genesisHash string
if s.settings != nil && s.settings.ChainCfgParams != nil && s.settings.ChainCfgParams.GenesisHash != nil {
genesisHash = s.settings.ChainCfgParams.GenesisHash.String()
Copy link
Contributor

Choose a reason for hiding this comment

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

Issue: Using a hardcoded default genesis hash for regtest is brittle and may fail silently if the settings are unexpectedly nil.

Suggestion: Consider failing fast with an error if s.settings.ChainCfgParams.GenesisHash is nil, rather than falling back to a hardcoded value. This makes configuration issues visible immediately.

s.logger.Debugf("[Init] Asset address %s health check responded with status %d", assetURL, resp.StatusCode)

// Check for offline indicators in 404 responses
if resp.StatusCode == 404 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: Why limit to only the first 1024 bytes? If the response body is larger, the offline detection keywords might be missed if they appear later in the response.

Suggestion: Consider reading more (e.g., 8KB) or reading the entire response with a reasonable size limit to ensure reliable offline detection.

Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Review complete - please see inline comments for specific issues and suggestions.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 23, 2025

🤖 Claude Code Review

Status: Complete

Current Review:

This PR adds health checking for the asset HTTP address. The implementation is well-tested with comprehensive unit tests covering various failure scenarios. However, there are three design considerations flagged in inline comments that remain unaddressed:

  1. Settings mutation (line 478): Modifying s.settings.P2P.ListenMode after initialization could cause consistency issues
  2. Hardcoded fallback (line 504): Using a hardcoded regtest genesis hash as fallback may fail silently if config is incomplete
  3. Buffer size limitation (line 542): The 1024-byte read limit for offline detection may miss keywords in larger responses

These are architectural considerations rather than critical bugs. The core functionality works correctly and is well-covered by tests.

@sonarqubecloud
Copy link

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.

[FEAT] Peer service should sanity check asset_httpPublicAddress

2 participants