Files
zeekay 7cf87b230b node-unified is the node
The module already called itself github.com/luxfi/node while containing no node
in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and
the Go column of the matrix measured a VM plugin. A repo that fetches the thing
it claims to be has not replaced it, so the Go sources move in — 1515 files,
the daemon and everything under it — and the build reaches outside this module
for nothing.

Rust and C++ sit beside it unchanged and are still measured against it by the
differential. That is the point of one repo: the reference implementation and
the two ports are the same checkout, so parity is a thing you can run rather
than a thing you assert.

Verified: builds, and the closure carries no lux-private — checked at build time
rather than believed. The daemon starts twelve chains on a local network
(P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
2026-09-07 16:15:25 -07:00

157 lines
4.2 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package zwarp
import (
"context"
"fmt"
zapwire "github.com/luxfi/api/zap"
"github.com/luxfi/ids"
"github.com/luxfi/node/vms/platformvm/warp"
)
// Server implements the ZAP server for warp signing
type Server struct {
signer warp.Signer
}
// NewServer creates a new ZAP-based warp signer server
func NewServer(signer warp.Signer) *Server {
return &Server{signer: signer}
}
// HandleMessage handles incoming ZAP messages
func (s *Server) HandleMessage(ctx context.Context, msgType zapwire.MessageType, payload []byte) ([]byte, error) {
switch msgType {
case zapwire.MsgWarpSign:
return s.handleSign(ctx, payload)
case zapwire.MsgWarpGetPublicKey:
return s.handleGetPublicKey(ctx, payload)
case zapwire.MsgWarpBatchSign:
return s.handleBatchSign(ctx, payload)
default:
return nil, fmt.Errorf("zwarp server: unknown message type %d", msgType)
}
}
func (s *Server) handleSign(ctx context.Context, payload []byte) ([]byte, error) {
req := &zapwire.WarpSignRequest{}
if err := req.Decode(zapwire.NewReader(payload)); err != nil {
return nil, fmt.Errorf("zwarp decode sign request: %w", err)
}
sourceChainID, err := ids.ToID(req.SourceChainID)
if err != nil {
return s.encodeSignError(fmt.Sprintf("invalid source chain ID: %v", err))
}
msg, err := warp.NewUnsignedMessage(req.NetworkID, sourceChainID, req.Payload)
if err != nil {
return s.encodeSignError(fmt.Sprintf("invalid message: %v", err))
}
sig, err := s.signer.Sign(msg)
if err != nil {
return s.encodeSignError(err.Error())
}
resp := &zapwire.WarpSignResponse{
Signature: sig,
}
buf := zapwire.GetBuffer()
resp.Encode(buf)
// Copy bytes before returning buffer to pool
result := make([]byte, buf.Len())
copy(result, buf.Bytes())
zapwire.PutBuffer(buf)
return result, nil
}
func (s *Server) encodeSignError(errMsg string) ([]byte, error) {
resp := &zapwire.WarpSignResponse{
Error: errMsg,
}
buf := zapwire.GetBuffer()
resp.Encode(buf)
result := make([]byte, buf.Len())
copy(result, buf.Bytes())
zapwire.PutBuffer(buf)
return result, nil
}
func (s *Server) handleGetPublicKey(ctx context.Context, payload []byte) ([]byte, error) {
// Get public key if signer supports it
type publicKeyGetter interface {
PublicKey() []byte
}
resp := &zapwire.WarpGetPublicKeyResponse{}
if getter, ok := s.signer.(publicKeyGetter); ok {
resp.PublicKey = getter.PublicKey()
} else {
resp.Error = "signer does not support public key retrieval"
}
buf := zapwire.GetBuffer()
resp.Encode(buf)
result := make([]byte, buf.Len())
copy(result, buf.Bytes())
zapwire.PutBuffer(buf)
return result, nil
}
func (s *Server) handleBatchSign(ctx context.Context, payload []byte) ([]byte, error) {
req := &zapwire.WarpBatchSignRequest{}
if err := req.Decode(zapwire.NewReader(payload)); err != nil {
return nil, fmt.Errorf("zwarp decode batch sign request: %w", err)
}
resp := &zapwire.WarpBatchSignResponse{
Signatures: make([][]byte, len(req.Messages)),
Errors: make([]string, len(req.Messages)),
}
for i, msgReq := range req.Messages {
sourceChainID, err := ids.ToID(msgReq.SourceChainID)
if err != nil {
resp.Errors[i] = fmt.Sprintf("invalid source chain ID: %v", err)
continue
}
msg, err := warp.NewUnsignedMessage(msgReq.NetworkID, sourceChainID, msgReq.Payload)
if err != nil {
resp.Errors[i] = fmt.Sprintf("invalid message: %v", err)
continue
}
sig, err := s.signer.Sign(msg)
if err != nil {
resp.Errors[i] = err.Error()
continue
}
resp.Signatures[i] = sig
}
buf := zapwire.GetBuffer()
resp.Encode(buf)
result := make([]byte, buf.Len())
copy(result, buf.Bytes())
zapwire.PutBuffer(buf)
return result, nil
}
// Handler returns a zapwire.HandlerFunc that processes warp messages
func (s *Server) Handler() zapwire.HandlerFunc {
return func(ctx context.Context, msgType zapwire.MessageType, payload []byte) (zapwire.MessageType, []byte, error) {
respPayload, err := s.HandleMessage(ctx, msgType, payload)
if err != nil {
return msgType | zapwire.MsgResponseFlag, nil, err
}
return msgType | zapwire.MsgResponseFlag, respPayload, nil
}
}