Skip to content

Commit 04c4d0a

Browse files
authored
fix: handle mining.extranonce.subscribe and prevent nil pointer crash (#83)
## Summary Fixes crash loop caused by new miners sending `mining.extranonce.subscribe` messages during handshake phase. ## Root Cause New miners added to seller node on 2026-02-10 send the `mining.extranonce.subscribe` Stratum extension message during initial handshake. This legitimate protocol message wasn't explicitly handled in the handshake switch statement, causing it to fall through to the default case. The default case attempted to log a warning, which called `logWithContext()`. This logging function accessed `p.dest.conn.conn.LocalAddr()` which was nil during early handshake, triggering a panic and container restart every 5-6 minutes. ## Changes Made ### 1. Defensive Logging (proxy.go) Made `logWithContext()` nil-safe by checking all pointer levels before accessing: - Checks if `p.dest` is nil - Checks if `p.dest.conn` is nil - Checks if `p.dest.conn.conn` is nil - Returns "not-connected" or "not-initialized" instead of panicking ### 2. Handle mining.extranonce.subscribe (handler_first_connect.go) Added explicit case for `MiningExtranonceSubscribe` messages: - Logs at debug level for visibility - Forwards message transparently to pool - Prevents falling through to unknown message handler ## Impact - ✅ Resolves continuous crash loop since 2026-02-10 13:16 ET - ✅ Enables modern miners with extranonce support to connect properly - ✅ Future-proofs logging against similar edge cases with nil connections - ✅ No performance impact (just pointer checks) ## Testing - Code compiles successfully - Crash pattern analysis confirms this fixes the exact panic location - Logs show the message is a legitimate Stratum extension that should pass through ## CloudWatch Evidence All crashes showed identical stack trace: ``` panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x110 pc=0x90b25f] at proxy.go:453 in logWithContext() ``` Preceded by unknown message logs showing `mining.extranonce.subscribe`. Made with [Cursor](https://cursor.com)
2 parents ddec6a4 + 3d2a337 commit 04c4d0a

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

internal/resources/hashrate/proxy/handler_first_connect.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ func (p *HandlerFirstConnect) handleSource(ctx context.Context, msg i.MiningMess
6969
case *m.MiningAuthorize:
7070
return nil, p.onMiningAuthorize(ctx, msgTyped)
7171

72+
case *m.MiningExtranonceSubscribe:
73+
// Pass through extranonce subscription to pool
74+
p.proxy.logDebugf("forwarding mining.extranonce.subscribe from source")
75+
return nil, p.proxy.dest.Write(ctx, msgTyped)
76+
7277
case *m.MiningSubmit:
7378
return nil, fmt.Errorf("unexpected handshake message from source: %s", string(msg.Serialize()))
7479

internal/resources/hashrate/proxy/proxy.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,5 +450,21 @@ func (p *Proxy) logErrorf(template string, args ...interface{}) {
450450
p.logWithContext(p.log.Errorw, template, args...)
451451
}
452452
func (p *Proxy) logWithContext(logFn func(t string, a ...interface{}), t string, a ...interface{}) {
453-
logFn(fmt.Sprintf(t, a...), "DstAddr", p.dest.ID(), "DstPort", lib.ParsePort(p.dest.conn.conn.LocalAddr().String()))
453+
logFields := []interface{}{}
454+
455+
// Add destination address if available
456+
if p.dest != nil {
457+
logFields = append(logFields, "DstAddr", p.dest.ID())
458+
459+
// Add port if connection is established
460+
if p.dest.conn != nil && p.dest.conn.conn != nil {
461+
logFields = append(logFields, "DstPort", lib.ParsePort(p.dest.conn.conn.LocalAddr().String()))
462+
} else {
463+
logFields = append(logFields, "DstPort", "not-connected")
464+
}
465+
} else {
466+
logFields = append(logFields, "DstAddr", "not-initialized", "DstPort", "not-connected")
467+
}
468+
469+
logFn(fmt.Sprintf(t, a...), logFields...)
454470
}

0 commit comments

Comments
 (0)