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
- Variables
- func PutBuffer(buf *Buffer)
- func WriteMessage(w io.Writer, msgType MessageType, payload []byte) error
- type AtomicApplyRequest
- type AtomicChainRequests
- type AtomicElement
- type AtomicGetRequest
- type AtomicGetResponse
- type AtomicIndexedRequest
- type AtomicIndexedResponse
- type BatchedParseBlockRequest
- type BatchedParseBlockResponse
- type BlockAcceptRequest
- type BlockRejectRequest
- type BlockResponse
- type BlockVerifyRequest
- type BlockVerifyResponse
- type Buffer
- func (b *Buffer) Bytes() []byte
- func (b *Buffer) Grow(n int)
- func (b *Buffer) Len() int
- func (b *Buffer) Reset()
- func (b *Buffer) WriteBool(v bool)
- func (b *Buffer) WriteBytes(data []byte)
- func (b *Buffer) WriteInt32(v int32)
- func (b *Buffer) WriteInt64(v int64)
- func (b *Buffer) WriteString(s string)
- func (b *Buffer) WriteUint8(v uint8)
- func (b *Buffer) WriteUint16(v uint16)
- func (b *Buffer) WriteUint32(v uint32)
- func (b *Buffer) WriteUint64(v uint64)
- type BuildBlockRequest
- type Config
- type Conn
- type ConnectedRequest
- type CreateHandlersResponse
- type DisconnectedRequest
- type Error
- type GetAncestorsRequest
- type GetAncestorsResponse
- type GetBlockIDAtHeightRequest
- type GetBlockIDAtHeightResponse
- type GetBlockRequest
- type GetStateSummaryRequest
- type GossipMsg
- type HTTPHandler
- type Handler
- type HandlerFunc
- type HealthResponse
- type InitializeRequest
- type InitializeResponse
- type Listener
- type MessageType
- type NewHTTPHandlerResponse
- type ParseBlockRequest
- type ParseStateSummaryRequest
- type QuasarHeightResponse
- type Reader
- func (r *Reader) ReadBool() (bool, error)
- func (r *Reader) ReadBytes() ([]byte, error)
- func (r *Reader) ReadCount() (uint32, error)
- func (r *Reader) ReadInt32() (int32, error)
- func (r *Reader) ReadInt64() (int64, error)
- func (r *Reader) ReadString() (string, error)
- func (r *Reader) ReadUint8() (uint8, error)
- func (r *Reader) ReadUint16() (uint16, error)
- func (r *Reader) ReadUint32() (uint32, error)
- func (r *Reader) ReadUint64() (uint64, error)
- func (r *Reader) Remaining() int
- type RequestFailedMsg
- type RequestMsg
- type ResponseMsg
- type SendErrorMsg
- type SendGossipMsg
- type SendRequestMsg
- type SendResponseMsg
- type Server
- type ServerConn
- type SetPreferenceRequest
- type SetQuasarFinalizedRequest
- type SetStateRequest
- type SetStateResponse
- type State
- type StateSummaryAcceptRequest
- type StateSummaryAcceptResponse
- type StateSyncEnabledResponse
- type SummaryResponse
- type VersionResponse
- type WaitForEventResponse
- type WarpBatchSignRequest
- type WarpBatchSignResponse
- type WarpGetPublicKeyRequest
- type WarpGetPublicKeyResponse
- type WarpSignRequest
- type WarpSignResponse
Constants ¶
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 )
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 )
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.
Variables ¶
var ( ErrClosed = errors.New("zap: connection closed") ErrTimeout = errors.New("zap: request timeout") ErrResponseFailed = errors.New("zap: response failed") )
var ( ErrMessageTooLarge = errors.New("zap: message exceeds maximum size") ErrInvalidMessage = errors.New("zap: invalid message format") ErrUnknownType = errors.New("zap: unknown message type") )
var BufferPool = sync.Pool{ New: func() interface{} { return &Buffer{ Data: make([]byte, DefaultBufferSize), } }, }
BufferPool manages reusable buffers to minimize allocations
Functions ¶
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
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
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
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 ¶
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 (*Buffer) WriteBytes ¶
WriteBytes writes a length-prefixed byte slice to the buffer
func (*Buffer) WriteInt32 ¶
WriteInt32 writes an int32 to the buffer (big-endian)
func (*Buffer) WriteInt64 ¶
WriteInt64 writes an int64 to the buffer (big-endian)
func (*Buffer) WriteString ¶
WriteString writes a length-prefixed string to the buffer
func (*Buffer) WriteUint8 ¶
WriteUint8 writes a uint8 to the buffer
func (*Buffer) WriteUint16 ¶
WriteUint16 writes a uint16 to the buffer (big-endian)
func (*Buffer) WriteUint32 ¶
WriteUint32 writes a uint32 to the buffer (big-endian)
func (*Buffer) WriteUint64 ¶
WriteUint64 writes a uint64 to the buffer (big-endian)
type BuildBlockRequest ¶
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 ¶
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 (*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
type ConnectedRequest ¶
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 ¶
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 ¶
GossipMsg contains gossip message
type HTTPHandler ¶
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
// 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 and DChainID 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 NewListener ¶ added in v1.0.10
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
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 // 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 (*Reader) ReadBytes ¶
ReadBytes reads a length-prefixed byte slice (zero-copy - returns slice into original buffer)
func (*Reader) ReadCount ¶ added in v1.0.14
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) ReadString ¶
ReadString reads a length-prefixed string
func (*Reader) ReadUint16 ¶
ReadUint16 reads a uint16 from the buffer (big-endian)
func (*Reader) ReadUint32 ¶
ReadUint32 reads a uint32 from the buffer (big-endian)
func (*Reader) ReadUint64 ¶
ReadUint64 reads a uint64 from the buffer (big-endian)
type RequestFailedMsg ¶
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 ¶
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 ¶
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 ¶
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 ¶
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
type ServerConn ¶
type ServerConn struct {
// contains filtered or unexported fields
}
ServerConn is a server-side ZAP 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 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
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
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
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 ¶
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 ¶
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 ¶
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 ¶
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