From b28c6d93b8f334b8205a144a6e9afa687311bd34 Mon Sep 17 00:00:00 2001 From: SAY-5 Date: Wed, 22 Apr 2026 22:39:01 -0700 Subject: [PATCH] fix(mpc): return error instead of panic when publicKey is nil in BroadcastPublicKey registerReadyPairs spawns a goroutine that calls triggerECDHExchange -> BroadcastPublicKey. If the peer restarts between scheduling and the goroutine reading the local publicKey, e.publicKey is nil and crypto/ecdh.(*PublicKey).Bytes panics with 'invalid memory address or nil pointer dereference', killing the goroutine and forcing a container restart+rejoin cycle of ~10-15s per occurrence. Nil-check the receiver and e.publicKey at the top of BroadcastPublicKey and return a descriptive error so the caller's ECDH retrigger logic takes over instead of a panic propagating to stderr. Refs fystack/mpcium issue 158. Signed-off-by: SAY-5 --- pkg/mpc/key_exchange_session.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/mpc/key_exchange_session.go b/pkg/mpc/key_exchange_session.go index d8065540..6213b144 100644 --- a/pkg/mpc/key_exchange_session.go +++ b/pkg/mpc/key_exchange_session.go @@ -152,6 +152,13 @@ func (s *ecdhSession) Close() error { } func (e *ecdhSession) BroadcastPublicKey() error { + // Peer restart mid-handshake can schedule this broadcast goroutine + // before the local publicKey is populated; crypto/ecdh.(*PublicKey).Bytes + // then panics with nil pointer dereference. Return an error so the + // caller's retrigger logic takes over instead of the goroutine dying. + if e == nil || e.publicKey == nil { + return fmt.Errorf("ecdh session %s has no public key to broadcast yet", e.nodeID) + } publicKeyBytes := e.publicKey.Bytes() msg := types.ECDHMessage{ From: e.nodeID,