Documentation
¶
Overview ¶
Package zapwire provides a 100%-native ZAP client/server for the netrunner control protocol. No protobuf, no gRPC, no codegen.
This package replaces the legacy netrunner/client/client.go (gRPC) and netrunner/server/server.go (gRPC) with a hand-written ZAP layer over luxfi/api/zap. The migration happens RPC-by-RPC; consumers switch to zapwire.Client when the server-side handler for a given op has been converted.
Package zapwire defines the ZAP opcodes and message types for the netrunner control protocol. It replaces the legacy gRPC/protobuf netrunner/rpcpb package with native ZAP types — no protobuf, no .proto files, no codegen — every message is a hand-written Go struct that encodes/decodes via luxfi/api/zap.Buffer / luxfi/api/zap.Reader.
The control protocol is a request/response RPC that runs on TCP between a netrunner client (luxfi/cli, automation tooling, tests) and a netrunner server (this repo). Streaming RPCs (StreamStatus) use multiple response frames keyed by the same request ID.
Index ¶
- Constants
- type Backend
- type Client
- func (c *Client) AddNode(ctx context.Context, req *types.AddNodeRequest) (*types.AddNodeResponse, error)
- func (c *Client) AttachPeer(ctx context.Context, req *types.AttachPeerRequest) (*types.AttachPeerResponse, error)
- func (c *Client) Close() error
- func (c *Client) Health(ctx context.Context) (*types.HealthResponse, error)
- func (c *Client) PauseNode(ctx context.Context, req *types.PauseNodeRequest) (*types.PauseNodeResponse, error)
- func (c *Client) Ping(ctx context.Context) (*types.PingResponse, error)
- func (c *Client) RPCVersion(ctx context.Context) (*types.RPCVersionResponse, error)
- func (c *Client) RemoveNode(ctx context.Context, req *types.RemoveNodeRequest) (*types.RemoveNodeResponse, error)
- func (c *Client) RestartNode(ctx context.Context, req *types.RestartNodeRequest) (*types.RestartNodeResponse, error)
- func (c *Client) ResumeNode(ctx context.Context, req *types.ResumeNodeRequest) (*types.ResumeNodeResponse, error)
- func (c *Client) SendOutboundMessage(ctx context.Context, req *types.SendOutboundMessageRequest) (*types.SendOutboundMessageResponse, error)
- func (c *Client) Status(ctx context.Context) (*types.StatusResponse, error)
- func (c *Client) Stop(ctx context.Context) (*types.StopResponse, error)
- func (c *Client) URIs(ctx context.Context) ([]string, error)
- func (c *Client) WaitForHealthy(ctx context.Context) (*types.WaitForHealthyResponse, error)
- type Server
- type SubOpcode
Constants ¶
const ( // Lifecycle OpPing zap.MessageType = 60 OpRPCVersion zap.MessageType = 61 OpStart zap.MessageType = 62 OpStop zap.MessageType = 63 )
Netrunner control opcodes occupy ZAP message-type range [60, 99]. Per zap/wire.go layout: bits 0..5 carry the opcode (max 63), bit 6 is MsgErrorFlag, bit 7 is MsgResponseFlag. Stay below 0x40 so the flags remain free.
Reserved ranges (see ~/work/lux/api/zap/wire.go):
1..31 — VM service methods 40..43 — p2p.Sender methods 50..52 — Warp signing 60..63 — netrunner control (this file)
Hitting the 0x40 ceiling: keep opcodes <=63. If we need more than 4 opcodes here, use a sub-opcode byte at the start of the payload rather than expanding the opcode range.
const DefaultAddr = "127.0.0.1:9999"
DefaultAddr is the canonical loopback bind address for local development and tests. Production deployments bind to a routable interface, not loopback.
const DefaultPort = 9999
DefaultPort is the canonical Lux ZAP TCP port — used by netrunner control, KMS ZAP transport, and other in-cluster ZAP services. Override only when running multiple ZAP servers on the same host.
const ProtocolVersion uint32 = 1
Wire-protocol version. Bumped on breaking changes to encoding.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Backend ¶
type Backend interface {
Ping(ctx context.Context) (*types.PingResponse, error)
RPCVersion(ctx context.Context) (*types.RPCVersionResponse, error)
Health(ctx context.Context) (*types.HealthResponse, error)
URIs(ctx context.Context) (*types.URIsResponse, error)
Status(ctx context.Context) (*types.StatusResponse, error)
Stop(ctx context.Context) (*types.StopResponse, error)
AddNode(ctx context.Context, req *types.AddNodeRequest) (*types.AddNodeResponse, error)
RemoveNode(ctx context.Context, req *types.RemoveNodeRequest) (*types.RemoveNodeResponse, error)
RestartNode(ctx context.Context, req *types.RestartNodeRequest) (*types.RestartNodeResponse, error)
PauseNode(ctx context.Context, req *types.PauseNodeRequest) (*types.PauseNodeResponse, error)
ResumeNode(ctx context.Context, req *types.ResumeNodeRequest) (*types.ResumeNodeResponse, error)
AttachPeer(ctx context.Context, req *types.AttachPeerRequest) (*types.AttachPeerResponse, error)
SendOutboundMessage(ctx context.Context, req *types.SendOutboundMessageRequest) (*types.SendOutboundMessageResponse, error)
WaitForHealthy(ctx context.Context) (*types.WaitForHealthyResponse, error)
}
Backend is the interface a netrunner server implementation provides to the ZAP wire layer. Each method maps 1:1 to an RPC opcode in opcodes.go. The wire layer is fully decoupled from the underlying network/orchestrator/local-cluster impl — just plug in any Backend.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the netrunner control RPC client over a Z-Wing channel.
All netrunner control traffic is post-quantum encrypted and mutually authenticated. There is no cleartext mode. If a control plane needs to talk to a netrunner server, it presents a Z-Wing identity, period.
func Dial ¶
Dial opens a ZAP control connection to a netrunner server over Z-Wing. cfg must carry a LocalIdentity; ExpectedRemote optionally pins the server's identity.
func (*Client) AddNode ¶ added in v1.17.0
func (c *Client) AddNode(ctx context.Context, req *types.AddNodeRequest) (*types.AddNodeResponse, error)
AddNode adds a single node to the running cluster.
func (*Client) AttachPeer ¶ added in v1.17.0
func (c *Client) AttachPeer(ctx context.Context, req *types.AttachPeerRequest) (*types.AttachPeerResponse, error)
AttachPeer attaches a synthetic test peer to the named node and returns the new peer's identity.
func (*Client) PauseNode ¶ added in v1.17.0
func (c *Client) PauseNode(ctx context.Context, req *types.PauseNodeRequest) (*types.PauseNodeResponse, error)
PauseNode pauses a single node (process suspended, peers see it as offline).
func (*Client) RPCVersion ¶
RPCVersion returns the netrunner control wire-protocol version.
func (*Client) RemoveNode ¶ added in v1.17.0
func (c *Client) RemoveNode(ctx context.Context, req *types.RemoveNodeRequest) (*types.RemoveNodeResponse, error)
RemoveNode removes a single node from the running cluster.
func (*Client) RestartNode ¶ added in v1.17.0
func (c *Client) RestartNode(ctx context.Context, req *types.RestartNodeRequest) (*types.RestartNodeResponse, error)
RestartNode restarts a node, optionally with a new exec path / config.
func (*Client) ResumeNode ¶ added in v1.17.0
func (c *Client) ResumeNode(ctx context.Context, req *types.ResumeNodeRequest) (*types.ResumeNodeResponse, error)
ResumeNode resumes a previously-paused node.
func (*Client) SendOutboundMessage ¶ added in v1.17.0
func (c *Client) SendOutboundMessage(ctx context.Context, req *types.SendOutboundMessageRequest) (*types.SendOutboundMessageResponse, error)
SendOutboundMessage sends a raw p2p message from the named node to a peer; intended for adversarial / fuzzing tests.
func (*Client) WaitForHealthy ¶ added in v1.17.0
WaitForHealthy blocks server-side until the cluster reports healthy on every node, then returns the snapshot.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server hosts a netrunner control RPC over ZAP.
func NewServer ¶
NewServer creates a netrunner ZAP server listening on addr behind a Z-Wing post-quantum handshake. cfg must carry a LocalIdentity. The server has no cleartext mode.
type SubOpcode ¶
type SubOpcode uint8
Sub-opcode dispatcher — encoded as the first byte of payload after the 4-byte request ID. This lets us multiplex many RPCs onto a small opcode footprint while keeping the wire format simple.
[hdr][reqID:uint32][subOp:uint8][rpc-specific bytes...]
const ( // Network lifecycle (alongside OpStart/OpStop opcodes above) SubHealth SubOpcode = 1 SubWaitForHealthy SubOpcode = 2 SubURIs SubOpcode = 3 SubStatus SubOpcode = 4 SubStreamStatus SubOpcode = 5 // Chain operations SubCreateBlockchains SubOpcode = 10 SubCreateChains SubOpcode = 11 SubTransformElasticChains SubOpcode = 12 SubAddPermissionlessValidator SubOpcode = 13 SubRemoveChainValidator SubOpcode = 14 // Node operations SubAddNode SubOpcode = 20 SubRemoveNode SubOpcode = 21 SubRestartNode SubOpcode = 22 SubPauseNode SubOpcode = 23 SubResumeNode SubOpcode = 24 // Peer / message operations SubAttachPeer SubOpcode = 30 SubSendOutboundMessage SubOpcode = 31 // Snapshot operations SubSaveSnapshot SubOpcode = 40 SubSaveHotSnapshot SubOpcode = 41 SubLoadSnapshot SubOpcode = 42 SubRemoveSnapshot SubOpcode = 43 SubGetSnapshotNames SubOpcode = 44 )