zap

package
v1.1.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2026 License: BSD-3-Clause Imports: 11 Imported by: 6

Documentation

Overview

Package zap provides Zero-Copy App Proto (ZAP) serialization for high-performance RPC communication. ZAP minimizes CPU overhead and memory allocations through:

  • Direct memory access for fixed-size fields
  • Length-prefixed variable data without copying
  • Buffer pooling to avoid allocations
  • Simple framing for TCP transport (no HTTP/2 overhead)

Wire protocol:

[4 bytes: message length][1 byte: message type][payload...]

The message type allows multiplexing multiple RPC calls over a single connection.

Index

Constants

View Source
const (
	// CapQuasarExport: the VM tracks a Quasar (⅔-by-stake) EXPORT-FINAL height
	// distinct from its reorgable local accept tip, and answers
	// MsgSetQuasarFinalized / MsgQuasarHeight. Set by the C-Chain EVM; the node
	// wires the consensus export-frontier observer only when this bit is set.
	CapQuasarExport uint64 = 1 << 0

	// CapStateSync: the VM can adopt a peer's state summary instead of replaying
	// to it, and answers the six MsgStateSync*/MsgStateSummary* messages. Set by
	// any VM implementing the syncable surface.
	//
	// The node needs this at the handshake because the alternative is asking and
	// reading a refusal, and a VM that cannot answer at all is indistinguishable
	// on the wire from one that answered "no". A node repairing a damaged chain
	// must tell those apart: the first means find another way, the second means
	// this VM chose to replay.
	CapStateSync uint64 = 1 << 1
)

VM capability bits advertised in InitializeResponse.Capabilities. A VM sets a bit to tell the node it implements the corresponding OPTIONAL add-on that is NOT part of the generic ChainVM contract. Discovered at the handshake, never braided into ChainVM — generic VMs leave every bit clear.

View Source
const (
	// MaxMessageSize is the maximum allowed message size (16MB)
	MaxMessageSize = 16 * 1024 * 1024

	// HeaderSize is the size of the message header (4 bytes length + 1 byte type)
	HeaderSize = 5

	// DefaultBufferSize for pooled buffers
	DefaultBufferSize = 64 * 1024
)

Variables

View Source
var (
	ErrClosed         = errors.New("zap: connection closed")
	ErrTimeout        = errors.New("zap: request timeout")
	ErrResponseFailed = errors.New("zap: response failed")
)
View Source
var (
	ErrMessageTooLarge = errors.New("zap: message exceeds maximum size")
	ErrInvalidMessage  = errors.New("zap: invalid message format")
	ErrUnknownType     = errors.New("zap: unknown message type")
)
View Source
var BufferPool = sync.Pool{
	New: func() interface{} {
		return &Buffer{
			Data: make([]byte, DefaultBufferSize),
		}
	},
}

BufferPool manages reusable buffers to minimize allocations

Functions

func PutBuffer

func PutBuffer(buf *Buffer)

PutBuffer returns a buffer to the pool

func WriteMessage

func WriteMessage(w io.Writer, msgType MessageType, payload []byte) error

WriteMessage writes a complete ZAP message with header

Types

type AtomicApplyRequest added in v1.1.3

type AtomicApplyRequest struct {
	Requests []*AtomicChainRequests
}

AtomicApplyRequest is SharedMemory.Apply(requests) — the atomic commit of a block's cross-chain puts and removes.

NO BATCH CROSSES THIS WIRE. In-process, Apply takes the caller's database batch so the state commit and the shared-memory mutation land as one write; a batch is a live handle over a database the node owns and cannot be serialized. The plugin therefore relies on the property its flush window already has: the ops are derived from a monotone seq in CONSENSUS state, so a replayed window yields byte-identical Puts and Removes. Both are idempotent under replay, so at-least-once delivery of this message has exactly-once effect — which is why the caller must advance its flushed-seq marker only AFTER this call returns.

func (*AtomicApplyRequest) Decode added in v1.1.3

func (m *AtomicApplyRequest) Decode(r *Reader) error

Decode deserializes AtomicApplyRequest from the reader

func (*AtomicApplyRequest) Encode added in v1.1.3

func (m *AtomicApplyRequest) Encode(buf *Buffer)

Encode serializes AtomicApplyRequest to the buffer

type AtomicChainRequests added in v1.1.3

type AtomicChainRequests struct {
	PeerChainID    []byte
	RemoveRequests [][]byte
	PutRequests    []*AtomicElement
}

AtomicChainRequests is one peer chain's operations. Mirrors atomic.Requests.

type AtomicElement added in v1.1.3

type AtomicElement struct {
	Key    []byte
	Value  []byte
	Traits [][]byte
}

AtomicElement is one published cross-chain object: the value stored under Key, plus the traits it is indexed by. Mirrors atomic.Element field-for-field.

type AtomicGetRequest added in v1.1.3

type AtomicGetRequest struct {
	PeerChainID []byte
	Keys        [][]byte
}

AtomicGetRequest asks the node for the values a peer chain published for this chain. It is SharedMemory.Get(peerChainID, keys) verbatim.

func (*AtomicGetRequest) Decode added in v1.1.3

func (m *AtomicGetRequest) Decode(r *Reader) error

Decode deserializes AtomicGetRequest from the reader

func (*AtomicGetRequest) Encode added in v1.1.3

func (m *AtomicGetRequest) Encode(buf *Buffer)

Encode serializes AtomicGetRequest to the buffer

type AtomicGetResponse added in v1.1.3

type AtomicGetResponse struct {
	Values [][]byte
}

AtomicGetResponse carries the values, positionally aligned with the request's keys. SharedMemory.Get guarantees len(values) == len(keys); an absent key is an EMPTY value at its index, never a short slice — the caller distinguishes "no such object" from "object present" by length, so that invariant is part of the wire contract and is asserted on decode by the caller.

func (*AtomicGetResponse) Decode added in v1.1.3

func (m *AtomicGetResponse) Decode(r *Reader) error

Decode deserializes AtomicGetResponse from the reader

func (*AtomicGetResponse) Encode added in v1.1.3

func (m *AtomicGetResponse) Encode(buf *Buffer)

Encode serializes AtomicGetResponse to the buffer

type AtomicIndexedRequest added in v1.1.3

type AtomicIndexedRequest struct {
	PeerChainID []byte
	Traits      [][]byte
	StartTrait  []byte
	StartKey    []byte
	Limit       uint32
}

