Skip to content

Add sanity health check for public asset service#34

Closed
galt-tr wants to merge 10 commits into
bsv-blockchain:mainfrom
galt-tr:sanity
Closed

Add sanity health check for public asset service#34
galt-tr wants to merge 10 commits into
bsv-blockchain:mainfrom
galt-tr:sanity

Conversation

@galt-tr

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

Copy link
Copy Markdown
Contributor

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

galt-tr commented Oct 22, 2025

Copy link
Copy Markdown
Contributor Author

/claude-review

@claude

claude Bot commented Oct 22, 2025

Copy link
Copy Markdown
Contributor

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

Comment thread services/p2p/Server.go
// 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
Copy Markdown
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.

Comment thread services/p2p/Server.go
// 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
Copy Markdown
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.

Comment thread services/p2p/Server.go
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
Copy Markdown
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.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

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

github-actions Bot commented Oct 23, 2025

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

Status: Complete


Current Review:

The implementation adds automatic asset address health checking during P2P server initialization, with comprehensive test coverage. The approach is sound and follows project patterns.

Minor observations:

  1. Settings mutation in Init() (line 474): Modifying s.settings.P2P.ListenMode during initialization could cause inconsistencies if other components have already read the original value. Consider returning an error instead, or document this behavior clearly.

  2. Hardcoded genesis hash fallback (line 500): The regtest genesis hash fallback is brittle—if settings are unexpectedly nil, this will use the wrong genesis hash for mainnet/testnet without clear indication. Consider requiring ChainCfgParams to be set, or logging a warning about the fallback.

  3. Test coverage is excellent: The test suite thoroughly covers reachable/unreachable scenarios, server errors, offline detection, and edge cases.

The health check logic is well-implemented and will prevent nodes from advertising unavailable asset endpoints to peers.

@sonarqubecloud

Copy link
Copy Markdown

@sonarqubecloud

Copy link
Copy Markdown

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

3 participants