Summary
`pow/ipc_client.go:27-37` — The `http.Client` created in `NewIPCClient` has no `Timeout` set. The `DialContext` function in the transport uses `net.Dial` instead of `net.DialContext`, ignoring the provided context (and any deadline on it).
If the PoW node socket exists but the process hangs, the HTTP request blocks indefinitely, halting the entire BFT partition.
Severity
High — liveness issue; a single unresponsive PoW node can halt the finality gadget.
Suggested Fix
client := &http.Client{
Timeout: 10 * time.Second, // adjust as appropriate
Transport: &http.Transport{
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
d := net.Dialer{}
return d.DialContext(ctx, "unix", socketPath)
},
},
}
Related
- `io.ReadAll(resp.Body)` at line 89 has no size limit — a compromised PoW node can return an arbitrarily large response causing OOM.
- No validation of block header data from the PoW node (hash format, length, consistency with queried parameters) at lines 150-156.
- JSON-RPC request ID is hardcoded to `1` and response ID is never validated.
Summary
`pow/ipc_client.go:27-37` — The `http.Client` created in `NewIPCClient` has no `Timeout` set. The `DialContext` function in the transport uses `net.Dial` instead of `net.DialContext`, ignoring the provided context (and any deadline on it).
If the PoW node socket exists but the process hangs, the HTTP request blocks indefinitely, halting the entire BFT partition.
Severity
High — liveness issue; a single unresponsive PoW node can halt the finality gadget.
Suggested Fix
Related