AtomicIndexedRequest is SharedMemory.Indexed — a paginated walk of the objects a peer chain published that carry any of the given traits.

It exists on this wire for exactly one caller: the D-Chain's autonomous seam drive, which enumerates pending C->D intents by a fixed discovery trait inside BuildBlock. A shared-memory object does not carry its own key in its value, so the drive recovers keys through the LastKey cursor rather than by parsing values — which is why LastTrait/LastKey are part of the response and not an optimization.

func (*AtomicIndexedRequest) Decode added in v1.1.3

func (m *AtomicIndexedRequest) Decode(r *Reader) error

Decode deserializes AtomicIndexedRequest from the reader

func (*AtomicIndexedRequest) Encode added in v1.1.3

func (m *AtomicIndexedRequest) Encode(buf *Buffer)

Encode serializes AtomicIndexedRequest to the buffer

type AtomicIndexedResponse added in v1.1.3

type AtomicIndexedResponse struct {
	Values    [][]byte
	LastTrait []byte
	LastKey   []byte
}

AtomicIndexedResponse carries one page plus the cursor to resume from.

func (*AtomicIndexedResponse) Decode added in v1.1.3

func (m *AtomicIndexedResponse) Decode(r *Reader) error

Decode deserializes AtomicIndexedResponse from the reader

func (*AtomicIndexedResponse) Encode added in v1.1.3

func (m *AtomicIndexedResponse) Encode(buf *Buffer)

Encode serializes AtomicIndexedResponse to the buffer

type BatchedParseBlockRequest

type BatchedParseBlockRequest struct {
	Requests [][]byte
}

BatchedParseBlockRequest contains multiple blocks to parse

func (*BatchedParseBlockRequest) Decode

func (m *BatchedParseBlockRequest) Decode(r *Reader) error

Decode deserializes BatchedParseBlockRequest from the reader

func (*BatchedParseBlockRequest) Encode

func (m *BatchedParseBlockRequest) Encode(buf *Buffer)

Encode serializes BatchedParseBlockRequest to the buffer

type BatchedParseBlockResponse

type BatchedParseBlockResponse struct {
	Responses []BlockResponse
}

BatchedParseBlockResponse contains parsed blocks

func (*BatchedParseBlockResponse) Decode

func (m *BatchedParseBlockResponse) Decode(r *Reader) error

Decode deserializes BatchedParseBlockResponse from the reader

func (*BatchedParseBlockResponse) Encode

func (m *BatchedParseBlockResponse) Encode(buf *Buffer)

Encode serializes BatchedParseBlockResponse to the buffer

type BlockAcceptRequest

type BlockAcceptRequest struct {
	ID []byte
}

BlockAcceptRequest contains block ID to accept

func (*BlockAcceptRequest) Decode

func (m *BlockAcceptRequest) Decode(r *Reader) error

Decode deserializes BlockAcceptRequest from the reader

func (*BlockAcceptRequest) Encode

func (m *BlockAcceptRequest) Encode(buf *Buffer)

Encode serializes BlockAcceptRequest to the buffer

type BlockRejectRequest

type BlockRejectRequest struct {
	ID []byte
}

BlockRejectRequest contains block ID to reject

func (*BlockRejectRequest) Decode

func (m *BlockRejectRequest) Decode(r *Reader) error

Decode deserializes BlockRejectRequest from the reader

func (*BlockRejectRequest) Encode

func (m *BlockRejectRequest) Encode(buf *Buffer)

Encode serializes BlockRejectRequest to the buffer

type BlockResponse

type BlockResponse struct {
	ID                []byte
	ParentID          []byte
	Bytes             []byte // Zero-copy block data
	Height            uint64
	Timestamp         int64
	VerifyWithContext bool
	Err               Error
}

BlockResponse contains block data (used by BuildBlock, ParseBlock, GetBlock)

func (*BlockResponse) Decode

func (m *BlockResponse) Decode(r *Reader) error

Decode deserializes BlockResponse from the reader

func (*BlockResponse) Encode

func (m *BlockResponse) Encode(buf *Buffer)

Encode serializes BlockResponse to the buffer

type BlockVerifyRequest

type BlockVerifyRequest struct {
	Bytes           []byte
	PChainHeight    uint64
	HasPChainHeight bool
}

BlockVerifyRequest contains block verification parameters

func (*BlockVerifyRequest) Decode

func (m *BlockVerifyRequest) Decode(r *Reader) error

Decode deserializes BlockVerifyRequest from the reader

func (*BlockVerifyRequest) Encode

func (m *BlockVerifyRequest) Encode(buf *Buffer)

Encode serializes BlockVerifyRequest to the buffer

type BlockVerifyResponse

type BlockVerifyResponse struct {
	Timestamp int64
}

BlockVerifyResponse contains verification result

func (*BlockVerifyResponse) Decode

func (m *BlockVerifyResponse) Decode(r *Reader) error

Decode deserializes BlockVerifyResponse from the reader

func (*BlockVerifyResponse) Encode

func (m *BlockVerifyResponse) Encode(buf *Buffer)

Encode serializes BlockVerifyResponse to the buffer

type Buffer

type Buffer struct {
	Data []byte
	// contains filtered or unexported fields
}

Buffer is a reusable byte buffer for zero-copy operations

func GetBuffer

func GetBuffer() *Buffer

GetBuffer retrieves a buffer from the pool

func (*Buffer) Bytes

func (b *Buffer) Bytes() []byte

Bytes returns the written portion of the buffer

func (*Buffer) Grow

func (b *Buffer) Grow(n int)

Grow ensures the buffer has at least n bytes available

func (*Buffer) Len

func (b *Buffer) Len() int

Len returns the number of bytes written

func (*Buffer) Reset

func (b *Buffer) Reset()

Reset prepares the buffer for reuse

func (*Buffer) WriteBool

func (b *Buffer) WriteBool(v bool)

WriteBool writes a boolean to the buffer

func (*Buffer) WriteBytes

func (b *Buffer) WriteBytes(data []byte)

WriteBytes writes a length-prefixed byte slice to the buffer

func (*Buffer) WriteInt32

func (b *Buffer) WriteInt32(v int32)

WriteInt32 writes an int32 to the buffer (big-endian)

func (*Buffer) WriteInt64

func (b *Buffer) WriteInt64(v int64)

