mirror of
https://github.com/luxfi/mpc.git
synced 2026-09-24 00:26:24 +00:00
136 lines
3.6 KiB
Go
136 lines
3.6 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// Package transport provides a consensus-embedded transport layer for MPC
|
|
// that uses ZAP wire protocol instead of NATS/Consul.
|
|
package transport
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// MPC Message Types (60-79 range in ZAP protocol)
|
|
// These extend the base ZAP message types defined in api/zap/wire.go
|
|
const (
|
|
// MsgMPCBroadcast is used for pub/sub broadcasts to all nodes
|
|
MsgMPCBroadcast uint8 = 60
|
|
|
|
// MsgMPCDirect is used for point-to-point messaging
|
|
MsgMPCDirect uint8 = 61
|
|
|
|
// MsgMPCReady is used for peer registry readiness signaling
|
|
MsgMPCReady uint8 = 62
|
|
|
|
// MsgMPCSubscribe is used for subscription management
|
|
MsgMPCSubscribe uint8 = 63
|
|
|
|
// MsgMPCKeygen is used for DKG protocol messages
|
|
MsgMPCKeygen uint8 = 64
|
|
|
|
// MsgMPCSign is used for signing protocol messages
|
|
MsgMPCSign uint8 = 65
|
|
|
|
// MsgMPCReshare is used for key resharing protocol messages
|
|
MsgMPCReshare uint8 = 66
|
|
|
|
// MsgMPCResult is used for session result messages
|
|
MsgMPCResult uint8 = 67
|
|
|
|
// MsgMPCPing is used for health checks
|
|
MsgMPCPing uint8 = 68
|
|
|
|
// MsgMPCPong is the response to ping
|
|
MsgMPCPong uint8 = 69
|
|
|
|
// HeaderSize is 4 bytes length + 1 byte type
|
|
HeaderSize = 5
|
|
|
|
// MaxMessageSize is 16MB
|
|
MaxMessageSize = 16 * 1024 * 1024
|
|
)
|
|
|
|
// Message represents an MPC protocol message
|
|
type Message struct {
|
|
Type uint8 `json:"type"`
|
|
Topic string `json:"topic,omitempty"`
|
|
From string `json:"from"`
|
|
To string `json:"to,omitempty"` // Empty for broadcasts
|
|
ReplyTo string `json:"reply_to,omitempty"`
|
|
Headers map[string]string `json:"headers,omitempty"`
|
|
Data []byte `json:"data"`
|
|
}
|
|
|
|
// Envelope wraps a message with correlation ID for request/response
|
|
type Envelope struct {
|
|
ID uint32 `json:"id"`
|
|
Message Message `json:"message"`
|
|
}
|
|
|
|
// ReadySignal is sent when a node becomes ready
|
|
type ReadySignal struct {
|
|
NodeID string `json:"node_id"`
|
|
PublicKey []byte `json:"public_key"` // Ed25519 public key
|
|
Ready bool `json:"ready"`
|
|
Timestamp int64 `json:"timestamp"`
|
|
}
|
|
|
|
// SubscribeRequest is sent to subscribe to a topic
|
|
type SubscribeRequest struct {
|
|
Topic string `json:"topic"`
|
|
NodeID string `json:"node_id"`
|
|
}
|
|
|
|
// Marshal serializes a message to bytes
|
|
func (m *Message) Marshal() ([]byte, error) {
|
|
return json.Marshal(m)
|
|
}
|
|
|
|
// Unmarshal deserializes bytes to a message
|
|
func (m *Message) Unmarshal(data []byte) error {
|
|
return json.Unmarshal(data, m)
|
|
}
|
|
|
|
// WriteMessage writes a complete ZAP message with header to the writer
|
|
func WriteMessage(w io.Writer, msgType uint8, payload []byte) error {
|
|
if len(payload) > MaxMessageSize {
|
|
return fmt.Errorf("message too large: %d > %d", len(payload), MaxMessageSize)
|
|
}
|
|
|
|
header := make([]byte, HeaderSize)
|
|
binary.BigEndian.PutUint32(header[0:4], uint32(len(payload)))
|
|
header[4] = msgType
|
|
|
|
if _, err := w.Write(header); err != nil {
|
|
return err
|
|
}
|
|
if _, err := w.Write(payload); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ReadMessage reads a complete ZAP message with header from the reader
|
|
func ReadMessage(r io.Reader) (uint8, []byte, error) {
|
|
header := make([]byte, HeaderSize)
|
|
if _, err := io.ReadFull(r, header); err != nil {
|
|
return 0, nil, err
|
|
}
|
|
|
|
length := binary.BigEndian.Uint32(header[0:4])
|
|
msgType := header[4]
|
|
|
|
if length > MaxMessageSize {
|
|
return 0, nil, fmt.Errorf("message too large: %d > %d", length, MaxMessageSize)
|
|
}
|
|
|
|
payload := make([]byte, length)
|
|
if _, err := io.ReadFull(r, payload); err != nil {
|
|
return 0, nil, err
|
|
}
|
|
|
|
return msgType, payload, nil
|
|
}
|