20 Commits
Author SHA1 Message Date
zeekay 05e7482ac4 run on the native fleet
Adds .hanzo/workflows/cicd.yml calling the canonical pipeline and drops the
GitHub-hosted workflows it replaces. Lands here because this is where the repo
is written — git.hanzo.ai is upstream and github.com is its push mirror, so the
same change made on github.com never reaches the runner fleet.
2026-08-20 20:20:09 -07:00
zeekayandHanzo Dev 31058e5e41 zap: add Indexed to the atomic surface, and stop Serve panicking after Close
Indexed looked superfluous from the C-Chain side — no settlement path calls
it — so the first cut of this surface omitted it. That was wrong. The
D-Chain's autonomous seam drive is built on it: inside BuildBlock it
enumerates pending C->D intents by a fixed discovery trait, recovering each
key from the LastKey cursor, because a shared-memory object does not carry
its own key in its value. Without Indexed the drive finds nothing and no
intent is ever imported, which would have left the seam as dark as it is
today while looking fixed.

Also fixes a shutdown race that a round-trip test surfaced. Close() nils
the conns map under s.mu and Serve's accept loop then assigned into it,
panicking — fatally, since Serve runs on a detached goroutine. Any server
whose stop path is "cancel then Close" with a connection in flight could
hit it, which already includes the node's per-chain rpcdb server. The
regression test forces the interleaving rather than racing for it, and
fails with the exact panic when the guard is removed.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-06 14:21:00 -07:00
zeekayandHanzo Dev 8743bbe098 zap: carry the cross-chain atomic seam across the plugin boundary
One atomic.Memory exists per node and every chain gets a handle carved out
of it. A VM linked into the node reaches its handle off runtime.Runtime; a
VM hosted as a ZAP plugin — the C-Chain EVM and the dexvm both are — does
not, because the node rebuilds the plugin's Runtime from InitializeRequest
fields and neither an interface over a live database (SharedMemory) nor the
chain-alias lookup (BCLookup) survives a struct literal. The plugin's
SharedMemory was therefore nil and every DEX 0x9999 settlement reverted
"requires the cross-chain atomic capability".

Adds the wire for it: MsgAtomicGet/MsgAtomicApply, and AtomicServerAddr +
DChainID appended to InitializeRequest. The node binds a ZAP server over
its own handle and the plugin dials it, so the node is the server and the
existing strictly request/response transport carries this with no duplex
framing and no gRPC — the same shape already used for DBServerAddr.

Indexed is deliberately not proxied: no settlement path calls it.

Both skew directions are pinned by test rather than reasoned about, since a
wire change that forks a mixed fleet is the failure this design exists to
avoid. New node -> old plugin: the appended bytes are inert, the plugin
keeps its nil handle and its existing fail-closed revert. Old node -> new
plugin: Remaining() is 0, so the capability reads as ABSENT instead of
raising the ErrUnexpectedEOF that the Capabilities append once caused.
Neither direction changes how any block executes.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-06 14:08:52 -07:00
zeekayandHanzo Dev 400b37b91d fix(zap): length-tolerant InitializeResponse decode (evolvable VM wire)
InitializeResponse.Decode now reads the trailing Capabilities field only when >=8 bytes remain, so a
newer node decoding a pre-v1.0.16 plugin's short payload yields Capabilities=0 instead of the
unexpected-EOF that broke every EVM Initialize in the v1.36.11 skew (Capabilities appended at protocol
42 without a bump). Appending a future trailing field can no longer EOF-break an older peer. New test
locks the tolerance.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-16 12:31:15 -07:00
zeekayandHanzo Dev eb596a6fb1 zap: infer transport network from addr (unix socket / in-proc fast path)
Dial + Listen now infer the network from the address instead of hardcoding
tcp: a socket path (/tmp/vm.sock, @abstract, or any '/' path) → unix-domain
socket (same-host IPC, no TCP/UDP stack, no ephemeral-port exhaustion); a
host:port → tcp (genuinely remote). Strict backward-compat: existing
127.0.0.1:port addrs still dial tcp. Enables the rpcchainvm same-host fast
path — a co-located plugin VM connects back over a unix socket with zero
plugin-side code change once rebuilt against this api.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-11 23:29:19 -07:00
zeekayandHanzo Dev 8bdf9cbf1b zap: carry the Quasar EXPORT capability across the rpcchainvm boundary (wire)
Two-tier consensus v1.36 splits finality into Nova (local, reorgable accept tip)
and Quasar (⅔-by-stake EXPORT-final). A VM's `finalized`/`safe` tags and its
cross-chain (warp) export gate must resolve to the Quasar height. But the
C-Chain EVM runs as a SEPARATE rpcchainvm plugin process, and nothing carried
the export height across the ZAP boundary — so the whole export tier was dormant
in the real deploy (finalized/safe stuck at genesis).

Wire additions (OPTIONAL, capability-gated — generic VMs are unaffected):
- MsgSetQuasarFinalized (60) / MsgQuasarHeight (61): the two export RPCs. Kept
  < 0x40 so the response/error flags OR in cleanly, grouped after Warp (50-59).
- InitializeResponse.Capabilities (uint64) + CapQuasarExport bit: the plugin
  advertises the export capability in the handshake so the node wires the
  observer only for an export-capable VM. Appended to the struct codec (all four
  encode/decode sites go through the struct methods, so it stays consistent).