WriteInt64 writes an int64 to the buffer (big-endian)

func (*Buffer) WriteString

func (b *Buffer) WriteString(s string)

WriteString writes a length-prefixed string to the buffer

func (*Buffer) WriteUint8

func (b *Buffer) WriteUint8(v uint8)

WriteUint8 writes a uint8 to the buffer

func (*Buffer) WriteUint16

func (b *Buffer) WriteUint16(v uint16)

WriteUint16 writes a uint16 to the buffer (big-endian)

func (*Buffer) WriteUint32

func (b *Buffer) WriteUint32(v uint32)

WriteUint32 writes a uint32 to the buffer (big-endian)

func (*Buffer) WriteUint64

func (b *Buffer) WriteUint64(v uint64)

WriteUint64 writes a uint64 to the buffer (big-endian)

type BuildBlockRequest

type BuildBlockRequest struct {
	PChainHeight    uint64
	HasPChainHeight bool
}

BuildBlockRequest contains block building parameters

func (*BuildBlockRequest) Decode

func (m *BuildBlockRequest) Decode(r *Reader) error

Decode deserializes BuildBlockRequest from the reader

func (*BuildBlockRequest) Encode

func (m *BuildBlockRequest) Encode(buf *Buffer)

Encode serializes BuildBlockRequest to the buffer

type Config

type Config struct {
	// ReadTimeout is the timeout for reading a message
	ReadTimeout time.Duration
	// WriteTimeout is the timeout for writing a message
	WriteTimeout time.Duration
	// MaxConcurrent is the maximum number of concurrent requests
	MaxConcurrent int
	// BufferSize is the read/write buffer size
	BufferSize int
}

Config contains transport configuration

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a Config with reasonable defaults

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a ZAP connection that multiplexes requests

func Dial

func Dial(ctx context.Context, addr string, config *Config) (*Conn, error)

Dial connects to a ZAP server. The network transport is inferred from addr: a filesystem path ("/tmp/vm.sock", "@abstract", or anything containing no ':' host:port) dials a unix-domain socket — no TCP/UDP stack, the in-proc / same-host fast path; a "host:port" addr dials TCP for a genuinely remote server. Backward compatible: existing "127.0.0.1:port" addrs still dial tcp.

func NewConn

func NewConn(conn net.Conn, config *Config) *Conn

NewConn wraps an existing net.Conn as a ZAP connection

func (*Conn) Call

func (c *Conn) Call(ctx context.Context, msgType MessageType, payload []byte) (MessageType, []byte, error)

Call sends a request and waits for a response

func (*Conn) Close

func (c *Conn) Close() error

Close closes the connection

func (*Conn) Send

func (c *Conn) Send(msgType MessageType, payload []byte) error

Send sends a one-way message (no response expected)

type ConnectedRequest

type ConnectedRequest struct {
	NodeID []byte
	Name   string
	Major  uint32
	Minor  uint32
	Patch  uint32
}

ConnectedRequest contains connection info

func (*ConnectedRequest) Decode

func (m *ConnectedRequest) Decode(r *Reader) error

Decode deserializes ConnectedRequest from the reader

func (*ConnectedRequest) Encode

func (m *ConnectedRequest) Encode(buf *Buffer)

Encode serializes ConnectedRequest to the buffer

type CreateHandlersResponse

type CreateHandlersResponse struct {
	Handlers []HTTPHandler
}

CreateHandlersResponse contains handler list

func (*CreateHandlersResponse) Decode

func (m *CreateHandlersResponse) Decode(r *Reader) error

Decode deserializes CreateHandlersResponse from the reader

func (*CreateHandlersResponse) Encode

func (m *CreateHandlersResponse) Encode(buf *Buffer)

Encode serializes CreateHandlersResponse to the buffer

type DisconnectedRequest

type DisconnectedRequest struct {
	NodeID []byte
}

DisconnectedRequest contains disconnection info

func (*DisconnectedRequest) Decode

func (m *DisconnectedRequest) Decode(r *Reader) error

Decode deserializes DisconnectedRequest from the reader

func (*DisconnectedRequest) Encode

func (m *DisconnectedRequest) Encode(buf *Buffer)

Encode serializes DisconnectedRequest to the buffer

type Error

type Error uint8

Error represents VM errors

const (
	ErrorUnspecified Error = iota
	ErrorClosed
	ErrorNotFound
	ErrorStateSyncNotImplemented
	ErrorInternal
)

The zero value carries "the call succeeded" — a reply whose Err is ErrorUnspecified is read as a good answer and its fields are trusted. Every other value names a failure, so a failure the vocabulary has no word for must reach the caller as ErrorInternal. Mapping it onto the zero instead hands back a zero-valued block under the name of success.

type GetAncestorsRequest

type GetAncestorsRequest struct {
	BlkID                 []byte
	MaxBlocksNum          int32
	MaxBlocksSize         int32
	MaxBlocksRetrivalTime int64
}

GetAncestorsRequest contains ancestor retrieval parameters

func (*GetAncestorsRequest) Decode

func (m *GetAncestorsRequest) Decode(r *Reader) error

Decode deserializes GetAncestorsRequest from the reader

func (*GetAncestorsRequest) Encode

func (m *GetAncestorsRequest) Encode(buf *Buffer)

Encode serializes GetAncestorsRequest to the buffer

type GetAncestorsResponse

type GetAncestorsResponse struct {
	BlksBytes [][]byte
}

GetAncestorsResponse contains ancestor blocks

func (*GetAncestorsResponse) Decode

func (m *GetAncestorsResponse) Decode(r *Reader) error

Decode deserializes GetAncestorsResponse from the reader

func (*GetAncestorsResponse) Encode

func (m *GetAncestorsResponse) Encode(buf *Buffer)

Encode serializes GetAncestorsResponse to the buffer

type GetBlockIDAtHeightRequest

type GetBlockIDAtHeightRequest struct {
	Height uint64
}

GetBlockIDAtHeightRequest contains height to query

func (*GetBlockIDAtHeightRequest) Decode

func (m *GetBlockIDAtHeightRequest) Decode(r *Reader) error

Decode deserializes GetBlockIDAtHeightRequest from the reader

func (*GetBlockIDAtHeightRequest) Encode

func (m *GetBlockIDAtHeightRequest) Encode(buf *Buffer)

Encode serializes GetBlockIDAtHeightRequest to the buffer

