Wave 2G-Archive extracted github.com/luxfi/codec/zapcodec into its own top-level module so consumers (proto/zap_codec at the canonical wallet codec construction site) can depend on it without pulling in the soon-to-be-archived luxfi/codec module. Self-contained design: - own sentinel errors (errors.go) - embedded struct-fielder (struct_fielder.go, lifted from codec/reflectcodec) - own packer (packer.go, local little-endian implementation) - external dependency only on luxfi/utils/wrappers for the cross-module Packer type Wire format is byte-identical to codec/zapcodec — extraction is a code-level move, not a wire-format change. Migrated callers: - github.com/luxfi/proto/zap_codec (v1.3.0+) - github.com/luxfi/genesis/builder (post v1.13.12)
3.7 KiB
zapcodec — ZAP-native little-endian reflection codec
What this module is
github.com/luxfi/zapcodec is the standalone reflection-driven codec
that emits the ZAP-native little-endian wire layout consumed by
proto/p, proto/x, proto/p/warp, and the proto/zap_codec Manager wired
into the SDK wallet.
It originated inside github.com/luxfi/codec (as codec/zapcodec) and
was extracted into its own top-level module by the Wave 2G-Archive sweep
once every production caller of luxfi/codec had been migrated away.
The codec module itself is archived at tag v1.1.5; any historical
bench fixture or test that wants to compare against the legacy
linearcodec output pins that frozen tag.
Wire format
| Field shape | Encoding |
|---|---|
uint8/int8/bool |
1 byte |
uint16/int16 |
2 bytes, little-endian |
uint32/int32 |
4 bytes, little-endian |
uint64/int64 |
8 bytes, little-endian |
string |
uint16 LE length prefix + UTF-8 body |
[]byte |
uint32 LE length prefix + raw bytes |
[N]byte |
N raw bytes, no prefix |
[]T (T ≠ byte) |
uint32 LE length prefix + N marshalled elements |
[N]T (T ≠ byte) |
N marshalled elements, no prefix |
struct |
fields emitted in serialize:"true" declaration order |
interface |
uint32 LE registered-type-id + concrete value |
map[K]V |
uint32 LE entry count + key-sorted entries |
*T |
the marshalled T (no nil sentinel — nil is rejected) |
Slice/map length prefixes cap at math.MaxInt32. Interface registration
is sequential — RegisterType assigns IDs 0, 1, 2, … in call order.
SkipRegistrations(n) bumps the counter by n without registering, so
callers can preserve historical slot layouts during a migration.
API
import (
"github.com/luxfi/zapcodec"
"github.com/luxfi/utils/wrappers"
)
c := zapcodec.NewDefault() // honours `serialize:"true"`
_ = c.RegisterType(&MyConcrete{})
p := &wrappers.Packer{MaxSize: 1 << 20}
_ = c.MarshalInto(value, p)
// p.Bytes[:p.Offset] is the wire payload (no outer version prefix)
q := &wrappers.Packer{Bytes: p.Bytes[:p.Offset], MaxSize: 1 << 20}
var out MyType
_ = c.UnmarshalFrom(q, &out)
For the canonical version-prefix outer layer the SDK wallet / proto
consumers use, see github.com/luxfi/proto/zap_codec.NewVersionedManager.
Module boundary
- No
Managertype here. Callers compose the version-prefix outer layer themselves. The canonical Manager wrapper lives atproto/zap_codec. - No comparative tests here. Head-to-head benches vs linearcodec
live at
bench/modes/zap_vs_codec. The standalone module is testable without pulling in the archived codec module. - Single external dependency:
luxfi/utils/wrappers. That's the canonical home of thePackertype that crosses module boundaries on MarshalInto/UnmarshalFrom. Everything else (sentinels, struct-field discovery, interface dispatch) is internal to this module.
History
| Wave | Outcome |
|---|---|
| 2A | proto/p, proto/x deleted codec.Manager — wire format moved to ZAP-native |
| 2D | node/vms/* funneled through node/vms/pcodecs (codec.Manager type alias) |
| 2E | vm/chains/atomic deleted codec — hand-rolled big-endian binary |
| 2F | codec/wrappers → luxfi/utils/wrappers; codec/jsonrpc → luxfi/utils/json; codec/hierarchycodec deleted |
| 2G-Wallet | proto v1.2.1 + sdk v1.17.5 — proto/zap_codec canonical site established; wallet migrated |
| 2G-Genesis | genesis v1.13.12 — genesis builder ZAP-native via staging shim |
| 2G-Internal | proto v1.3.0 + node 1201692215 + coreth 7f195c239 — pcodecs + test mocks + secpfx migrated |
| 2G-Archive | codec/zapcodec → luxfi/zapcodec; codec module archived at v1.1.5 |