Skip to content

Commit 4fd1dff

Browse files
feat: add connectioncount check, hash pining and switch to json rpc 2.0 version
1 parent f48c894 commit 4fd1dff

4 files changed

Lines changed: 55 additions & 16 deletions

File tree

images/go_chains_hc/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang AS builder
1+
FROM golang:1.25.5-alpine@sha256:8bbd14091f2c61916134fa6aeb8f76b18693fcb29a39ec6d8be9242c0a7e9260 AS builder
22

33
WORKDIR /app
44
COPY go.mod ./

images/go_chains_hc/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ On each `/readyz` request, the sidecar runs a configurable set of checks against
1212
|---|---|---|
1313
| `blockdownload` | `getblockchaininfo` | Passes when `initialblockdownload` is `false`. Default for all chains. |
1414
| `txindex` | `getindexinfo` | Passes when `txindex.synced` is `true`. |
15+
| `connectioncount` | `getconnectioncount` | Passes when the node has at least `MIN_CONNECTIONS` peers. |
1516

1617
### Environment Variables
1718

@@ -20,7 +21,9 @@ On each `/readyz` request, the sidecar runs a configurable set of checks against
2021
| `NODE_URL` | yes || RPC endpoint, e.g. `http://localhost:8332` |
2122
| `NODE_USER` | no || RPC auth username |
2223
| `NODE_PASS` | no || RPC auth password |
23-
| `CHECKS` | no | `blockdownload` | Comma-separated list of checks to run (blockdownload,txindex) |
24+
| `CHECKS` | no | `blockdownload` | Comma-separated list of checks to run (`blockdownload, txindex, connectioncount`) |
25+
| `MIN_CONNECTIONS` | no | `8` | Minimum peer connections required for the `connectioncount` check |
26+
2427

2528
### Running Locally
2629

images/go_chains_hc/checks.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ import (
1212

1313
type Check func(ctx context.Context, client *http.Client, cfg Config) error
1414

15+
const jsonRPCVersion = "2.0"
16+
1517
var registry = map[string]Check{
16-
"blockdownload": checkBlockDownload,
17-
"txindex": checkTxIndex,
18+
"blockdownload": checkBlockDownload,
19+
"txindex": checkTxIndex,
20+
"connectioncount": checkConnectionCount,
1821
}
1922

2023
type rpcRequest struct {
@@ -26,7 +29,7 @@ type rpcRequest struct {
2629

2730
func doRPC(ctx context.Context, client *http.Client, cfg Config, method string) (json.RawMessage, error) {
2831
logger := slog.Default()
29-
body, err := json.Marshal(rpcRequest{JSONRPC: "1.0", ID: "hc", Method: method, Params: []any{}})
32+
body, err := json.Marshal(rpcRequest{JSONRPC: jsonRPCVersion, ID: "hc", Method: method, Params: []any{}})
3033
if err != nil {
3134
return nil, fmt.Errorf("marshal request: %w", err)
3235
}
@@ -46,7 +49,7 @@ func doRPC(ctx context.Context, client *http.Client, cfg Config, method string)
4649
}
4750
defer resp.Body.Close()
4851

49-
if resp.StatusCode != http.StatusOK {
52+
if resp.StatusCode >= http.StatusBadRequest {
5053
return nil, fmt.Errorf("node returned HTTP %d", resp.StatusCode)
5154
}
5255

@@ -117,3 +120,20 @@ func checkTxIndex(ctx context.Context, client *http.Client, cfg Config) error {
117120

118121
return nil
119122
}
123+
124+
func checkConnectionCount(ctx context.Context, client *http.Client, cfg Config) error {
125+
result, err := doRPC(ctx, client, cfg, "getconnectioncount")
126+
if err != nil {
127+
return err
128+
}
129+
130+
var count int
131+
if err := json.Unmarshal(result, &count); err != nil {
132+
return fmt.Errorf("parse getconnectioncount: %w", err)
133+
}
134+
if count < cfg.MinConnections {
135+
return fmt.Errorf("not enough connections: %d < %d", count, cfg.MinConnections)
136+
}
137+
138+
return nil
139+
}

images/go_chains_hc/main.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ import (
66
"log/slog"
77
"net/http"
88
"os"
9+
"strconv"
910
"strings"
1011
"time"
1112
)
1213

1314
type Config struct {
14-
NodeURL string
15-
NodeUser string
16-
NodePass string
17-
Checks []string
18-
Addr string
15+
NodeURL string
16+
NodeUser string
17+
NodePass string
18+
Checks []string
19+
Addr string
20+
MinConnections int
1921
}
2022

23+
const MIN_CONNECTIONS = 8
24+
2125
func configFromEnv() (Config, error) {
2226
nodeURL := os.Getenv("NODE_URL")
2327
if nodeURL == "" {
@@ -35,12 +39,24 @@ func configFromEnv() (Config, error) {
3539
}
3640
}
3741

42+
minConns := MIN_CONNECTIONS
43+
if raw := os.Getenv("MIN_CONNECTIONS"); raw != "" {
44+
n, err := strconv.Atoi(raw)
45+
46+
if err != nil || n < 0 {
47+
return Config{}, fmt.Errorf("MIN_CONNECTIONS must be a non-negative integer")
48+
}
49+
50+
minConns = n
51+
}
52+
3853
return Config{
39-
NodeURL: nodeURL,
40-
NodeUser: os.Getenv("NODE_USER"),
41-
NodePass: os.Getenv("NODE_PASS"),
42-
Checks: checks,
43-
Addr: ":8080",
54+
NodeURL: nodeURL,
55+
NodeUser: os.Getenv("NODE_USER"),
56+
NodePass: os.Getenv("NODE_PASS"),
57+
Checks: checks,
58+
Addr: ":8080",
59+
MinConnections: minConns,
4460
}, nil
4561
}
4662

0 commit comments

Comments
 (0)