type GetBlockIDAtHeightResponse

type GetBlockIDAtHeightResponse struct {
	BlkID []byte
	Err   Error
}

GetBlockIDAtHeightResponse contains block ID at height

func (*GetBlockIDAtHeightResponse) Decode

func (m *GetBlockIDAtHeightResponse) Decode(r *Reader) error

Decode deserializes GetBlockIDAtHeightResponse from the reader

func (*GetBlockIDAtHeightResponse) Encode

func (m *GetBlockIDAtHeightResponse) Encode(buf *Buffer)

Encode serializes GetBlockIDAtHeightResponse to the buffer

type GetBlockRequest

type GetBlockRequest struct {
	ID []byte
}

GetBlockRequest contains block ID to retrieve

func (*GetBlockRequest) Decode

func (m *GetBlockRequest) Decode(r *Reader) error

Decode deserializes GetBlockRequest from the reader

func (*GetBlockRequest) Encode

func (m *GetBlockRequest) Encode(buf *Buffer)

Encode serializes GetBlockRequest to the buffer

type GetStateSummaryRequest added in v1.1.5

type GetStateSummaryRequest struct {
	Height uint64
}

GetStateSummaryRequest names the height whose summary is wanted.

func (*GetStateSummaryRequest) Decode added in v1.1.5

func (m *GetStateSummaryRequest) Decode(r *Reader) error

func (*GetStateSummaryRequest) Encode added in v1.1.5

func (m *GetStateSummaryRequest) Encode(buf *Buffer)

type GossipMsg

type GossipMsg struct {
	NodeID []byte
	Msg    []byte
}

GossipMsg contains gossip message

func (*GossipMsg) Decode

func (m *GossipMsg) Decode(r *Reader) error

Decode deserializes GossipMsg from the reader

func (*GossipMsg) Encode

func (m *GossipMsg) Encode(buf *Buffer)

Encode serializes GossipMsg to the buffer

type HTTPHandler

type HTTPHandler struct {
	Prefix     string
	ServerAddr string
}

HTTPHandler contains HTTP handler info

func (*HTTPHandler) Decode

func (m *HTTPHandler) Decode(r *Reader) error

Decode deserializes HTTPHandler from the reader

func (*HTTPHandler) Encode

func (m *HTTPHandler) Encode(buf *Buffer)

Encode serializes HTTPHandler to the buffer

type Handler

type Handler interface {
	// Handle processes a request and returns a response
	Handle(ctx context.Context, msgType MessageType, payload []byte) (MessageType, []byte, error)
}

Handler processes ZAP requests

type HandlerFunc

type HandlerFunc func(ctx context.Context, msgType MessageType, payload []byte) (MessageType, []byte, error)

HandlerFunc is a function that implements Handler

func (HandlerFunc) Handle

func (f HandlerFunc) Handle(ctx context.Context, msgType MessageType, payload []byte) (MessageType, []byte, error)

Handle implements Handler

type HealthResponse

type HealthResponse struct {
	Details []byte
}

HealthResponse contains health check result

func (*HealthResponse) Decode

func (m *HealthResponse) Decode(r *Reader) error

Decode deserializes HealthResponse from the reader

func (*HealthResponse) Encode

func (m *HealthResponse) Encode(buf *Buffer)

Encode serializes HealthResponse to the buffer

type InitializeRequest

type InitializeRequest struct {
	NetworkID    uint32
	ChainID      []byte
	NodeID       []byte
	PublicKey    []byte
	XChainID     []byte
	CChainID     []byte
	UTXOAssetID  []byte
	ChainDataDir string
	GenesisBytes []byte
	UpgradeBytes []byte
	ConfigBytes  []byte
	DBServerAddr string
	ServerAddr   string

	// AtomicServerAddr is the address of a ZAP server the node bound over THIS
	// chain's atomic shared-memory handle before calling Initialize. A plugin
	// dials it to reach the primary network's cross-chain import/export
	// primitive, which cannot be copied into the plugin's rebuilt Runtime
	// because it is an interface over a live database the node owns. Same shape
	// and lifetime as DBServerAddr.
	//
	// Empty means the node wired no shared memory for this chain. The plugin
	// MUST then leave Runtime.SharedMemory nil so a settlement precompile
	// reverts fail-closed rather than fabricate value.
	AtomicServerAddr string

	// ValidatorServerAddr is the address of a ZAP server the node bound over its
	// validator state before calling Initialize. A plugin dials it to learn who
	// the validators are at a P-chain height.
	//
	// It rides here for the same reason AtomicServerAddr does: validator state is
	// an interface over live node-owned state, so it cannot be copied into the
	// plugin's rebuilt Runtime. Without it a plugin-hosted VM sees a nil handle
	// and can form no committee — which is why M-Chain, whose whole job is a
	// threshold ceremony among validators, could never run one.
	//
	// Empty means the node wired no validator state for this chain. The plugin
	// MUST then leave Runtime.ValidatorState nil so a committee lookup fails
	// with a clear "no committee" rather than fabricating an empty set — an
	// empty validator set is a quorum of nobody.
	ValidatorServerAddr string

	// DChainID is the D-Chain (dexvm) blockchain id, resolved node-side from the
	// chain alias "D". It rides here because the plugin's Runtime has no
	// BCLookup — that field is an interface onto the node's chain manager and,
	// like SharedMemory, does not survive the boundary. The DEX settlement seam
	// needs exactly one alias resolved, so the resolved ID is carried instead of
	// proxying a whole lookup service.
	//
	// Empty means the network has no dexvm deployed; the settlement seam then
	// stays closed rather than guess a peer.
	DChainID []byte
}

InitializeRequest contains initialization parameters.

Note: the upstream upgrade-timestamp surface was ripped under the activate- all-implicitly directive — every chain runs the post-Granite rule-set from genesis, so there are no per-upgrade timestamps to ship over the wire.

func (*InitializeRequest) Decode

func (m *InitializeRequest) Decode(r *Reader) error

Decode deserializes InitializeRequest from the reader.

LENGTH-TOLERANT trailing fields, the same contract InitializeResponse.Decode documents. AtomicServerAddr, DChainID and ValidatorServerAddr were APPENDED for the cross-chain atomic seam without bumping version.RPCChainVMProtocol, so both skew directions stay safe:

  • NEW node -> OLD plugin: the old decoder stops after ServerAddr and ignores the trailing bytes (ZAP frames are length-prefixed). The plugin keeps its nil SharedMemory and its settlements keep reverting fail-closed — the behavior it already had, never a silent divergence.
  • OLD node -> NEW plugin: Remaining() is 0 at these reads, so both fields stay zero-valued and the plugin treats the atomic capability as absent.