- SetQuasarFinalizedRequest / QuasarHeightResponse message structs.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-10 10:14:31 -07:00
zooqueenandHanzo Dev 6e47416df8 refactor(zap): rename InitializeRequest.LuxAssetID -> UTXOAssetID (canonical)
Decomplect step: the primary-network fee asset is canonically UTXOAssetID (named for the function, not the chain), matching runtime.Runtime.UTXOAssetID (runtime v1.1.0). Wire layout is unchanged (positional encoding), so this is source-only and wire-compatible; vm/node consumers switch from req.LuxAssetID to req.UTXOAssetID when they bump to the released api carrying this rename. Kept separate from the ReadCount safety commit.

Co-authored-by: Hanzo Dev <[email protected]>
2026-06-06 20:46:47 -07:00
zooqueenandHanzo Dev 3cce18ef60 fix(zap): bound element counts before make() to stop unbounded-alloc DoS
A decoded uint32 element count fed make([]T,count) before the per-element loop consumed any bytes, so a ~9-byte message with count=0xFFFFFFFF could drive a ~100GB allocation (OOM; the 16MB message cap and handler recover() do not bound it). Add Reader.ReadCount(), which rejects any count exceeding Remaining(), and use it in the 9 collection decoders across vm.go, sender.go, warp.go.

Co-authored-by: Hanzo Dev <[email protected]>
2026-06-06 20:46:47 -07:00
zeekay 83f31044c5 fix: gofmt -s across repo (CI format check) 2026-06-02 11:39:38 -07:00
zeekay f256a553ae decomplect: rip NetworkUpgrades interface + wire struct (16 fork-time fields) from zap/runtime 2026-05-18 23:16:14 -07:00
zeekay a42c840107 zap: add NewListener so any net.Listener can serve ZAP
zap.Listen("tcp", ...) is the common path. NewListener is the
escape hatch that lets a Z-Wing listener (or any other net.Listener
that yields post-handshake net.Conns) feed zap.Server unchanged.

This is the seam zwing.ListenZAP uses to compose a one-call
PQ-on-the-wire ZAP server.
2026-05-06 12:50:29 -07:00
zeekay 6993f40700 docs(zap): canonical TCP port 9999 documented 2026-05-06 10:37:28 -07:00
zeekay d89d3a16e5 docs(zap): call out X-Wing — IETF-standardized X25519+ML-KEM hybrid
X25519 + ML-KEM-768 is the IETF X-Wing construction
(draft-connolly-cfrg-xwing-kem). Document where Lux uses X-Wing
(zap-protocol Rust core, AI-agent ZAP) vs the RNS hybrid (Lux node
sessions with identity-bound handshake). Comparison table added so
new code picks the right one.
2026-05-06 10:23:33 -07:00
zeekay 8ad962dc42 docs(zap): comprehensive LLM.md — wire format, PQ scope, two-implementation reality 2026-05-06 10:21:13 -07:00
zeekay 99631b3b4e fix(zap): correctness — distinct MsgErrorFlag, response flag on success, drop debug stderr
Three real bugs in luxfi/api/zap:

1. Debug fmt.Fprintf(os.Stderr, ...) prints on every wire read/write/
   handler invocation. Visible in production logs as [ZAP-WIRE-READ],
   [ZAP-CLIENT-READ], [ZAP-SERVER-WRITE], [ZAP-HANDLER]. Stripped.

2. Server's success path sent the handler's returned msgType directly
   without OR'ing MsgResponseFlag. Echo-style handlers (return same
   msgType) produced responses that looked like fresh inbound requests
   to the client demultiplexer, which dropped them. Tests caught this
   as 'Expected response type 137, got 9'.

3. Client treated every response as an error because the protocol used
   a single MsgResponseFlag for both success and error paths. Added
   MsgErrorFlag (0x40) — error responses now carry MsgResponseFlag
   AND MsgErrorFlag; success responses carry only MsgResponseFlag.
   All msg types must stay < 0x40 (the existing range 1-52 is fine).
2026-05-06 10:19:43 -07:00
zeekay d24119bc75 feat: add typed State enum to ZAP VM protocol 2026-03-11 12:09:33 -07:00
zeekay f51e8ffb83 debug(zap): add wire-level debug output for Initialize diagnosis
Add temporary stderr debug prints to ReadMessage, readLoop, handleConn,
and ServerConn.Write to capture exact msgType bytes on the wire. This
will reveal why the client sees MsgResponseFlag set on Initialize
responses that the server sends as MsgInitialize (0x01).
2026-02-10 22:07:02 -08:00
zeekay d38045dba5 feat(zap): add error response protocol and concurrent request handling
Add MsgResponseFlag for error responses over the wire, enable concurrent
request dispatch with per-goroutine panic recovery, and simplify State
type to use canonical vm.State. Update consensus dependency to v1.22.67.
2026-02-10 18:54:45 -08:00
zeekay 57d45de11a chore: sync dependencies and format code 2026-02-04 15:46:05 -08:00
zeekay dd2f2c716e Add ZAP wire protocol transport for VM communication
- Add zap/ package with zero-copy binary wire protocol
- Support for VM client/server communication over ZAP
- Wire format: [4-byte length][1-byte message type][payload]
- Includes sender, transport, and VM implementations
2026-01-24 11:39:40 -08:00