Neither direction changes how any block executes, which is what makes this safe to roll one validator at a time.

func (*InitializeRequest) Encode

func (m *InitializeRequest) Encode(buf *Buffer)

Encode serializes InitializeRequest to the buffer

type InitializeResponse

type InitializeResponse struct {
	LastAcceptedID       []byte
	LastAcceptedParentID []byte
	Height               uint64
	Bytes                []byte
	Timestamp            int64
	// Capabilities is a bitfield of OPTIONAL cross-boundary add-ons the VM
	// implements (see the Cap* constants). The node reads it once at handshake
	// to decide which add-ons to wire; an unset bit → the node treats that
	// capability as absent and stays on the generic path.
	Capabilities uint64
}

InitializeResponse contains initialization results

func (*InitializeResponse) Decode

func (m *InitializeResponse) Decode(r *Reader) error

Decode deserializes InitializeResponse from the reader.

LENGTH-TOLERANT trailing field. Capabilities is OPTIONAL on the wire: it was APPENDED in api v1.0.16 (the Quasar-export handshake) WITHOUT bumping version.RPCChainVMProtocol, so a peer built before it — a stale VM plugin — sends a payload that ends right after Timestamp. Guarding the read on Remaining() lets a newer decoder read that short payload as "Capabilities = 0" (Nova-only, no optional add-ons) instead of failing with io.ErrUnexpectedEOF — exactly the v1.36.11 skew that broke every EVM Initialize with "zap decode initialize response: unexpected EOF". The mirror case (an OLDER decoder reading a NEWER payload) already works: a length-prefixed ZAP frame lets the old decoder stop after Timestamp and ignore the trailing bytes.

EVOLUTION RULE: any FUTURE field is appended AFTER Capabilities and read the same way — guard each read on Remaining(), and keep Encode writing fields in this exact order. Never insert or reorder a field in the middle: that is a breaking wire change and MUST bump version.RPCChainVMProtocol.

func (*InitializeResponse) Encode

func (m *InitializeResponse) Encode(buf *Buffer)

Encode serializes InitializeResponse to the buffer

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

Listener accepts ZAP connections

func Listen

func Listen(addr string, config *Config) (*Listener, error)

Listen creates a new ZAP listener

func NewListener added in v1.0.10

func NewListener(raw net.Listener, config *Config) *Listener

NewListener wraps an existing net.Listener as a ZAP listener. Any transport that yields net.Conn — Unix sockets, in-memory pipes, a post-handshake Z-Wing listener — can be served as ZAP this way.

func (*Listener) Accept

func (l *Listener) Accept() (*ServerConn, error)

Accept accepts a new connection

func (*Listener) Addr

func (l *Listener) Addr() net.Addr

Addr returns the listener's address

func (*Listener) Close

func (l *Listener) Close() error

Close closes the listener

type MessageType

type MessageType uint8

MessageType identifies the RPC method being called

const (
	// VM service methods (1-31)
	MsgInitialize MessageType = iota + 1
	MsgSetState
	MsgShutdown
	MsgCreateHandlers
	MsgNewHTTPHandler
	MsgWaitForEvent
	MsgConnected
	MsgDisconnected
	MsgBuildBlock
	MsgParseBlock
	MsgGetBlock
	MsgSetPreference
	MsgHealth
	MsgVersion
	MsgRequest
	MsgRequestFailed
	MsgResponse
	MsgGossip
	MsgGather
	MsgGetAncestors
	MsgBatchedParseBlock
	MsgGetBlockIDAtHeight
	MsgStateSyncEnabled
	MsgGetOngoingSyncStateSummary
	MsgGetLastStateSummary
	MsgParseStateSummary
	MsgGetStateSummary
	MsgBlockVerify
	MsgBlockAccept
	MsgBlockReject
	MsgStateSummaryAccept // = 31

	// Atomic shared-memory methods (32-39). The cross-chain atomic import/
	// export primitive (the SAME one platformvm and the dexvm use) lives in the
	// NODE process — one atomic.Memory per node, shared by every chain. A VM
	// hosted OUT of process (the C-Chain EVM, the dexvm) therefore cannot reach
	// it through its Runtime, which is why these exist.
	//
	// DIRECTION: unlike every other message in this file, these travel
	// plugin->node. The plugin DIALS a per-chain ZAP server the node binds
	// before Initialize and names in InitializeRequest.AtomicServerAddr — the
	// SAME shape as DBServerAddr. The node is the server; the transport stays
	// strictly request/response and needs no duplex.
	//
	// SCOPE: the whole SharedMemory interface — Get, Indexed, Apply. Indexed
	// looks superfluous from the C-Chain side (no settlement path calls it), but
	// the D-Chain's autonomous seam drive is built on it: it enumerates pending
	// C->D intents by trait inside BuildBlock, because a shared-memory object is
	// not self-identifying and cannot otherwise be discovered without already
	// knowing its owner. Omitting it would leave D unable to find any intent.
	MsgAtomicGet     MessageType = 32
	MsgAtomicApply   MessageType = 33
	MsgAtomicIndexed MessageType = 34

	// p2p.Sender methods (40-49)
	MsgSendRequest  MessageType = 40
	MsgSendResponse MessageType = 41
	MsgSendError    MessageType = 42
	MsgSendGossip   MessageType = 43

	// Warp signing methods (50-59)
	MsgWarpSign         MessageType = 50
	MsgWarpGetPublicKey MessageType = 51
	MsgWarpBatchSign    MessageType = 52

	// Quasar EXPORT methods (60-63): the two-tier consensus (v1.36) export
	// frontier — Quasar = ⅔-by-stake, the reorg-safe finality a VM's
	// `finalized`/`safe` tags and cross-chain (warp) export gate must resolve
	// to instead of the reorgable Nova accept tip — carried across the plugin
	// process boundary. OPTIONAL: only a VM that advertises CapQuasarExport in
	// the Initialize handshake (see vm.go) is ever sent these; a generic VM is
	// never asked. Kept < 0x40 so the response/error flags OR in cleanly.
	MsgSetQuasarFinalized MessageType = 60
	MsgQuasarHeight       MessageType = 61

	// validators.State (53). Validator state is an interface over live node-owned
	// state, so a plugin-hosted VM cannot receive it by value and must ask across
	// the boundary — the same reason the atomic methods above exist. M-Chain
	// forms its threshold committee from these answers.
	//
	// ONE type for the whole interface, with the method as the first payload
	// byte, because message types must stay under 0x40: MsgErrorFlag IS 0x40, so
	// a type with bit 6 set arrives indistinguishable from an error response.
	// validators.State has eight methods and no eight-wide run remains below the
	// limit, so a type per method could not be spelled correctly even once.
	MsgValidatorState MessageType = 53

	// Response flag - set on response messages (bit 7 / high bit).
	// All message types must be < 64 (0x40) to allow OR with this flag
	// AND with MsgErrorFlag below.
	MsgResponseFlag MessageType = 0x80

	// Error flag - set on response messages that carry an error.
	// Always co-occurs with MsgResponseFlag on the wire:
	//   success response: msgType | MsgResponseFlag
	//   error response:   msgType | MsgResponseFlag | MsgErrorFlag
	// Payload of an error response is the error string (length-prefixed
	// after the request ID).
	MsgErrorFlag MessageType = 0x40
)

func ReadMessage

func ReadMessage(r io.Reader) (MessageType, []byte, error)

ReadMessage reads a complete ZAP message with header

type NewHTTPHandlerResponse

type NewHTTPHandlerResponse struct {
	ServerAddr string
}

NewHTTPHandlerResponse contains HTTP handler address

func (*NewHTTPHandlerResponse) Decode

func (m *NewHTTPHandlerResponse) Decode(r *Reader) error

Decode deserializes NewHTTPHandlerResponse from the reader

func (*NewHTTPHandlerResponse) Encode

func (m *NewHTTPHandlerResponse) Encode(buf *Buffer)

Encode serializes NewHTTPHandlerResponse to the buffer

type ParseBlockRequest

type ParseBlockRequest struct {
	Bytes []byte // Zero-copy input
}

ParseBlockRequest contains bytes to parse

func (*ParseBlockRequest) Decode

func (m *ParseBlockRequest) Decode(r *Reader) error

Decode deserializes ParseBlockRequest from the reader

func (*ParseBlockRequest) Encode

func (m *ParseBlockRequest) Encode(buf *Buffer)

Encode serializes ParseBlockRequest to the buffer

type ParseStateSummaryRequest added in v1.1.5

type ParseStateSummaryRequest struct {
	Bytes []byte
}

ParseStateSummaryRequest carries a peer's summary bytes for the VM to read.

func (*ParseStateSummaryRequest) Decode added in v1.1.5

func (m *ParseStateSummaryRequest) Decode(r *Reader) error

func (*ParseStateSummaryRequest) Encode added in v1.1.5

func (m *ParseStateSummaryRequest) Encode(buf *Buffer)

type QuasarHeightResponse added in v1.0.16

type QuasarHeightResponse struct {
	Height uint64
}

QuasarHeightResponse carries the VM's current accept-tip-CLAMPED Quasar EXPORT-FINAL height (MsgQuasarHeight) — 0 before the first export forms. The MsgQuasarHeight request has no fields (empty payload).

func (*QuasarHeightResponse) Decode added in v1.0.16

func (m *QuasarHeightResponse) Decode(r *Reader) error

Decode deserializes QuasarHeightResponse from the reader

func (*QuasarHeightResponse) Encode added in v1.0.16

func (m *QuasarHeightResponse) Encode(buf *Buffer)

Encode serializes QuasarHeightResponse to the buffer

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader provides zero-copy reading from a byte slice

func NewReader

func NewReader(data []byte) *Reader

NewReader creates a new reader from a byte slice

func (*Reader) ReadBool

func (r *Reader) ReadBool() (bool, error)

ReadBool reads a boolean from the buffer

func (*Reader) ReadBytes

func (r *Reader) ReadBytes() ([]byte, error)

ReadBytes reads a length-prefixed byte slice (zero-copy - returns slice into original buffer)

func (*Reader) ReadCount added in v1.0.14

func (r *Reader) ReadCount() (uint32, error)

ReadCount reads a uint32 element count and rejects any value larger than the number of unread bytes. Every element costs at least one byte on the wire, so a count exceeding Remaining() can never be satisfied by the payload. Rejecting it here stops a hostile count (e.g. 0xFFFFFFFF) from driving a huge make([]T, count) allocation before the per-element decode loop reaches EOF.

func (*Reader) ReadInt32

func (r *Reader) ReadInt32() (int32, error)

ReadInt32 reads an int32 from the buffer (big-endian)

func (*Reader) ReadInt64

func (r *Reader) ReadInt64() (int64, error)

ReadInt64 reads an int64 from the buffer (big-endian)

func (*Reader) ReadString

func (r *Reader) ReadString() (string, error)

ReadString reads a length-prefixed string

func (*Reader) ReadUint8

func (r *Reader) ReadUint8() (uint8, error)

ReadUint8 reads a uint8 from the buffer

func (*Reader) ReadUint16

func (r *Reader) ReadUint16() (uint16, error)

ReadUint16 reads a uint16 from the buffer (big-endian)

func (*Reader) ReadUint32

func (r *Reader) ReadUint32() (uint32, error)

ReadUint32 reads a uint32 from the buffer (big-endian)

func (*Reader) ReadUint64

func (r *Reader) ReadUint64() (uint64, error)

ReadUint64 reads a uint64 from the buffer (big-endian)

func (*Reader) Remaining

func (r *Reader) Remaining() int

Remaining returns the number of unread bytes

type RequestFailedMsg

type RequestFailedMsg struct {
	NodeID       []byte
	RequestID    uint32
	ErrorCode    int32
	ErrorMessage string
}

RequestFailedMsg contains failed request info

func (*RequestFailedMsg) Decode

func (m *RequestFailedMsg) Decode(r *Reader) error

Decode deserializes RequestFailedMsg from the reader

func (*RequestFailedMsg) Encode

func (m *RequestFailedMsg) Encode(buf *Buffer)

Encode serializes RequestFailedMsg to the buffer

type RequestMsg

type RequestMsg struct {
	NodeID    []byte
	RequestID uint32
	Deadline  int64
	Request   []byte
}

RequestMsg contains incoming request data

func (*RequestMsg) Decode

func (m *RequestMsg) Decode(r *Reader) error

Decode deserializes RequestMsg from the reader

func (*RequestMsg) Encode

func (m *RequestMsg) Encode(buf *Buffer)

Encode serializes RequestMsg to the buffer

type ResponseMsg

type ResponseMsg struct {
	NodeID    []byte
	RequestID uint32
	Response  []byte
}

ResponseMsg contains response data

func (*ResponseMsg) Decode

func (m *ResponseMsg) Decode(r *Reader) error

Decode deserializes ResponseMsg from the reader

func (*ResponseMsg) Encode

func (m *ResponseMsg) Encode(buf *Buffer)

Encode serializes ResponseMsg to the buffer

type SendErrorMsg

type SendErrorMsg struct {
	NodeID       []byte
	RequestID    uint32
	ErrorCode    int32
	ErrorMessage string
}

SendErrorMsg contains error to send to a node (p2p.Sender.SendError)

func (*SendErrorMsg) Decode

func (m *SendErrorMsg) Decode(r *Reader) error

Decode deserializes SendErrorMsg from the reader

func (*SendErrorMsg) Encode

func (m *SendErrorMsg) Encode(buf *Buffer)

Encode serializes SendErrorMsg to the buffer

type SendGossipMsg

type SendGossipMsg struct {
	NodeIDs       [][]byte
	Validators    uint64
	NonValidators uint64
	Peers         uint64
	Msg           []byte // Zero-copy gossip payload
}

SendGossipMsg contains gossip message to send (p2p.Sender.SendGossip)

func (*SendGossipMsg) Decode

func (m *SendGossipMsg) Decode(r *Reader) error

Decode deserializes SendGossipMsg from the reader

func (*SendGossipMsg) Encode

func (m *SendGossipMsg) Encode(buf *Buffer)

Encode serializes SendGossipMsg to the buffer

type SendRequestMsg

type SendRequestMsg struct {
	NodeIDs   [][]byte
	RequestID uint32
	Request   []byte // Zero-copy payload
}

SendRequestMsg contains request to send to nodes (p2p.Sender.SendRequest)

func (*SendRequestMsg) Decode

func (m *SendRequestMsg) Decode(r *Reader) error

Decode deserializes SendRequestMsg from the reader

func (*SendRequestMsg) Encode

func (m *SendRequestMsg) Encode(buf *Buffer)

Encode serializes SendRequestMsg to the buffer

type SendResponseMsg

type SendResponseMsg struct {
	NodeID    []byte
	RequestID uint32
	Response  []byte // Zero-copy payload
}

SendResponseMsg contains response to send to a node (p2p.Sender.SendResponse)

func (*SendResponseMsg) Decode

func (m *SendResponseMsg) Decode(r *Reader) error

Decode deserializes SendResponseMsg from the reader

func (*SendResponseMsg) Encode

func (m *SendResponseMsg) Encode(buf *Buffer)

Encode serializes SendResponseMsg to the buffer

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server serves ZAP requests

func NewServer

func NewServer(listener *Listener, handler Handler) *Server

NewServer creates a new ZAP server

func (*Server) Close

func (s *Server) Close() error

Close closes the server

func (*Server) Serve

func (s *Server) Serve(ctx context.Context) error

Serve accepts and processes connections

type ServerConn

type ServerConn struct {
	// contains filtered or unexported fields
}

ServerConn is a server-side ZAP connection

func (*ServerConn) Close

func (c *ServerConn) Close() error

Close closes the server connection

func (*ServerConn) Read

func (c *ServerConn) Read() (uint32, MessageType, []byte, error)

Read reads the next request from the connection

func (*ServerConn) RemoteAddr

func (c *ServerConn) RemoteAddr() net.Addr

RemoteAddr returns the remote address

func (*ServerConn) Write

func (c *ServerConn) Write(reqID uint32, msgType MessageType, payload []byte) error

Write writes a response

type SetPreferenceRequest

type SetPreferenceRequest struct {
	ID []byte
}

SetPreferenceRequest contains preferred block ID

func (*SetPreferenceRequest) Decode

func (m *SetPreferenceRequest) Decode(r *Reader) error

Decode deserializes SetPreferenceRequest from the reader

func (*SetPreferenceRequest) Encode

func (m *SetPreferenceRequest) Encode(buf *Buffer)

Encode serializes SetPreferenceRequest to the buffer

type SetQuasarFinalizedRequest added in v1.0.16

type SetQuasarFinalizedRequest struct {
	Height uint64
}

SetQuasarFinalizedRequest carries a new Quasar (⅔-by-stake) EXPORT-FINAL height from the node's consensus export-frontier observer to the VM (MsgSetQuasarFinalized). The VM persists it; the response is empty.

func (*SetQuasarFinalizedRequest) Decode added in v1.0.16

func (m *SetQuasarFinalizedRequest) Decode(r *Reader) error

Decode deserializes SetQuasarFinalizedRequest from the reader

func (*SetQuasarFinalizedRequest) Encode added in v1.0.16

func (m *SetQuasarFinalizedRequest) Encode(buf *Buffer)

Encode serializes SetQuasarFinalizedRequest to the buffer

type SetStateRequest

type SetStateRequest struct {
	State State
}

SetStateRequest contains state change request. State values are defined in github.com/luxfi/vm (vm.State):

Unknown=0, Starting=1, Syncing=2, Bootstrapping=3,
Ready=4, Degraded=5, Stopping=6, Stopped=7

func (*SetStateRequest) Decode

func (m *SetStateRequest) Decode(r *Reader) error

Decode deserializes SetStateRequest from the reader

func (*SetStateRequest) Encode

func (m *SetStateRequest) Encode(buf *Buffer)

Encode serializes SetStateRequest to the buffer

type SetStateResponse

type SetStateResponse struct {
	LastAcceptedID       []byte
	LastAcceptedParentID []byte
	Height               uint64
	Bytes                []byte
	Timestamp            int64
}

SetStateResponse contains state change results

func (*SetStateResponse) Decode

func (m *SetStateResponse) Decode(r *Reader) error

Decode deserializes SetStateResponse from the reader

func (*SetStateResponse) Encode

func (m *SetStateResponse) Encode(buf *Buffer)

Encode serializes SetStateResponse to the buffer

type State

type State uint8

State represents VM state values

const (
	StateUnknown       State = 0
	StateStarting      State = 1
	StateSyncing       State = 2
	StateBootstrapping State = 3
	StateReady         State = 4
	StateDegraded      State = 5
	StateStopping      State = 6
	StateStopped       State = 7
)

type StateSummaryAcceptRequest added in v1.1.5

type StateSummaryAcceptRequest struct {
	ID []byte
}

StateSummaryAcceptRequest names the summary to accept.

By id, because accepting is the summary's own behaviour and the summary is on the far side. The server resolves the id against the summaries it has handed out; an id it never produced is refused rather than reconstructed, since a summary rebuilt from bytes a caller supplies is not the one that was ratified.

func (*StateSummaryAcceptRequest) Decode added in v1.1.5

func (m *StateSummaryAcceptRequest) Decode(r *Reader) error

func (*StateSummaryAcceptRequest) Encode added in v1.1.5

func (m *StateSummaryAcceptRequest) Encode(buf *Buffer)

type StateSummaryAcceptResponse added in v1.1.5

type StateSummaryAcceptResponse struct {
	Mode uint8
	Err  Error
}

StateSummaryAcceptResponse reports which way the VM decided to sync.

func (*StateSummaryAcceptResponse) Decode added in v1.1.5

func (m *StateSummaryAcceptResponse) Decode(r *Reader) error

func (*StateSummaryAcceptResponse) Encode added in v1.1.5

func (m *StateSummaryAcceptResponse) Encode(buf *Buffer)

type StateSyncEnabledResponse added in v1.1.5

type StateSyncEnabledResponse struct {
	Enabled bool
	Err     Error
}

StateSyncEnabledResponse answers whether this VM syncs state at all.

func (*StateSyncEnabledResponse) Decode added in v1.1.5

func (m *StateSyncEnabledResponse) Decode(r *Reader) error

func (*StateSyncEnabledResponse) Encode added in v1.1.5

func (m *StateSyncEnabledResponse) Encode(buf *Buffer)

type SummaryResponse added in v1.1.5

type SummaryResponse struct {
	ID     []byte
	Height uint64
	Bytes  []byte
	Err    Error
}

SummaryResponse carries one state summary: what a caller can read off it without holding the object. Every question that answers with a summary answers with this, because the answers differ only in which summary they name, never in what a summary is.

An absent summary is not an error and not a zero-valued one: Err says ErrorNotFound and the caller must not read the fields. A VM that does not sync state at all says ErrorStateSyncNotImplemented, which is a different answer from "I sync, and have nothing".

func (*SummaryResponse) Decode added in v1.1.5

func (m *SummaryResponse) Decode(r *Reader) error

func (*SummaryResponse) Encode added in v1.1.5

func (m *SummaryResponse) Encode(buf *Buffer)

type VersionResponse

type VersionResponse struct {
	Version string
}

VersionResponse contains version info

func (*VersionResponse) Decode

func (m *VersionResponse) Decode(r *Reader) error

Decode deserializes VersionResponse from the reader

func (*VersionResponse) Encode

func (m *VersionResponse) Encode(buf *Buffer)

Encode serializes VersionResponse to the buffer

type WaitForEventResponse

type WaitForEventResponse struct {
	Message uint8
}

WaitForEventResponse contains event type

func (*WaitForEventResponse) Decode

func (m *WaitForEventResponse) Decode(r *Reader) error

Decode deserializes WaitForEventResponse from the reader

func (*WaitForEventResponse) Encode

func (m *WaitForEventResponse) Encode(buf *Buffer)

Encode serializes WaitForEventResponse to the buffer

type WarpBatchSignRequest

type WarpBatchSignRequest struct {
	Messages []WarpSignRequest
}

WarpBatchSignRequest encodes a batch signing request

func (*WarpBatchSignRequest) Decode

func (r *WarpBatchSignRequest) Decode(rd *Reader) error

Decode reads the request from the reader

func (*WarpBatchSignRequest) Encode

func (r *WarpBatchSignRequest) Encode(buf *Buffer)

Encode writes the request to the buffer

type WarpBatchSignResponse

type WarpBatchSignResponse struct {
	Signatures [][]byte
	Errors     []string
}

WarpBatchSignResponse encodes a batch signing response

func (*WarpBatchSignResponse) Decode

func (r *WarpBatchSignResponse) Decode(rd *Reader) error

Decode reads the response from the reader

func (*WarpBatchSignResponse) Encode

func (r *WarpBatchSignResponse) Encode(buf *Buffer)

Encode writes the response to the buffer

type WarpGetPublicKeyRequest

type WarpGetPublicKeyRequest struct{}

WarpGetPublicKeyRequest encodes a get public key request

func (*WarpGetPublicKeyRequest) Decode

func (r *WarpGetPublicKeyRequest) Decode(rd *Reader) error

Decode reads the request from the reader

func (*WarpGetPublicKeyRequest) Encode

func (r *WarpGetPublicKeyRequest) Encode(buf *Buffer)

Encode writes the request to the buffer

type WarpGetPublicKeyResponse

type WarpGetPublicKeyResponse struct {
	PublicKey []byte
	Error     string
}

WarpGetPublicKeyResponse encodes a get public key response

func (*WarpGetPublicKeyResponse) Decode

func (r *WarpGetPublicKeyResponse) Decode(rd *Reader) error

Decode reads the response from the reader

func (*WarpGetPublicKeyResponse) Encode

func (r *WarpGetPublicKeyResponse) Encode(buf *Buffer)

Encode writes the response to the buffer

type WarpSignRequest

type WarpSignRequest struct {
	NetworkID     uint32
	SourceChainID []byte // 32 bytes
	Payload       []byte
}

WarpSignRequest encodes a warp signing request

func (*WarpSignRequest) Decode

func (r *WarpSignRequest) Decode(rd *Reader) error

Decode reads the request from the reader

func (*WarpSignRequest) Encode

func (r *WarpSignRequest) Encode(buf *Buffer)

Encode writes the request to the buffer

type WarpSignResponse

type WarpSignResponse struct {
	Signature []byte
	Error     string
}

WarpSignResponse encodes a warp signing response

func (*WarpSignResponse) Decode

func (r *WarpSignResponse) Decode(rd *Reader) error

Decode reads the response from the reader

func (*WarpSignResponse) Encode

func (r *WarpSignResponse) Encode(buf *Buffer)

Encode writes the response to the buffer

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL